From 9be3314f7bca7e91f099d27ca11177639b76b468 Mon Sep 17 00:00:00 2001 From: antstalepresh <36045227+antstalepresh@users.noreply.github.com> Date: Thu, 17 Nov 2022 14:00:41 -0500 Subject: [PATCH] Feature/airdrop (#315) --- app/app.go | 35 +- app/upgrades.go | 12 + app/upgrades/v3/allocations.go | 6 + app/upgrades/v3/upgrades.go | 52 + proto/claim/v1beta1/claim.proto | 38 + proto/claim/v1beta1/genesis.proto | 27 + proto/claim/v1beta1/params.proto | 34 + proto/claim/v1beta1/query.proto | 99 + proto/claim/v1beta1/tx.proto | 57 + proto/vesting/tx.proto | 12 + proto/vesting/vesting.proto | 53 + testutil/cli/cli.go | 14 + testutil/keeper/claim.go | 20 + utils/utils.go | 60 + x/claim/client/cli/cli_test.go | 305 +++ x/claim/client/cli/query.go | 212 ++ x/claim/client/cli/tx.go | 27 + x/claim/client/cli/tx_claim_free_amount.go | 39 + x/claim/client/cli/tx_create_airdrop.go | 53 + x/claim/client/cli/tx_delete_airdrop.go | 39 + .../client/cli/tx_set_airdrop_allocations.go | 57 + x/claim/client/rest/rest.go | 15 + x/claim/genesis_test.go | 73 + x/claim/handler.go | 37 + x/claim/keeper/abci.go | 26 + x/claim/keeper/claim.go | 570 ++++ x/claim/keeper/claim_test.go | 420 +++ x/claim/keeper/genesis.go | 31 + x/claim/keeper/grpc_query.go | 98 + x/claim/keeper/hooks.go | 103 + x/claim/keeper/keeper.go | 41 + x/claim/keeper/keeper_test.go | 93 + x/claim/keeper/msg_server.go | 129 + x/claim/keeper/msg_server_test.go | 135 + x/claim/keeper/params.go | 27 + x/claim/keeper/query.go | 28 + x/claim/module.go | 165 ++ x/claim/spec/01_concepts.md | 14 + x/claim/spec/02_state.md | 45 + x/claim/spec/03_events.md | 15 + x/claim/spec/04_keeper.md | 24 + x/claim/spec/05_react_hooks.md | 12 + x/claim/spec/06_queries.md | 42 + x/claim/spec/07_params.md | 33 + x/claim/spec/README.md | 79 + x/claim/types/claim.pb.go | 562 ++++ x/claim/types/codec.go | 37 + x/claim/types/errors.go | 23 + x/claim/types/events.go | 6 + x/claim/types/expected_keepers.go | 44 + x/claim/types/genesis.go | 40 + x/claim/types/genesis.pb.go | 397 +++ x/claim/types/keys.go | 38 + x/claim/types/msgs.go | 233 ++ x/claim/types/params.go | 14 + x/claim/types/params.pb.go | 728 ++++++ x/claim/types/query.pb.go | 2300 +++++++++++++++++ x/claim/types/query.pb.gw.go | 621 +++++ x/claim/types/tx.pb.go | 2024 +++++++++++++++ x/claim/vesting/client/cli/tx.go | 22 + x/claim/vesting/client/testutil/cli_test.go | 17 + x/claim/vesting/client/testutil/suite.go | 32 + x/claim/vesting/exported/exported.go | 42 + x/claim/vesting/handler.go | 19 + x/claim/vesting/module.go | 133 + x/claim/vesting/msg_server.go | 20 + x/claim/vesting/types/codec.go | 48 + x/claim/vesting/types/common_test.go | 9 + x/claim/vesting/types/constants.go | 12 + x/claim/vesting/types/expected_keepers.go | 13 + x/claim/vesting/types/msgs.go | 1 + x/claim/vesting/types/period.go | 60 + x/claim/vesting/types/test_common.go | 29 + x/claim/vesting/types/tx.pb.go | 87 + x/claim/vesting/types/vesting.pb.go | 1019 ++++++++ x/claim/vesting/types/vesting_account.go | 356 +++ x/claim/vesting/types/vesting_account_test.go | 267 ++ x/stakeibc/keeper/keeper.go | 15 +- x/stakeibc/keeper/msg_server_liquid_stake.go | 1 + x/stakeibc/types/expected_keepers.go | 9 + x/stakeibc/types/hooks.go | 18 + 81 files changed, 12797 insertions(+), 5 deletions(-) create mode 100644 app/upgrades/v3/allocations.go create mode 100644 app/upgrades/v3/upgrades.go create mode 100644 proto/claim/v1beta1/claim.proto create mode 100644 proto/claim/v1beta1/genesis.proto create mode 100644 proto/claim/v1beta1/params.proto create mode 100644 proto/claim/v1beta1/query.proto create mode 100644 proto/claim/v1beta1/tx.proto create mode 100644 proto/vesting/tx.proto create mode 100644 proto/vesting/vesting.proto create mode 100644 testutil/cli/cli.go create mode 100644 testutil/keeper/claim.go create mode 100644 x/claim/client/cli/cli_test.go create mode 100644 x/claim/client/cli/query.go create mode 100644 x/claim/client/cli/tx.go create mode 100644 x/claim/client/cli/tx_claim_free_amount.go create mode 100644 x/claim/client/cli/tx_create_airdrop.go create mode 100644 x/claim/client/cli/tx_delete_airdrop.go create mode 100644 x/claim/client/cli/tx_set_airdrop_allocations.go create mode 100644 x/claim/client/rest/rest.go create mode 100644 x/claim/genesis_test.go create mode 100644 x/claim/handler.go create mode 100644 x/claim/keeper/abci.go create mode 100644 x/claim/keeper/claim.go create mode 100644 x/claim/keeper/claim_test.go create mode 100644 x/claim/keeper/genesis.go create mode 100644 x/claim/keeper/grpc_query.go create mode 100644 x/claim/keeper/hooks.go create mode 100644 x/claim/keeper/keeper.go create mode 100644 x/claim/keeper/keeper_test.go create mode 100644 x/claim/keeper/msg_server.go create mode 100644 x/claim/keeper/msg_server_test.go create mode 100644 x/claim/keeper/params.go create mode 100644 x/claim/keeper/query.go create mode 100644 x/claim/module.go create mode 100644 x/claim/spec/01_concepts.md create mode 100644 x/claim/spec/02_state.md create mode 100644 x/claim/spec/03_events.md create mode 100644 x/claim/spec/04_keeper.md create mode 100644 x/claim/spec/05_react_hooks.md create mode 100644 x/claim/spec/06_queries.md create mode 100644 x/claim/spec/07_params.md create mode 100644 x/claim/spec/README.md create mode 100644 x/claim/types/claim.pb.go create mode 100644 x/claim/types/codec.go create mode 100644 x/claim/types/errors.go create mode 100644 x/claim/types/events.go create mode 100644 x/claim/types/expected_keepers.go create mode 100644 x/claim/types/genesis.go create mode 100644 x/claim/types/genesis.pb.go create mode 100644 x/claim/types/keys.go create mode 100644 x/claim/types/msgs.go create mode 100644 x/claim/types/params.go create mode 100644 x/claim/types/params.pb.go create mode 100644 x/claim/types/query.pb.go create mode 100644 x/claim/types/query.pb.gw.go create mode 100644 x/claim/types/tx.pb.go create mode 100644 x/claim/vesting/client/cli/tx.go create mode 100644 x/claim/vesting/client/testutil/cli_test.go create mode 100644 x/claim/vesting/client/testutil/suite.go create mode 100644 x/claim/vesting/exported/exported.go create mode 100644 x/claim/vesting/handler.go create mode 100644 x/claim/vesting/module.go create mode 100644 x/claim/vesting/msg_server.go create mode 100644 x/claim/vesting/types/codec.go create mode 100644 x/claim/vesting/types/common_test.go create mode 100644 x/claim/vesting/types/constants.go create mode 100644 x/claim/vesting/types/expected_keepers.go create mode 100644 x/claim/vesting/types/msgs.go create mode 100644 x/claim/vesting/types/period.go create mode 100644 x/claim/vesting/types/test_common.go create mode 100644 x/claim/vesting/types/tx.pb.go create mode 100644 x/claim/vesting/types/vesting.pb.go create mode 100644 x/claim/vesting/types/vesting_account.go create mode 100644 x/claim/vesting/types/vesting_account_test.go create mode 100644 x/stakeibc/types/hooks.go diff --git a/app/app.go b/app/app.go index 38abaeabd6..90edc222e9 100644 --- a/app/app.go +++ b/app/app.go @@ -54,6 +54,9 @@ import ( govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + claimvesting "github.com/Stride-Labs/stride/x/claim/vesting" + claimvestingtypes "github.com/Stride-Labs/stride/x/claim/vesting/types" + "github.com/Stride-Labs/stride/x/mint" mintkeeper "github.com/Stride-Labs/stride/x/mint/keeper" minttypes "github.com/Stride-Labs/stride/x/mint/types" @@ -111,6 +114,9 @@ import ( interchainquerykeeper "github.com/Stride-Labs/stride/x/interchainquery/keeper" interchainquerytypes "github.com/Stride-Labs/stride/x/interchainquery/types" + "github.com/Stride-Labs/stride/x/claim" + claimkeeper "github.com/Stride-Labs/stride/x/claim/keeper" + claimtypes "github.com/Stride-Labs/stride/x/claim/types" icacallbacksmodule "github.com/Stride-Labs/stride/x/icacallbacks" icacallbacksmodulekeeper "github.com/Stride-Labs/stride/x/icacallbacks/keeper" icacallbacksmoduletypes "github.com/Stride-Labs/stride/x/icacallbacks/types" @@ -175,6 +181,7 @@ var ( evidence.AppModuleBasic{}, transfer.AppModuleBasic{}, vesting.AppModuleBasic{}, + claimvesting.AppModuleBasic{}, // monitoringp.AppModuleBasic{}, stakeibcmodule.AppModuleBasic{}, epochsmodule.AppModuleBasic{}, @@ -182,6 +189,7 @@ var ( ica.AppModuleBasic{}, recordsmodule.AppModuleBasic{}, icacallbacksmodule.AppModuleBasic{}, + claim.AppModuleBasic{}, // this line is used by starport scaffolding # stargate/app/moduleBasic ) @@ -196,6 +204,7 @@ var ( govtypes.ModuleName: {authtypes.Burner}, ibctransfertypes.ModuleName: {authtypes.Minter, authtypes.Burner}, stakeibcmoduletypes.ModuleName: {authtypes.Minter, authtypes.Burner, authtypes.Staking}, + claimtypes.ModuleName: nil, interchainquerytypes.ModuleName: nil, icatypes.ModuleName: nil, // this line is used by starport scaffolding # stargate/app/maccPerms @@ -269,6 +278,7 @@ type StrideApp struct { RecordsKeeper recordsmodulekeeper.Keeper ScopedIcacallbacksKeeper capabilitykeeper.ScopedKeeper IcacallbacksKeeper icacallbacksmodulekeeper.Keeper + ClaimKeeper claimkeeper.Keeper // this line is used by starport scaffolding # stargate/app/keeperDeclaration mm *module.Manager @@ -310,6 +320,7 @@ func NewStrideApp( icacontrollertypes.StoreKey, icahosttypes.StoreKey, recordsmoduletypes.StoreKey, icacallbacksmoduletypes.StoreKey, + claimtypes.StoreKey, // this line is used by starport scaffolding # stargate/app/storeKey ) tkeys := sdk.NewTransientStoreKeys(paramstypes.TStoreKey) @@ -352,6 +363,7 @@ func NewStrideApp( stakingKeeper := stakingkeeper.NewKeeper( appCodec, keys[stakingtypes.StoreKey], app.AccountKeeper, app.BankKeeper, app.GetSubspace(stakingtypes.ModuleName), ) + epochsKeeper := epochsmodulekeeper.NewKeeper(appCodec, keys[epochsmoduletypes.StoreKey]) app.MintKeeper = mintkeeper.NewKeeper( appCodec, keys[minttypes.StoreKey], app.GetSubspace(minttypes.ModuleName), app.AccountKeeper, app.BankKeeper, app.DistrKeeper, app.EpochsKeeper, authtypes.FeeCollectorName, ) @@ -366,13 +378,19 @@ func NewStrideApp( app.GetSubspace(crisistypes.ModuleName), invCheckPeriod, app.BankKeeper, authtypes.FeeCollectorName, ) + app.ClaimKeeper = *claimkeeper.NewKeeper( + appCodec, + keys[claimtypes.StoreKey], + app.AccountKeeper, + app.BankKeeper, app.StakingKeeper, app.DistrKeeper, epochsKeeper) + app.FeeGrantKeeper = feegrantkeeper.NewKeeper(appCodec, keys[feegrant.StoreKey], app.AccountKeeper) app.UpgradeKeeper = upgradekeeper.NewKeeper(skipUpgradeHeights, keys[upgradetypes.StoreKey], appCodec, homePath, app.BaseApp) // register the staking hooks // NOTE: stakingKeeper above is passed by reference, so that it will contain these hooks app.StakingKeeper = *stakingKeeper.SetHooks( - stakingtypes.NewMultiStakingHooks(app.DistrKeeper.Hooks(), app.SlashingKeeper.Hooks()), + stakingtypes.NewMultiStakingHooks(app.DistrKeeper.Hooks(), app.SlashingKeeper.Hooks(), app.ClaimKeeper.Hooks()), ) // ... other modules keepers @@ -455,7 +473,7 @@ func NewStrideApp( scopedStakeibcKeeper := app.CapabilityKeeper.ScopeToModule(stakeibcmoduletypes.ModuleName) app.ScopedStakeibcKeeper = scopedStakeibcKeeper - app.StakeibcKeeper = stakeibcmodulekeeper.NewKeeper( + stakeibcKeeper := stakeibcmodulekeeper.NewKeeper( appCodec, keys[stakeibcmoduletypes.StoreKey], keys[stakeibcmoduletypes.MemStoreKey], @@ -472,6 +490,9 @@ func NewStrideApp( app.StakingKeeper, app.IcacallbacksKeeper, ) + app.StakeibcKeeper = *stakeibcKeeper.SetHooks( + stakeibcmoduletypes.NewMultiStakeIBCHooks(app.ClaimKeeper.Hooks()), + ) stakeibcModule := stakeibcmodule.NewAppModule(appCodec, app.StakeibcKeeper, app.AccountKeeper, app.BankKeeper) stakeibcIBCModule := stakeibcmodule.NewIBCModule(app.StakeibcKeeper) @@ -496,11 +517,11 @@ func NewStrideApp( return nil } - epochsKeeper := epochsmodulekeeper.NewKeeper(appCodec, keys[epochsmoduletypes.StoreKey]) app.EpochsKeeper = *epochsKeeper.SetHooks( epochsmoduletypes.NewMultiEpochHooks( app.StakeibcKeeper.Hooks(), app.MintKeeper.Hooks(), + app.ClaimKeeper.Hooks(), ), ) epochsModule := epochsmodule.NewAppModule(appCodec, app.EpochsKeeper) @@ -576,6 +597,7 @@ func NewStrideApp( ), auth.NewAppModule(appCodec, app.AccountKeeper, nil), vesting.NewAppModule(app.AccountKeeper, app.BankKeeper), + claimvesting.NewAppModule(app.AccountKeeper, app.BankKeeper), bank.NewAppModule(appCodec, app.BankKeeper, app.AccountKeeper), capability.NewAppModule(appCodec, *app.CapabilityKeeper), feegrantmodule.NewAppModule(appCodec, app.AccountKeeper, app.BankKeeper, app.FeeGrantKeeper, app.interfaceRegistry), @@ -589,6 +611,7 @@ func NewStrideApp( evidence.NewAppModule(app.EvidenceKeeper), ibc.NewAppModule(app.IBCKeeper), params.NewAppModule(app.ParamsKeeper), + claim.NewAppModule(appCodec, app.ClaimKeeper), transferModule, // monitoringModule, stakeibcModule, @@ -613,6 +636,7 @@ func NewStrideApp( evidencetypes.ModuleName, stakingtypes.ModuleName, vestingtypes.ModuleName, + claimvestingtypes.ModuleName, ibchost.ModuleName, ibctransfertypes.ModuleName, authtypes.ModuleName, @@ -629,6 +653,7 @@ func NewStrideApp( interchainquerytypes.ModuleName, recordsmoduletypes.ModuleName, icacallbacksmoduletypes.ModuleName, + claimtypes.ModuleName, // this line is used by starport scaffolding # stargate/app/beginBlockers ) @@ -642,6 +667,7 @@ func NewStrideApp( distrtypes.ModuleName, slashingtypes.ModuleName, vestingtypes.ModuleName, + claimvestingtypes.ModuleName, minttypes.ModuleName, genutiltypes.ModuleName, evidencetypes.ModuleName, @@ -657,6 +683,7 @@ func NewStrideApp( interchainquerytypes.ModuleName, recordsmoduletypes.ModuleName, icacallbacksmoduletypes.ModuleName, + claimtypes.ModuleName, // this line is used by starport scaffolding # stargate/app/endBlockers ) @@ -672,6 +699,7 @@ func NewStrideApp( distrtypes.ModuleName, stakingtypes.ModuleName, vestingtypes.ModuleName, + claimvestingtypes.ModuleName, slashingtypes.ModuleName, govtypes.ModuleName, minttypes.ModuleName, @@ -690,6 +718,7 @@ func NewStrideApp( interchainquerytypes.ModuleName, recordsmoduletypes.ModuleName, icacallbacksmoduletypes.ModuleName, + claimtypes.ModuleName, // this line is used by starport scaffolding # stargate/app/initGenesis ) diff --git a/app/upgrades.go b/app/upgrades.go index 344c451bd4..051bc2a692 100644 --- a/app/upgrades.go +++ b/app/upgrades.go @@ -7,6 +7,8 @@ import ( upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" v2 "github.com/Stride-Labs/stride/app/upgrades/v2" + v3 "github.com/Stride-Labs/stride/app/upgrades/v3" + claimtypes "github.com/Stride-Labs/stride/x/claim/types" ) func (app *StrideApp) setupUpgradeHandlers() { @@ -16,6 +18,12 @@ func (app *StrideApp) setupUpgradeHandlers() { v2.CreateUpgradeHandler(app.mm, app.configurator), ) + // v3 upgrade handler + app.UpgradeKeeper.SetUpgradeHandler( + v3.UpgradeName, + v3.CreateUpgradeHandler(app.mm, app.configurator, app.ClaimKeeper), + ) + upgradeInfo, err := app.UpgradeKeeper.ReadUpgradeInfoFromDisk() if err != nil { panic(fmt.Errorf("Failed to read upgrade info from disk: %w", err)) @@ -29,6 +37,10 @@ func (app *StrideApp) setupUpgradeHandlers() { switch upgradeInfo.Name { // no store upgrades + case "v3": + storeUpgrades = &storetypes.StoreUpgrades{ + Added: []string{claimtypes.StoreKey}, + } } if storeUpgrades != nil { diff --git a/app/upgrades/v3/allocations.go b/app/upgrades/v3/allocations.go new file mode 100644 index 0000000000..73cbc189e4 --- /dev/null +++ b/app/upgrades/v3/allocations.go @@ -0,0 +1,6 @@ +package v3 + +// allocation data for airdrop users in csv format +var allocations = `identifier,address,weight +stride,stride1g7yxhuppp5x3yqkah5mw29eqq5s4sv2f222xmk,0.5 +stride,stride1h4astdfzjhcwahtfrh24qtvndzzh49xvqtfftk,0.3` diff --git a/app/upgrades/v3/upgrades.go b/app/upgrades/v3/upgrades.go new file mode 100644 index 0000000000..3dd3f6ca99 --- /dev/null +++ b/app/upgrades/v3/upgrades.go @@ -0,0 +1,52 @@ +package v3 + +import ( + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" + + claimkeeper "github.com/Stride-Labs/stride/x/claim/keeper" + claimtypes "github.com/Stride-Labs/stride/x/claim/types" +) + +// Note: ensure these values are properly set before running upgrade +var ( + UpgradeName = "v3" + airdropDistributors = []string{ + "stride1thl8e7smew8q7jrz8at4f64wrjjl8mwan3nc4l", + "stride104az7rd5yh3p8qn4ary8n3xcwquuwgee4vnvvc", + "stride17kvetgthwt6caku5qjs2rx2njgh26vmg448r5u", + "stride1swvv9kpp75e60pvlv5x6mcw5f54qgpph239e5s", + "stride1ywrhas3ae7z3ljqxmgdzjx8wyaf3djwuh4hdlj", + } + airdropIdentifiers = []string{"stride", "gaia", "osmosis", "juno", "stars"} + airdropDuration = time.Hour * 24 * 30 * 12 * 3 // 3 years +) + +// CreateUpgradeHandler creates an SDK upgrade handler for v3 +func CreateUpgradeHandler( + mm *module.Manager, + configurator module.Configurator, + ck claimkeeper.Keeper, +) upgradetypes.UpgradeHandler { + return func(ctx sdk.Context, _ upgradetypes.Plan, vm module.VersionMap) (module.VersionMap, error) { + newVm, err := mm.RunMigrations(ctx, configurator, vm) + if err != nil { + return newVm, err + } + + // total number of airdrop distributors must be equal to identifiers + if len(airdropDistributors) == len(airdropIdentifiers) { + for idx, airdropDistributor := range airdropDistributors { + err = ck.CreateAirdropAndEpoch(ctx, airdropDistributor, claimtypes.DefaultClaimDenom, uint64(ctx.BlockTime().Unix()), uint64(airdropDuration.Seconds()), airdropIdentifiers[idx]) + if err != nil { + return newVm, err + } + } + } + ck.LoadAllocationData(ctx, allocations) + return newVm, nil + } +} diff --git a/proto/claim/v1beta1/claim.proto b/proto/claim/v1beta1/claim.proto new file mode 100644 index 0000000000..8ca285d962 --- /dev/null +++ b/proto/claim/v1beta1/claim.proto @@ -0,0 +1,38 @@ +syntax = "proto3"; +package Stridelabs.stride.claim.v1beta1; + +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "cosmos/bank/v1beta1/genesis.proto"; + +option go_package = "github.com/Stride-Labs/stride/x/claim/types"; + +enum Action { + option (gogoproto.goproto_enum_prefix) = false; + + ActionFree = 0; + ActionLiquidStake = 1; + ActionDelegateStake = 2; +} + +// A Claim Records is the metadata of claim data per address +message ClaimRecord { + // airdrop identifier + string airdrop_identifier = 1 [ (gogoproto.moretags) = "yaml:\"airdrop_identifier\"" ]; + + // address of claim user + string address = 2 [ (gogoproto.moretags) = "yaml:\"address\"" ]; + + // weight that represent the portion from total allocation + string weight = 3 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false, + (gogoproto.moretags) = "yaml:\"weight\"" + ]; + + // true if action is completed + // index of bool in array refers to action enum # + repeated bool action_completed = 4 [ + (gogoproto.moretags) = "yaml:\"action_completed\"" + ]; +} \ No newline at end of file diff --git a/proto/claim/v1beta1/genesis.proto b/proto/claim/v1beta1/genesis.proto new file mode 100644 index 0000000000..7939dffdcf --- /dev/null +++ b/proto/claim/v1beta1/genesis.proto @@ -0,0 +1,27 @@ +syntax = "proto3"; +package Stridelabs.stride.claim.v1beta1; + +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "cosmos/bank/v1beta1/genesis.proto"; +import "google/protobuf/duration.proto"; +import "google/protobuf/timestamp.proto"; +import "claim/v1beta1/claim.proto"; +import "claim/v1beta1/params.proto"; + +option go_package = "github.com/Stride-Labs/stride/x/claim/types"; + +// GenesisState defines the claim module's genesis state. +message GenesisState { + // params defines all the parameters of the module. + Params params = 1 [ + (gogoproto.moretags) = "yaml:\"params\"", + (gogoproto.nullable) = false + ]; + + // list of claim records, one for every airdrop recipient + repeated ClaimRecord claim_records = 2 [ + (gogoproto.moretags) = "yaml:\"claim_records\"", + (gogoproto.nullable) = false + ]; +} diff --git a/proto/claim/v1beta1/params.proto b/proto/claim/v1beta1/params.proto new file mode 100644 index 0000000000..ae6e9fe171 --- /dev/null +++ b/proto/claim/v1beta1/params.proto @@ -0,0 +1,34 @@ +syntax = "proto3"; +package Stridelabs.stride.claim.v1beta1; + +import "gogoproto/gogo.proto"; +import "google/protobuf/duration.proto"; +import "google/protobuf/timestamp.proto"; + +option go_package = "github.com/Stride-Labs/stride/x/claim/types"; + +// Params defines the claim module's parameters. +message Params { + repeated Airdrop airdrops = 1; +} + +message Airdrop { + string airdrop_identifier = 1 [ (gogoproto.moretags) = "yaml:\"airdrop_identifier\"" ]; + // seconds + google.protobuf.Timestamp airdrop_start_time = 2 [ + (gogoproto.stdtime) = true, + (gogoproto.nullable) = false, + (gogoproto.moretags) = "yaml:\"airdrop_start_time\"" + ]; + // seconds + google.protobuf.Duration airdrop_duration = 3 [ + (gogoproto.nullable) = false, + (gogoproto.stdduration) = true, + (gogoproto.jsontag) = "airdrop_duration,omitempty", + (gogoproto.moretags) = "yaml:\"airdrop_duration\"" + ]; + // denom of claimable asset + string claim_denom = 4; + // airdrop distribution account + string distributor_address = 5; +} \ No newline at end of file diff --git a/proto/claim/v1beta1/query.proto b/proto/claim/v1beta1/query.proto new file mode 100644 index 0000000000..f9b7bdbac2 --- /dev/null +++ b/proto/claim/v1beta1/query.proto @@ -0,0 +1,99 @@ +syntax = "proto3"; +package Stridelabs.stride.claim.v1beta1; + +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "claim/v1beta1/claim.proto"; +import "claim/v1beta1/params.proto"; + +option go_package = "github.com/Stride-Labs/stride/x/claim/types"; + +// Query defines the gRPC querier service. +service Query { + rpc DistributorAccountBalance(QueryDistributorAccountBalanceRequest) + returns (QueryDistributorAccountBalanceResponse) { + option (google.api.http).get = + "/claim/v1beta1/module_account_balance"; + } + rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { + option (google.api.http).get = "/claim/v1beta1/params"; + } + rpc ClaimRecord(QueryClaimRecordRequest) returns (QueryClaimRecordResponse) { + option (google.api.http).get = + "/claim/v1beta1/claim_record/{address}"; + } + rpc ClaimableForAction(QueryClaimableForActionRequest) + returns (QueryClaimableForActionResponse) { + option (google.api.http).get = + "/claim/v1beta1/claimable_for_action/{address}/{action}"; + } + rpc TotalClaimable(QueryTotalClaimableRequest) + returns (QueryTotalClaimableResponse) { + option (google.api.http).get = + "/claim/v1beta1/total_claimable/{address}"; + } +} + +// QueryParamsRequest is the request type for the Query/Params RPC method. +message QueryDistributorAccountBalanceRequest { + string airdrop_identifier = 1 [ (gogoproto.moretags) = "yaml:\"airdrop_identifier\"" ]; +} + +// QueryParamsResponse is the response type for the Query/Params RPC method. +message QueryDistributorAccountBalanceResponse { + // params defines the parameters of the module. + repeated cosmos.base.v1beta1.Coin distributor_account_balance = 1 [ + (gogoproto.moretags) = "yaml:\"distributor_account_balance\"", + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" + ]; +} + +// QueryParamsRequest is the request type for the Query/Params RPC method. +message QueryParamsRequest {} + +// QueryParamsResponse is the response type for the Query/Params RPC method. +message QueryParamsResponse { + // params defines the parameters of the module. + Params params = 1 [ (gogoproto.nullable) = false ]; +} + +message QueryClaimRecordRequest { + string airdrop_identifier = 1 [ (gogoproto.moretags) = "yaml:\"airdrop_identifier\"" ]; + string address = 2 [ (gogoproto.moretags) = "yaml:\"address\"" ]; +} + +message QueryClaimRecordResponse { + ClaimRecord claim_record = 1 [ + (gogoproto.moretags) = "yaml:\"claim_record\"", + (gogoproto.nullable) = false + ]; +} + +message QueryClaimableForActionRequest { + string airdrop_identifier = 1 [ (gogoproto.moretags) = "yaml:\"airdrop_identifier\"" ]; + string address = 2 [ (gogoproto.moretags) = "yaml:\"address\"" ]; + Action action = 3 [ (gogoproto.moretags) = "yaml:\"action\"" ]; +} + +message QueryClaimableForActionResponse { + repeated cosmos.base.v1beta1.Coin coins = 1 [ + (gogoproto.moretags) = "yaml:\"coins\"", + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" + ]; +} + +message QueryTotalClaimableRequest { + string airdrop_identifier = 1 [ (gogoproto.moretags) = "yaml:\"airdrop_identifier\"" ]; + string address = 2 [ (gogoproto.moretags) = "yaml:\"address\"" ]; +} + +message QueryTotalClaimableResponse { + repeated cosmos.base.v1beta1.Coin coins = 1 [ + (gogoproto.moretags) = "yaml:\"coins\"", + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" + ]; +} \ No newline at end of file diff --git a/proto/claim/v1beta1/tx.proto b/proto/claim/v1beta1/tx.proto new file mode 100644 index 0000000000..c1f5620113 --- /dev/null +++ b/proto/claim/v1beta1/tx.proto @@ -0,0 +1,57 @@ +syntax = "proto3"; +package Stridelabs.stride.claim.v1beta1; + +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; + +option go_package = "github.com/Stride-Labs/stride/x/claim/types"; + +// Msg defines the Msg service. +service Msg { + rpc SetAirdropAllocations(MsgSetAirdropAllocations) returns (MsgSetAirdropAllocationsResponse); + rpc ClaimFreeAmount(MsgClaimFreeAmount) returns (MsgClaimFreeAmountResponse); + rpc CreateAirdrop(MsgCreateAirdrop) returns (MsgCreateAirdropResponse); + rpc DeleteAirdrop(MsgDeleteAirdrop) returns (MsgDeleteAirdropResponse); +} + +message MsgSetAirdropAllocations { + string allocator = 1; + string airdrop_identifier = 2 [ (gogoproto.moretags) = "yaml:\"airdrop_identifier\"" ]; + repeated string users = 3; + repeated string weights = 4 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false, + (gogoproto.moretags) = "yaml:\"weights\"" + ]; +} + +message MsgSetAirdropAllocationsResponse {} + +message MsgClaimFreeAmount { + string user = 1; + string airdrop_identifier = 2 [ (gogoproto.moretags) = "yaml:\"airdrop_identifier\"" ]; +} + +message MsgClaimFreeAmountResponse { + repeated cosmos.base.v1beta1.Coin claimed_amount = 3 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" + ]; +} + +message MsgCreateAirdrop { + string distributor = 1; + string identifier = 2; + uint64 start_time = 3; + uint64 duration = 4; + string denom = 5; +} + +message MsgCreateAirdropResponse {} + +message MsgDeleteAirdrop { + string distributor = 1; + string identifier = 2; +} + +message MsgDeleteAirdropResponse {} diff --git a/proto/vesting/tx.proto b/proto/vesting/tx.proto new file mode 100644 index 0000000000..dbb5a3fde7 --- /dev/null +++ b/proto/vesting/tx.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; +package Stridelabs.stride.vesting; + +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "cosmos/auth/v1beta1/auth.proto"; + +option go_package = "github.com/Stride-Labs/stride/x/claim/vesting/types"; + +// Msg defines the bank Msg service. +service Msg { +} diff --git a/proto/vesting/vesting.proto b/proto/vesting/vesting.proto new file mode 100644 index 0000000000..c464aefbfd --- /dev/null +++ b/proto/vesting/vesting.proto @@ -0,0 +1,53 @@ +syntax = "proto3"; +package Stridelabs.stride.vesting; + +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "cosmos/auth/v1beta1/auth.proto"; + +option go_package = "github.com/Stride-Labs/stride/x/claim/vesting/types"; + +// BaseVestingAccount implements the VestingAccount interface. It contains all +// the necessary fields needed for any vesting account implementation. +message BaseVestingAccount { + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + + cosmos.auth.v1beta1.BaseAccount base_account = 1 [(gogoproto.embed) = true]; + repeated cosmos.base.v1beta1.Coin original_vesting = 2 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", + (gogoproto.moretags) = "yaml:\"original_vesting\"" + ]; + repeated cosmos.base.v1beta1.Coin delegated_free = 3 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", + (gogoproto.moretags) = "yaml:\"delegated_free\"" + ]; + repeated cosmos.base.v1beta1.Coin delegated_vesting = 4 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", + (gogoproto.moretags) = "yaml:\"delegated_vesting\"" + ]; + int64 end_time = 5 [(gogoproto.moretags) = "yaml:\"end_time\""]; +} + +// Period defines a length of time and amount of coins that will vest. +message Period { + option (gogoproto.goproto_stringer) = false; + + int64 start_time = 1; + int64 length = 2; + repeated cosmos.base.v1beta1.Coin amount = 3 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; +} + +// StridePeriodicVestingAccount implements the VestingAccount interface. It +// periodically vests by unlocking coins during each specified period. +message StridePeriodicVestingAccount { + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + + BaseVestingAccount base_vesting_account = 1 [(gogoproto.embed) = true]; + repeated Period vesting_periods = 3 [(gogoproto.moretags) = "yaml:\"vesting_periods\"", (gogoproto.nullable) = false]; +} diff --git a/testutil/cli/cli.go b/testutil/cli/cli.go new file mode 100644 index 0000000000..5cd72443d5 --- /dev/null +++ b/testutil/cli/cli.go @@ -0,0 +1,14 @@ +package cli + +import ( + "fmt" + + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/testutil/network" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func DefaultFeeString(cfg network.Config) string { + feeCoins := sdk.NewCoins(sdk.NewCoin(cfg.BondDenom, sdk.NewInt(10))) + return fmt.Sprintf("--%s=%s", flags.FlagFees, feeCoins.String()) +} diff --git a/testutil/keeper/claim.go b/testutil/keeper/claim.go new file mode 100644 index 0000000000..8944b21c2e --- /dev/null +++ b/testutil/keeper/claim.go @@ -0,0 +1,20 @@ +package keeper + +import ( + "testing" + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + + strideapp "github.com/Stride-Labs/stride/app" + "github.com/Stride-Labs/stride/x/claim/keeper" +) + +func ClaimKeeper(t testing.TB) (*keeper.Keeper, sdk.Context) { + app := strideapp.InitStrideTestApp(true) + claimKeeper := app.ClaimKeeper + ctx := app.BaseApp.NewContext(false, tmproto.Header{Height: 1, ChainID: "stride-1", Time: time.Now().UTC()}) + + return &claimKeeper, ctx +} diff --git a/utils/utils.go b/utils/utils.go index 7cd31b102e..01688f8651 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -7,11 +7,13 @@ import ( "strconv" "strings" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/address" "github.com/cosmos/cosmos-sdk/types/bech32" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + config "github.com/Stride-Labs/stride/cmd/strided/config" recordstypes "github.com/Stride-Labs/stride/x/records/types" ) @@ -152,6 +154,49 @@ func AccAddressFromBech32(address string, bech32prefix string) (addr AccAddress, return AccAddress(bz), nil } +//============================== AIRDROP UTILS ================================ +// max64 returns the maximum of its inputs. +func Max64(i, j int64) int64 { + if i > j { + return i + } + return j +} + +// Min64 returns the minimum of its inputs. +func Min64(i, j int64) int64 { + if i < j { + return i + } + return j +} + +// Compute coin amount for specific period using linear vesting calculation algorithm. +func GetVestedCoinsAt(vAt int64, vStart int64, vLength int64, vCoins sdk.Coins) sdk.Coins { + var vestedCoins sdk.Coins + + if vAt < 0 || vStart < 0 || vLength < 0 { + return sdk.Coins{} + } + + vEnd := vStart + vLength + if vAt <= vStart { + return sdk.Coins{} + } else if vAt >= vEnd { + return vCoins + } + + // calculate the vesting scalar + portion := sdk.NewDec(vAt - vStart).Quo(sdk.NewDec(vLength)) + + for _, ovc := range vCoins { + vestedAmt := ovc.Amount.ToDec().Mul(portion).RoundInt() + vestedCoins = append(vestedCoins, sdk.NewCoin(ovc.Denom, vestedAmt)) + } + + return vestedCoins +} + // check string array inclusion func ContainsString(s []string, e string) bool { for _, a := range s { @@ -161,3 +206,18 @@ func ContainsString(s []string, e string) bool { } return false } + +// Convert any bech32 to stride address +func ConvertAddressToStrideAddress(address string) string { + _, bz, err := bech32.DecodeAndConvert(address) + if err != nil { + return "" + } + + bech32Addr, err := bech32.ConvertAndEncode(config.Bech32PrefixAccAddr, bz) + if err != nil { + return "" + } + + return bech32Addr +} diff --git a/x/claim/client/cli/cli_test.go b/x/claim/client/cli/cli_test.go new file mode 100644 index 0000000000..74d5514ec6 --- /dev/null +++ b/x/claim/client/cli/cli_test.go @@ -0,0 +1,305 @@ +package cli_test + +import ( + // "fmt" + "fmt" + "strconv" + "testing" + "time" + + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/crypto/hd" + "github.com/cosmos/cosmos-sdk/crypto/keyring" + "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" + + clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" + banktestutil "github.com/cosmos/cosmos-sdk/x/bank/client/testutil" + + strideclitestutil "github.com/Stride-Labs/stride/testutil/cli" + + "github.com/Stride-Labs/stride/testutil/network" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/suite" + + tmcli "github.com/tendermint/tendermint/libs/cli" + + "github.com/Stride-Labs/stride/x/claim/client/cli" + + "github.com/Stride-Labs/stride/app" + cmdcfg "github.com/Stride-Labs/stride/cmd/strided/config" + "github.com/Stride-Labs/stride/x/claim/types" + claimtypes "github.com/Stride-Labs/stride/x/claim/types" +) + +var addr1 sdk.AccAddress +var addr2 sdk.AccAddress +var distributorMnemonics []string +var distributorAddrs []string + +func init() { + cmdcfg.SetupConfig() + addr1 = ed25519.GenPrivKey().PubKey().Address().Bytes() + addr2 = ed25519.GenPrivKey().PubKey().Address().Bytes() + distributorMnemonics = []string{ + "chronic learn inflict great answer reward evidence stool open moon skate resource arch raccoon decade tell improve stay onion section blouse carry primary fabric", + "catalog govern other escape eye resemble dirt hundred birth build dirt jacket network blame credit palace similar carry knock auction exotic bus business machine", + } + + distributorAddrs = []string{ + "stride1ajerf2nmxsg0u728ga7665fmlfguqxcd8e36vf", + "stride1zkfk3q70ranm3han4lvutvcvetncxg829j972a", + } +} + +type IntegrationTestSuite struct { + suite.Suite + + cfg network.Config + network *network.Network +} + +func (s *IntegrationTestSuite) SetupSuite() { + s.T().Log("setting up integration test suite") + + s.cfg = network.DefaultConfig() + + genState := app.ModuleBasics.DefaultGenesis(s.cfg.Codec) + claimGenState := claimtypes.DefaultGenesis() + claimGenState.ClaimRecords = []types.ClaimRecord{ + { + Address: addr2.String(), + Weight: sdk.NewDecWithPrec(50, 2), // 50% + ActionCompleted: []bool{false, false, false}, + AirdropIdentifier: claimtypes.DefaultAirdropIdentifier, + }, + } + claimGenStateBz := s.cfg.Codec.MustMarshalJSON(claimGenState) + genState[claimtypes.ModuleName] = claimGenStateBz + + s.cfg.GenesisState = genState + s.network = network.New(s.T(), s.cfg) + + _, err := s.network.WaitForHeight(1) + s.Require().NoError(err) + + // Initiate distributor accounts + val := s.network.Validators[0] + for idx := range distributorMnemonics { + info, _ := val.ClientCtx.Keyring.NewAccount("distributor"+strconv.Itoa(idx), distributorMnemonics[idx], keyring.DefaultBIP39Passphrase, sdk.FullFundraiserPath, hd.Secp256k1) + distributorAddr := sdk.AccAddress(info.GetPubKey().Address()) + _, err = banktestutil.MsgSendExec( + val.ClientCtx, + val.Address, + distributorAddr, + sdk.NewCoins(sdk.NewInt64Coin(s.cfg.BondDenom, 1020)), fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), + strideclitestutil.DefaultFeeString(s.cfg), + ) + s.Require().NoError(err) + } + + // Create a new airdrop + cmd := cli.CmdCreateAirdrop() + clientCtx := val.ClientCtx + + _, err = clitestutil.ExecTestCLICmd(clientCtx, cmd, []string{ + claimtypes.DefaultAirdropIdentifier, + strconv.Itoa(int(time.Now().Unix())), + strconv.Itoa(int(claimtypes.DefaultAirdropDuration.Seconds())), + s.cfg.BondDenom, + fmt.Sprintf("--%s=json", tmcli.OutputFlag), + fmt.Sprintf("--%s=%s", flags.FlagFrom, distributorAddrs[0]), + // common args + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), + strideclitestutil.DefaultFeeString(s.cfg), + }) + + s.Require().NoError(err) +} + +func (s *IntegrationTestSuite) TearDownSuite() { + // s.T().Log("tearing down integration test suite") + // s.network.Cleanup() +} + +func (s *IntegrationTestSuite) TestCmdQueryClaimRecord() { + val := s.network.Validators[0] + + testCases := []struct { + name string + args []string + }{ + { + "query claim record", + []string{ + claimtypes.DefaultAirdropIdentifier, + addr1.String(), + fmt.Sprintf("--%s=json", tmcli.OutputFlag), + }, + }, + } + + for _, tc := range testCases { + tc := tc + + s.Run(tc.name, func() { + cmd := cli.GetCmdQueryClaimRecord() + clientCtx := val.ClientCtx + + out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) + s.Require().NoError(err) + + var result types.QueryClaimRecordResponse + s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &result)) + }) + } +} + +func (s *IntegrationTestSuite) TestCmdTxSetAirdropAllocations() { + val := s.network.Validators[0] + + claimRecords := []claimtypes.ClaimRecord{ + { + Address: "stride1k8g9sagjpdwreqqf0qgqmd46l37595ea5ft9x6", + Weight: sdk.NewDecWithPrec(50, 2), // 50% + ActionCompleted: []bool{false, false, false}, + AirdropIdentifier: claimtypes.DefaultAirdropIdentifier, + }, + { + Address: "stride1av5lwh0msnafn04xkhdyk6mrykxthrawy7uf3d", + Weight: sdk.NewDecWithPrec(30, 2), // 30% + ActionCompleted: []bool{false, false, false}, + AirdropIdentifier: claimtypes.DefaultAirdropIdentifier, + }, + } + + testCases := []struct { + name string + args []string + expClaimableAmounts []sdk.Coins + }{ + { + "set-airdrop-allocations tx", + []string{ + claimtypes.DefaultAirdropIdentifier, + fmt.Sprintf("%s,%s", claimRecords[0].Address, claimRecords[1].Address), + fmt.Sprintf("%s,%s", claimRecords[0].Weight.String(), claimRecords[1].Weight.String()), + fmt.Sprintf("--%s=json", tmcli.OutputFlag), + fmt.Sprintf("--%s=%s", flags.FlagFrom, distributorAddrs[0]), + // common args + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), + strideclitestutil.DefaultFeeString(s.cfg), + }, + []sdk.Coins{ + sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(77))), + sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(46))), + }, + }, + } + + for _, tc := range testCases { + tc := tc + + s.Run(tc.name, func() { + cmd := cli.CmdSetAirdropAllocations() + clientCtx := val.ClientCtx + + _, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) + s.Require().NoError(err) + + // Check if claim record is properly set + cmd = cli.GetCmdQueryClaimRecord() + out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, []string{ + claimtypes.DefaultAirdropIdentifier, + claimRecords[0].Address, + fmt.Sprintf("--%s=json", tmcli.OutputFlag), + }) + s.Require().NoError(err) + + var result types.QueryClaimRecordResponse + s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &result)) + s.Require().Equal(result.ClaimRecord.String(), claimRecords[0].String()) + + // Check if claimable amount for actions is correct + cmd = cli.GetCmdQueryClaimableForAction() + clientCtx = val.ClientCtx + + out, err = clitestutil.ExecTestCLICmd(clientCtx, cmd, []string{ + claimtypes.DefaultAirdropIdentifier, + claimRecords[0].Address, + types.ActionFree.String(), + fmt.Sprintf("--%s=json", tmcli.OutputFlag), + }) + s.Require().NoError(err) + + var result1 types.QueryClaimableForActionResponse + s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &result1)) + s.Require().Equal(tc.expClaimableAmounts[0].String(), result1.Coins.String()) + }) + } +} + +func (s *IntegrationTestSuite) TestCmdTxCreateAirdrop() { + val := s.network.Validators[0] + + airdrop := claimtypes.Airdrop{ + AirdropIdentifier: "stride-1", + AirdropStartTime: time.Now(), + AirdropDuration: claimtypes.DefaultAirdropDuration, + DistributorAddress: distributorAddrs[1], + ClaimDenom: claimtypes.DefaultClaimDenom, + } + + testCases := []struct { + name string + args []string + expAirdrop claimtypes.Airdrop + }{ + { + "create-airdrop tx", + []string{ + "stride-1", + strconv.Itoa(int(time.Now().Unix())), + strconv.Itoa(int(claimtypes.DefaultAirdropDuration.Seconds())), + s.cfg.BondDenom, + fmt.Sprintf("--%s=json", tmcli.OutputFlag), + fmt.Sprintf("--%s=%s", flags.FlagFrom, distributorAddrs[1]), + // common args + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), + strideclitestutil.DefaultFeeString(s.cfg), + }, + airdrop, + }, + } + + for _, tc := range testCases { + tc := tc + + s.Run(tc.name, func() { + cmd := cli.CmdCreateAirdrop() + clientCtx := val.ClientCtx + + _, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) + s.Require().NoError(err) + + // Check if airdrop was created properly + cmd = cli.GetCmdQueryParams() + out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, []string{ + fmt.Sprintf("--%s=json", tmcli.OutputFlag), + }) + s.Require().NoError(err) + + var result types.Params + s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &result)) + s.Require().Equal(tc.expAirdrop.AirdropDuration, result.Airdrops[1].AirdropDuration) + }) + } +} + +func TestIntegrationTestSuite(t *testing.T) { + suite.Run(t, new(IntegrationTestSuite)) +} diff --git a/x/claim/client/cli/query.go b/x/claim/client/cli/query.go new file mode 100644 index 0000000000..4bc1462c7d --- /dev/null +++ b/x/claim/client/cli/query.go @@ -0,0 +1,212 @@ +package cli + +import ( + "context" + "fmt" + "strings" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/version" + "github.com/spf13/cobra" + + "github.com/Stride-Labs/stride/x/claim/types" +) + +// GetQueryCmd returns the cli query commands for this module +func GetQueryCmd(queryRoute string) *cobra.Command { + claimQueryCmd := &cobra.Command{ + Use: types.ModuleName, + Short: fmt.Sprintf("Querying commands for the %s module", types.ModuleName), + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + + claimQueryCmd.AddCommand( + GetCmdQueryDistributorAccountBalance(), + GetCmdQueryParams(), + GetCmdQueryClaimRecord(), + GetCmdQueryClaimableForAction(), + GetCmdQueryTotalClaimable(), + ) + + return claimQueryCmd +} + +// GetCmdQueryParams implements a command to return the current minting +// parameters. +func GetCmdQueryDistributorAccountBalance() *cobra.Command { + cmd := &cobra.Command{ + Use: "distributor-account-balance [airdrop-identifier]", + Short: "Query the current distributor's account balance", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + argAirdropIdentifier := args[0] + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + queryClient := types.NewQueryClient(clientCtx) + + req := &types.QueryDistributorAccountBalanceRequest{ + AirdropIdentifier: argAirdropIdentifier, + } + res, err := queryClient.DistributorAccountBalance(context.Background(), req) + + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} + +// GetCmdQueryParams implements a command to return the current minting +// parameters. +func GetCmdQueryParams() *cobra.Command { + cmd := &cobra.Command{ + Use: "params", + Short: "Query the current claims parameters", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + queryClient := types.NewQueryClient(clientCtx) + + params := &types.QueryParamsRequest{} + res, err := queryClient.Params(context.Background(), params) + + if err != nil { + return err + } + + return clientCtx.PrintProto(&res.Params) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} + +// GetCmdQueryClaimRecord implements the query claim-records command. +func GetCmdQueryClaimRecord() *cobra.Command { + cmd := &cobra.Command{ + Use: "claim-record [airdrop-identifier] [address]", + Args: cobra.ExactArgs(2), + Short: "Query the claim record for an account.", + Long: strings.TrimSpace( + fmt.Sprintf(`Query the claim record for an account. +This contains an address' initial claimable amounts, and the completed actions. + +Example: +$ %s query claim claim-record
+`, + version.AppName, + ), + ), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + queryClient := types.NewQueryClient(clientCtx) + + // Query store + res, err := queryClient.ClaimRecord(context.Background(), &types.QueryClaimRecordRequest{AirdropIdentifier: args[0], Address: args[1]}) + if err != nil { + return err + } + return clientCtx.PrintObjectLegacy(res) + }, + } + flags.AddQueryFlagsToCmd(cmd) + return cmd +} + +// GetCmdQueryClaimableForAction implements the query claimable for action command. +func GetCmdQueryClaimableForAction() *cobra.Command { + cmd := &cobra.Command{ + Use: "claimable-for-action [airdrop-identifier] [address] [action]", + Args: cobra.ExactArgs(3), + Short: "Query an address' claimable amount for a specific action", + Long: strings.TrimSpace( + fmt.Sprintf(`Query an address' claimable amount for a specific action + +Example: +$ %s query claim claimable-for-action stride1h4astdfzjhcwahtfrh24qtvndzzh49xvqtfftk ActionLiquidStake +`, + version.AppName, + ), + ), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + queryClient := types.NewQueryClient(clientCtx) + + action, ok := types.Action_value[args[2]] + if !ok { + return fmt.Errorf("invalid Action type: %s. Valid actions are %s, %s, %s", args[2], + types.ActionFree, types.ActionLiquidStake, types.ActionDelegateStake) + } + + // Query store + res, err := queryClient.ClaimableForAction(context.Background(), &types.QueryClaimableForActionRequest{ + AirdropIdentifier: args[0], + Address: args[1], + Action: types.Action(action), + }) + if err != nil { + return err + } + return clientCtx.PrintObjectLegacy(res) + }, + } + flags.AddQueryFlagsToCmd(cmd) + return cmd +} + +// GetCmdQueryClaimable implements the query claimables command. +func GetCmdQueryTotalClaimable() *cobra.Command { + cmd := &cobra.Command{ + Use: "total-claimable [airdrop-identifier] [address]", + Args: cobra.ExactArgs(2), + Short: "Query the total claimable amount remaining for an account.", + Long: strings.TrimSpace( + fmt.Sprintf(`Query the total claimable amount remaining for an account. +Example: +$ %s query claim total-claimable stride1h4astdfzjhcwahtfrh24qtvndzzh49xvqtfftk +`, + version.AppName, + ), + ), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + queryClient := types.NewQueryClient(clientCtx) + // Query store + res, err := queryClient.TotalClaimable(context.Background(), &types.QueryTotalClaimableRequest{ + AirdropIdentifier: args[0], + Address: args[1], + }) + if err != nil { + return err + } + return clientCtx.PrintObjectLegacy(res) + }, + } + flags.AddQueryFlagsToCmd(cmd) + return cmd +} diff --git a/x/claim/client/cli/tx.go b/x/claim/client/cli/tx.go new file mode 100644 index 0000000000..355223b4f7 --- /dev/null +++ b/x/claim/client/cli/tx.go @@ -0,0 +1,27 @@ +package cli + +import ( + "fmt" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/spf13/cobra" + + "github.com/Stride-Labs/stride/x/claim/types" +) + +// GetTxCmd returns the transaction commands for this module +func GetTxCmd() *cobra.Command { + claimTxCmd := &cobra.Command{ + Use: types.ModuleName, + Short: fmt.Sprintf("%s transactions subcommands", types.ModuleName), + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + + claimTxCmd.AddCommand(CmdClaimFreeAmount()) + claimTxCmd.AddCommand(CmdSetAirdropAllocations()) + claimTxCmd.AddCommand(CmdCreateAirdrop()) + claimTxCmd.AddCommand(CmdDeleteAirdrop()) + return claimTxCmd +} diff --git a/x/claim/client/cli/tx_claim_free_amount.go b/x/claim/client/cli/tx_claim_free_amount.go new file mode 100644 index 0000000000..bc67e62a0e --- /dev/null +++ b/x/claim/client/cli/tx_claim_free_amount.go @@ -0,0 +1,39 @@ +package cli + +import ( + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/client/tx" + "github.com/spf13/cobra" + + "github.com/Stride-Labs/stride/x/claim/types" +) + +func CmdClaimFreeAmount() *cobra.Command { + cmd := &cobra.Command{ + Use: "claim-free-amount [airdrop-identifier]", + Short: "Broadcast message claim-free-amount", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) (err error) { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + msg := types.NewMsgClaimFreeAmount( + clientCtx.GetFromAddress().String(), + args[0], + ) + + if err := msg.ValidateBasic(); err != nil { + return err + } + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + + return cmd +} diff --git a/x/claim/client/cli/tx_create_airdrop.go b/x/claim/client/cli/tx_create_airdrop.go new file mode 100644 index 0000000000..8d07ac9c2a --- /dev/null +++ b/x/claim/client/cli/tx_create_airdrop.go @@ -0,0 +1,53 @@ +package cli + +import ( + "strconv" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/client/tx" + "github.com/spf13/cobra" + + "github.com/Stride-Labs/stride/x/claim/types" +) + +func CmdCreateAirdrop() *cobra.Command { + cmd := &cobra.Command{ + Use: "create-airdrop [identifier] [start] [duration] [denom]", + Short: "Broadcast message create-airdrop", + Args: cobra.ExactArgs(4), + RunE: func(cmd *cobra.Command, args []string) (err error) { + argStartTime, err := strconv.Atoi(args[1]) + if err != nil { + return err + } + + argDuration, err := strconv.Atoi(args[2]) + if err != nil { + return err + } + + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + msg := types.NewMsgCreateAirdrop( + clientCtx.GetFromAddress().String(), + args[0], + uint64(argStartTime), + uint64(argDuration), + args[3], + ) + + if err := msg.ValidateBasic(); err != nil { + return err + } + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + + return cmd +} diff --git a/x/claim/client/cli/tx_delete_airdrop.go b/x/claim/client/cli/tx_delete_airdrop.go new file mode 100644 index 0000000000..c8f8fba785 --- /dev/null +++ b/x/claim/client/cli/tx_delete_airdrop.go @@ -0,0 +1,39 @@ +package cli + +import ( + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/client/tx" + "github.com/spf13/cobra" + + "github.com/Stride-Labs/stride/x/claim/types" +) + +func CmdDeleteAirdrop() *cobra.Command { + cmd := &cobra.Command{ + Use: "delete-airdrop [identifier]", + Short: "Broadcast message delete-airdrop", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) (err error) { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + msg := types.NewMsgDeleteAirdrop( + clientCtx.GetFromAddress().String(), + args[0], + ) + + if err := msg.ValidateBasic(); err != nil { + return err + } + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + + return cmd +} diff --git a/x/claim/client/cli/tx_set_airdrop_allocations.go b/x/claim/client/cli/tx_set_airdrop_allocations.go new file mode 100644 index 0000000000..a0d79aedaa --- /dev/null +++ b/x/claim/client/cli/tx_set_airdrop_allocations.go @@ -0,0 +1,57 @@ +package cli + +import ( + "strings" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/client/tx" + "github.com/spf13/cobra" + + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/Stride-Labs/stride/x/claim/types" +) + +func CmdSetAirdropAllocations() *cobra.Command { + cmd := &cobra.Command{ + Use: "set-airdrop-allocations [airdrop-identifier] [user-addresses] [user-weights]", + Short: "Broadcast message set-airdrop-allocations", + Args: cobra.ExactArgs(3), + RunE: func(cmd *cobra.Command, args []string) (err error) { + argAddresses := strings.Split(args[1], ",") + argWeights := strings.Split(args[2], ",") + weights := []sdk.Dec{} + + for _, weight := range argWeights { + weightDec, err := sdk.NewDecFromStr(weight) + if err != nil { + return err + } + weights = append(weights, weightDec) + } + + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + msg := types.NewMsgSetAirdropAllocations( + clientCtx.GetFromAddress().String(), + args[0], + argAddresses, + weights, + ) + + if err := msg.ValidateBasic(); err != nil { + return err + } + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + + return cmd +} diff --git a/x/claim/client/rest/rest.go b/x/claim/client/rest/rest.go new file mode 100644 index 0000000000..b6fe002b89 --- /dev/null +++ b/x/claim/client/rest/rest.go @@ -0,0 +1,15 @@ +package rest + +import ( + "github.com/gorilla/mux" + + "github.com/cosmos/cosmos-sdk/client" +) + +const ( + MethodGet = "GET" +) + +// RegisterRoutes registers claim-related REST handlers to a router +func RegisterRoutes(clientCtx client.Context, r *mux.Router) { +} diff --git a/x/claim/genesis_test.go b/x/claim/genesis_test.go new file mode 100644 index 0000000000..f7cf50bc90 --- /dev/null +++ b/x/claim/genesis_test.go @@ -0,0 +1,73 @@ +package claim_test + +import ( + "testing" + "time" + + "github.com/stretchr/testify/require" + "github.com/tendermint/tendermint/crypto/secp256k1" + + sdk "github.com/cosmos/cosmos-sdk/types" + + keepertest "github.com/Stride-Labs/stride/testutil/keeper" + "github.com/Stride-Labs/stride/testutil/nullify" + "github.com/Stride-Labs/stride/x/claim/types" +) + +func TestGenesis(t *testing.T) { + pub1 := secp256k1.GenPrivKey().PubKey() + addr1 := sdk.AccAddress(pub1.Address()) + + pub2 := secp256k1.GenPrivKey().PubKey() + addr2 := sdk.AccAddress(pub2.Address()) + + pub3 := secp256k1.GenPrivKey().PubKey() + addr3 := sdk.AccAddress(pub3.Address()) + + genesisState := types.GenesisState{ + Params: types.Params{ + Airdrops: []*types.Airdrop{ + { + AirdropIdentifier: types.DefaultAirdropIdentifier, + AirdropStartTime: time.Now(), + AirdropDuration: types.DefaultAirdropDuration, + ClaimDenom: sdk.DefaultBondDenom, + DistributorAddress: addr3.String(), + }, + }, + }, + ClaimRecords: []types.ClaimRecord{ + { + Address: addr1.String(), + Weight: sdk.NewDecWithPrec(50, 2), // 50% + ActionCompleted: []bool{false, false, false}, + AirdropIdentifier: types.DefaultAirdropIdentifier, + }, + { + Address: addr2.String(), + Weight: sdk.NewDecWithPrec(50, 2), // 50% + ActionCompleted: []bool{false, false, false}, + AirdropIdentifier: "juno", + }, + }, + } + + k, ctx := keepertest.ClaimKeeper(t) + k.InitGenesis(ctx, genesisState) + got := k.ExportGenesis(ctx) + require.NotNil(t, got) + + totalWeightStride, err := k.GetTotalWeight(ctx, types.DefaultAirdropIdentifier) + require.NoError(t, err) + require.Equal(t, totalWeightStride, genesisState.ClaimRecords[0].Weight) + + totalWeightJuno, err := k.GetTotalWeight(ctx, types.DefaultAirdropIdentifier) + require.NoError(t, err) + require.Equal(t, totalWeightJuno, genesisState.ClaimRecords[1].Weight) + + nullify.Fill(&genesisState) + nullify.Fill(got) + + require.Equal(t, genesisState.Params, got.Params) + require.Equal(t, genesisState.ClaimRecords, got.ClaimRecords) +} diff --git a/x/claim/handler.go b/x/claim/handler.go new file mode 100644 index 0000000000..fa67ff81b9 --- /dev/null +++ b/x/claim/handler.go @@ -0,0 +1,37 @@ +package claim + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + + "github.com/Stride-Labs/stride/x/claim/keeper" + "github.com/Stride-Labs/stride/x/claim/types" +) + +// NewHandler returns claim module messages +func NewHandler(k keeper.Keeper) sdk.Handler { + msgServer := keeper.NewMsgServerImpl(k) + return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) { + ctx = ctx.WithEventManager(sdk.NewEventManager()) + + switch msg := msg.(type) { + case *types.MsgSetAirdropAllocations: + res, err := msgServer.SetAirdropAllocations(sdk.WrapSDKContext(ctx), msg) + return sdk.WrapServiceResult(ctx, res, err) + case *types.MsgClaimFreeAmount: + res, err := msgServer.ClaimFreeAmount(sdk.WrapSDKContext(ctx), msg) + return sdk.WrapServiceResult(ctx, res, err) + case *types.MsgCreateAirdrop: + res, err := msgServer.CreateAirdrop(sdk.WrapSDKContext(ctx), msg) + return sdk.WrapServiceResult(ctx, res, err) + case *types.MsgDeleteAirdrop: + res, err := msgServer.DeleteAirdrop(sdk.WrapSDKContext(ctx), msg) + return sdk.WrapServiceResult(ctx, res, err) + default: + errMsg := fmt.Sprintf("unrecognized %s message type: %T", types.ModuleName, msg) + return nil, sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, errMsg) + } + } +} diff --git a/x/claim/keeper/abci.go b/x/claim/keeper/abci.go new file mode 100644 index 0000000000..5d0726c7f7 --- /dev/null +++ b/x/claim/keeper/abci.go @@ -0,0 +1,26 @@ +package keeper + +import sdk "github.com/cosmos/cosmos-sdk/types" + +// Endblocker handler +func (k Keeper) EndBlocker(ctx sdk.Context) { + // Check airdrop elapsed time every 1000 blocks + if ctx.BlockHeight()%1000 == 0 { + params, err := k.GetParams(ctx) + if err != nil { + panic(err) + } + + // End Airdrop + for _, airdrop := range params.Airdrops { + goneTime := ctx.BlockTime().Sub(airdrop.AirdropStartTime) + if goneTime > airdrop.AirdropDuration { + // airdrop time has passed + err := k.EndAirdrop(ctx, airdrop.AirdropIdentifier) + if err != nil { + panic(err) + } + } + } + } +} diff --git a/x/claim/keeper/claim.go b/x/claim/keeper/claim.go new file mode 100644 index 0000000000..2b5927ce0d --- /dev/null +++ b/x/claim/keeper/claim.go @@ -0,0 +1,570 @@ +package keeper + +import ( + "fmt" + "strconv" + "strings" + "time" + + "github.com/cosmos/cosmos-sdk/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + authvestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types" + "github.com/gogo/protobuf/proto" + + "github.com/Stride-Labs/stride/utils" + "github.com/Stride-Labs/stride/x/claim/types" + vestingtypes "github.com/Stride-Labs/stride/x/claim/vesting/types" + epochstypes "github.com/Stride-Labs/stride/x/epochs/types" +) + +func (k Keeper) LoadAllocationData(ctx sdk.Context, allocationData string) bool { + records := []types.ClaimRecord{} + + lines := strings.Split(allocationData, "\n") + allocatedFlags := map[string]bool{} + for _, line := range lines { + data := strings.Split(line, ",") + if data[0] == "" || data[1] == "" || data[2] == "" { + continue + } + + airdropIdentifier := data[0] + sourceChainAddr := data[1] + airdropWeight := data[2] + strideAddr := utils.ConvertAddressToStrideAddress(sourceChainAddr) + if strideAddr == "" { + continue + } + allocationIdentifier := airdropIdentifier + strideAddr + + // Round weight value so that it always has 10 decimal places + weightFloat64, err := strconv.ParseFloat(airdropWeight, 64) + if err != nil { + continue + } + + weightStr := fmt.Sprintf("%.10f", weightFloat64) + weight, err := sdk.NewDecFromStr(weightStr) + if weight.IsNegative() || weight.IsZero() { + continue + } + + if err != nil || allocatedFlags[allocationIdentifier] { + continue + } + + _, err = sdk.AccAddressFromBech32(strideAddr) + if err != nil { + continue + } + + records = append(records, types.ClaimRecord{ + AirdropIdentifier: airdropIdentifier, + Address: strideAddr, + Weight: weight, + ActionCompleted: []bool{false, false, false}, + }) + + allocatedFlags[allocationIdentifier] = true + } + + if err := k.SetClaimRecordsWithWeights(ctx, records); err != nil { + panic(err) + } + return true +} + +// Remove duplicated airdrops for given params +func (k Keeper) GetUnallocatedUsers(ctx sdk.Context, identifier string, users []string, weights []sdk.Dec) ([]string, []sdk.Dec) { + store := ctx.KVStore(k.storeKey) + prefixStore := prefix.NewStore(store, append([]byte(types.ClaimRecordsStorePrefix), []byte(identifier)...)) + newUsers := []string{} + newWeights := []sdk.Dec{} + for idx, user := range users { + strideAddr := utils.ConvertAddressToStrideAddress(user) + addr, _ := sdk.AccAddressFromBech32(strideAddr) + // If new user, then append user and weight + if !prefixStore.Has(addr) { + newUsers = append(newUsers, user) + newWeights = append(newWeights, weights[idx]) + } + } + + return newUsers, newWeights +} + +// Get airdrop duration for action +func GetAirdropDurationForAction(action types.Action) int64 { + if action == types.ActionDelegateStake { + return int64(types.DefaultVestingDurationForDelegateStake.Seconds()) + } else if action == types.ActionLiquidStake { + return int64(types.DefaultVestingDurationForLiquidStake.Seconds()) + } + return int64(0) +} + +// Get airdrop by distributor +func (k Keeper) GetAirdropByDistributor(ctx sdk.Context, distributor string) *types.Airdrop { + params, err := k.GetParams(ctx) + if err != nil { + panic(err) + } + + if distributor == "" { + return nil + } + + for _, airdrop := range params.Airdrops { + if airdrop.DistributorAddress == distributor { + return airdrop + } + } + + return nil +} + +// Get airdrop by identifier +func (k Keeper) GetAirdropByIdentifier(ctx sdk.Context, airdropIdentifier string) *types.Airdrop { + params, err := k.GetParams(ctx) + if err != nil { + panic(err) + } + + if airdropIdentifier == "" { + return nil + } + + for _, airdrop := range params.Airdrops { + if airdrop.AirdropIdentifier == airdropIdentifier { + return airdrop + } + } + + return nil +} + +// GetDistributorAccountBalance gets the airdrop coin balance of module account +func (k Keeper) GetDistributorAccountBalance(ctx sdk.Context, airdropIdentifier string) (sdk.Coin, error) { + airdrop := k.GetAirdropByIdentifier(ctx, airdropIdentifier) + if airdrop == nil { + return sdk.Coin{}, sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid airdrop identifier: GetDistributorAccountBalance") + } + + addr, err := k.GetAirdropDistributor(ctx, airdropIdentifier) + if err != nil { + return sdk.Coin{}, err + } + return k.bankKeeper.GetBalance(ctx, addr, airdrop.ClaimDenom), nil +} + +// EndAirdrop ends airdrop and clear all user claim records +func (k Keeper) EndAirdrop(ctx sdk.Context, airdropIdentifier string) error { + ctx.Logger().Info("Clearing claims module state entries") + k.clearInitialClaimables(ctx, airdropIdentifier) + k.DeleteTotalWeight(ctx, airdropIdentifier) + return k.DeleteAirdropAndEpoch(ctx, airdropIdentifier) +} + +func (k Keeper) IsInitialPeriodPassed(ctx sdk.Context, airdropIdentifier string) bool { + airdrop := k.GetAirdropByIdentifier(ctx, airdropIdentifier) + if airdrop == nil { + return false + } + goneTime := ctx.BlockTime().Sub(airdrop.AirdropStartTime) + // Check if elapsed time since airdrop start is over the initial period of vesting + return goneTime.Seconds() >= types.DefaultVestingInitialPeriod.Seconds() +} + +// ClearClaimedStatus clear users' claimed status only after initial period of vesting is passed +func (k Keeper) ClearClaimedStatus(ctx sdk.Context, airdropIdentifier string) { + if k.IsInitialPeriodPassed(ctx, airdropIdentifier) { + records := k.GetClaimRecords(ctx, airdropIdentifier) + for idx := range records { + records[idx].ActionCompleted = []bool{false, false, false} + } + + if err := k.SetClaimRecords(ctx, records); err != nil { + panic(err) + } + } +} + +// ClearClaimables clear claimable amounts +func (k Keeper) clearInitialClaimables(ctx sdk.Context, airdropIdentifier string) { + store := ctx.KVStore(k.storeKey) + iterator := sdk.KVStorePrefixIterator(store, append([]byte(types.ClaimRecordsStorePrefix), []byte(airdropIdentifier)...)) + defer iterator.Close() + for ; iterator.Valid(); iterator.Next() { + key := iterator.Key() + store.Delete(key) + } +} + +func (k Keeper) SetClaimRecordsWithWeights(ctx sdk.Context, claimRecords []types.ClaimRecord) error { + // Set total weights + weights := make(map[string]sdk.Dec) + for _, record := range claimRecords { + if weights[record.AirdropIdentifier].IsNil() { + weights[record.AirdropIdentifier] = sdk.ZeroDec() + } + + weights[record.AirdropIdentifier] = weights[record.AirdropIdentifier].Add(record.Weight) + } + + for identifier, weight := range weights { + k.SetTotalWeight(ctx, weight, identifier) + } + + // Set claim records + return k.SetClaimRecords(ctx, claimRecords) +} + +// SetClaimRecords set claim records and total weights +func (k Keeper) SetClaimRecords(ctx sdk.Context, claimRecords []types.ClaimRecord) error { + for _, claimRecord := range claimRecords { + err := k.SetClaimRecord(ctx, claimRecord) + if err != nil { + return err + } + } + return nil +} + +// GetClaimables get claimables for genesis export +func (k Keeper) GetClaimRecords(ctx sdk.Context, airdropIdentifier string) []types.ClaimRecord { + store := ctx.KVStore(k.storeKey) + prefixStore := prefix.NewStore(store, append([]byte(types.ClaimRecordsStorePrefix), []byte(airdropIdentifier)...)) + + iterator := prefixStore.Iterator(nil, nil) + defer iterator.Close() + + claimRecords := []types.ClaimRecord{} + for ; iterator.Valid(); iterator.Next() { + + claimRecord := types.ClaimRecord{} + + err := proto.Unmarshal(iterator.Value(), &claimRecord) + if err != nil { + panic(err) + } + + claimRecords = append(claimRecords, claimRecord) + } + return claimRecords +} + +// GetClaimRecord returns the claim record for a specific address +func (k Keeper) GetClaimRecord(ctx sdk.Context, addr sdk.AccAddress, airdropIdentifier string) (types.ClaimRecord, error) { + store := ctx.KVStore(k.storeKey) + prefixStore := prefix.NewStore(store, append([]byte(types.ClaimRecordsStorePrefix), []byte(airdropIdentifier)...)) + if !prefixStore.Has(addr) { + return types.ClaimRecord{}, nil + } + bz := prefixStore.Get(addr) + + claimRecord := types.ClaimRecord{} + err := proto.Unmarshal(bz, &claimRecord) + if err != nil { + return types.ClaimRecord{}, err + } + + return claimRecord, nil +} + +// SetTotalWeight sets total sum of user weights in store +func (k Keeper) SetTotalWeight(ctx sdk.Context, totalWeight sdk.Dec, airdropIdentifier string) { + store := ctx.KVStore(k.storeKey) + store.Set(append([]byte(types.TotalWeightKey), []byte(airdropIdentifier)...), []byte(totalWeight.String())) +} + +// DeleteTotalWeight deletes total weights for airdrop +func (k Keeper) DeleteTotalWeight(ctx sdk.Context, airdropIdentifier string) { + store := ctx.KVStore(k.storeKey) + store.Delete(append([]byte(types.TotalWeightKey), []byte(airdropIdentifier)...)) +} + +// GetTotalWeight gets total sum of user weights in store +func (k Keeper) GetTotalWeight(ctx sdk.Context, airdropIdentifier string) (sdk.Dec, error) { + store := ctx.KVStore(k.storeKey) + b := store.Get(append([]byte(types.TotalWeightKey), []byte(airdropIdentifier)...)) + if b == nil { + return sdk.ZeroDec(), nil + } + totalWeight, err := sdk.NewDecFromStr(string(b)) + if err != nil { + return sdk.ZeroDec(), types.ErrTotalWeightParse + } + return totalWeight, nil +} + +// SetClaimRecord sets a claim record for an address in store +func (k Keeper) SetClaimRecord(ctx sdk.Context, claimRecord types.ClaimRecord) error { + store := ctx.KVStore(k.storeKey) + prefixStore := prefix.NewStore(store, append([]byte(types.ClaimRecordsStorePrefix), []byte(claimRecord.AirdropIdentifier)...)) + + bz, err := proto.Marshal(&claimRecord) + if err != nil { + return err + } + + addr, err := sdk.AccAddressFromBech32(claimRecord.Address) + if err != nil { + return err + } + + prefixStore.Set(addr, bz) + return nil +} + +// Get airdrop distributor address +func (k Keeper) GetAirdropDistributor(ctx sdk.Context, airdropIdentifier string) (sdk.AccAddress, error) { + airdrop := k.GetAirdropByIdentifier(ctx, airdropIdentifier) + if airdrop == nil { + return sdk.AccAddress{}, sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid airdrop identifier: GetAirdropDistributor") + } + return sdk.AccAddressFromBech32(airdrop.DistributorAddress) +} + +// Get airdrop claim denom +func (k Keeper) GetAirdropClaimDenom(ctx sdk.Context, airdropIdentifier string) (string, error) { + airdrop := k.GetAirdropByIdentifier(ctx, airdropIdentifier) + if airdrop == nil { + return "", sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid airdrop identifier: GetAirdropClaimDenom") + } + return airdrop.ClaimDenom, nil +} + +// GetClaimable returns claimable amount for a specific action done by an address +func (k Keeper) GetClaimableAmountForAction(ctx sdk.Context, addr sdk.AccAddress, action types.Action, airdropIdentifier string) (sdk.Coins, error) { + claimRecord, err := k.GetClaimRecord(ctx, addr, airdropIdentifier) + if err != nil { + return nil, err + } + + if claimRecord.Address == "" { + return sdk.Coins{}, nil + } + + // if action already completed, nothing is claimable + if claimRecord.ActionCompleted[action] { + return sdk.Coins{}, nil + } + + airdrop := k.GetAirdropByIdentifier(ctx, airdropIdentifier) + if ctx.BlockTime().Before(airdrop.AirdropStartTime) { + return sdk.Coins{}, nil + } + + totalWeight, err := k.GetTotalWeight(ctx, airdropIdentifier) + if err != nil { + return nil, types.ErrFailedToGetTotalWeight + } + + percentageForAction := types.PercentageForFree + if action == types.ActionDelegateStake { + percentageForAction = types.PercentageForStake + } else if action == types.ActionLiquidStake { + percentageForAction = types.PercentageForLiquidStake + } + + poolBal, err := k.GetDistributorAccountBalance(ctx, airdropIdentifier) + if err != nil { + return sdk.Coins{}, err + } + + claimableAmount := poolBal.Amount.ToDec(). + Mul(percentageForAction). + Mul(claimRecord.Weight). + Quo(totalWeight).RoundInt() + claimableCoins := sdk.NewCoins(sdk.NewCoin(airdrop.ClaimDenom, claimableAmount)) + + elapsedAirdropTime := ctx.BlockTime().Sub(airdrop.AirdropStartTime) + // The entire airdrop has completed + if elapsedAirdropTime > airdrop.AirdropDuration { + return sdk.Coins{}, nil + } + return claimableCoins, nil +} + +// GetClaimable returns claimable amount for a specific action done by an address +func (k Keeper) GetUserTotalClaimable(ctx sdk.Context, addr sdk.AccAddress, airdropIdentifier string) (sdk.Coins, error) { + claimRecord, err := k.GetClaimRecord(ctx, addr, airdropIdentifier) + if err != nil { + return sdk.Coins{}, err + } + if claimRecord.Address == "" { + return sdk.Coins{}, nil + } + + totalClaimable := sdk.Coins{} + + for action := range types.Action_name { + claimableForAction, err := k.GetClaimableAmountForAction(ctx, addr, types.Action(action), airdropIdentifier) + if err != nil { + return sdk.Coins{}, err + } + if !claimableForAction.Empty() { + totalClaimable = totalClaimable.Add(claimableForAction...) + } + } + return totalClaimable, nil +} + +// Get airdrop identifier corresponding to the user address +func (k Keeper) GetAirdropIdentifiersForUser(ctx sdk.Context, addr sdk.AccAddress) []string { + store := ctx.KVStore(k.storeKey) + params, err := k.GetParams(ctx) + identifiers := []string{} + if err != nil { + return identifiers + } + + for _, airdrop := range params.Airdrops { + prefixStore := prefix.NewStore(store, append([]byte(types.ClaimRecordsStorePrefix), []byte(airdrop.AirdropIdentifier)...)) + if prefixStore.Has(addr) { + identifiers = append(identifiers, airdrop.AirdropIdentifier) + } + } + return identifiers +} + +// ClaimCoins remove claimable amount entry and transfer it to user's account +func (k Keeper) ClaimCoinsForAction(ctx sdk.Context, addr sdk.AccAddress, action types.Action, airdropIdentifier string) (sdk.Coins, error) { + isPassed := k.IsInitialPeriodPassed(ctx, airdropIdentifier) + if airdropIdentifier == "" { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid airdrop identifier: ClaimCoinsForAction") + } + + claimableAmount, err := k.GetClaimableAmountForAction(ctx, addr, action, airdropIdentifier) + if err != nil { + return claimableAmount, err + } + + if claimableAmount.Empty() { + return claimableAmount, nil + } + + claimRecord, err := k.GetClaimRecord(ctx, addr, airdropIdentifier) + if err != nil { + return nil, err + } + + // If the account is a default vesting account, don't grant new vestings + acc := k.accountKeeper.GetAccount(ctx, addr) + _, isDefaultVestingAccount := acc.(*authvestingtypes.BaseVestingAccount) + if isDefaultVestingAccount { + return nil, err + } + + // Claims don't vest if action type is ActionFree or initial period of vesting is passed + if action != types.ActionFree && !isPassed { + acc = k.accountKeeper.GetAccount(ctx, addr) + strideVestingAcc, isStrideVestingAccount := acc.(*vestingtypes.StridePeriodicVestingAccount) + // Check if vesting tokens already exist for this account. + if !isStrideVestingAccount { + // Convert user account into stride veting account. + baseAccount := k.accountKeeper.NewAccountWithAddress(ctx, addr) + if _, ok := baseAccount.(*authtypes.BaseAccount); !ok { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid account type; expected: BaseAccount, got: %T", baseAccount) + } + + periodLength := GetAirdropDurationForAction(action) + vestingAcc := vestingtypes.NewStridePeriodicVestingAccount(baseAccount.(*authtypes.BaseAccount), claimableAmount, []vestingtypes.Period{{ + StartTime: ctx.BlockTime().Unix(), + Length: periodLength, + Amount: claimableAmount, + }}) + k.accountKeeper.SetAccount(ctx, vestingAcc) + } else { + // Grant a new vesting to the existing stride vesting account + periodLength := GetAirdropDurationForAction(action) + strideVestingAcc.AddNewGrant(vestingtypes.Period{ + StartTime: ctx.BlockTime().Unix(), + Length: periodLength, + Amount: claimableAmount, + }) + k.accountKeeper.SetAccount(ctx, strideVestingAcc) + } + } + + distributor, err := k.GetAirdropDistributor(ctx, airdropIdentifier) + if err != nil { + return nil, err + } + + err = k.bankKeeper.SendCoins(ctx, distributor, addr, claimableAmount) + if err != nil { + return nil, err + } + + claimRecord.ActionCompleted[action] = true + + err = k.SetClaimRecord(ctx, claimRecord) + if err != nil { + return claimableAmount, err + } + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeClaim, + sdk.NewAttribute(sdk.AttributeKeySender, addr.String()), + sdk.NewAttribute(sdk.AttributeKeyAmount, claimableAmount.String()), + ), + }) + + return claimableAmount, nil +} + +// CreateAirdropAndEpoch creates a new airdrop and epoch for that. +func (k Keeper) CreateAirdropAndEpoch(ctx sdk.Context, distributor string, denom string, startTime uint64, duration uint64, identifier string) error { + params, err := k.GetParams(ctx) + if err != nil { + panic(err) + } + + for _, airdrop := range params.Airdrops { + if airdrop.AirdropIdentifier == identifier { + return types.ErrAirdropAlreadyExists + } + } + + airdrop := types.Airdrop{ + AirdropIdentifier: identifier, + AirdropDuration: time.Duration(duration * uint64(time.Second)), + ClaimDenom: denom, + DistributorAddress: distributor, + AirdropStartTime: time.Unix(int64(startTime), 0), + } + + params.Airdrops = append(params.Airdrops, &airdrop) + k.epochsKeeper.SetEpochInfo(ctx, epochstypes.EpochInfo{ + Identifier: fmt.Sprintf("airdrop-%s", identifier), + StartTime: airdrop.AirdropStartTime.Add(time.Minute), + Duration: time.Hour * 24 * 30, + CurrentEpoch: 0, + CurrentEpochStartHeight: 0, + CurrentEpochStartTime: time.Time{}, + EpochCountingStarted: false, + }) + return k.SetParams(ctx, params) +} + +// DeleteAirdropAndEpoch deletes existing airdrop and corresponding epoch. +func (k Keeper) DeleteAirdropAndEpoch(ctx sdk.Context, identifier string) error { + params, err := k.GetParams(ctx) + if err != nil { + panic(err) + } + + newAirdrops := []*types.Airdrop{} + for _, airdrop := range params.Airdrops { + if airdrop.AirdropIdentifier != identifier { + newAirdrops = append(newAirdrops, airdrop) + } + } + params.Airdrops = newAirdrops + k.epochsKeeper.DeleteEpochInfo(ctx, fmt.Sprintf("airdrop-%s", identifier)) + return k.SetParams(ctx, params) +} diff --git a/x/claim/keeper/claim_test.go b/x/claim/keeper/claim_test.go new file mode 100644 index 0000000000..460bde5803 --- /dev/null +++ b/x/claim/keeper/claim_test.go @@ -0,0 +1,420 @@ +package keeper_test + +import ( + "time" + + "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + + "github.com/Stride-Labs/stride/x/claim/types" +) + +// Test functionality for loading allocation data(csv) +func (suite *KeeperTestSuite) TestLoadAllocationData() { + suite.SetupTest() + var allocations = `identifier,address,weight +osmosis,osmo1g7yxhuppp5x3yqkah5mw29eqq5s4sv2fp6e2eg,0.5 +osmosis,osmo1h4astdfzjhcwahtfrh24qtvndzzh49xvtm69fg,0.3 +stride,stride1av5lwh0msnafn04xkhdyk6mrykxthrawy7uf3d,0.7 +stride,stride1g7yxhuppp5x3yqkah5mw29eqq5s4sv2f222xmk,0.3 +stride,stride1g7yxhuppp5x3yqkah5mw29eqq5s4sv2f222xmk,0.5` + + ok := suite.app.ClaimKeeper.LoadAllocationData(suite.ctx, allocations) + suite.Require().True(ok) + + totalWeight, err := suite.app.ClaimKeeper.GetTotalWeight(suite.ctx, "osmosis") + suite.Require().NoError(err) + suite.Require().True(totalWeight.Equal(sdk.MustNewDecFromStr("0.8"))) + + totalWeight, err = suite.app.ClaimKeeper.GetTotalWeight(suite.ctx, "stride") + suite.Require().NoError(err) + suite.Require().True(totalWeight.Equal(sdk.MustNewDecFromStr("1"))) + + addr, _ := sdk.AccAddressFromBech32("stride1g7yxhuppp5x3yqkah5mw29eqq5s4sv2f222xmk") // hex(stride1g7yxhuppp5x3yqkah5mw29eqq5s4sv2f222xmk) = hex(osmo1g7yxhuppp5x3yqkah5mw29eqq5s4sv2fp6e2eg) + claimRecord, err := suite.app.ClaimKeeper.GetClaimRecord(suite.ctx, addr, "osmosis") + suite.Require().NoError(err) + suite.Require().Equal(claimRecord.Address, "stride1g7yxhuppp5x3yqkah5mw29eqq5s4sv2f222xmk") + suite.Require().True(claimRecord.Weight.Equal(sdk.MustNewDecFromStr("0.5"))) + suite.Require().Equal(claimRecord.ActionCompleted, []bool{false, false, false}) + + claimRecord, err = suite.app.ClaimKeeper.GetClaimRecord(suite.ctx, addr, "stride") + suite.Require().NoError(err) + suite.Require().True(claimRecord.Weight.Equal(sdk.MustNewDecFromStr("0.3"))) + suite.Require().Equal(claimRecord.ActionCompleted, []bool{false, false, false}) +} + +// Check unclaimable account's balance after staking +func (suite *KeeperTestSuite) TestHookOfUnclaimableAccount() { + suite.SetupTest() + + // Set a normal user account + pub1 := secp256k1.GenPrivKey().PubKey() + addr1 := sdk.AccAddress(pub1.Address()) + suite.app.AccountKeeper.SetAccount(suite.ctx, authtypes.NewBaseAccount(addr1, nil, 0, 0)) + + claim, err := suite.app.ClaimKeeper.GetClaimRecord(suite.ctx, addr1, "stride") + suite.NoError(err) + suite.Equal(types.ClaimRecord{}, claim) + + suite.app.ClaimKeeper.AfterLiquidStake(suite.ctx, addr1) + + // Get balances for the account + balances := suite.app.BankKeeper.GetAllBalances(suite.ctx, addr1) + suite.Equal(sdk.Coins{}, balances) +} + +//Check balances before and after airdrop starts +func (suite *KeeperTestSuite) TestHookBeforeAirdropStart() { + suite.SetupTest() + + airdropStartTime := time.Now().Add(time.Hour) + + err := suite.app.ClaimKeeper.SetParams(suite.ctx, types.Params{ + Airdrops: []*types.Airdrop{ + { + AirdropIdentifier: types.DefaultAirdropIdentifier, + AirdropStartTime: airdropStartTime, + AirdropDuration: types.DefaultAirdropDuration, + ClaimDenom: sdk.DefaultBondDenom, + DistributorAddress: distributors[types.DefaultAirdropIdentifier].String(), + }, + }, + }) + suite.Require().NoError(err) + + pub1 := secp256k1.GenPrivKey().PubKey() + addr1 := sdk.AccAddress(pub1.Address()) + val1 := sdk.ValAddress(addr1) + + claimRecords := []types.ClaimRecord{ + { + Address: addr1.String(), + Weight: sdk.NewDecWithPrec(50, 2), // 50% + ActionCompleted: []bool{false, false, false}, + AirdropIdentifier: types.DefaultAirdropIdentifier, + }, + } + suite.app.AccountKeeper.SetAccount(suite.ctx, authtypes.NewBaseAccount(addr1, nil, 0, 0)) + err = suite.app.ClaimKeeper.SetClaimRecordsWithWeights(suite.ctx, claimRecords) + suite.Require().NoError(err) + + coins, err := suite.app.ClaimKeeper.GetUserTotalClaimable(suite.ctx, addr1, "stride") + suite.NoError(err) + // Now, it is before starting air drop, so this value should return the empty coins + suite.True(coins.Empty()) + + coins, err = suite.app.ClaimKeeper.GetClaimableAmountForAction(suite.ctx, addr1, types.ActionFree, "stride") + suite.NoError(err) + // Now, it is before starting air drop, so this value should return the empty coins + suite.True(coins.Empty()) + + suite.app.ClaimKeeper.AfterDelegationModified(suite.ctx, addr1, val1) + balances := suite.app.BankKeeper.GetAllBalances(suite.ctx, addr1) + // Now, it is before starting air drop, so claim module should not send the balances to the user after swap. + suite.True(balances.Empty()) + + suite.app.ClaimKeeper.AfterLiquidStake(suite.ctx.WithBlockTime(airdropStartTime), addr1) + balances = suite.app.BankKeeper.GetAllBalances(suite.ctx, addr1) + // Now, it is the time for air drop, so claim module should send the balances to the user after liquid stake. + claimableAmountForLiquidStake := sdk.NewDecWithPrec(60, 2). + Mul(sdk.NewDec(100_000_000)). + RoundInt64() // 60% for liquid stake + suite.Require().Equal(balances.String(), sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, claimableAmountForLiquidStake)).String()) +} + +// Check original user balances after being converted into stride vesting account +func (suite *KeeperTestSuite) TestBalancesAfterAccountConversion() { + suite.SetupTest() + + // set a normal account + addr := sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) + suite.app.AccountKeeper.SetAccount(suite.ctx, authtypes.NewBaseAccount(addr, nil, 0, 0)) + + initialBal := int64(1000) + err := suite.app.BankKeeper.SendCoins(suite.ctx, distributors["stride"], addr, sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, initialBal))) + suite.Require().NoError(err) + + claimRecords := []types.ClaimRecord{ + { + Address: addr.String(), + Weight: sdk.NewDecWithPrec(50, 2), // 50% + ActionCompleted: []bool{false, false, false}, + AirdropIdentifier: types.DefaultAirdropIdentifier, + }, + } + + err = suite.app.ClaimKeeper.SetClaimRecordsWithWeights(suite.ctx, claimRecords) + suite.Require().NoError(err) + + // check if original account tokens are not affected after stride vesting + _, err = suite.app.ClaimKeeper.ClaimCoinsForAction(suite.ctx, addr, types.ActionDelegateStake, "stride") + suite.Require().NoError(err) + claimableAmountForStake := sdk.NewDecWithPrec(20, 2). + Mul(sdk.NewDec(100_000_000 - initialBal)). + RoundInt64() // remaining balance is 100000000*(80/100), claim 20% for stake + + coinsBal := suite.app.BankKeeper.GetAllBalances(suite.ctx, addr) + suite.Require().Equal(coinsBal.String(), sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, initialBal+claimableAmountForStake)).String()) + + spendableCoinsBal := suite.app.BankKeeper.SpendableCoins(suite.ctx, addr) + suite.Require().Equal(spendableCoinsBal.String(), sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, initialBal)).String()) +} + +// Run all airdrop flow +func (suite *KeeperTestSuite) TestAirdropFlow() { + suite.SetupTest() + + addr1 := sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) + addr2 := sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) + + claimRecords := []types.ClaimRecord{ + { + Address: addr1.String(), + Weight: sdk.NewDecWithPrec(50, 2), // 50% + ActionCompleted: []bool{false, false, false}, + AirdropIdentifier: types.DefaultAirdropIdentifier, + }, + } + + err := suite.app.ClaimKeeper.SetClaimRecordsWithWeights(suite.ctx, claimRecords) + suite.Require().NoError(err) + + coins, err := suite.app.ClaimKeeper.GetUserTotalClaimable(suite.ctx, addr1, "stride") + suite.Require().NoError(err) + suite.Require().Equal(coins.String(), sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, 100_000_000)).String()) + + coins, err = suite.app.ClaimKeeper.GetUserTotalClaimable(suite.ctx, addr2, "stride") + suite.Require().NoError(err) + suite.Require().Equal(coins, sdk.Coins{}) + + // get rewards amount for free + coins, err = suite.app.ClaimKeeper.ClaimCoinsForAction(suite.ctx, addr1, types.ActionFree, "stride") + suite.Require().NoError(err) + claimableAmountForFree := sdk.NewDecWithPrec(20, 2). + Mul(sdk.NewDec(100_000_000)). + RoundInt64() // remaining balance is 100000000, claim 20% for free + suite.Require().Equal(coins.String(), sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, claimableAmountForFree)).String()) + + // get rewards amount for stake + coins, err = suite.app.ClaimKeeper.ClaimCoinsForAction(suite.ctx, addr1, types.ActionDelegateStake, "stride") + suite.Require().NoError(err) + claimableAmountForStake := sdk.NewDecWithPrec(80, 2). + Mul(sdk.NewDecWithPrec(20, 2)). + Mul(sdk.NewDec(100_000_000)). + RoundInt64() // remaining balance is 100000000*(80/100), claim 20% for stake + suite.Require().Equal(coins.String(), sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, claimableAmountForStake)).String()) + + // get rewards amount for liquid stake + coins, err = suite.app.ClaimKeeper.ClaimCoinsForAction(suite.ctx, addr1, types.ActionLiquidStake, "stride") + suite.Require().NoError(err) + claimableAmountForLiquidStake := sdk.NewDecWithPrec(80, 2). + Mul(sdk.NewDecWithPrec(80, 2)). + Mul(sdk.NewDecWithPrec(60, 2)). + Mul(sdk.NewDec(100_000_000)). + RoundInt64() // remaining balance = 100000000*(80/100)*(80/100), claim 60% for liquid stake + suite.Require().Equal(coins.String(), sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, claimableAmountForLiquidStake)).String()) + + // get balance after all claim + coins = suite.app.BankKeeper.GetAllBalances(suite.ctx, addr1) + suite.Require().Equal(coins.String(), sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, claimableAmountForFree+claimableAmountForStake+claimableAmountForLiquidStake)).String()) + + // get spendable balances 3 months later + ctx := suite.ctx.WithBlockTime(time.Now().Add(types.DefaultVestingDurationForDelegateStake)) + coinsSpendable := suite.app.BankKeeper.SpendableCoins(ctx, addr1) + suite.Require().Equal(coins.String(), coinsSpendable.String()) + + // check if claims don't vest after initial period of 3 months + suite.ctx = suite.ctx.WithBlockTime(time.Now().Add(types.DefaultVestingInitialPeriod)) + suite.app.ClaimKeeper.ClearClaimedStatus(suite.ctx, "stride") + _, err = suite.app.ClaimKeeper.ClaimCoinsForAction(suite.ctx, addr1, types.ActionLiquidStake, "stride") + suite.Require().NoError(err) + claimableAmountForLiquidStake2 := sdk.NewDecWithPrec(80, 2). + Mul(sdk.NewDecWithPrec(80, 2)). + Mul(sdk.NewDecWithPrec(40, 2)). + Mul(sdk.NewDecWithPrec(60, 2)). + Mul(sdk.NewDec(100_000_000)). + RoundInt64() // remaining balance = 100000000*(80/100)*(80/100)*(40/100), claim 60% for liquid stake + + coins = suite.app.BankKeeper.GetAllBalances(suite.ctx, addr1) + suite.Require().Equal(coins.String(), sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, claimableAmountForFree+claimableAmountForStake+claimableAmountForLiquidStake+claimableAmountForLiquidStake2)).String()) + coinsSpendable = suite.app.BankKeeper.SpendableCoins(ctx, addr1) + suite.Require().Equal(coins.String(), coinsSpendable.String()) + + // end airdrop + err = suite.app.ClaimKeeper.EndAirdrop(suite.ctx, "stride") + suite.Require().NoError(err) +} + +// Run multi chain airdrop flow +func (suite *KeeperTestSuite) TestMultiChainAirdropFlow() { + suite.SetupTest() + + addr1 := sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) + addr2 := sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) + + claimRecords := []types.ClaimRecord{ + { + Address: addr1.String(), + Weight: sdk.NewDecWithPrec(50, 2), // 50% + ActionCompleted: []bool{false, false, false}, + AirdropIdentifier: types.DefaultAirdropIdentifier, + }, + { + Address: addr2.String(), + Weight: sdk.NewDecWithPrec(50, 2), // 50% + ActionCompleted: []bool{false, false, false}, + AirdropIdentifier: "juno", + }, + { + Address: addr1.String(), + Weight: sdk.NewDecWithPrec(30, 2), // 30% + ActionCompleted: []bool{false, false, false}, + AirdropIdentifier: "osmosis", + }, + } + + err := suite.app.ClaimKeeper.SetClaimRecordsWithWeights(suite.ctx, claimRecords) + suite.Require().NoError(err) + + coins, err := suite.app.ClaimKeeper.GetUserTotalClaimable(suite.ctx, addr1, "stride") + suite.Require().NoError(err) + suite.Require().Equal(coins.String(), sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, 100_000_000)).String()) + + coins, err = suite.app.ClaimKeeper.GetUserTotalClaimable(suite.ctx, addr2, "juno") + suite.Require().NoError(err) + suite.Require().Equal(coins.String(), sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, 0)).String()) + + identifiers := suite.app.ClaimKeeper.GetAirdropIdentifiersForUser(suite.ctx, addr1) + suite.Require().Equal(identifiers[0], types.DefaultAirdropIdentifier) + suite.Require().Equal(identifiers[1], "osmosis") + + // get rewards amount for free (stride, osmosis addresses) + coins, err = suite.app.ClaimKeeper.ClaimCoinsForAction(suite.ctx, addr1, types.ActionFree, "stride") + suite.Require().NoError(err) + + coins1, err := suite.app.ClaimKeeper.ClaimCoinsForAction(suite.ctx, addr1, types.ActionFree, "osmosis") + suite.Require().NoError(err) + + claimableAmountForFree := sdk.NewDecWithPrec(20, 2). + Mul(sdk.NewDec(100_000_000)). + RoundInt64() // remaining balance is 100000000, claim 20% for free + suite.Require().Equal(coins.String(), sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, claimableAmountForFree)).String()) + suite.Require().Equal(coins1.String(), sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, claimableAmountForFree)).String()) + + // get rewards amount for stake (stride, osmosis addresses) + coins, err = suite.app.ClaimKeeper.ClaimCoinsForAction(suite.ctx, addr1, types.ActionDelegateStake, "stride") + suite.Require().NoError(err) + + coins1, err = suite.app.ClaimKeeper.ClaimCoinsForAction(suite.ctx, addr1, types.ActionDelegateStake, "osmosis") + suite.Require().NoError(err) + + claimableAmountForStake := sdk.NewDecWithPrec(80, 2). + Mul(sdk.NewDecWithPrec(20, 2)). + Mul(sdk.NewDec(100_000_000)). + RoundInt64() // remaining balance is 100000000*(80/100), claim 20% for stake + suite.Require().Equal(coins.String(), sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, claimableAmountForStake)).String()) + suite.Require().Equal(coins1.String(), sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, claimableAmountForStake)).String()) + + // get rewards amount for liquid stake (stride, osmosis addresses) + coins, err = suite.app.ClaimKeeper.ClaimCoinsForAction(suite.ctx, addr1, types.ActionLiquidStake, "stride") + suite.Require().NoError(err) + + coins1, err = suite.app.ClaimKeeper.ClaimCoinsForAction(suite.ctx, addr1, types.ActionLiquidStake, "osmosis") + suite.Require().NoError(err) + + claimableAmountForLiquidStake := sdk.NewDecWithPrec(80, 2). + Mul(sdk.NewDecWithPrec(80, 2)). + Mul(sdk.NewDecWithPrec(60, 2)). + Mul(sdk.NewDec(100_000_000)). + RoundInt64() // remaining balance = 100000000*(80/100)*(80/100), claim 60% for liquid stake + suite.Require().Equal(coins.String(), sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, claimableAmountForLiquidStake)).String()) + suite.Require().Equal(coins1.String(), sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, claimableAmountForLiquidStake)).String()) + + // get balance after all claim + coins = suite.app.BankKeeper.GetAllBalances(suite.ctx, addr1) + suite.Require().Equal(coins.String(), sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, (claimableAmountForFree+claimableAmountForStake+claimableAmountForLiquidStake)*2)).String()) + + // check if stride and osmosis airdrops ended properly + suite.ctx = suite.ctx.WithBlockHeight(1000) + suite.app.ClaimKeeper.EndBlocker(suite.ctx.WithBlockTime(time.Now().Add(types.DefaultAirdropDuration))) + // for stride + weight, err := suite.app.ClaimKeeper.GetTotalWeight(suite.ctx, types.DefaultAirdropIdentifier) + suite.Require().NoError(err) + suite.Require().Equal(weight, sdk.ZeroDec()) + + records := suite.app.ClaimKeeper.GetClaimRecords(suite.ctx, types.DefaultAirdropIdentifier) + suite.Require().Equal(0, len(records)) + + // for osmosis + weight, err = suite.app.ClaimKeeper.GetTotalWeight(suite.ctx, "osmosis") + suite.Require().NoError(err) + suite.Require().Equal(weight, sdk.ZeroDec()) + + records = suite.app.ClaimKeeper.GetClaimRecords(suite.ctx, "osmosis") + suite.Require().Equal(0, len(records)) + + //*********************** End of Stride, Osmosis airdrop ************************* + + // claim airdrops for juno users after ending stride airdrop + // get rewards amount for free (juno user) + coins, err = suite.app.ClaimKeeper.ClaimCoinsForAction(suite.ctx.WithBlockTime(time.Now().Add(time.Hour)), addr2, types.ActionFree, "juno") + suite.Require().NoError(err) + claimableAmountForFree = sdk.NewDecWithPrec(20, 2). + Mul(sdk.NewDec(100_000_000)). + RoundInt64() // remaining balance is 100000000, claim 20% for free + suite.Require().Equal(coins.String(), sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, claimableAmountForFree)).String()) + + // get rewards amount for stake (juno user) + coins, err = suite.app.ClaimKeeper.ClaimCoinsForAction(suite.ctx.WithBlockTime(time.Now().Add(time.Hour)), addr2, types.ActionDelegateStake, "juno") + suite.Require().NoError(err) + claimableAmountForStake = sdk.NewDecWithPrec(80, 2). + Mul(sdk.NewDecWithPrec(20, 2)). + Mul(sdk.NewDec(100_000_000)). + RoundInt64() // remaining balance is 100000000*(80/100), claim 20% for stake + suite.Require().Equal(coins.String(), sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, claimableAmountForStake)).String()) + + // get rewards amount for liquid stake (juno user) + coins, err = suite.app.ClaimKeeper.ClaimCoinsForAction(suite.ctx.WithBlockTime(time.Now().Add(time.Hour)), addr2, types.ActionLiquidStake, "juno") + suite.Require().NoError(err) + claimableAmountForLiquidStake = sdk.NewDecWithPrec(80, 2). + Mul(sdk.NewDecWithPrec(80, 2)). + Mul(sdk.NewDecWithPrec(60, 2)). + Mul(sdk.NewDec(100_000_000)). + RoundInt64() // remaining balance = 100000000*(80/100)*(80/100), claim 60% for liquid stake + suite.Require().Equal(coins.String(), sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, claimableAmountForLiquidStake)).String()) + + // get balance after all claim + coins = suite.app.BankKeeper.GetAllBalances(suite.ctx, addr2) + suite.Require().Equal(coins.String(), sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, claimableAmountForFree+claimableAmountForStake+claimableAmountForLiquidStake)).String()) + + // after 3 years, juno users should be still able to claim + suite.ctx = suite.ctx.WithBlockTime(time.Now().Add(types.DefaultAirdropDuration)) + suite.app.ClaimKeeper.ClearClaimedStatus(suite.ctx, "juno") + coins, err = suite.app.ClaimKeeper.ClaimCoinsForAction(suite.ctx, addr2, types.ActionFree, "juno") + suite.Require().NoError(err) + + claimableAmountForFree = sdk.NewDecWithPrec(80, 2). + Mul(sdk.NewDecWithPrec(80, 2)). + Mul(sdk.NewDecWithPrec(40, 2)). + Mul(sdk.NewDecWithPrec(20, 2)). + Mul(sdk.NewDec(100_000_000)). + RoundInt64() // remaining balance = 100000000*(80/100)*(80/100)*(40/100), claim 20% for free + suite.Require().Equal(coins.String(), sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, claimableAmountForFree)).String()) + + // after 3 years + 1 hour, juno users shouldn't be able to claim anymore + suite.ctx = suite.ctx.WithBlockTime(time.Now().Add(time.Hour).Add(types.DefaultAirdropDuration)) + suite.app.ClaimKeeper.EndBlocker(suite.ctx) + suite.app.ClaimKeeper.ClearClaimedStatus(suite.ctx, "juno") + coins, err = suite.app.ClaimKeeper.ClaimCoinsForAction(suite.ctx.WithBlockTime(time.Now().Add(time.Hour).Add(types.DefaultAirdropDuration)), addr2, types.ActionFree, "juno") + suite.Require().NoError(err) + suite.Require().Equal(coins.String(), sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, 0)).String()) + + weight, err = suite.app.ClaimKeeper.GetTotalWeight(suite.ctx, types.DefaultAirdropIdentifier) + suite.Require().NoError(err) + suite.Require().Equal(weight, sdk.ZeroDec()) + + records = suite.app.ClaimKeeper.GetClaimRecords(suite.ctx, types.DefaultAirdropIdentifier) + suite.Require().Equal(0, len(records)) + //*********************** End of Juno airdrop ************************* +} diff --git a/x/claim/keeper/genesis.go b/x/claim/keeper/genesis.go new file mode 100644 index 0000000000..25dcf5d4a1 --- /dev/null +++ b/x/claim/keeper/genesis.go @@ -0,0 +1,31 @@ +package keeper + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/Stride-Labs/stride/x/claim/types" +) + +// InitGenesis initializes the capability module's state from a provided genesis +// state. +func (k Keeper) InitGenesis(ctx sdk.Context, genState types.GenesisState) { + // If its the chain genesis, set the airdrop start time to be now, and setup the needed module accounts. + if err := k.SetParams(ctx, genState.Params); err != nil { + panic(err) + } + if err := k.SetClaimRecordsWithWeights(ctx, genState.ClaimRecords); err != nil { + panic(err) + } +} + +// ExportGenesis returns the capability module's exported genesis. +func (k Keeper) ExportGenesis(ctx sdk.Context) *types.GenesisState { + params, err := k.GetParams(ctx) + if err != nil { + panic(err) + } + genesis := types.DefaultGenesis() + genesis.Params = params + genesis.ClaimRecords = k.GetClaimRecords(ctx, "") + return genesis +} diff --git a/x/claim/keeper/grpc_query.go b/x/claim/keeper/grpc_query.go new file mode 100644 index 0000000000..8421a293ec --- /dev/null +++ b/x/claim/keeper/grpc_query.go @@ -0,0 +1,98 @@ +package keeper + +import ( + "context" + + sdk "github.com/cosmos/cosmos-sdk/types" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + + "github.com/Stride-Labs/stride/x/claim/types" +) + +var _ types.QueryServer = Keeper{} + +// Params returns balances of the distributor account +func (k Keeper) DistributorAccountBalance(c context.Context, req *types.QueryDistributorAccountBalanceRequest) (*types.QueryDistributorAccountBalanceResponse, error) { + ctx := sdk.UnwrapSDKContext(c) + bal, err := k.GetDistributorAccountBalance(ctx, req.AirdropIdentifier) + if err != nil { + return nil, err + } + return &types.QueryDistributorAccountBalanceResponse{DistributorAccountBalance: sdk.NewCoins(bal)}, nil +} + +// Params returns params of the claim module. +func (k Keeper) Params(c context.Context, _ *types.QueryParamsRequest) (*types.QueryParamsResponse, error) { + ctx := sdk.UnwrapSDKContext(c) + params, err := k.GetParams(ctx) + if err != nil { + return nil, err + } + + return &types.QueryParamsResponse{Params: params}, nil +} + +// ClaimRecord returns user claim record by address and airdrop identifier +func (k Keeper) ClaimRecord( + goCtx context.Context, + req *types.QueryClaimRecordRequest, +) (*types.QueryClaimRecordResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "empty request") + } + + ctx := sdk.UnwrapSDKContext(goCtx) + + addr, err := sdk.AccAddressFromBech32(req.Address) + if err != nil { + return nil, err + } + + claimRecord, err := k.GetClaimRecord(ctx, addr, req.AirdropIdentifier) + return &types.QueryClaimRecordResponse{ClaimRecord: claimRecord}, err +} + +// ClaimableForAction returns claimable amount per action +func (k Keeper) ClaimableForAction( + goCtx context.Context, + req *types.QueryClaimableForActionRequest, +) (*types.QueryClaimableForActionResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "empty request") + } + + ctx := sdk.UnwrapSDKContext(goCtx) + addr, err := sdk.AccAddressFromBech32(req.Address) + if err != nil { + return nil, err + } + + coins, err := k.GetClaimableAmountForAction(ctx, addr, req.Action, req.AirdropIdentifier) + + return &types.QueryClaimableForActionResponse{ + Coins: coins, + }, err +} + +// TotalClaimable returns total claimable amount for user +func (k Keeper) TotalClaimable( + goCtx context.Context, + req *types.QueryTotalClaimableRequest, +) (*types.QueryTotalClaimableResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "empty request") + } + + ctx := sdk.UnwrapSDKContext(goCtx) + addr, err := sdk.AccAddressFromBech32(req.Address) + if err != nil { + return nil, err + } + + coins, err := k.GetUserTotalClaimable(ctx, addr, req.AirdropIdentifier) + + return &types.QueryTotalClaimableResponse{ + Coins: coins, + }, err +} diff --git a/x/claim/keeper/hooks.go b/x/claim/keeper/hooks.go new file mode 100644 index 0000000000..a42cfe6652 --- /dev/null +++ b/x/claim/keeper/hooks.go @@ -0,0 +1,103 @@ +package keeper + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + + epochstypes "github.com/Stride-Labs/stride/x/epochs/types" + stakingibctypes "github.com/Stride-Labs/stride/x/stakeibc/types" + + "github.com/Stride-Labs/stride/x/claim/types" +) + +func (k Keeper) AfterDelegationModified(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) { + identifiers := k.GetAirdropIdentifiersForUser(ctx, delAddr) + for _, identifier := range identifiers { + cacheCtx, write := ctx.CacheContext() + _, err := k.ClaimCoinsForAction(cacheCtx, delAddr, types.ActionDelegateStake, identifier) + if err == nil { + write() + } else { + k.Logger(ctx).Error(fmt.Sprintf("airdrop claim failure for %s on delegation hook: %s", delAddr.String(), err.Error())) + } + } +} + +func (k Keeper) AfterLiquidStake(ctx sdk.Context, addr sdk.AccAddress) { + identifiers := k.GetAirdropIdentifiersForUser(ctx, addr) + for _, identifier := range identifiers { + cacheCtx, write := ctx.CacheContext() + _, err := k.ClaimCoinsForAction(cacheCtx, addr, types.ActionLiquidStake, identifier) + if err == nil { + write() + } else { + k.Logger(ctx).Error(fmt.Sprintf("airdrop claim failure for %s on liquid staking hook: %s", addr.String(), err.Error())) + } + } +} + +func (k Keeper) BeforeEpochStart(ctx sdk.Context, epochInfo epochstypes.EpochInfo) { +} + +func (k Keeper) AfterEpochEnd(ctx sdk.Context, epochInfo epochstypes.EpochInfo) { + k.ClearClaimedStatus(ctx, epochInfo.Identifier) +} + +// ________________________________________________________________________________________ + +// Hooks wrapper struct for claim keeper +type Hooks struct { + k Keeper +} + +var _ stakingtypes.StakingHooks = Hooks{} +var _ stakingibctypes.StakeIBCHooks = Hooks{} +var _ epochstypes.EpochHooks = Hooks{} + +// Return the wrapper struct +func (k Keeper) Hooks() Hooks { + return Hooks{k} +} + +// ibcstaking hooks +func (h Hooks) AfterLiquidStake(ctx sdk.Context, addr sdk.AccAddress) { + h.k.AfterLiquidStake(ctx, addr) +} + +// epochs hooks +func (h Hooks) BeforeEpochStart(ctx sdk.Context, epochInfo epochstypes.EpochInfo) { + h.k.BeforeEpochStart(ctx, epochInfo) +} + +func (h Hooks) AfterEpochEnd(ctx sdk.Context, epochInfo epochstypes.EpochInfo) { + h.k.AfterEpochEnd(ctx, epochInfo) +} + +// staking hooks +func (h Hooks) AfterValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) {} +func (h Hooks) BeforeValidatorModified(ctx sdk.Context, valAddr sdk.ValAddress) {} +func (h Hooks) AfterValidatorRemoved(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) { +} +func (h Hooks) AfterValidatorBonded(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) { +} +func (h Hooks) AfterValidatorBeginUnbonding(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) { +} +func (h Hooks) BeforeDelegationCreated(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) { +} +func (h Hooks) BeforeDelegationSharesModified(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) { +} +func (h Hooks) BeforeDelegationRemoved(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) { +} +func (h Hooks) AfterDelegationModified(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) { + h.k.AfterDelegationModified(ctx, delAddr, valAddr) +} +func (h Hooks) BeforeValidatorSlashed(ctx sdk.Context, valAddr sdk.ValAddress, fraction sdk.Dec) {} +func (h Hooks) BeforeSlashingUnbondingDelegation(ctx sdk.Context, unbondingDelegation stakingtypes.UnbondingDelegation, + infractionHeight int64, slashFactor sdk.Dec) { +} + +func (h Hooks) BeforeSlashingRedelegation(ctx sdk.Context, srcValidator stakingtypes.Validator, redelegation stakingtypes.Redelegation, + infractionHeight int64, slashFactor sdk.Dec) { +} diff --git a/x/claim/keeper/keeper.go b/x/claim/keeper/keeper.go new file mode 100644 index 0000000000..43814caeb0 --- /dev/null +++ b/x/claim/keeper/keeper.go @@ -0,0 +1,41 @@ +package keeper + +import ( + "fmt" + + "github.com/tendermint/tendermint/libs/log" + + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/Stride-Labs/stride/x/claim/types" +) + +// Keeper struct +type Keeper struct { + cdc codec.Codec + storeKey sdk.StoreKey + accountKeeper types.AccountKeeper + bankKeeper types.BankKeeper + stakingKeeper types.StakingKeeper + distrKeeper types.DistrKeeper + epochsKeeper types.EpochsKeeper +} + +// NewKeeper returns keeper +func NewKeeper(cdc codec.Codec, storeKey sdk.StoreKey, ak types.AccountKeeper, bk types.BankKeeper, sk types.StakingKeeper, dk types.DistrKeeper, ek types.EpochsKeeper) *Keeper { + return &Keeper{ + cdc: cdc, + storeKey: storeKey, + accountKeeper: ak, + bankKeeper: bk, + stakingKeeper: sk, + distrKeeper: dk, + epochsKeeper: ek, + } +} + +// Logger returns logger +func (k Keeper) Logger(ctx sdk.Context) log.Logger { + return ctx.Logger().With("module", fmt.Sprintf("x/%s", types.ModuleName)) +} diff --git a/x/claim/keeper/keeper_test.go b/x/claim/keeper/keeper_test.go new file mode 100644 index 0000000000..b4e2b5331d --- /dev/null +++ b/x/claim/keeper/keeper_test.go @@ -0,0 +1,93 @@ +package keeper_test + +import ( + "testing" + "time" + + "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + "github.com/stretchr/testify/suite" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + + "github.com/Stride-Labs/stride/app" + "github.com/Stride-Labs/stride/x/claim/types" + minttypes "github.com/Stride-Labs/stride/x/mint/types" +) + +type KeeperTestSuite struct { + suite.Suite + + ctx sdk.Context + // querier sdk.Querier + app *app.StrideApp +} + +var distributors map[string]sdk.AccAddress + +func (suite *KeeperTestSuite) SetupTest() { + suite.app = app.InitStrideTestApp(true) + suite.ctx = suite.app.BaseApp.NewContext(false, tmproto.Header{Height: 1, ChainID: "stride-1", Time: time.Now().UTC()}) + distributors = make(map[string]sdk.AccAddress) + + // Initiate a distributor account for stride user airdrop + pub1 := secp256k1.GenPrivKey().PubKey() + addr1 := sdk.AccAddress(pub1.Address()) + suite.app.AccountKeeper.SetAccount(suite.ctx, authtypes.NewBaseAccount(addr1, nil, 0, 0)) + distributors[types.DefaultAirdropIdentifier] = addr1 + + // Initiate a distributor account for juno user airdrop + pub2 := secp256k1.GenPrivKey().PubKey() + addr2 := sdk.AccAddress(pub2.Address()) + suite.app.AccountKeeper.SetAccount(suite.ctx, authtypes.NewBaseAccount(addr2, nil, 0, 0)) + distributors["juno"] = addr2 + + // Initiate a distributor account for juno user airdrop + pub3 := secp256k1.GenPrivKey().PubKey() + addr3 := sdk.AccAddress(pub3.Address()) + suite.app.AccountKeeper.SetAccount(suite.ctx, authtypes.NewBaseAccount(addr3, nil, 0, 0)) + distributors["osmosis"] = addr3 + + // Mint coins to airdrop module + err := suite.app.BankKeeper.MintCoins(suite.ctx, minttypes.ModuleName, sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(300000000)))) + if err != nil { + panic(err) + } + err = suite.app.BankKeeper.SendCoinsFromModuleToAccount(suite.ctx, minttypes.ModuleName, addr1, sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100000000)))) + if err != nil { + panic(err) + } + err = suite.app.BankKeeper.SendCoinsFromModuleToAccount(suite.ctx, minttypes.ModuleName, addr2, sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100000000)))) + if err != nil { + panic(err) + } + err = suite.app.BankKeeper.SendCoinsFromModuleToAccount(suite.ctx, minttypes.ModuleName, addr3, sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100000000)))) + if err != nil { + panic(err) + } + + // Stride airdrop + airdropStartTime := time.Now() + err = suite.app.ClaimKeeper.CreateAirdropAndEpoch(suite.ctx, addr1.String(), sdk.DefaultBondDenom, uint64(airdropStartTime.Unix()), uint64(types.DefaultAirdropDuration.Seconds()), types.DefaultAirdropIdentifier) + if err != nil { + panic(err) + } + + // Juno airdrop + err = suite.app.ClaimKeeper.CreateAirdropAndEpoch(suite.ctx, addr2.String(), sdk.DefaultBondDenom, uint64(airdropStartTime.Add(time.Hour).Unix()), uint64(types.DefaultAirdropDuration.Seconds()), "juno") + if err != nil { + panic(err) + } + + // Osmosis airdrop + err = suite.app.ClaimKeeper.CreateAirdropAndEpoch(suite.ctx, addr3.String(), sdk.DefaultBondDenom, uint64(airdropStartTime.Unix()), uint64(types.DefaultAirdropDuration.Seconds()), "osmosis") + if err != nil { + panic(err) + } + + suite.ctx = suite.ctx.WithBlockTime(airdropStartTime) +} + +func TestKeeperTestSuite(t *testing.T) { + suite.Run(t, new(KeeperTestSuite)) +} diff --git a/x/claim/keeper/msg_server.go b/x/claim/keeper/msg_server.go new file mode 100644 index 0000000000..83894faab6 --- /dev/null +++ b/x/claim/keeper/msg_server.go @@ -0,0 +1,129 @@ +package keeper + +import ( + "context" + + sdk "github.com/cosmos/cosmos-sdk/types" + + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + + "github.com/Stride-Labs/stride/x/claim/types" +) + +type msgServer struct { + keeper Keeper +} + +func NewMsgServerImpl(keeper Keeper) types.MsgServer { + return &msgServer{ + keeper: keeper, + } +} + +var _ types.MsgServer = msgServer{} + +func (server msgServer) SetAirdropAllocations(goCtx context.Context, msg *types.MsgSetAirdropAllocations) (*types.MsgSetAirdropAllocationsResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + records := []types.ClaimRecord{} + totalWeight, err := server.keeper.GetTotalWeight(ctx, msg.AirdropIdentifier) + if err != nil { + return nil, err + } + + airdropDistributor, err := server.keeper.GetAirdropDistributor(ctx, msg.AirdropIdentifier) + if err != nil { + return nil, err + } + + addr, err := sdk.AccAddressFromBech32(msg.Allocator) + if err != nil { + return nil, err + } + + if !addr.Equals(airdropDistributor) { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid distributor address") + } + + users, weights := server.keeper.GetUnallocatedUsers(ctx, msg.AirdropIdentifier, msg.Users, msg.Weights) + for idx, user := range users { + record := types.ClaimRecord{ + Address: user, + Weight: weights[idx], + ActionCompleted: []bool{false, false, false}, + AirdropIdentifier: msg.AirdropIdentifier, + } + + records = append(records, record) + totalWeight = totalWeight.Add(weights[idx]) + } + + server.keeper.SetTotalWeight(ctx, totalWeight, msg.AirdropIdentifier) + err = server.keeper.SetClaimRecords(ctx, records) + if err != nil { + return nil, err + } + + return &types.MsgSetAirdropAllocationsResponse{}, nil +} + +func (server msgServer) ClaimFreeAmount(goCtx context.Context, msg *types.MsgClaimFreeAmount) (*types.MsgClaimFreeAmountResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + addr, err := sdk.AccAddressFromBech32(msg.User) + if err != nil { + return nil, err + } + + coins, err := server.keeper.ClaimCoinsForAction(ctx, addr, types.ActionFree, msg.AirdropIdentifier) + if err != nil { + return nil, err + } + + return &types.MsgClaimFreeAmountResponse{ClaimedAmount: coins}, nil +} + +func (server msgServer) CreateAirdrop(goCtx context.Context, msg *types.MsgCreateAirdrop) (*types.MsgCreateAirdropResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + _, err := sdk.AccAddressFromBech32(msg.Distributor) + if err != nil { + return nil, err + } + + airdrop := server.keeper.GetAirdropByDistributor(ctx, msg.Distributor) + if airdrop != nil { + return nil, types.ErrDistributorAlreadyExists + } + + err = server.keeper.CreateAirdropAndEpoch(ctx, msg.Distributor, msg.Denom, msg.StartTime, msg.Duration, msg.Identifier) + if err != nil { + return nil, err + } + + return &types.MsgCreateAirdropResponse{}, nil +} + +func (server msgServer) DeleteAirdrop(goCtx context.Context, msg *types.MsgDeleteAirdrop) (*types.MsgDeleteAirdropResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + addr, err := sdk.AccAddressFromBech32(msg.Distributor) + if err != nil { + return nil, err + } + + distributor, err := server.keeper.GetAirdropDistributor(ctx, msg.Identifier) + if err != nil { + return nil, err + } + + if !addr.Equals(distributor) { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid distributor address") + } + + err = server.keeper.DeleteAirdropAndEpoch(ctx, msg.Identifier) + if err != nil { + return nil, err + } + + return &types.MsgDeleteAirdropResponse{}, nil +} diff --git a/x/claim/keeper/msg_server_test.go b/x/claim/keeper/msg_server_test.go new file mode 100644 index 0000000000..beaa8e5beb --- /dev/null +++ b/x/claim/keeper/msg_server_test.go @@ -0,0 +1,135 @@ +package keeper_test + +import ( + "time" + + "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/Stride-Labs/stride/x/claim/keeper" + "github.com/Stride-Labs/stride/x/claim/types" +) + +func (suite *KeeperTestSuite) TestSetAirdropAllocationsForMultiAirdrops() { + suite.SetupTest() + msgServer := keeper.NewMsgServerImpl(suite.app.ClaimKeeper) + + // Set initial allocations for each airdrop + addr1 := sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) + addr2 := sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) + + allocations := []types.ClaimRecord{ + { + Address: addr1.String(), + Weight: sdk.NewDecWithPrec(50, 2), // 50% + ActionCompleted: []bool{false, false, false}, + AirdropIdentifier: types.DefaultAirdropIdentifier, + }, + { + Address: addr2.String(), + Weight: sdk.NewDecWithPrec(30, 2), // 30% + ActionCompleted: []bool{false, false, false}, + AirdropIdentifier: "juno", + }, + } + + for _, record := range allocations { + _, err := msgServer.SetAirdropAllocations(sdk.WrapSDKContext(suite.ctx), &types.MsgSetAirdropAllocations{ + Allocator: distributors[record.AirdropIdentifier].String(), + AirdropIdentifier: record.AirdropIdentifier, + Users: []string{record.Address}, + Weights: []sdk.Dec{record.Weight}, + }) + suite.Require().NoError(err) + } + + // Set second allocations for each airdrop + addr1 = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) + addr2 = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) + + allocations2 := []types.ClaimRecord{ + { + Address: addr1.String(), + Weight: sdk.NewDecWithPrec(40, 2), // 40% + ActionCompleted: []bool{false, false, false}, + AirdropIdentifier: types.DefaultAirdropIdentifier, + }, + { + Address: addr2.String(), + Weight: sdk.NewDecWithPrec(20, 2), // 20% + ActionCompleted: []bool{false, false, false}, + AirdropIdentifier: "juno", + }, + } + + for _, record := range allocations2 { + _, err := msgServer.SetAirdropAllocations(sdk.WrapSDKContext(suite.ctx), &types.MsgSetAirdropAllocations{ + Allocator: distributors[record.AirdropIdentifier].String(), + AirdropIdentifier: record.AirdropIdentifier, + Users: []string{record.Address}, + Weights: []sdk.Dec{record.Weight}, + }) + suite.Require().NoError(err) + } + + totalWeightStride, err := suite.app.ClaimKeeper.GetTotalWeight(suite.ctx, types.DefaultAirdropIdentifier) + suite.Require().NoError(err) + suite.Require().Equal(totalWeightStride, sdk.NewDecWithPrec(90, 2)) + + totalWeightJuno, err := suite.app.ClaimKeeper.GetTotalWeight(suite.ctx, "juno") + suite.Require().NoError(err) + suite.Require().Equal(totalWeightJuno, sdk.NewDecWithPrec(50, 2)) + + claimRecords := suite.app.ClaimKeeper.GetClaimRecords(suite.ctx, types.DefaultAirdropIdentifier) + suite.Require().Equal(2, len(claimRecords)) + + claimRecords = suite.app.ClaimKeeper.GetClaimRecords(suite.ctx, "juno") + suite.Require().Equal(2, len(claimRecords)) + + // Multiple airdrop allocations for same user should be ignored + addr2 = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) + allocations3 := []types.ClaimRecord{ + { + Address: addr1.String(), // duplicated airdrop address + Weight: sdk.NewDecWithPrec(40, 2), // 40% + ActionCompleted: []bool{false, false, false}, + AirdropIdentifier: types.DefaultAirdropIdentifier, + }, + { + Address: addr2.String(), + Weight: sdk.NewDecWithPrec(20, 2), // 20% + ActionCompleted: []bool{false, false, false}, + AirdropIdentifier: "juno", + }, + } + for _, record := range allocations3 { + _, err := msgServer.SetAirdropAllocations(sdk.WrapSDKContext(suite.ctx), &types.MsgSetAirdropAllocations{ + Allocator: distributors[record.AirdropIdentifier].String(), + AirdropIdentifier: record.AirdropIdentifier, + Users: []string{record.Address}, + Weights: []sdk.Dec{record.Weight}, + }) + suite.Require().NoError(err) + } + + claimRecords = suite.app.ClaimKeeper.GetClaimRecords(suite.ctx, types.DefaultAirdropIdentifier) + suite.Require().Equal(2, len(claimRecords)) + + claimRecords = suite.app.ClaimKeeper.GetClaimRecords(suite.ctx, "juno") + suite.Require().Equal(3, len(claimRecords)) +} + +func (suite *KeeperTestSuite) TestCreateAirdrop() { + suite.SetupTest() + msgServer := keeper.NewMsgServerImpl(suite.app.ClaimKeeper) + + _, err := msgServer.CreateAirdrop(sdk.WrapSDKContext(suite.ctx), &types.MsgCreateAirdrop{ + Distributor: distributors[types.DefaultAirdropIdentifier].String(), + Identifier: "stride-1", + StartTime: uint64(time.Now().Unix()), + Duration: uint64(time.Hour), + Denom: "stake", + }) + + suite.Require().Error(err) +} diff --git a/x/claim/keeper/params.go b/x/claim/keeper/params.go new file mode 100644 index 0000000000..8631c771ca --- /dev/null +++ b/x/claim/keeper/params.go @@ -0,0 +1,27 @@ +package keeper + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/Stride-Labs/stride/x/claim/types" +) + +// GetParams get params +func (k Keeper) GetParams(ctx sdk.Context) (types.Params, error) { + store := ctx.KVStore(k.storeKey) + bz := store.Get([]byte(types.ParamsKey)) + params := types.Params{} + err := k.cdc.UnmarshalJSON(bz, ¶ms) + return params, err +} + +// SetParams set params +func (k Keeper) SetParams(ctx sdk.Context, params types.Params) error { + store := ctx.KVStore(k.storeKey) + bz, err := k.cdc.MarshalJSON(¶ms) + if err != nil { + return err + } + store.Set([]byte(types.ParamsKey), bz) + return nil +} diff --git a/x/claim/keeper/query.go b/x/claim/keeper/query.go new file mode 100644 index 0000000000..62fd954123 --- /dev/null +++ b/x/claim/keeper/query.go @@ -0,0 +1,28 @@ +package keeper + +import ( + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + + "github.com/Stride-Labs/stride/x/claim/types" + + abci "github.com/tendermint/tendermint/abci/types" +) + +// NewQuerier returns legacy querier endpoint +func NewQuerier(k Keeper, legacyQuerierCdc *codec.LegacyAmino) sdk.Querier { + return func(ctx sdk.Context, path []string, req abci.RequestQuery) ([]byte, error) { + var ( + res []byte + err error + ) + + switch path[0] { + default: + err = sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown %s query endpoint: %s", types.ModuleName, path[0]) + } + + return res, err + } +} diff --git a/x/claim/module.go b/x/claim/module.go new file mode 100644 index 0000000000..a3ee38420b --- /dev/null +++ b/x/claim/module.go @@ -0,0 +1,165 @@ +package claim + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/gorilla/mux" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/spf13/cobra" + + abci "github.com/tendermint/tendermint/abci/types" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" + cdctypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + + "github.com/Stride-Labs/stride/x/claim/client/cli" + "github.com/Stride-Labs/stride/x/claim/client/rest" + "github.com/Stride-Labs/stride/x/claim/keeper" + "github.com/Stride-Labs/stride/x/claim/types" +) + +var ( + _ module.AppModule = AppModule{} + _ module.AppModuleBasic = AppModuleBasic{} +) + +// ---------------------------------------------------------------------------- +// AppModuleBasic +// ---------------------------------------------------------------------------- + +// AppModuleBasic implements the AppModuleBasic interface for the capability module. +type AppModuleBasic struct { + cdc codec.Codec +} + +func NewAppModuleBasic(cdc codec.Codec) AppModuleBasic { + return AppModuleBasic{cdc: cdc} +} + +// Name returns the capability module's name. +func (AppModuleBasic) Name() string { + return types.ModuleName +} + +func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { +} + +// RegisterInterfaces registers the module's interface types +func (a AppModuleBasic) RegisterInterfaces(reg cdctypes.InterfaceRegistry) { + types.RegisterInterfaces(reg) +} + +// DefaultGenesis returns the capability module's default genesis state. +func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { + return cdc.MustMarshalJSON(types.DefaultGenesis()) +} + +// ValidateGenesis performs genesis state validation for the capability module. +func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, bz json.RawMessage) error { + var genState types.GenesisState + if err := cdc.UnmarshalJSON(bz, &genState); err != nil { + return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err) + } + return genState.Validate() +} + +// RegisterRESTRoutes registers the capability module's REST service handlers. +func (AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Router) { + rest.RegisterRoutes(clientCtx, rtr) +} + +// RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the module. +func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { + types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)) //nolint:errcheck +} + +// GetTxCmd returns the capability module's root tx command. +func (a AppModuleBasic) GetTxCmd() *cobra.Command { + return cli.GetTxCmd() +} + +// GetQueryCmd returns the capability module's root query command. +func (AppModuleBasic) GetQueryCmd() *cobra.Command { + return cli.GetQueryCmd(types.StoreKey) +} + +// ---------------------------------------------------------------------------- +// AppModule +// ---------------------------------------------------------------------------- + +// AppModule implements the AppModule interface for the capability module. +type AppModule struct { + AppModuleBasic + + keeper keeper.Keeper +} + +func NewAppModule(cdc codec.Codec, keeper keeper.Keeper) AppModule { + return AppModule{ + AppModuleBasic: NewAppModuleBasic(cdc), + keeper: keeper, + } +} + +// Name returns the capability module's name. +func (am AppModule) Name() string { + return am.AppModuleBasic.Name() +} + +// Route returns the capability module's message routing key. +func (am AppModule) Route() sdk.Route { + return sdk.NewRoute(types.RouterKey, NewHandler(am.keeper)) +} + +// QuerierRoute returns the capability module's query routing key. +func (AppModule) QuerierRoute() string { return types.QuerierRoute } + +// LegacyQuerierHandler returns the capability module's Querier. +func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sdk.Querier { + return keeper.NewQuerier(am.keeper, legacyQuerierCdc) +} + +// RegisterServices registers a GRPC query service to respond to the +// module-specific GRPC queries. +func (am AppModule) RegisterServices(cfg module.Configurator) { + types.RegisterQueryServer(cfg.QueryServer(), am.keeper) + types.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(am.keeper)) +} + +// RegisterInvariants registers the capability module's invariants. +func (am AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {} + +// InitGenesis performs the capability module's genesis initialization It returns +// no validator updates. +func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, gs json.RawMessage) []abci.ValidatorUpdate { + var genState types.GenesisState + // Initialize global index to index in genesis state + cdc.MustUnmarshalJSON(gs, &genState) + + am.keeper.InitGenesis(ctx, genState) + return []abci.ValidatorUpdate{} +} + +// ExportGenesis returns the capability module's exported genesis state as raw JSON bytes. +func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage { + genState := am.keeper.ExportGenesis(ctx) + return cdc.MustMarshalJSON(genState) +} + +// BeginBlock executes all ABCI BeginBlock logic respective to the capability module. +func (am AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) {} + +// EndBlock executes all ABCI EndBlock logic respective to the capability module. It +// returns no validator updates. +func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { + am.keeper.EndBlocker(ctx) + return []abci.ValidatorUpdate{} +} + +// ConsensusVersion implements AppModule/ConsensusVersion. +func (AppModule) ConsensusVersion() uint64 { return 1 } diff --git a/x/claim/spec/01_concepts.md b/x/claim/spec/01_concepts.md new file mode 100644 index 0000000000..1bbd9bb4f7 --- /dev/null +++ b/x/claim/spec/01_concepts.md @@ -0,0 +1,14 @@ + + +# Concepts + +In Stride, users are required to claim their airdrop by participating in core network activities. An Airdrop recipient is given 20% of the airdrop amount which is not in vesting, and then they have to perform the following activities to get the rest: + +* 20% vesting over 3 months by staking +* 60% vesting over 3 months by liquid staking + +At initial, module stores all airdrop users with amounts from genesis inside KVStore. + +Airdrop users are eligible to claim their vesting or free amount only once in the initial period of 3 months and after the initial period, users can claim tokens monthly not in vesting format. diff --git a/x/claim/spec/02_state.md b/x/claim/spec/02_state.md new file mode 100644 index 0000000000..51a1a0df02 --- /dev/null +++ b/x/claim/spec/02_state.md @@ -0,0 +1,45 @@ + + +# State + +### Claim Records + +```protobuf +// A Claim Records is the metadata of claim data per address +message ClaimRecord { + // address of claim user + string address = 1 [ (gogoproto.moretags) = "yaml:\"address\"" ]; + + // weight that represent the portion from total allocations + double weight = 2; + + // true if action is completed + // index of bool in array refers to action enum # + repeated bool action_completed = 3 [ + (gogoproto.moretags) = "yaml:\"action_completed\"" + ]; +} +``` +When a user get airdrop for his/her action, claim record is created to prevent duplicated actions on future actions. + +### State + +```protobuf +message GenesisState { + // params defines all the parameters of the module. + Params params = 2 [ + (gogoproto.moretags) = "yaml:\"params\"", + (gogoproto.nullable) = false + ]; + + // list of claim records, one for every airdrop recipient + repeated ClaimRecord claim_records = 3 [ + (gogoproto.moretags) = "yaml:\"claim_records\"", + (gogoproto.nullable) = false + ]; +} +``` + +Claim module's state consists of `params`, and `claim_records`. diff --git a/x/claim/spec/03_events.md b/x/claim/spec/03_events.md new file mode 100644 index 0000000000..6c50792493 --- /dev/null +++ b/x/claim/spec/03_events.md @@ -0,0 +1,15 @@ + + +# Events + +## External module hooks + +`claim` module emits the following events at the time of hooks: + +| Type | Attribute Key | Attribute Value | +| ----- | ------------- | --------------- | +| claim | sender | {receiver} | +| claim | amount | {claim_amount} | + diff --git a/x/claim/spec/04_keeper.md b/x/claim/spec/04_keeper.md new file mode 100644 index 0000000000..d347fe3e7f --- /dev/null +++ b/x/claim/spec/04_keeper.md @@ -0,0 +1,24 @@ + + +# Keepers + +## Keeper functions + +Claim keeper module provides utility functions to manage epochs. + +```go + GetModuleAccountAddress(ctx sdk.Context) sdk.AccAddress + GetDistributorAccountBalance(ctx sdk.Context) sdk.Coin + EndAirdrop(ctx sdk.Context) error + GetClaimRecord(ctx sdk.Context, addr sdk.AccAddress) (types.ClaimRecord, error) + GetClaimRecords(ctx sdk.Context) []types.ClaimRecord + SetClaimRecord(ctx sdk.Context, claimRecord types.ClaimRecord) error + SetClaimRecords(ctx sdk.Context, claimRecords []types.ClaimRecord) error + GetClaimableAmountForAction(ctx sdk.Context, addr sdk.AccAddress, action types.Action) (sdk.Coins, error) + GetUserTotalClaimable(ctx sdk.Context, addr sdk.AccAddress) (sdk.Coins, error) + ClaimCoinsForAction(ctx sdk.Context, addr sdk.AccAddress, action types.Action) (sdk.Coins, error) + clearInitialClaimables(ctx sdk.Context) + fundRemainingsToCommunity(ctx sdk.Context) error +``` diff --git a/x/claim/spec/05_react_hooks.md b/x/claim/spec/05_react_hooks.md new file mode 100644 index 0000000000..4613696c86 --- /dev/null +++ b/x/claim/spec/05_react_hooks.md @@ -0,0 +1,12 @@ + + +# React Hooks + +Claim module react on following hooks of external modules. + +20% of airdrop is sent to a vesting account when `staking.AfterDelegationModified` hook is triggered. +20% of airdrop is sent to a vesting account when `stakeibc.AfterLiquidStake` hook is triggered. + +When airdrop is claimed for specific hook type, it can't be claimed double. diff --git a/x/claim/spec/06_queries.md b/x/claim/spec/06_queries.md new file mode 100644 index 0000000000..bceef87300 --- /dev/null +++ b/x/claim/spec/06_queries.md @@ -0,0 +1,42 @@ + + +# Queries + +## GRPC queries + +Claim module provides below GRPC queries to query claim status + +```protobuf +service Query { + rpc DistributorAccountBalance(QueryDistributorAccountBalanceRequest) returns (QueryDistributorAccountBalanceResponse) {} + rpc Params(QueryParamsRequest) returns (QueryParamsResponse) {} + rpc ClaimRecord(QueryClaimRecordRequest) returns (QueryClaimRecordResponse) {} + rpc ClaimableForAction(QueryClaimableForActionRequest) returns (QueryClaimableForActionResponse) {} + rpc TotalClaimable(QueryTotalClaimableRequest) returns (QueryTotalClaimableResponse) {} +} +``` + +## CLI commands + +For the following commands, you can change `$(strided keys show -a {your key name})` with the address directly. + +Query the claim record for a given address + +```sh +strided query claim claim-record $(strided keys show -a {your key name}) +``` + +Query the claimable amount that would be earned if a specific action is completed right now. + +```sh + +strided query claim claimable-for-action $(strided keys show -a {your key name}) ActionAddLiquidity +``` + +Query the total claimable amount that would be earned if all remaining actions were completed right now. + +```sh +strided query claim total-claimable $(strided keys show -a {your key name}) ActionAddLiquidity +``` diff --git a/x/claim/spec/07_params.md b/x/claim/spec/07_params.md new file mode 100644 index 0000000000..17caa888c9 --- /dev/null +++ b/x/claim/spec/07_params.md @@ -0,0 +1,33 @@ + + +# Params + +Claim module provides below params + +```protobuf +// Params defines the claim module's parameters. +message Params { + google.protobuf.Timestamp airdrop_start_time = 1 [ + (gogoproto.stdtime) = true, + (gogoproto.nullable) = false, + (gogoproto.moretags) = "yaml:\"airdrop_start_time\"" + ]; + google.protobuf.Timestamp airdrop_duration = 2 [ + (gogoproto.nullable) = false, + (gogoproto.stdduration) = true, + (gogoproto.jsontag) = "airdrop_duration,omitempty", + (gogoproto.moretags) = "yaml:\"airdrop_duration\"" + ]; + // denom of claimable asset + string claim_denom = 3; + // airdrop distribution account + string distributor_address = 4; +} +``` + +1. `airdrop_start_time` refers to the time when user can start to claim airdrop. +2. `airdrop_duration` refers to the duration from start time to end time. +3. `claim_denom` refers to the denomination of claiming tokens. As a default, it's `ustrd`. +4. `distributor_address` refers to the address of distribution account. \ No newline at end of file diff --git a/x/claim/spec/README.md b/x/claim/spec/README.md new file mode 100644 index 0000000000..17baa63adb --- /dev/null +++ b/x/claim/spec/README.md @@ -0,0 +1,79 @@ +# Claims module + +## Abstract + +The Stride claims module has users claim higher percentages as they perform certain tasks on-chain. +Furthermore, these claimable assets 'expire' if not claimed. +Users have three months (`AirdropDuration`) to claim their full airdrop amount +After three months from launch, all unclaimed tokens get sent to the community pool. + +## Contents + +1. **[Concept](01_concepts.md)** +2. **[State](02_state.md)** +3. **[Events](03_events.md)** +4. **[Keeper](04_keeper.md)** +5. **[React Hooks](05_react_hooks.md)** +6. **[Queries](06_queries.md)** +7. **[Params](07_params.md)** + +## Genesis State + +## Actions + +There are 2 types of actions, each of which release another 50% of the airdrop allocation. +The 2 actions are as follows: + +```golang +ActionLiquidStake Action = 0 +ActionDelegateStake Action = 1 +``` + +These actions are monitored by registring claim **hooks** to the stakeibc, and staking modules. +This means that when you perform an action, the claims module will immediately unlock those coins if they are applicable. +These actions can be performed in any order. + +The code is structured by separating out a segment of the tokens as "claimable", indexed by each action type. +So if Alice delegates tokens, the claims module will move the 50% of the claimables associated with staking to her liquid balance. +If she delegates again, there will not be additional tokens given, as the relevant action has already been performed. +Every action must be performed to claim the full amount. + +## ClaimRecords + +A claim record is a struct that contains data about the claims process of each airdrop recipient. + +It contains an address, the initial claimable airdrop amount, and an array of bools representing +whether each action has been completed. The position in the array refers to enum number of the action. + +So for example, `[true, true]` means that `ActionLiquidStake` and `ActionDelegateStake` are completed. + +```golang +type ClaimRecord struct { + // address of claim user + Address string + // weight that represent the portion from total allocation + Weight sdk.Dec + // true if action is completed + // index of bool in array refers to action enum # + ActionCompleted []bool +} + +``` + + +## Params + +The airdrop logic has 4 parameters: + +```golang +type Params struct { + // Time that marks the beginning of the airdrop disbursal, + // should be set to chain launch time. + AirdropStartTime time.Time + AirdropDuration time.Duration + // denom of claimable asset + ClaimDenom string + // address of distributor account + DistributorAddress string +} +``` diff --git a/x/claim/types/claim.pb.go b/x/claim/types/claim.pb.go new file mode 100644 index 0000000000..143bcf6d00 --- /dev/null +++ b/x/claim/types/claim.pb.go @@ -0,0 +1,562 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: claim/v1beta1/claim.proto + +package types + +import ( + fmt "fmt" + _ "github.com/cosmos/cosmos-sdk/types" + github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" + _ "github.com/cosmos/cosmos-sdk/x/bank/types" + _ "github.com/gogo/protobuf/gogoproto" + proto "github.com/gogo/protobuf/proto" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +type Action int32 + +const ( + ActionFree Action = 0 + ActionLiquidStake Action = 1 + ActionDelegateStake Action = 2 +) + +var Action_name = map[int32]string{ + 0: "ActionFree", + 1: "ActionLiquidStake", + 2: "ActionDelegateStake", +} + +var Action_value = map[string]int32{ + "ActionFree": 0, + "ActionLiquidStake": 1, + "ActionDelegateStake": 2, +} + +func (x Action) String() string { + return proto.EnumName(Action_name, int32(x)) +} + +func (Action) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_14c07c0e7ea7a052, []int{0} +} + +// A Claim Records is the metadata of claim data per address +type ClaimRecord struct { + // airdrop identifier + AirdropIdentifier string `protobuf:"bytes,1,opt,name=airdrop_identifier,json=airdropIdentifier,proto3" json:"airdrop_identifier,omitempty" yaml:"airdrop_identifier"` + // address of claim user + Address string `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty" yaml:"address"` + // weight that represent the portion from total allocation + Weight github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,3,opt,name=weight,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"weight" yaml:"weight"` + // true if action is completed + // index of bool in array refers to action enum # + ActionCompleted []bool `protobuf:"varint,4,rep,packed,name=action_completed,json=actionCompleted,proto3" json:"action_completed,omitempty" yaml:"action_completed"` +} + +func (m *ClaimRecord) Reset() { *m = ClaimRecord{} } +func (m *ClaimRecord) String() string { return proto.CompactTextString(m) } +func (*ClaimRecord) ProtoMessage() {} +func (*ClaimRecord) Descriptor() ([]byte, []int) { + return fileDescriptor_14c07c0e7ea7a052, []int{0} +} +func (m *ClaimRecord) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ClaimRecord) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ClaimRecord.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ClaimRecord) XXX_Merge(src proto.Message) { + xxx_messageInfo_ClaimRecord.Merge(m, src) +} +func (m *ClaimRecord) XXX_Size() int { + return m.Size() +} +func (m *ClaimRecord) XXX_DiscardUnknown() { + xxx_messageInfo_ClaimRecord.DiscardUnknown(m) +} + +var xxx_messageInfo_ClaimRecord proto.InternalMessageInfo + +func (m *ClaimRecord) GetAirdropIdentifier() string { + if m != nil { + return m.AirdropIdentifier + } + return "" +} + +func (m *ClaimRecord) GetAddress() string { + if m != nil { + return m.Address + } + return "" +} + +func (m *ClaimRecord) GetActionCompleted() []bool { + if m != nil { + return m.ActionCompleted + } + return nil +} + +func init() { + proto.RegisterEnum("Stridelabs.stride.claim.v1beta1.Action", Action_name, Action_value) + proto.RegisterType((*ClaimRecord)(nil), "Stridelabs.stride.claim.v1beta1.ClaimRecord") +} + +func init() { proto.RegisterFile("claim/v1beta1/claim.proto", fileDescriptor_14c07c0e7ea7a052) } + +var fileDescriptor_14c07c0e7ea7a052 = []byte{ + // 421 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x64, 0x92, 0xc1, 0x6e, 0xd4, 0x30, + 0x10, 0x86, 0x93, 0x6d, 0xb5, 0x80, 0x11, 0x65, 0x6b, 0x40, 0x4d, 0x17, 0xe1, 0x94, 0x1c, 0x50, + 0x05, 0x34, 0x56, 0xc5, 0x8d, 0x0b, 0x62, 0x5b, 0x2a, 0x21, 0xad, 0x38, 0xa4, 0x07, 0x24, 0x2e, + 0x95, 0x13, 0x0f, 0xa9, 0xb5, 0x49, 0x1c, 0x6c, 0x17, 0xe8, 0x1b, 0x70, 0xe4, 0x1d, 0xb8, 0xf1, + 0x24, 0x3d, 0xf6, 0x88, 0x38, 0x44, 0x68, 0xf7, 0x0d, 0xf2, 0x04, 0xa8, 0x99, 0xec, 0x82, 0xe0, + 0x94, 0x99, 0xff, 0xff, 0xf2, 0xdb, 0x23, 0x0f, 0xd9, 0xce, 0x0a, 0xa1, 0x4a, 0xfe, 0x71, 0x3f, + 0x05, 0x27, 0xf6, 0x79, 0xd7, 0xc5, 0xb5, 0xd1, 0x4e, 0xd3, 0xf0, 0xd8, 0x19, 0x25, 0xa1, 0x10, + 0xa9, 0x8d, 0x6d, 0x57, 0xc6, 0x68, 0xf7, 0xf0, 0xf8, 0x6e, 0xae, 0x73, 0xdd, 0xb1, 0xfc, 0xaa, + 0xc2, 0xdf, 0xc6, 0x2c, 0xd3, 0xb6, 0xd4, 0x96, 0xa7, 0xc2, 0xc2, 0x9f, 0x5c, 0xad, 0xaa, 0xde, + 0x7f, 0xb8, 0xf2, 0xab, 0xd9, 0xca, 0xcf, 0xa1, 0x02, 0xab, 0x2c, 0x22, 0xd1, 0xf7, 0x01, 0xb9, + 0x79, 0x70, 0x75, 0x54, 0x02, 0x99, 0x36, 0x92, 0x4e, 0x09, 0x15, 0xca, 0x48, 0xa3, 0xeb, 0x13, + 0x25, 0xa1, 0x72, 0xea, 0xbd, 0x02, 0x13, 0xf8, 0x3b, 0xfe, 0xee, 0x8d, 0xc9, 0x83, 0xb6, 0x09, + 0xb7, 0xcf, 0x45, 0x59, 0x3c, 0x8f, 0xfe, 0x67, 0xa2, 0x64, 0xb3, 0x17, 0x5f, 0xaf, 0x34, 0xfa, + 0x94, 0x5c, 0x13, 0x52, 0x1a, 0xb0, 0x36, 0x18, 0x74, 0x11, 0xb4, 0x6d, 0xc2, 0x8d, 0x3e, 0x02, + 0x8d, 0x28, 0x59, 0x22, 0xf4, 0x2d, 0x19, 0x7e, 0x02, 0x95, 0x9f, 0xba, 0x60, 0xad, 0x83, 0x5f, + 0x5c, 0x34, 0xa1, 0xf7, 0xb3, 0x09, 0x1f, 0xe5, 0xca, 0x9d, 0x9e, 0xa5, 0x71, 0xa6, 0x4b, 0xde, + 0x4f, 0x84, 0x9f, 0x3d, 0x2b, 0x67, 0xdc, 0x9d, 0xd7, 0x60, 0xe3, 0x43, 0xc8, 0xda, 0x26, 0xbc, + 0x85, 0xd1, 0x98, 0x12, 0x25, 0x7d, 0x1c, 0x3d, 0x22, 0x23, 0x91, 0x39, 0xa5, 0xab, 0x93, 0x4c, + 0x97, 0x75, 0x01, 0x0e, 0x64, 0xb0, 0xbe, 0xb3, 0xb6, 0x7b, 0x7d, 0x72, 0xbf, 0x6d, 0xc2, 0xad, + 0xfe, 0x3e, 0xff, 0x10, 0x51, 0x72, 0x1b, 0xa5, 0x83, 0xa5, 0xf2, 0xf8, 0x0d, 0x19, 0xbe, 0xec, + 0x24, 0xba, 0x41, 0x08, 0x56, 0x47, 0x06, 0x60, 0xe4, 0xd1, 0x7b, 0x64, 0x13, 0xfb, 0xa9, 0xfa, + 0x70, 0xa6, 0xe4, 0xb1, 0x13, 0x33, 0x18, 0xf9, 0x74, 0x8b, 0xdc, 0x41, 0xf9, 0x10, 0x0a, 0xc8, + 0x85, 0x03, 0x34, 0x06, 0xe3, 0xf5, 0x2f, 0xdf, 0x98, 0x37, 0x79, 0x75, 0x31, 0x67, 0xfe, 0xe5, + 0x9c, 0xf9, 0xbf, 0xe6, 0xcc, 0xff, 0xba, 0x60, 0xde, 0xe5, 0x82, 0x79, 0x3f, 0x16, 0xcc, 0x7b, + 0xf7, 0xe4, 0xaf, 0x91, 0x71, 0x37, 0xf6, 0xa6, 0x22, 0xb5, 0x1c, 0x97, 0x83, 0x7f, 0xc6, 0xed, + 0xc1, 0xd9, 0xd3, 0x61, 0xf7, 0x94, 0xcf, 0x7e, 0x07, 0x00, 0x00, 0xff, 0xff, 0x35, 0x29, 0xfd, + 0x51, 0x61, 0x02, 0x00, 0x00, +} + +func (m *ClaimRecord) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ClaimRecord) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ClaimRecord) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.ActionCompleted) > 0 { + for iNdEx := len(m.ActionCompleted) - 1; iNdEx >= 0; iNdEx-- { + i-- + if m.ActionCompleted[iNdEx] { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + } + i = encodeVarintClaim(dAtA, i, uint64(len(m.ActionCompleted))) + i-- + dAtA[i] = 0x22 + } + { + size := m.Weight.Size() + i -= size + if _, err := m.Weight.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintClaim(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + if len(m.Address) > 0 { + i -= len(m.Address) + copy(dAtA[i:], m.Address) + i = encodeVarintClaim(dAtA, i, uint64(len(m.Address))) + i-- + dAtA[i] = 0x12 + } + if len(m.AirdropIdentifier) > 0 { + i -= len(m.AirdropIdentifier) + copy(dAtA[i:], m.AirdropIdentifier) + i = encodeVarintClaim(dAtA, i, uint64(len(m.AirdropIdentifier))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintClaim(dAtA []byte, offset int, v uint64) int { + offset -= sovClaim(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *ClaimRecord) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.AirdropIdentifier) + if l > 0 { + n += 1 + l + sovClaim(uint64(l)) + } + l = len(m.Address) + if l > 0 { + n += 1 + l + sovClaim(uint64(l)) + } + l = m.Weight.Size() + n += 1 + l + sovClaim(uint64(l)) + if len(m.ActionCompleted) > 0 { + n += 1 + sovClaim(uint64(len(m.ActionCompleted))) + len(m.ActionCompleted)*1 + } + return n +} + +func sovClaim(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozClaim(x uint64) (n int) { + return sovClaim(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *ClaimRecord) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowClaim + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ClaimRecord: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ClaimRecord: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AirdropIdentifier", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowClaim + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthClaim + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthClaim + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AirdropIdentifier = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowClaim + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthClaim + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthClaim + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Address = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Weight", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowClaim + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthClaim + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthClaim + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Weight.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType == 0 { + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowClaim + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.ActionCompleted = append(m.ActionCompleted, bool(v != 0)) + } else if wireType == 2 { + var packedLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowClaim + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + packedLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if packedLen < 0 { + return ErrInvalidLengthClaim + } + postIndex := iNdEx + packedLen + if postIndex < 0 { + return ErrInvalidLengthClaim + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var elementCount int + elementCount = packedLen + if elementCount != 0 && len(m.ActionCompleted) == 0 { + m.ActionCompleted = make([]bool, 0, elementCount) + } + for iNdEx < postIndex { + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowClaim + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.ActionCompleted = append(m.ActionCompleted, bool(v != 0)) + } + } else { + return fmt.Errorf("proto: wrong wireType = %d for field ActionCompleted", wireType) + } + default: + iNdEx = preIndex + skippy, err := skipClaim(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthClaim + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipClaim(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowClaim + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowClaim + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowClaim + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthClaim + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupClaim + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthClaim + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthClaim = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowClaim = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupClaim = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/claim/types/codec.go b/x/claim/types/codec.go new file mode 100644 index 0000000000..cd09a39931 --- /dev/null +++ b/x/claim/types/codec.go @@ -0,0 +1,37 @@ +package types + +import ( + "github.com/cosmos/cosmos-sdk/codec" + cdctypes "github.com/cosmos/cosmos-sdk/codec/types" + cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/msgservice" +) + +func RegisterCodec(cdc *codec.LegacyAmino) { + cdc.RegisterConcrete(&MsgSetAirdropAllocations{}, "claim/SetAirdropAllocation", nil) + cdc.RegisterConcrete(&MsgClaimFreeAmount{}, "claim/ClaimFreeAmount", nil) + cdc.RegisterConcrete(&MsgCreateAirdrop{}, "claim/MsgCreateAirdrop", nil) + cdc.RegisterConcrete(&MsgDeleteAirdrop{}, "claim/MsgDeleteAirdrop", nil) +} + +func RegisterInterfaces(registry cdctypes.InterfaceRegistry) { + registry.RegisterImplementations((*sdk.Msg)(nil), + &MsgSetAirdropAllocations{}, + &MsgClaimFreeAmount{}, + &MsgCreateAirdrop{}, + &MsgDeleteAirdrop{}, + ) + msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) +} + +var ( + Amino = codec.NewLegacyAmino() + ModuleCdc = codec.NewAminoCodec(Amino) +) + +func init() { + RegisterCodec(Amino) + cryptocodec.RegisterCrypto(Amino) + sdk.RegisterLegacyAminoCodec(Amino) +} diff --git a/x/claim/types/errors.go b/x/claim/types/errors.go new file mode 100644 index 0000000000..1b11fce743 --- /dev/null +++ b/x/claim/types/errors.go @@ -0,0 +1,23 @@ +package types + +// DONTCOVER + +import ( + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + +// x/claim module sentinel errors +var ( + ErrTotalWeightNotSet = sdkerrors.Register(ModuleName, 1101, + "total weight not set") + ErrTotalWeightParse = sdkerrors.Register(ModuleName, 1102, + "total weight parse error") + ErrFailedToGetTotalWeight = sdkerrors.Register(ModuleName, 1104, + "failed to get total weight") + ErrFailedToParseDec = sdkerrors.Register(ModuleName, 1105, + "failed to parse dec from str") + ErrAirdropAlreadyExists = sdkerrors.Register(ModuleName, 1106, + "airdrop with same identifier already exists") + ErrDistributorAlreadyExists = sdkerrors.Register(ModuleName, 1107, + "airdrop with same distributor already exists") +) diff --git a/x/claim/types/events.go b/x/claim/types/events.go new file mode 100644 index 0000000000..de74ec9d57 --- /dev/null +++ b/x/claim/types/events.go @@ -0,0 +1,6 @@ +package types + +// claim module event typs +const ( + EventTypeClaim = "claim" +) diff --git a/x/claim/types/expected_keepers.go b/x/claim/types/expected_keepers.go new file mode 100644 index 0000000000..91a448c46a --- /dev/null +++ b/x/claim/types/expected_keepers.go @@ -0,0 +1,44 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + + epochstypes "github.com/Stride-Labs/stride/x/epochs/types" +) + +// BankKeeper defines the banking contract that must be fulfilled when +// creating a x/claim keeper. +type BankKeeper interface { + SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) error + GetBalance(ctx sdk.Context, addr sdk.AccAddress, denom string) sdk.Coin +} + +// AccountKeeper defines the expected account keeper used for simulations (noalias) +type AccountKeeper interface { + GetModuleAddress(name string) sdk.AccAddress + SetModuleAccount(ctx sdk.Context, macc authtypes.ModuleAccountI) + GetAccount(sdk.Context, sdk.AccAddress) authtypes.AccountI + SetAccount(sdk.Context, authtypes.AccountI) + NewAccountWithAddress(sdk.Context, sdk.AccAddress) authtypes.AccountI + // Fetch the sequence of an account at a specified address. + GetSequence(sdk.Context, sdk.AccAddress) (uint64, error) +} + +// DistrKeeper is the keeper of the distribution store +type DistrKeeper interface { + FundCommunityPool(ctx sdk.Context, amount sdk.Coins, sender sdk.AccAddress) error +} + +// StakingKeeper expected staking keeper (noalias) +type StakingKeeper interface { + // BondDenom - Bondable coin denomination + BondDenom(sdk.Context) string +} + +// EpochsKeeper expected epoch keeper +type EpochsKeeper interface { + SetEpochInfo(ctx sdk.Context, epoch epochstypes.EpochInfo) + DeleteEpochInfo(ctx sdk.Context, identifier string) + AllEpochInfos(ctx sdk.Context) []epochstypes.EpochInfo +} diff --git a/x/claim/types/genesis.go b/x/claim/types/genesis.go new file mode 100644 index 0000000000..be27bb144e --- /dev/null +++ b/x/claim/types/genesis.go @@ -0,0 +1,40 @@ +package types + +import ( + "encoding/json" + + "github.com/cosmos/cosmos-sdk/codec" +) + +type Actions []Action + +// DefaultIndex is the default capability global index +const DefaultIndex uint64 = 1 + +// DefaultGenesis returns the default Capability genesis state +func DefaultGenesis() *GenesisState { + return &GenesisState{ + Params: Params{ + Airdrops: []*Airdrop{}, + }, + ClaimRecords: []ClaimRecord{}, + } +} + +// GetGenesisStateFromAppState returns x/claims GenesisState given raw application +// genesis state. +func GetGenesisStateFromAppState(cdc codec.JSONCodec, appState map[string]json.RawMessage) *GenesisState { + var genesisState GenesisState + + if appState[ModuleName] != nil { + cdc.MustUnmarshalJSON(appState[ModuleName], &genesisState) + } + + return &genesisState +} + +// Validate performs basic genesis state validation returning an error upon any +// failure. +func (gs GenesisState) Validate() error { + return nil +} diff --git a/x/claim/types/genesis.pb.go b/x/claim/types/genesis.pb.go new file mode 100644 index 0000000000..8bcdc11486 --- /dev/null +++ b/x/claim/types/genesis.pb.go @@ -0,0 +1,397 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: claim/v1beta1/genesis.proto + +package types + +import ( + fmt "fmt" + _ "github.com/cosmos/cosmos-sdk/types" + _ "github.com/cosmos/cosmos-sdk/x/bank/types" + _ "github.com/gogo/protobuf/gogoproto" + proto "github.com/gogo/protobuf/proto" + _ "google.golang.org/protobuf/types/known/durationpb" + _ "google.golang.org/protobuf/types/known/timestamppb" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// GenesisState defines the claim module's genesis state. +type GenesisState struct { + // params defines all the parameters of the module. + Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params" yaml:"params"` + // list of claim records, one for every airdrop recipient + ClaimRecords []ClaimRecord `protobuf:"bytes,2,rep,name=claim_records,json=claimRecords,proto3" json:"claim_records" yaml:"claim_records"` +} + +func (m *GenesisState) Reset() { *m = GenesisState{} } +func (m *GenesisState) String() string { return proto.CompactTextString(m) } +func (*GenesisState) ProtoMessage() {} +func (*GenesisState) Descriptor() ([]byte, []int) { + return fileDescriptor_cf4a9b016e59a7d2, []int{0} +} +func (m *GenesisState) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *GenesisState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_GenesisState.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *GenesisState) XXX_Merge(src proto.Message) { + xxx_messageInfo_GenesisState.Merge(m, src) +} +func (m *GenesisState) XXX_Size() int { + return m.Size() +} +func (m *GenesisState) XXX_DiscardUnknown() { + xxx_messageInfo_GenesisState.DiscardUnknown(m) +} + +var xxx_messageInfo_GenesisState proto.InternalMessageInfo + +func (m *GenesisState) GetParams() Params { + if m != nil { + return m.Params + } + return Params{} +} + +func (m *GenesisState) GetClaimRecords() []ClaimRecord { + if m != nil { + return m.ClaimRecords + } + return nil +} + +func init() { + proto.RegisterType((*GenesisState)(nil), "Stridelabs.stride.claim.v1beta1.GenesisState") +} + +func init() { proto.RegisterFile("claim/v1beta1/genesis.proto", fileDescriptor_cf4a9b016e59a7d2) } + +var fileDescriptor_cf4a9b016e59a7d2 = []byte{ + // 334 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x90, 0x31, 0x4f, 0x02, 0x31, + 0x18, 0x86, 0xef, 0x34, 0x61, 0x38, 0x60, 0x21, 0x98, 0xe0, 0x69, 0x7a, 0x78, 0x8b, 0x24, 0x6a, + 0x1b, 0x70, 0x73, 0xc4, 0x18, 0x17, 0x07, 0x03, 0x89, 0x83, 0x8b, 0x69, 0x8f, 0x7a, 0x36, 0x5e, + 0xf9, 0x2e, 0xd7, 0x62, 0xe4, 0x5f, 0xf8, 0xb3, 0x18, 0xd9, 0x74, 0x22, 0x06, 0xfe, 0x81, 0xbf, + 0xc0, 0xd0, 0x56, 0xcc, 0x19, 0x13, 0xb6, 0x7e, 0x79, 0x9f, 0xef, 0x7d, 0xbf, 0xbe, 0xc1, 0x41, + 0x92, 0x51, 0x21, 0xc9, 0x4b, 0x97, 0x71, 0x4d, 0xbb, 0x24, 0xe5, 0x63, 0xae, 0x84, 0xc2, 0x79, + 0x01, 0x1a, 0x1a, 0xd1, 0x50, 0x17, 0x62, 0xc4, 0x33, 0xca, 0x14, 0x56, 0xe6, 0x89, 0x0d, 0x8e, + 0x1d, 0x1e, 0x36, 0x53, 0x48, 0xc1, 0xb0, 0x64, 0xfd, 0xb2, 0x6b, 0x21, 0x4a, 0x40, 0x49, 0x50, + 0x84, 0x51, 0xc5, 0x37, 0xce, 0x09, 0x88, 0xb1, 0xd3, 0x8f, 0x36, 0xfa, 0xf8, 0xf9, 0xff, 0xe4, + 0x10, 0xa5, 0x00, 0x69, 0xc6, 0x89, 0x99, 0xd8, 0xe4, 0x91, 0x8c, 0x26, 0x05, 0xd5, 0x02, 0x7e, + 0x2c, 0xa2, 0xbf, 0xba, 0x16, 0x92, 0x2b, 0x4d, 0x65, 0xee, 0x80, 0xfd, 0xf2, 0xbf, 0xec, 0xd9, + 0x56, 0x0a, 0xcb, 0x52, 0x4e, 0x0b, 0x2a, 0x5d, 0x6e, 0xfc, 0xee, 0x07, 0xb5, 0x6b, 0x7b, 0xc9, + 0x50, 0x53, 0xcd, 0x1b, 0x77, 0x41, 0xc5, 0x02, 0x2d, 0xbf, 0xed, 0x77, 0xaa, 0xbd, 0x63, 0xbc, + 0xa5, 0x13, 0x7c, 0x6b, 0xf0, 0xfe, 0xde, 0x6c, 0x11, 0x79, 0x5f, 0x8b, 0xa8, 0x3e, 0xa5, 0x32, + 0xbb, 0x88, 0xad, 0x49, 0x3c, 0x70, 0x6e, 0x0d, 0x08, 0xea, 0x66, 0xed, 0xa1, 0xe0, 0x09, 0x14, + 0x23, 0xd5, 0xda, 0x69, 0xef, 0x76, 0xaa, 0xbd, 0xd3, 0xad, 0xf6, 0x97, 0xeb, 0x69, 0x60, 0x96, + 0xfa, 0x87, 0x2e, 0xa3, 0x69, 0x33, 0x4a, 0x86, 0xf1, 0xa0, 0x96, 0xfc, 0xa2, 0xaa, 0x7f, 0x35, + 0x5b, 0x22, 0x7f, 0xbe, 0x44, 0xfe, 0xe7, 0x12, 0xf9, 0x6f, 0x2b, 0xe4, 0xcd, 0x57, 0xc8, 0xfb, + 0x58, 0x21, 0xef, 0xfe, 0x24, 0x15, 0xfa, 0x69, 0xc2, 0x70, 0x02, 0x92, 0xd8, 0xf4, 0xb3, 0x1b, + 0xca, 0x14, 0xb1, 0xf1, 0xe4, 0xd5, 0x96, 0x47, 0xf4, 0x34, 0xe7, 0x8a, 0x55, 0x4c, 0x4f, 0xe7, + 0xdf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x1f, 0x7d, 0x87, 0x40, 0x38, 0x02, 0x00, 0x00, +} + +func (m *GenesisState) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GenesisState) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.ClaimRecords) > 0 { + for iNdEx := len(m.ClaimRecords) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.ClaimRecords[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + { + size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int { + offset -= sovGenesis(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *GenesisState) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Params.Size() + n += 1 + l + sovGenesis(uint64(l)) + if len(m.ClaimRecords) > 0 { + for _, e := range m.ClaimRecords { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + return n +} + +func sovGenesis(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozGenesis(x uint64) (n int) { + return sovGenesis(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *GenesisState) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GenesisState: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GenesisState: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ClaimRecords", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ClaimRecords = append(m.ClaimRecords, ClaimRecord{}) + if err := m.ClaimRecords[len(m.ClaimRecords)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipGenesis(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenesis + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenesis + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenesis + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthGenesis + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupGenesis + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthGenesis + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthGenesis = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowGenesis = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupGenesis = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/claim/types/keys.go b/x/claim/types/keys.go new file mode 100644 index 0000000000..4bf60723f5 --- /dev/null +++ b/x/claim/types/keys.go @@ -0,0 +1,38 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" +) + +const ( + // ModuleName defines the module name + ModuleName = "claim" + + // StoreKey defines the primary module store key + StoreKey = ModuleName + + // RouterKey is the message route for slashing + RouterKey = ModuleName + + // QuerierRoute defines the module's query routing key + QuerierRoute = ModuleName + + // ClaimRecordsStorePrefix defines the store prefix for the claim records + ClaimRecordsStorePrefix = "claimrecords" + + // ParamsKey defines the store key for claim module parameters + ParamsKey = "params" + + // ActionKey defines the store key to store user accomplished actions + ActionKey = "action" + + // TotalWeightKey defines the store key for total weight + TotalWeightKey = "totalweight" +) + +var ( + // Percentages for actions + PercentageForFree = sdk.NewDecWithPrec(20, 2) //20% + PercentageForStake = sdk.NewDecWithPrec(20, 2) //20% + PercentageForLiquidStake = sdk.NewDecWithPrec(60, 2) //60% +) diff --git a/x/claim/types/msgs.go b/x/claim/types/msgs.go new file mode 100644 index 0000000000..a0fe2f295d --- /dev/null +++ b/x/claim/types/msgs.go @@ -0,0 +1,233 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + + "github.com/Stride-Labs/stride/utils" +) + +// Msg type for MsgSetAirdropAllocations +const TypeMsgSetAirdropAllocations = "set_airdrop_allocation" + +var _ sdk.Msg = &MsgSetAirdropAllocations{} + +func NewMsgSetAirdropAllocations(allocator string, airdropIdentifier string, users []string, weights []sdk.Dec) *MsgSetAirdropAllocations { + return &MsgSetAirdropAllocations{ + Allocator: allocator, + AirdropIdentifier: airdropIdentifier, + Users: users, + Weights: weights, + } +} + +func (msg *MsgSetAirdropAllocations) Route() string { + return RouterKey +} + +func (msg *MsgSetAirdropAllocations) Type() string { + return TypeMsgSetAirdropAllocations +} + +func (msg *MsgSetAirdropAllocations) GetSigners() []sdk.AccAddress { + allocator, err := sdk.AccAddressFromBech32(msg.Allocator) + if err != nil { + panic(err) + } + return []sdk.AccAddress{allocator} +} + +func (msg *MsgSetAirdropAllocations) GetSignBytes() []byte { + bz := ModuleCdc.MustMarshalJSON(msg) + return sdk.MustSortJSON(bz) +} + +func (msg *MsgSetAirdropAllocations) ValidateBasic() error { + _, err := sdk.AccAddressFromBech32(msg.Allocator) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid allocator address (%s)", err) + } + + if msg.AirdropIdentifier == "" { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "airdrop identifier not set") + } + + if len(msg.Users) == 0 { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "empty users list") + } + + if len(msg.Weights) == 0 { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "empty weights list") + } + + if len(msg.Users) != len(msg.Weights) { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "different length") + } + + for _, user := range msg.Users { + strideAddr := utils.ConvertAddressToStrideAddress(user) + if strideAddr == "" { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid bech32 address") + } + + _, err := sdk.AccAddressFromBech32(strideAddr) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid user address (%s)", err) + } + } + + for _, weight := range msg.Weights { + if weight.Equal(sdk.NewDec(0)) { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid user weight") + } + } + + return nil +} + +// Msg type for MsgClaimFreeAmount +const TypeMsgClaimFreeAmount = "claim_free_amount" + +var _ sdk.Msg = &MsgClaimFreeAmount{} + +func NewMsgClaimFreeAmount(user string, airdropIdentifier string) *MsgClaimFreeAmount { + return &MsgClaimFreeAmount{ + User: user, + AirdropIdentifier: airdropIdentifier, + } +} + +func (msg *MsgClaimFreeAmount) Route() string { + return RouterKey +} + +func (msg *MsgClaimFreeAmount) Type() string { + return TypeMsgClaimFreeAmount +} + +func (msg *MsgClaimFreeAmount) GetSigners() []sdk.AccAddress { + allocator, err := sdk.AccAddressFromBech32(msg.User) + if err != nil { + panic(err) + } + return []sdk.AccAddress{allocator} +} + +func (msg *MsgClaimFreeAmount) GetSignBytes() []byte { + bz := ModuleCdc.MustMarshalJSON(msg) + return sdk.MustSortJSON(bz) +} + +func (msg *MsgClaimFreeAmount) ValidateBasic() error { + if msg.AirdropIdentifier == "" { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "airdrop identifier not set") + } + + _, err := sdk.AccAddressFromBech32(msg.User) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid user address (%s)", err) + } + + return nil +} + +// Msg type for MsgCreateAirdrop +const TypeMsgCreateAirdrop = "create_airdrop" + +var _ sdk.Msg = &MsgCreateAirdrop{} + +func NewMsgCreateAirdrop(distributor string, identifier string, startTime uint64, duration uint64, denom string) *MsgCreateAirdrop { + return &MsgCreateAirdrop{ + Distributor: distributor, + Identifier: identifier, + StartTime: startTime, + Duration: duration, + Denom: denom, + } +} + +func (msg *MsgCreateAirdrop) Route() string { + return RouterKey +} + +func (msg *MsgCreateAirdrop) Type() string { + return TypeMsgCreateAirdrop +} + +func (msg *MsgCreateAirdrop) GetSigners() []sdk.AccAddress { + distributor, err := sdk.AccAddressFromBech32(msg.Distributor) + if err != nil { + panic(err) + } + return []sdk.AccAddress{distributor} +} + +func (msg *MsgCreateAirdrop) GetSignBytes() []byte { + bz := ModuleCdc.MustMarshalJSON(msg) + return sdk.MustSortJSON(bz) +} + +func (msg *MsgCreateAirdrop) ValidateBasic() error { + _, err := sdk.AccAddressFromBech32(msg.Distributor) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid distributor address (%s)", err) + } + + if msg.Identifier == "" { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "airdrop identifier not set") + } + + if msg.StartTime == 0 { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "airdrop start time not set") + } + + if msg.Duration == 0 { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "airdrop duration not set") + } + return nil +} + +// Msg type for MsgDeleteAirdrop +const TypeMsgDeleteAirdrop = "delete_airdrop" + +var _ sdk.Msg = &MsgDeleteAirdrop{} + +func NewMsgDeleteAirdrop(distributor string, identifier string) *MsgDeleteAirdrop { + return &MsgDeleteAirdrop{ + Distributor: distributor, + Identifier: identifier, + } +} + +func (msg *MsgDeleteAirdrop) Route() string { + return RouterKey +} + +func (msg *MsgDeleteAirdrop) Type() string { + return TypeMsgDeleteAirdrop +} + +func (msg *MsgDeleteAirdrop) GetSigners() []sdk.AccAddress { + distributor, err := sdk.AccAddressFromBech32(msg.Distributor) + if err != nil { + panic(err) + } + return []sdk.AccAddress{distributor} +} + +func (msg *MsgDeleteAirdrop) GetSignBytes() []byte { + bz := ModuleCdc.MustMarshalJSON(msg) + return sdk.MustSortJSON(bz) +} + +func (msg *MsgDeleteAirdrop) ValidateBasic() error { + _, err := sdk.AccAddressFromBech32(msg.Distributor) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid distributor address (%s)", err) + } + + if msg.Identifier == "" { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "airdrop identifier not set") + } + return nil +} diff --git a/x/claim/types/params.go b/x/claim/types/params.go new file mode 100644 index 0000000000..0567433149 --- /dev/null +++ b/x/claim/types/params.go @@ -0,0 +1,14 @@ +package types + +import ( + "time" +) + +var ( + DefaultClaimDenom = "ustrd" + DefaultAirdropDuration = time.Hour * 24 * 30 * 12 * 3 // 3 years + DefaultVestingDurationForDelegateStake = time.Hour * 24 * 30 * 3 // 3 months + DefaultVestingDurationForLiquidStake = time.Hour * 24 * 30 * 3 // 3 months + DefaultVestingInitialPeriod = time.Hour * 24 * 30 * 3 // 3 months + DefaultAirdropIdentifier = "stride" +) diff --git a/x/claim/types/params.pb.go b/x/claim/types/params.pb.go new file mode 100644 index 0000000000..2beecda310 --- /dev/null +++ b/x/claim/types/params.pb.go @@ -0,0 +1,728 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: claim/v1beta1/params.proto + +package types + +import ( + fmt "fmt" + _ "github.com/gogo/protobuf/gogoproto" + proto "github.com/gogo/protobuf/proto" + github_com_gogo_protobuf_types "github.com/gogo/protobuf/types" + _ "google.golang.org/protobuf/types/known/durationpb" + _ "google.golang.org/protobuf/types/known/timestamppb" + io "io" + math "math" + math_bits "math/bits" + time "time" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf +var _ = time.Kitchen + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// Params defines the claim module's parameters. +type Params struct { + Airdrops []*Airdrop `protobuf:"bytes,1,rep,name=airdrops,proto3" json:"airdrops,omitempty"` +} + +func (m *Params) Reset() { *m = Params{} } +func (m *Params) String() string { return proto.CompactTextString(m) } +func (*Params) ProtoMessage() {} +func (*Params) Descriptor() ([]byte, []int) { + return fileDescriptor_9d53416573264e2f, []int{0} +} +func (m *Params) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Params) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Params.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Params) XXX_Merge(src proto.Message) { + xxx_messageInfo_Params.Merge(m, src) +} +func (m *Params) XXX_Size() int { + return m.Size() +} +func (m *Params) XXX_DiscardUnknown() { + xxx_messageInfo_Params.DiscardUnknown(m) +} + +var xxx_messageInfo_Params proto.InternalMessageInfo + +func (m *Params) GetAirdrops() []*Airdrop { + if m != nil { + return m.Airdrops + } + return nil +} + +type Airdrop struct { + AirdropIdentifier string `protobuf:"bytes,1,opt,name=airdrop_identifier,json=airdropIdentifier,proto3" json:"airdrop_identifier,omitempty" yaml:"airdrop_identifier"` + // seconds + AirdropStartTime time.Time `protobuf:"bytes,2,opt,name=airdrop_start_time,json=airdropStartTime,proto3,stdtime" json:"airdrop_start_time" yaml:"airdrop_start_time"` + // seconds + AirdropDuration time.Duration `protobuf:"bytes,3,opt,name=airdrop_duration,json=airdropDuration,proto3,stdduration" json:"airdrop_duration,omitempty" yaml:"airdrop_duration"` + // denom of claimable asset + ClaimDenom string `protobuf:"bytes,4,opt,name=claim_denom,json=claimDenom,proto3" json:"claim_denom,omitempty"` + // airdrop distribution account + DistributorAddress string `protobuf:"bytes,5,opt,name=distributor_address,json=distributorAddress,proto3" json:"distributor_address,omitempty"` +} + +func (m *Airdrop) Reset() { *m = Airdrop{} } +func (m *Airdrop) String() string { return proto.CompactTextString(m) } +func (*Airdrop) ProtoMessage() {} +func (*Airdrop) Descriptor() ([]byte, []int) { + return fileDescriptor_9d53416573264e2f, []int{1} +} +func (m *Airdrop) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Airdrop) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Airdrop.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Airdrop) XXX_Merge(src proto.Message) { + xxx_messageInfo_Airdrop.Merge(m, src) +} +func (m *Airdrop) XXX_Size() int { + return m.Size() +} +func (m *Airdrop) XXX_DiscardUnknown() { + xxx_messageInfo_Airdrop.DiscardUnknown(m) +} + +var xxx_messageInfo_Airdrop proto.InternalMessageInfo + +func (m *Airdrop) GetAirdropIdentifier() string { + if m != nil { + return m.AirdropIdentifier + } + return "" +} + +func (m *Airdrop) GetAirdropStartTime() time.Time { + if m != nil { + return m.AirdropStartTime + } + return time.Time{} +} + +func (m *Airdrop) GetAirdropDuration() time.Duration { + if m != nil { + return m.AirdropDuration + } + return 0 +} + +func (m *Airdrop) GetClaimDenom() string { + if m != nil { + return m.ClaimDenom + } + return "" +} + +func (m *Airdrop) GetDistributorAddress() string { + if m != nil { + return m.DistributorAddress + } + return "" +} + +func init() { + proto.RegisterType((*Params)(nil), "Stridelabs.stride.claim.v1beta1.Params") + proto.RegisterType((*Airdrop)(nil), "Stridelabs.stride.claim.v1beta1.Airdrop") +} + +func init() { proto.RegisterFile("claim/v1beta1/params.proto", fileDescriptor_9d53416573264e2f) } + +var fileDescriptor_9d53416573264e2f = []byte{ + // 434 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x52, 0x3f, 0x6f, 0x13, 0x31, + 0x14, 0x8f, 0x09, 0x14, 0x70, 0x06, 0xc0, 0x20, 0x71, 0x3d, 0x89, 0xbb, 0xe8, 0x24, 0xa4, 0x48, + 0x80, 0xad, 0x96, 0x8d, 0x2d, 0x51, 0x18, 0x90, 0x2a, 0x84, 0x52, 0x26, 0x96, 0x93, 0xaf, 0x76, + 0x0f, 0x4b, 0x71, 0x7c, 0xb2, 0x1d, 0x44, 0x3e, 0x01, 0x6b, 0x47, 0x3e, 0x00, 0x1f, 0xa6, 0x63, + 0x47, 0xa6, 0x03, 0x25, 0x1b, 0x63, 0x3f, 0x01, 0xf2, 0x9f, 0x6b, 0x21, 0x19, 0xba, 0xf9, 0x7e, + 0x7f, 0xde, 0x7b, 0xbf, 0xf7, 0x0e, 0xa6, 0x27, 0x73, 0x2a, 0x24, 0xf9, 0x72, 0x50, 0x71, 0x4b, + 0x0f, 0x48, 0x43, 0x35, 0x95, 0x06, 0x37, 0x5a, 0x59, 0x85, 0xf2, 0x63, 0xab, 0x05, 0xe3, 0x73, + 0x5a, 0x19, 0x6c, 0xfc, 0x13, 0x7b, 0x35, 0x8e, 0xea, 0xf4, 0x49, 0xad, 0x6a, 0xe5, 0xb5, 0xc4, + 0xbd, 0x82, 0x2d, 0xcd, 0x6a, 0xa5, 0xea, 0x39, 0x27, 0xfe, 0xab, 0x5a, 0x9e, 0x12, 0xb6, 0xd4, + 0xd4, 0x0a, 0xb5, 0x88, 0x7c, 0xbe, 0xcd, 0x5b, 0x21, 0xb9, 0xb1, 0x54, 0x36, 0x41, 0x50, 0xbc, + 0x87, 0x7b, 0x1f, 0xfc, 0x1c, 0x68, 0x0a, 0xef, 0x51, 0xa1, 0x99, 0x56, 0x8d, 0x49, 0xc0, 0xb0, + 0x3f, 0x1a, 0x1c, 0x8e, 0xf0, 0x0d, 0x43, 0xe1, 0x71, 0x30, 0xcc, 0xae, 0x9c, 0xc5, 0x8f, 0x3e, + 0xbc, 0x1b, 0x51, 0x74, 0x04, 0x51, 0xc4, 0x4b, 0xc1, 0xf8, 0xc2, 0x8a, 0x53, 0xc1, 0x75, 0x02, + 0x86, 0x60, 0x74, 0x7f, 0xf2, 0xec, 0xb2, 0xcd, 0xf7, 0x57, 0x54, 0xce, 0xdf, 0x14, 0xbb, 0x9a, + 0x62, 0xf6, 0x28, 0x82, 0xef, 0xae, 0x30, 0xa4, 0xae, 0xab, 0x19, 0x4b, 0xb5, 0x2d, 0x5d, 0x94, + 0xe4, 0xd6, 0x10, 0x8c, 0x06, 0x87, 0x29, 0x0e, 0x39, 0x71, 0x97, 0x13, 0x7f, 0xec, 0x72, 0x4e, + 0x9e, 0x9f, 0xb7, 0x79, 0x6f, 0xb7, 0xdb, 0x75, 0x8d, 0xe2, 0xec, 0x57, 0x0e, 0x66, 0x0f, 0x23, + 0x71, 0xec, 0x70, 0xe7, 0x46, 0xdf, 0x00, 0xec, 0xc0, 0xb2, 0x5b, 0x6b, 0xd2, 0xf7, 0xfd, 0xf6, + 0x77, 0xfa, 0x4d, 0xa3, 0x60, 0x32, 0x76, 0xed, 0xfe, 0xb4, 0x79, 0xba, 0x6d, 0x7d, 0xa9, 0xa4, + 0xb0, 0x5c, 0x36, 0x76, 0x75, 0xd9, 0xe6, 0x4f, 0xff, 0x1f, 0xa6, 0xd3, 0x14, 0xdf, 0xdd, 0x28, + 0x0f, 0x22, 0xdc, 0xd5, 0x44, 0x39, 0x1c, 0xf8, 0xbd, 0x97, 0x8c, 0x2f, 0x94, 0x4c, 0x6e, 0xbb, + 0x0d, 0xce, 0xa0, 0x87, 0xa6, 0x0e, 0x41, 0x04, 0x3e, 0x66, 0xc2, 0x5d, 0xa8, 0x5a, 0x5a, 0xa5, + 0x4b, 0xca, 0x98, 0xe6, 0xc6, 0x24, 0x77, 0xbc, 0x10, 0xfd, 0x43, 0x8d, 0x03, 0x33, 0x79, 0x7b, + 0xbe, 0xce, 0xc0, 0xc5, 0x3a, 0x03, 0xbf, 0xd7, 0x19, 0x38, 0xdb, 0x64, 0xbd, 0x8b, 0x4d, 0xd6, + 0xfb, 0xb9, 0xc9, 0x7a, 0x9f, 0x5e, 0xd4, 0xc2, 0x7e, 0x5e, 0x56, 0xf8, 0x44, 0x49, 0x12, 0xce, + 0xff, 0xea, 0x88, 0x56, 0x86, 0x84, 0xfb, 0x93, 0xaf, 0x24, 0xfc, 0xc4, 0x76, 0xd5, 0x70, 0x53, + 0xed, 0xf9, 0xfc, 0xaf, 0xff, 0x06, 0x00, 0x00, 0xff, 0xff, 0xb0, 0x12, 0xc4, 0x7d, 0xda, 0x02, + 0x00, 0x00, +} + +func (m *Params) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Params) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Airdrops) > 0 { + for iNdEx := len(m.Airdrops) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Airdrops[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintParams(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *Airdrop) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Airdrop) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Airdrop) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.DistributorAddress) > 0 { + i -= len(m.DistributorAddress) + copy(dAtA[i:], m.DistributorAddress) + i = encodeVarintParams(dAtA, i, uint64(len(m.DistributorAddress))) + i-- + dAtA[i] = 0x2a + } + if len(m.ClaimDenom) > 0 { + i -= len(m.ClaimDenom) + copy(dAtA[i:], m.ClaimDenom) + i = encodeVarintParams(dAtA, i, uint64(len(m.ClaimDenom))) + i-- + dAtA[i] = 0x22 + } + n1, err1 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.AirdropDuration, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.AirdropDuration):]) + if err1 != nil { + return 0, err1 + } + i -= n1 + i = encodeVarintParams(dAtA, i, uint64(n1)) + i-- + dAtA[i] = 0x1a + n2, err2 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.AirdropStartTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.AirdropStartTime):]) + if err2 != nil { + return 0, err2 + } + i -= n2 + i = encodeVarintParams(dAtA, i, uint64(n2)) + i-- + dAtA[i] = 0x12 + if len(m.AirdropIdentifier) > 0 { + i -= len(m.AirdropIdentifier) + copy(dAtA[i:], m.AirdropIdentifier) + i = encodeVarintParams(dAtA, i, uint64(len(m.AirdropIdentifier))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintParams(dAtA []byte, offset int, v uint64) int { + offset -= sovParams(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *Params) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Airdrops) > 0 { + for _, e := range m.Airdrops { + l = e.Size() + n += 1 + l + sovParams(uint64(l)) + } + } + return n +} + +func (m *Airdrop) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.AirdropIdentifier) + if l > 0 { + n += 1 + l + sovParams(uint64(l)) + } + l = github_com_gogo_protobuf_types.SizeOfStdTime(m.AirdropStartTime) + n += 1 + l + sovParams(uint64(l)) + l = github_com_gogo_protobuf_types.SizeOfStdDuration(m.AirdropDuration) + n += 1 + l + sovParams(uint64(l)) + l = len(m.ClaimDenom) + if l > 0 { + n += 1 + l + sovParams(uint64(l)) + } + l = len(m.DistributorAddress) + if l > 0 { + n += 1 + l + sovParams(uint64(l)) + } + return n +} + +func sovParams(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozParams(x uint64) (n int) { + return sovParams(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *Params) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Params: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Params: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Airdrops", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthParams + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthParams + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Airdrops = append(m.Airdrops, &Airdrop{}) + if err := m.Airdrops[len(m.Airdrops)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipParams(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthParams + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Airdrop) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Airdrop: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Airdrop: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AirdropIdentifier", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthParams + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthParams + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AirdropIdentifier = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AirdropStartTime", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthParams + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthParams + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.AirdropStartTime, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AirdropDuration", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthParams + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthParams + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := github_com_gogo_protobuf_types.StdDurationUnmarshal(&m.AirdropDuration, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ClaimDenom", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthParams + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthParams + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ClaimDenom = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DistributorAddress", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthParams + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthParams + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DistributorAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipParams(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthParams + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipParams(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowParams + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowParams + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowParams + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthParams + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupParams + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthParams + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthParams = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowParams = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupParams = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/claim/types/query.pb.go b/x/claim/types/query.pb.go new file mode 100644 index 0000000000..941c4398ba --- /dev/null +++ b/x/claim/types/query.pb.go @@ -0,0 +1,2300 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: claim/v1beta1/query.proto + +package types + +import ( + context "context" + fmt "fmt" + github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" + types "github.com/cosmos/cosmos-sdk/types" + _ "github.com/gogo/protobuf/gogoproto" + grpc1 "github.com/gogo/protobuf/grpc" + proto "github.com/gogo/protobuf/proto" + _ "google.golang.org/genproto/googleapis/api/annotations" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// QueryParamsRequest is the request type for the Query/Params RPC method. +type QueryDistributorAccountBalanceRequest struct { + AirdropIdentifier string `protobuf:"bytes,1,opt,name=airdrop_identifier,json=airdropIdentifier,proto3" json:"airdrop_identifier,omitempty" yaml:"airdrop_identifier"` +} + +func (m *QueryDistributorAccountBalanceRequest) Reset() { *m = QueryDistributorAccountBalanceRequest{} } +func (m *QueryDistributorAccountBalanceRequest) String() string { return proto.CompactTextString(m) } +func (*QueryDistributorAccountBalanceRequest) ProtoMessage() {} +func (*QueryDistributorAccountBalanceRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_45c620aecc0f41bd, []int{0} +} +func (m *QueryDistributorAccountBalanceRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryDistributorAccountBalanceRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryDistributorAccountBalanceRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryDistributorAccountBalanceRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryDistributorAccountBalanceRequest.Merge(m, src) +} +func (m *QueryDistributorAccountBalanceRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryDistributorAccountBalanceRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryDistributorAccountBalanceRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryDistributorAccountBalanceRequest proto.InternalMessageInfo + +func (m *QueryDistributorAccountBalanceRequest) GetAirdropIdentifier() string { + if m != nil { + return m.AirdropIdentifier + } + return "" +} + +// QueryParamsResponse is the response type for the Query/Params RPC method. +type QueryDistributorAccountBalanceResponse struct { + // params defines the parameters of the module. + DistributorAccountBalance github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,1,rep,name=distributor_account_balance,json=distributorAccountBalance,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"distributor_account_balance" yaml:"distributor_account_balance"` +} + +func (m *QueryDistributorAccountBalanceResponse) Reset() { + *m = QueryDistributorAccountBalanceResponse{} +} +func (m *QueryDistributorAccountBalanceResponse) String() string { return proto.CompactTextString(m) } +func (*QueryDistributorAccountBalanceResponse) ProtoMessage() {} +func (*QueryDistributorAccountBalanceResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_45c620aecc0f41bd, []int{1} +} +func (m *QueryDistributorAccountBalanceResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryDistributorAccountBalanceResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryDistributorAccountBalanceResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryDistributorAccountBalanceResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryDistributorAccountBalanceResponse.Merge(m, src) +} +func (m *QueryDistributorAccountBalanceResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryDistributorAccountBalanceResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryDistributorAccountBalanceResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryDistributorAccountBalanceResponse proto.InternalMessageInfo + +func (m *QueryDistributorAccountBalanceResponse) GetDistributorAccountBalance() github_com_cosmos_cosmos_sdk_types.Coins { + if m != nil { + return m.DistributorAccountBalance + } + return nil +} + +// QueryParamsRequest is the request type for the Query/Params RPC method. +type QueryParamsRequest struct { +} + +func (m *QueryParamsRequest) Reset() { *m = QueryParamsRequest{} } +func (m *QueryParamsRequest) String() string { return proto.CompactTextString(m) } +func (*QueryParamsRequest) ProtoMessage() {} +func (*QueryParamsRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_45c620aecc0f41bd, []int{2} +} +func (m *QueryParamsRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryParamsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryParamsRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryParamsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryParamsRequest.Merge(m, src) +} +func (m *QueryParamsRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryParamsRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryParamsRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryParamsRequest proto.InternalMessageInfo + +// QueryParamsResponse is the response type for the Query/Params RPC method. +type QueryParamsResponse struct { + // params defines the parameters of the module. + Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` +} + +func (m *QueryParamsResponse) Reset() { *m = QueryParamsResponse{} } +func (m *QueryParamsResponse) String() string { return proto.CompactTextString(m) } +func (*QueryParamsResponse) ProtoMessage() {} +func (*QueryParamsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_45c620aecc0f41bd, []int{3} +} +func (m *QueryParamsResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryParamsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryParamsResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryParamsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryParamsResponse.Merge(m, src) +} +func (m *QueryParamsResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryParamsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryParamsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryParamsResponse proto.InternalMessageInfo + +func (m *QueryParamsResponse) GetParams() Params { + if m != nil { + return m.Params + } + return Params{} +} + +type QueryClaimRecordRequest struct { + AirdropIdentifier string `protobuf:"bytes,1,opt,name=airdrop_identifier,json=airdropIdentifier,proto3" json:"airdrop_identifier,omitempty" yaml:"airdrop_identifier"` + Address string `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty" yaml:"address"` +} + +func (m *QueryClaimRecordRequest) Reset() { *m = QueryClaimRecordRequest{} } +func (m *QueryClaimRecordRequest) String() string { return proto.CompactTextString(m) } +func (*QueryClaimRecordRequest) ProtoMessage() {} +func (*QueryClaimRecordRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_45c620aecc0f41bd, []int{4} +} +func (m *QueryClaimRecordRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryClaimRecordRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryClaimRecordRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryClaimRecordRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryClaimRecordRequest.Merge(m, src) +} +func (m *QueryClaimRecordRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryClaimRecordRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryClaimRecordRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryClaimRecordRequest proto.InternalMessageInfo + +func (m *QueryClaimRecordRequest) GetAirdropIdentifier() string { + if m != nil { + return m.AirdropIdentifier + } + return "" +} + +func (m *QueryClaimRecordRequest) GetAddress() string { + if m != nil { + return m.Address + } + return "" +} + +type QueryClaimRecordResponse struct { + ClaimRecord ClaimRecord `protobuf:"bytes,1,opt,name=claim_record,json=claimRecord,proto3" json:"claim_record" yaml:"claim_record"` +} + +func (m *QueryClaimRecordResponse) Reset() { *m = QueryClaimRecordResponse{} } +func (m *QueryClaimRecordResponse) String() string { return proto.CompactTextString(m) } +func (*QueryClaimRecordResponse) ProtoMessage() {} +func (*QueryClaimRecordResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_45c620aecc0f41bd, []int{5} +} +func (m *QueryClaimRecordResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryClaimRecordResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryClaimRecordResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryClaimRecordResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryClaimRecordResponse.Merge(m, src) +} +func (m *QueryClaimRecordResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryClaimRecordResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryClaimRecordResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryClaimRecordResponse proto.InternalMessageInfo + +func (m *QueryClaimRecordResponse) GetClaimRecord() ClaimRecord { + if m != nil { + return m.ClaimRecord + } + return ClaimRecord{} +} + +type QueryClaimableForActionRequest struct { + AirdropIdentifier string `protobuf:"bytes,1,opt,name=airdrop_identifier,json=airdropIdentifier,proto3" json:"airdrop_identifier,omitempty" yaml:"airdrop_identifier"` + Address string `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty" yaml:"address"` + Action Action `protobuf:"varint,3,opt,name=action,proto3,enum=Stridelabs.stride.claim.v1beta1.Action" json:"action,omitempty" yaml:"action"` +} + +func (m *QueryClaimableForActionRequest) Reset() { *m = QueryClaimableForActionRequest{} } +func (m *QueryClaimableForActionRequest) String() string { return proto.CompactTextString(m) } +func (*QueryClaimableForActionRequest) ProtoMessage() {} +func (*QueryClaimableForActionRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_45c620aecc0f41bd, []int{6} +} +func (m *QueryClaimableForActionRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryClaimableForActionRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryClaimableForActionRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryClaimableForActionRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryClaimableForActionRequest.Merge(m, src) +} +func (m *QueryClaimableForActionRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryClaimableForActionRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryClaimableForActionRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryClaimableForActionRequest proto.InternalMessageInfo + +func (m *QueryClaimableForActionRequest) GetAirdropIdentifier() string { + if m != nil { + return m.AirdropIdentifier + } + return "" +} + +func (m *QueryClaimableForActionRequest) GetAddress() string { + if m != nil { + return m.Address + } + return "" +} + +func (m *QueryClaimableForActionRequest) GetAction() Action { + if m != nil { + return m.Action + } + return ActionFree +} + +type QueryClaimableForActionResponse struct { + Coins github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,1,rep,name=coins,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"coins" yaml:"coins"` +} + +func (m *QueryClaimableForActionResponse) Reset() { *m = QueryClaimableForActionResponse{} } +func (m *QueryClaimableForActionResponse) String() string { return proto.CompactTextString(m) } +func (*QueryClaimableForActionResponse) ProtoMessage() {} +func (*QueryClaimableForActionResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_45c620aecc0f41bd, []int{7} +} +func (m *QueryClaimableForActionResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryClaimableForActionResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryClaimableForActionResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryClaimableForActionResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryClaimableForActionResponse.Merge(m, src) +} +func (m *QueryClaimableForActionResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryClaimableForActionResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryClaimableForActionResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryClaimableForActionResponse proto.InternalMessageInfo + +func (m *QueryClaimableForActionResponse) GetCoins() github_com_cosmos_cosmos_sdk_types.Coins { + if m != nil { + return m.Coins + } + return nil +} + +type QueryTotalClaimableRequest struct { + AirdropIdentifier string `protobuf:"bytes,1,opt,name=airdrop_identifier,json=airdropIdentifier,proto3" json:"airdrop_identifier,omitempty" yaml:"airdrop_identifier"` + Address string `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty" yaml:"address"` +} + +func (m *QueryTotalClaimableRequest) Reset() { *m = QueryTotalClaimableRequest{} } +func (m *QueryTotalClaimableRequest) String() string { return proto.CompactTextString(m) } +func (*QueryTotalClaimableRequest) ProtoMessage() {} +func (*QueryTotalClaimableRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_45c620aecc0f41bd, []int{8} +} +func (m *QueryTotalClaimableRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryTotalClaimableRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryTotalClaimableRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryTotalClaimableRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryTotalClaimableRequest.Merge(m, src) +} +func (m *QueryTotalClaimableRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryTotalClaimableRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryTotalClaimableRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryTotalClaimableRequest proto.InternalMessageInfo + +func (m *QueryTotalClaimableRequest) GetAirdropIdentifier() string { + if m != nil { + return m.AirdropIdentifier + } + return "" +} + +func (m *QueryTotalClaimableRequest) GetAddress() string { + if m != nil { + return m.Address + } + return "" +} + +type QueryTotalClaimableResponse struct { + Coins github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,1,rep,name=coins,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"coins" yaml:"coins"` +} + +func (m *QueryTotalClaimableResponse) Reset() { *m = QueryTotalClaimableResponse{} } +func (m *QueryTotalClaimableResponse) String() string { return proto.CompactTextString(m) } +func (*QueryTotalClaimableResponse) ProtoMessage() {} +func (*QueryTotalClaimableResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_45c620aecc0f41bd, []int{9} +} +func (m *QueryTotalClaimableResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryTotalClaimableResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryTotalClaimableResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryTotalClaimableResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryTotalClaimableResponse.Merge(m, src) +} +func (m *QueryTotalClaimableResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryTotalClaimableResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryTotalClaimableResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryTotalClaimableResponse proto.InternalMessageInfo + +func (m *QueryTotalClaimableResponse) GetCoins() github_com_cosmos_cosmos_sdk_types.Coins { + if m != nil { + return m.Coins + } + return nil +} + +func init() { + proto.RegisterType((*QueryDistributorAccountBalanceRequest)(nil), "Stridelabs.stride.claim.v1beta1.QueryDistributorAccountBalanceRequest") + proto.RegisterType((*QueryDistributorAccountBalanceResponse)(nil), "Stridelabs.stride.claim.v1beta1.QueryDistributorAccountBalanceResponse") + proto.RegisterType((*QueryParamsRequest)(nil), "Stridelabs.stride.claim.v1beta1.QueryParamsRequest") + proto.RegisterType((*QueryParamsResponse)(nil), "Stridelabs.stride.claim.v1beta1.QueryParamsResponse") + proto.RegisterType((*QueryClaimRecordRequest)(nil), "Stridelabs.stride.claim.v1beta1.QueryClaimRecordRequest") + proto.RegisterType((*QueryClaimRecordResponse)(nil), "Stridelabs.stride.claim.v1beta1.QueryClaimRecordResponse") + proto.RegisterType((*QueryClaimableForActionRequest)(nil), "Stridelabs.stride.claim.v1beta1.QueryClaimableForActionRequest") + proto.RegisterType((*QueryClaimableForActionResponse)(nil), "Stridelabs.stride.claim.v1beta1.QueryClaimableForActionResponse") + proto.RegisterType((*QueryTotalClaimableRequest)(nil), "Stridelabs.stride.claim.v1beta1.QueryTotalClaimableRequest") + proto.RegisterType((*QueryTotalClaimableResponse)(nil), "Stridelabs.stride.claim.v1beta1.QueryTotalClaimableResponse") +} + +func init() { proto.RegisterFile("claim/v1beta1/query.proto", fileDescriptor_45c620aecc0f41bd) } + +var fileDescriptor_45c620aecc0f41bd = []byte{ + // 810 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x56, 0x4f, 0x4f, 0x1b, 0x39, + 0x1c, 0x8d, 0x61, 0x09, 0x5a, 0x87, 0x45, 0xc2, 0xb0, 0x22, 0x19, 0x96, 0x19, 0x64, 0x89, 0x25, + 0xda, 0x85, 0x99, 0x05, 0x56, 0x2b, 0xf6, 0x8f, 0x76, 0xd9, 0xb0, 0xb0, 0xaa, 0xc4, 0xa1, 0x9d, + 0x56, 0x3d, 0x54, 0x95, 0x22, 0xcf, 0x8c, 0x49, 0x47, 0x9d, 0x8c, 0xc3, 0x78, 0x52, 0x15, 0x21, + 0x2e, 0x3d, 0xf5, 0x88, 0xfa, 0x47, 0xea, 0x67, 0xe8, 0xad, 0x1f, 0xa0, 0x77, 0x8e, 0x48, 0x3d, + 0xb4, 0x52, 0xab, 0xb4, 0x82, 0x7e, 0x80, 0x2a, 0x9f, 0xa0, 0x1a, 0xdb, 0x90, 0x84, 0x84, 0x26, + 0x50, 0x55, 0xe5, 0x94, 0x91, 0xfd, 0xfb, 0x3d, 0xbf, 0xf7, 0x6c, 0x3f, 0x07, 0xe6, 0xdc, 0x80, + 0xf8, 0x65, 0xeb, 0xce, 0xbc, 0x43, 0x63, 0x32, 0x6f, 0x6d, 0x56, 0x69, 0xb4, 0x65, 0x56, 0x22, + 0x16, 0x33, 0x64, 0x5c, 0x8d, 0x23, 0xdf, 0xa3, 0x01, 0x71, 0xb8, 0xc9, 0xc5, 0xa7, 0x29, 0x8a, + 0x4d, 0x55, 0xac, 0x8d, 0x95, 0x58, 0x89, 0x89, 0x5a, 0x2b, 0xf9, 0x92, 0x6d, 0xda, 0x0f, 0x25, + 0xc6, 0x4a, 0x01, 0xb5, 0x48, 0xc5, 0xb7, 0x48, 0x18, 0xb2, 0x98, 0xc4, 0x3e, 0x0b, 0xb9, 0x9a, + 0xd5, 0x5d, 0xc6, 0xcb, 0x8c, 0x5b, 0x0e, 0xe1, 0xf4, 0x78, 0x55, 0x97, 0xf9, 0xa1, 0x9a, 0x3f, + 0xc1, 0x47, 0x2e, 0x28, 0xa7, 0xb4, 0xd6, 0xa9, 0x0a, 0x89, 0x48, 0x59, 0xc1, 0xe2, 0x2a, 0x9c, + 0xbe, 0x92, 0x50, 0xff, 0xcf, 0x4f, 0x98, 0x3a, 0xd5, 0x98, 0x45, 0xff, 0xba, 0x2e, 0xab, 0x86, + 0x71, 0x81, 0x04, 0x24, 0x74, 0xa9, 0x4d, 0x37, 0xab, 0x94, 0xc7, 0x68, 0x1d, 0x22, 0xe2, 0x47, + 0x5e, 0xc4, 0x2a, 0x45, 0xdf, 0xa3, 0x61, 0xec, 0x6f, 0xf8, 0x34, 0xca, 0x82, 0x29, 0x90, 0xff, + 0xb6, 0x30, 0x59, 0xaf, 0x19, 0xb9, 0x2d, 0x52, 0x0e, 0xfe, 0xc0, 0xed, 0x35, 0xd8, 0x1e, 0x51, + 0x83, 0x97, 0x1a, 0x63, 0x6f, 0x00, 0xfc, 0xb1, 0xdb, 0xba, 0xbc, 0xc2, 0x42, 0x4e, 0xd1, 0x33, + 0x00, 0x27, 0xbc, 0x46, 0x55, 0x91, 0xc8, 0xb2, 0xa2, 0x23, 0xeb, 0xb2, 0x60, 0xaa, 0x3f, 0x9f, + 0x59, 0xc8, 0x99, 0xd2, 0x1f, 0x33, 0xf1, 0xe7, 0xc8, 0x68, 0x73, 0x85, 0xf9, 0x61, 0xe1, 0xfa, + 0x5e, 0xcd, 0x48, 0xd5, 0x6b, 0x06, 0x96, 0x0c, 0x3f, 0x81, 0x85, 0x9f, 0xbe, 0x35, 0xf2, 0x25, + 0x3f, 0xbe, 0x55, 0x75, 0x4c, 0x97, 0x95, 0x2d, 0x65, 0xb9, 0xfc, 0x99, 0xe3, 0xde, 0x6d, 0x2b, + 0xde, 0xaa, 0x50, 0x2e, 0x60, 0xb9, 0x9d, 0xf3, 0x4e, 0xe3, 0x8e, 0xc7, 0x20, 0x12, 0xea, 0x2e, + 0x0b, 0xab, 0x95, 0x85, 0xf8, 0x26, 0x1c, 0x6d, 0x19, 0x55, 0x02, 0x57, 0x61, 0x5a, 0x6e, 0x89, + 0x70, 0x33, 0xb3, 0x30, 0x63, 0x76, 0x39, 0x3f, 0xa6, 0x04, 0x28, 0x7c, 0x93, 0x08, 0xb3, 0x55, + 0x33, 0x7e, 0x0c, 0xe0, 0xb8, 0x80, 0x5f, 0x49, 0x6a, 0x6d, 0xea, 0xb2, 0xc8, 0xfb, 0x22, 0x9b, + 0x87, 0x66, 0xe1, 0x20, 0xf1, 0xbc, 0x88, 0x72, 0x9e, 0xed, 0x13, 0x10, 0xa8, 0x5e, 0x33, 0x86, + 0x15, 0x84, 0x9c, 0xc0, 0xf6, 0x51, 0x09, 0xbe, 0x0f, 0x60, 0xb6, 0x9d, 0x97, 0xd2, 0x1e, 0xc0, + 0x21, 0x21, 0xad, 0x18, 0x89, 0x71, 0xe5, 0xc0, 0x6c, 0x57, 0x07, 0x9a, 0xb0, 0x0a, 0x13, 0x6a, + 0x7f, 0x47, 0x25, 0x83, 0x66, 0x3c, 0x6c, 0x67, 0xdc, 0x46, 0x25, 0xfe, 0x00, 0xa0, 0xde, 0xa0, + 0x42, 0x9c, 0x80, 0xae, 0x25, 0x5b, 0x97, 0x5c, 0xb3, 0x0b, 0xe0, 0x14, 0xb2, 0x61, 0x9a, 0x08, + 0x32, 0xd9, 0xfe, 0x29, 0x90, 0x1f, 0xee, 0xe1, 0x20, 0x48, 0xee, 0x85, 0x91, 0x7a, 0xcd, 0xf8, + 0x4e, 0xa1, 0x8a, 0x11, 0x6c, 0x2b, 0x24, 0xfc, 0x08, 0x40, 0xe3, 0x54, 0xc9, 0x6a, 0x13, 0x36, + 0xe1, 0x40, 0x12, 0x24, 0xbc, 0xfb, 0x55, 0x5a, 0x56, 0x56, 0x0f, 0x29, 0xab, 0x93, 0xae, 0xb3, + 0x5d, 0x1a, 0xb9, 0x12, 0x7e, 0x02, 0xa0, 0x26, 0x68, 0x5d, 0x63, 0x31, 0x09, 0x8e, 0xb9, 0x5d, + 0x84, 0xf3, 0xba, 0x0b, 0xe0, 0x44, 0x47, 0x6a, 0x5f, 0xcd, 0xad, 0x85, 0xbd, 0x41, 0x38, 0x20, + 0x28, 0xa1, 0xd7, 0x00, 0xe6, 0x4e, 0x8d, 0x4c, 0xb4, 0xd6, 0xf5, 0xc0, 0xf4, 0x94, 0xf5, 0xda, + 0xff, 0x9f, 0x8d, 0x23, 0xbd, 0xc2, 0x73, 0xf7, 0x5e, 0xbc, 0x7f, 0xd8, 0x37, 0x83, 0xa6, 0xad, + 0xd6, 0x27, 0xa8, 0xcc, 0xbc, 0x6a, 0x40, 0x4f, 0xc6, 0x2f, 0x7a, 0x00, 0x60, 0x5a, 0x66, 0x1b, + 0x5a, 0xec, 0x8d, 0x42, 0x4b, 0xc0, 0x6a, 0xbf, 0x9e, 0xad, 0x49, 0x91, 0x9c, 0x14, 0x24, 0xc7, + 0xd1, 0xf7, 0x56, 0xa7, 0x77, 0x32, 0x79, 0x7f, 0x32, 0x4d, 0x71, 0x83, 0x96, 0x7a, 0x5b, 0xa4, + 0x3d, 0x85, 0xb5, 0xdf, 0xcf, 0xd1, 0xd9, 0xc5, 0xc8, 0xe6, 0xb0, 0xb3, 0xb6, 0xd5, 0x11, 0xde, + 0x41, 0x2f, 0x01, 0x44, 0xed, 0x17, 0x1e, 0xfd, 0x73, 0x06, 0x02, 0x9d, 0xd2, 0x51, 0x5b, 0x3e, + 0x3f, 0x80, 0x12, 0xf2, 0xb7, 0x10, 0xb2, 0x84, 0x7e, 0xeb, 0x24, 0x24, 0x69, 0x29, 0x6e, 0x88, + 0x77, 0x39, 0x69, 0x6a, 0x08, 0xb2, 0xb6, 0xe5, 0xc8, 0x0e, 0x7a, 0x0e, 0xe0, 0x70, 0xeb, 0xc5, + 0x44, 0x7f, 0xf6, 0x46, 0xaa, 0x63, 0xd2, 0x68, 0x7f, 0x9d, 0xaf, 0x59, 0xa9, 0xf9, 0x45, 0xa8, + 0xf9, 0x09, 0xe5, 0x4f, 0xa8, 0x89, 0x93, 0xf2, 0xe2, 0xb1, 0xa6, 0x86, 0x90, 0xc2, 0xea, 0xde, + 0x81, 0x0e, 0xf6, 0x0f, 0x74, 0xf0, 0xee, 0x40, 0x07, 0xbb, 0x87, 0x7a, 0x6a, 0xff, 0x50, 0x4f, + 0xbd, 0x3a, 0xd4, 0x53, 0x37, 0x7e, 0x6e, 0x4a, 0x05, 0xc9, 0x69, 0x6e, 0x9d, 0x38, 0xdc, 0x92, + 0xa4, 0xac, 0xbb, 0x6a, 0x09, 0x11, 0x0f, 0x4e, 0x5a, 0xfc, 0x7b, 0x5b, 0xfc, 0x18, 0x00, 0x00, + 0xff, 0xff, 0x7f, 0xaa, 0x38, 0x61, 0x86, 0x0a, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// QueryClient is the client API for Query service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type QueryClient interface { + DistributorAccountBalance(ctx context.Context, in *QueryDistributorAccountBalanceRequest, opts ...grpc.CallOption) (*QueryDistributorAccountBalanceResponse, error) + Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) + ClaimRecord(ctx context.Context, in *QueryClaimRecordRequest, opts ...grpc.CallOption) (*QueryClaimRecordResponse, error) + ClaimableForAction(ctx context.Context, in *QueryClaimableForActionRequest, opts ...grpc.CallOption) (*QueryClaimableForActionResponse, error) + TotalClaimable(ctx context.Context, in *QueryTotalClaimableRequest, opts ...grpc.CallOption) (*QueryTotalClaimableResponse, error) +} + +type queryClient struct { + cc grpc1.ClientConn +} + +func NewQueryClient(cc grpc1.ClientConn) QueryClient { + return &queryClient{cc} +} + +func (c *queryClient) DistributorAccountBalance(ctx context.Context, in *QueryDistributorAccountBalanceRequest, opts ...grpc.CallOption) (*QueryDistributorAccountBalanceResponse, error) { + out := new(QueryDistributorAccountBalanceResponse) + err := c.cc.Invoke(ctx, "/Stridelabs.stride.claim.v1beta1.Query/DistributorAccountBalance", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) { + out := new(QueryParamsResponse) + err := c.cc.Invoke(ctx, "/Stridelabs.stride.claim.v1beta1.Query/Params", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) ClaimRecord(ctx context.Context, in *QueryClaimRecordRequest, opts ...grpc.CallOption) (*QueryClaimRecordResponse, error) { + out := new(QueryClaimRecordResponse) + err := c.cc.Invoke(ctx, "/Stridelabs.stride.claim.v1beta1.Query/ClaimRecord", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) ClaimableForAction(ctx context.Context, in *QueryClaimableForActionRequest, opts ...grpc.CallOption) (*QueryClaimableForActionResponse, error) { + out := new(QueryClaimableForActionResponse) + err := c.cc.Invoke(ctx, "/Stridelabs.stride.claim.v1beta1.Query/ClaimableForAction", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) TotalClaimable(ctx context.Context, in *QueryTotalClaimableRequest, opts ...grpc.CallOption) (*QueryTotalClaimableResponse, error) { + out := new(QueryTotalClaimableResponse) + err := c.cc.Invoke(ctx, "/Stridelabs.stride.claim.v1beta1.Query/TotalClaimable", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// QueryServer is the server API for Query service. +type QueryServer interface { + DistributorAccountBalance(context.Context, *QueryDistributorAccountBalanceRequest) (*QueryDistributorAccountBalanceResponse, error) + Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error) + ClaimRecord(context.Context, *QueryClaimRecordRequest) (*QueryClaimRecordResponse, error) + ClaimableForAction(context.Context, *QueryClaimableForActionRequest) (*QueryClaimableForActionResponse, error) + TotalClaimable(context.Context, *QueryTotalClaimableRequest) (*QueryTotalClaimableResponse, error) +} + +// UnimplementedQueryServer can be embedded to have forward compatible implementations. +type UnimplementedQueryServer struct { +} + +func (*UnimplementedQueryServer) DistributorAccountBalance(ctx context.Context, req *QueryDistributorAccountBalanceRequest) (*QueryDistributorAccountBalanceResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method DistributorAccountBalance not implemented") +} +func (*UnimplementedQueryServer) Params(ctx context.Context, req *QueryParamsRequest) (*QueryParamsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Params not implemented") +} +func (*UnimplementedQueryServer) ClaimRecord(ctx context.Context, req *QueryClaimRecordRequest) (*QueryClaimRecordResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ClaimRecord not implemented") +} +func (*UnimplementedQueryServer) ClaimableForAction(ctx context.Context, req *QueryClaimableForActionRequest) (*QueryClaimableForActionResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ClaimableForAction not implemented") +} +func (*UnimplementedQueryServer) TotalClaimable(ctx context.Context, req *QueryTotalClaimableRequest) (*QueryTotalClaimableResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method TotalClaimable not implemented") +} + +func RegisterQueryServer(s grpc1.Server, srv QueryServer) { + s.RegisterService(&_Query_serviceDesc, srv) +} + +func _Query_DistributorAccountBalance_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryDistributorAccountBalanceRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).DistributorAccountBalance(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/Stridelabs.stride.claim.v1beta1.Query/DistributorAccountBalance", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).DistributorAccountBalance(ctx, req.(*QueryDistributorAccountBalanceRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_Params_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryParamsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).Params(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/Stridelabs.stride.claim.v1beta1.Query/Params", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).Params(ctx, req.(*QueryParamsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_ClaimRecord_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryClaimRecordRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).ClaimRecord(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/Stridelabs.stride.claim.v1beta1.Query/ClaimRecord", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).ClaimRecord(ctx, req.(*QueryClaimRecordRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_ClaimableForAction_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryClaimableForActionRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).ClaimableForAction(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/Stridelabs.stride.claim.v1beta1.Query/ClaimableForAction", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).ClaimableForAction(ctx, req.(*QueryClaimableForActionRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_TotalClaimable_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryTotalClaimableRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).TotalClaimable(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/Stridelabs.stride.claim.v1beta1.Query/TotalClaimable", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).TotalClaimable(ctx, req.(*QueryTotalClaimableRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _Query_serviceDesc = grpc.ServiceDesc{ + ServiceName: "Stridelabs.stride.claim.v1beta1.Query", + HandlerType: (*QueryServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "DistributorAccountBalance", + Handler: _Query_DistributorAccountBalance_Handler, + }, + { + MethodName: "Params", + Handler: _Query_Params_Handler, + }, + { + MethodName: "ClaimRecord", + Handler: _Query_ClaimRecord_Handler, + }, + { + MethodName: "ClaimableForAction", + Handler: _Query_ClaimableForAction_Handler, + }, + { + MethodName: "TotalClaimable", + Handler: _Query_TotalClaimable_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "claim/v1beta1/query.proto", +} + +func (m *QueryDistributorAccountBalanceRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryDistributorAccountBalanceRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryDistributorAccountBalanceRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.AirdropIdentifier) > 0 { + i -= len(m.AirdropIdentifier) + copy(dAtA[i:], m.AirdropIdentifier) + i = encodeVarintQuery(dAtA, i, uint64(len(m.AirdropIdentifier))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryDistributorAccountBalanceResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryDistributorAccountBalanceResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryDistributorAccountBalanceResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.DistributorAccountBalance) > 0 { + for iNdEx := len(m.DistributorAccountBalance) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.DistributorAccountBalance[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *QueryParamsRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryParamsRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryParamsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *QueryParamsResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryParamsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryParamsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *QueryClaimRecordRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryClaimRecordRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryClaimRecordRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Address) > 0 { + i -= len(m.Address) + copy(dAtA[i:], m.Address) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Address))) + i-- + dAtA[i] = 0x12 + } + if len(m.AirdropIdentifier) > 0 { + i -= len(m.AirdropIdentifier) + copy(dAtA[i:], m.AirdropIdentifier) + i = encodeVarintQuery(dAtA, i, uint64(len(m.AirdropIdentifier))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryClaimRecordResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryClaimRecordResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryClaimRecordResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.ClaimRecord.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *QueryClaimableForActionRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryClaimableForActionRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryClaimableForActionRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Action != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.Action)) + i-- + dAtA[i] = 0x18 + } + if len(m.Address) > 0 { + i -= len(m.Address) + copy(dAtA[i:], m.Address) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Address))) + i-- + dAtA[i] = 0x12 + } + if len(m.AirdropIdentifier) > 0 { + i -= len(m.AirdropIdentifier) + copy(dAtA[i:], m.AirdropIdentifier) + i = encodeVarintQuery(dAtA, i, uint64(len(m.AirdropIdentifier))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryClaimableForActionResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryClaimableForActionResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryClaimableForActionResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Coins) > 0 { + for iNdEx := len(m.Coins) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Coins[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *QueryTotalClaimableRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryTotalClaimableRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryTotalClaimableRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Address) > 0 { + i -= len(m.Address) + copy(dAtA[i:], m.Address) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Address))) + i-- + dAtA[i] = 0x12 + } + if len(m.AirdropIdentifier) > 0 { + i -= len(m.AirdropIdentifier) + copy(dAtA[i:], m.AirdropIdentifier) + i = encodeVarintQuery(dAtA, i, uint64(len(m.AirdropIdentifier))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryTotalClaimableResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryTotalClaimableResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryTotalClaimableResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Coins) > 0 { + for iNdEx := len(m.Coins) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Coins[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { + offset -= sovQuery(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *QueryDistributorAccountBalanceRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.AirdropIdentifier) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryDistributorAccountBalanceResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.DistributorAccountBalance) > 0 { + for _, e := range m.DistributorAccountBalance { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + return n +} + +func (m *QueryParamsRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *QueryParamsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Params.Size() + n += 1 + l + sovQuery(uint64(l)) + return n +} + +func (m *QueryClaimRecordRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.AirdropIdentifier) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.Address) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryClaimRecordResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ClaimRecord.Size() + n += 1 + l + sovQuery(uint64(l)) + return n +} + +func (m *QueryClaimableForActionRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.AirdropIdentifier) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.Address) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + if m.Action != 0 { + n += 1 + sovQuery(uint64(m.Action)) + } + return n +} + +func (m *QueryClaimableForActionResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Coins) > 0 { + for _, e := range m.Coins { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + return n +} + +func (m *QueryTotalClaimableRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.AirdropIdentifier) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.Address) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryTotalClaimableResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Coins) > 0 { + for _, e := range m.Coins { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + return n +} + +func sovQuery(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozQuery(x uint64) (n int) { + return sovQuery(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *QueryDistributorAccountBalanceRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryDistributorAccountBalanceRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryDistributorAccountBalanceRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AirdropIdentifier", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AirdropIdentifier = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryDistributorAccountBalanceResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryDistributorAccountBalanceResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryDistributorAccountBalanceResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DistributorAccountBalance", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DistributorAccountBalance = append(m.DistributorAccountBalance, types.Coin{}) + if err := m.DistributorAccountBalance[len(m.DistributorAccountBalance)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryParamsRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryParamsRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryParamsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryParamsResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryParamsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryClaimRecordRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryClaimRecordRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryClaimRecordRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AirdropIdentifier", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AirdropIdentifier = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Address = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryClaimRecordResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryClaimRecordResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryClaimRecordResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ClaimRecord", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ClaimRecord.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryClaimableForActionRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryClaimableForActionRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryClaimableForActionRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AirdropIdentifier", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AirdropIdentifier = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Address = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Action", wireType) + } + m.Action = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Action |= Action(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryClaimableForActionResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryClaimableForActionResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryClaimableForActionResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Coins", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Coins = append(m.Coins, types.Coin{}) + if err := m.Coins[len(m.Coins)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryTotalClaimableRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryTotalClaimableRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryTotalClaimableRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AirdropIdentifier", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AirdropIdentifier = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Address = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryTotalClaimableResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryTotalClaimableResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryTotalClaimableResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Coins", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Coins = append(m.Coins, types.Coin{}) + if err := m.Coins[len(m.Coins)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipQuery(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowQuery + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowQuery + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowQuery + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthQuery + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupQuery + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthQuery + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthQuery = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowQuery = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupQuery = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/claim/types/query.pb.gw.go b/x/claim/types/query.pb.gw.go new file mode 100644 index 0000000000..cd3df4e487 --- /dev/null +++ b/x/claim/types/query.pb.gw.go @@ -0,0 +1,621 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: claim/v1beta1/query.proto + +/* +Package types is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package types + +import ( + "context" + "io" + "net/http" + + "github.com/golang/protobuf/descriptor" + "github.com/golang/protobuf/proto" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/grpc-ecosystem/grpc-gateway/utilities" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" +) + +// Suppress "imported and not used" errors +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray +var _ = descriptor.ForMessage +var _ = metadata.Join + +var ( + filter_Query_DistributorAccountBalance_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_Query_DistributorAccountBalance_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryDistributorAccountBalanceRequest + 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_DistributorAccountBalance_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.DistributorAccountBalance(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_DistributorAccountBalance_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryDistributorAccountBalanceRequest + 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_DistributorAccountBalance_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.DistributorAccountBalance(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Query_Params_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryParamsRequest + var metadata runtime.ServerMetadata + + msg, err := client.Params(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_Params_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryParamsRequest + var metadata runtime.ServerMetadata + + msg, err := server.Params(ctx, &protoReq) + return msg, metadata, err + +} + +var ( + filter_Query_ClaimRecord_0 = &utilities.DoubleArray{Encoding: map[string]int{"address": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} +) + +func request_Query_ClaimRecord_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryClaimRecordRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["address"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "address") + } + + protoReq.Address, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "address", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_ClaimRecord_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.ClaimRecord(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_ClaimRecord_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryClaimRecordRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["address"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "address") + } + + protoReq.Address, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "address", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_ClaimRecord_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.ClaimRecord(ctx, &protoReq) + return msg, metadata, err + +} + +var ( + filter_Query_ClaimableForAction_0 = &utilities.DoubleArray{Encoding: map[string]int{"address": 0, "action": 1}, Base: []int{1, 1, 2, 0, 0}, Check: []int{0, 1, 1, 2, 3}} +) + +func request_Query_ClaimableForAction_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryClaimableForActionRequest + var metadata runtime.ServerMetadata + + var ( + val string + e int32 + ok bool + err error + _ = err + ) + + val, ok = pathParams["address"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "address") + } + + protoReq.Address, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "address", err) + } + + val, ok = pathParams["action"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "action") + } + + e, err = runtime.Enum(val, Action_value) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "action", err) + } + + protoReq.Action = Action(e) + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_ClaimableForAction_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.ClaimableForAction(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_ClaimableForAction_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryClaimableForActionRequest + var metadata runtime.ServerMetadata + + var ( + val string + e int32 + ok bool + err error + _ = err + ) + + val, ok = pathParams["address"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "address") + } + + protoReq.Address, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "address", err) + } + + val, ok = pathParams["action"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "action") + } + + e, err = runtime.Enum(val, Action_value) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "action", err) + } + + protoReq.Action = Action(e) + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_ClaimableForAction_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.ClaimableForAction(ctx, &protoReq) + return msg, metadata, err + +} + +var ( + filter_Query_TotalClaimable_0 = &utilities.DoubleArray{Encoding: map[string]int{"address": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} +) + +func request_Query_TotalClaimable_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryTotalClaimableRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["address"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "address") + } + + protoReq.Address, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "address", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_TotalClaimable_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.TotalClaimable(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_TotalClaimable_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryTotalClaimableRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["address"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "address") + } + + protoReq.Address, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "address", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_TotalClaimable_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.TotalClaimable(ctx, &protoReq) + return msg, metadata, err + +} + +// RegisterQueryHandlerServer registers the http handlers for service Query to "mux". +// UnaryRPC :call QueryServer directly. +// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. +// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterQueryHandlerFromEndpoint instead. +func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, server QueryServer) error { + + mux.Handle("GET", pattern_Query_DistributorAccountBalance_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + 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_DistributorAccountBalance_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_DistributorAccountBalance_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_Params_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + 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_Params_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_Params_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_ClaimRecord_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + 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_ClaimRecord_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_ClaimRecord_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_ClaimableForAction_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + 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_ClaimableForAction_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_ClaimableForAction_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_TotalClaimable_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + 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_TotalClaimable_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_TotalClaimable_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +// RegisterQueryHandlerFromEndpoint is same as RegisterQueryHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterQueryHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.Dial(endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterQueryHandler(ctx, mux, conn) +} + +// RegisterQueryHandler registers the http handlers for service Query to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterQueryHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + return RegisterQueryHandlerClient(ctx, mux, NewQueryClient(conn)) +} + +// RegisterQueryHandlerClient registers the http handlers for service Query +// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "QueryClient". +// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "QueryClient" +// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in +// "QueryClient" to call the correct interceptors. +func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, client QueryClient) error { + + mux.Handle("GET", pattern_Query_DistributorAccountBalance_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_DistributorAccountBalance_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_DistributorAccountBalance_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_Params_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_Params_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_Params_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_ClaimRecord_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_ClaimRecord_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_ClaimRecord_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_ClaimableForAction_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_ClaimableForAction_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_ClaimableForAction_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_TotalClaimable_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_TotalClaimable_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_TotalClaimable_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_Query_DistributorAccountBalance_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"claim", "v1beta1", "module_account_balance"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_Query_Params_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"claim", "v1beta1", "params"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_Query_ClaimRecord_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"claim", "v1beta1", "claim_record", "address"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_Query_ClaimableForAction_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 1, 0, 4, 1, 5, 4}, []string{"claim", "v1beta1", "claimable_for_action", "address", "action"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_Query_TotalClaimable_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"claim", "v1beta1", "total_claimable", "address"}, "", runtime.AssumeColonVerbOpt(true))) +) + +var ( + forward_Query_DistributorAccountBalance_0 = runtime.ForwardResponseMessage + + forward_Query_Params_0 = runtime.ForwardResponseMessage + + forward_Query_ClaimRecord_0 = runtime.ForwardResponseMessage + + forward_Query_ClaimableForAction_0 = runtime.ForwardResponseMessage + + forward_Query_TotalClaimable_0 = runtime.ForwardResponseMessage +) diff --git a/x/claim/types/tx.pb.go b/x/claim/types/tx.pb.go new file mode 100644 index 0000000000..2b83ae35db --- /dev/null +++ b/x/claim/types/tx.pb.go @@ -0,0 +1,2024 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: claim/v1beta1/tx.proto + +package types + +import ( + context "context" + fmt "fmt" + github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" + types "github.com/cosmos/cosmos-sdk/types" + _ "github.com/gogo/protobuf/gogoproto" + grpc1 "github.com/gogo/protobuf/grpc" + proto "github.com/gogo/protobuf/proto" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +type MsgSetAirdropAllocations struct { + Allocator string `protobuf:"bytes,1,opt,name=allocator,proto3" json:"allocator,omitempty"` + AirdropIdentifier string `protobuf:"bytes,2,opt,name=airdrop_identifier,json=airdropIdentifier,proto3" json:"airdrop_identifier,omitempty" yaml:"airdrop_identifier"` + Users []string `protobuf:"bytes,3,rep,name=users,proto3" json:"users,omitempty"` + Weights []github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,4,rep,name=weights,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"weights" yaml:"weights"` +} + +func (m *MsgSetAirdropAllocations) Reset() { *m = MsgSetAirdropAllocations{} } +func (m *MsgSetAirdropAllocations) String() string { return proto.CompactTextString(m) } +func (*MsgSetAirdropAllocations) ProtoMessage() {} +func (*MsgSetAirdropAllocations) Descriptor() ([]byte, []int) { + return fileDescriptor_2477aa15a389ceb5, []int{0} +} +func (m *MsgSetAirdropAllocations) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgSetAirdropAllocations) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgSetAirdropAllocations.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgSetAirdropAllocations) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgSetAirdropAllocations.Merge(m, src) +} +func (m *MsgSetAirdropAllocations) XXX_Size() int { + return m.Size() +} +func (m *MsgSetAirdropAllocations) XXX_DiscardUnknown() { + xxx_messageInfo_MsgSetAirdropAllocations.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgSetAirdropAllocations proto.InternalMessageInfo + +func (m *MsgSetAirdropAllocations) GetAllocator() string { + if m != nil { + return m.Allocator + } + return "" +} + +func (m *MsgSetAirdropAllocations) GetAirdropIdentifier() string { + if m != nil { + return m.AirdropIdentifier + } + return "" +} + +func (m *MsgSetAirdropAllocations) GetUsers() []string { + if m != nil { + return m.Users + } + return nil +} + +type MsgSetAirdropAllocationsResponse struct { +} + +func (m *MsgSetAirdropAllocationsResponse) Reset() { *m = MsgSetAirdropAllocationsResponse{} } +func (m *MsgSetAirdropAllocationsResponse) String() string { return proto.CompactTextString(m) } +func (*MsgSetAirdropAllocationsResponse) ProtoMessage() {} +func (*MsgSetAirdropAllocationsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_2477aa15a389ceb5, []int{1} +} +func (m *MsgSetAirdropAllocationsResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgSetAirdropAllocationsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgSetAirdropAllocationsResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgSetAirdropAllocationsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgSetAirdropAllocationsResponse.Merge(m, src) +} +func (m *MsgSetAirdropAllocationsResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgSetAirdropAllocationsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgSetAirdropAllocationsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgSetAirdropAllocationsResponse proto.InternalMessageInfo + +type MsgClaimFreeAmount struct { + User string `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty"` + AirdropIdentifier string `protobuf:"bytes,2,opt,name=airdrop_identifier,json=airdropIdentifier,proto3" json:"airdrop_identifier,omitempty" yaml:"airdrop_identifier"` +} + +func (m *MsgClaimFreeAmount) Reset() { *m = MsgClaimFreeAmount{} } +func (m *MsgClaimFreeAmount) String() string { return proto.CompactTextString(m) } +func (*MsgClaimFreeAmount) ProtoMessage() {} +func (*MsgClaimFreeAmount) Descriptor() ([]byte, []int) { + return fileDescriptor_2477aa15a389ceb5, []int{2} +} +func (m *MsgClaimFreeAmount) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgClaimFreeAmount) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgClaimFreeAmount.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgClaimFreeAmount) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgClaimFreeAmount.Merge(m, src) +} +func (m *MsgClaimFreeAmount) XXX_Size() int { + return m.Size() +} +func (m *MsgClaimFreeAmount) XXX_DiscardUnknown() { + xxx_messageInfo_MsgClaimFreeAmount.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgClaimFreeAmount proto.InternalMessageInfo + +func (m *MsgClaimFreeAmount) GetUser() string { + if m != nil { + return m.User + } + return "" +} + +func (m *MsgClaimFreeAmount) GetAirdropIdentifier() string { + if m != nil { + return m.AirdropIdentifier + } + return "" +} + +type MsgClaimFreeAmountResponse struct { + ClaimedAmount github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,3,rep,name=claimed_amount,json=claimedAmount,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"claimed_amount"` +} + +func (m *MsgClaimFreeAmountResponse) Reset() { *m = MsgClaimFreeAmountResponse{} } +func (m *MsgClaimFreeAmountResponse) String() string { return proto.CompactTextString(m) } +func (*MsgClaimFreeAmountResponse) ProtoMessage() {} +func (*MsgClaimFreeAmountResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_2477aa15a389ceb5, []int{3} +} +func (m *MsgClaimFreeAmountResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgClaimFreeAmountResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgClaimFreeAmountResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgClaimFreeAmountResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgClaimFreeAmountResponse.Merge(m, src) +} +func (m *MsgClaimFreeAmountResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgClaimFreeAmountResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgClaimFreeAmountResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgClaimFreeAmountResponse proto.InternalMessageInfo + +func (m *MsgClaimFreeAmountResponse) GetClaimedAmount() github_com_cosmos_cosmos_sdk_types.Coins { + if m != nil { + return m.ClaimedAmount + } + return nil +} + +type MsgCreateAirdrop struct { + Distributor string `protobuf:"bytes,1,opt,name=distributor,proto3" json:"distributor,omitempty"` + Identifier string `protobuf:"bytes,2,opt,name=identifier,proto3" json:"identifier,omitempty"` + StartTime uint64 `protobuf:"varint,3,opt,name=start_time,json=startTime,proto3" json:"start_time,omitempty"` + Duration uint64 `protobuf:"varint,4,opt,name=duration,proto3" json:"duration,omitempty"` + Denom string `protobuf:"bytes,5,opt,name=denom,proto3" json:"denom,omitempty"` +} + +func (m *MsgCreateAirdrop) Reset() { *m = MsgCreateAirdrop{} } +func (m *MsgCreateAirdrop) String() string { return proto.CompactTextString(m) } +func (*MsgCreateAirdrop) ProtoMessage() {} +func (*MsgCreateAirdrop) Descriptor() ([]byte, []int) { + return fileDescriptor_2477aa15a389ceb5, []int{4} +} +func (m *MsgCreateAirdrop) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgCreateAirdrop) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgCreateAirdrop.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgCreateAirdrop) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgCreateAirdrop.Merge(m, src) +} +func (m *MsgCreateAirdrop) XXX_Size() int { + return m.Size() +} +func (m *MsgCreateAirdrop) XXX_DiscardUnknown() { + xxx_messageInfo_MsgCreateAirdrop.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgCreateAirdrop proto.InternalMessageInfo + +func (m *MsgCreateAirdrop) GetDistributor() string { + if m != nil { + return m.Distributor + } + return "" +} + +func (m *MsgCreateAirdrop) GetIdentifier() string { + if m != nil { + return m.Identifier + } + return "" +} + +func (m *MsgCreateAirdrop) GetStartTime() uint64 { + if m != nil { + return m.StartTime + } + return 0 +} + +func (m *MsgCreateAirdrop) GetDuration() uint64 { + if m != nil { + return m.Duration + } + return 0 +} + +func (m *MsgCreateAirdrop) GetDenom() string { + if m != nil { + return m.Denom + } + return "" +} + +type MsgCreateAirdropResponse struct { +} + +func (m *MsgCreateAirdropResponse) Reset() { *m = MsgCreateAirdropResponse{} } +func (m *MsgCreateAirdropResponse) String() string { return proto.CompactTextString(m) } +func (*MsgCreateAirdropResponse) ProtoMessage() {} +func (*MsgCreateAirdropResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_2477aa15a389ceb5, []int{5} +} +func (m *MsgCreateAirdropResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgCreateAirdropResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgCreateAirdropResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgCreateAirdropResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgCreateAirdropResponse.Merge(m, src) +} +func (m *MsgCreateAirdropResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgCreateAirdropResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgCreateAirdropResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgCreateAirdropResponse proto.InternalMessageInfo + +type MsgDeleteAirdrop struct { + Distributor string `protobuf:"bytes,1,opt,name=distributor,proto3" json:"distributor,omitempty"` + Identifier string `protobuf:"bytes,2,opt,name=identifier,proto3" json:"identifier,omitempty"` +} + +func (m *MsgDeleteAirdrop) Reset() { *m = MsgDeleteAirdrop{} } +func (m *MsgDeleteAirdrop) String() string { return proto.CompactTextString(m) } +func (*MsgDeleteAirdrop) ProtoMessage() {} +func (*MsgDeleteAirdrop) Descriptor() ([]byte, []int) { + return fileDescriptor_2477aa15a389ceb5, []int{6} +} +func (m *MsgDeleteAirdrop) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgDeleteAirdrop) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgDeleteAirdrop.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgDeleteAirdrop) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgDeleteAirdrop.Merge(m, src) +} +func (m *MsgDeleteAirdrop) XXX_Size() int { + return m.Size() +} +func (m *MsgDeleteAirdrop) XXX_DiscardUnknown() { + xxx_messageInfo_MsgDeleteAirdrop.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgDeleteAirdrop proto.InternalMessageInfo + +func (m *MsgDeleteAirdrop) GetDistributor() string { + if m != nil { + return m.Distributor + } + return "" +} + +func (m *MsgDeleteAirdrop) GetIdentifier() string { + if m != nil { + return m.Identifier + } + return "" +} + +type MsgDeleteAirdropResponse struct { +} + +func (m *MsgDeleteAirdropResponse) Reset() { *m = MsgDeleteAirdropResponse{} } +func (m *MsgDeleteAirdropResponse) String() string { return proto.CompactTextString(m) } +func (*MsgDeleteAirdropResponse) ProtoMessage() {} +func (*MsgDeleteAirdropResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_2477aa15a389ceb5, []int{7} +} +func (m *MsgDeleteAirdropResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgDeleteAirdropResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgDeleteAirdropResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgDeleteAirdropResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgDeleteAirdropResponse.Merge(m, src) +} +func (m *MsgDeleteAirdropResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgDeleteAirdropResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgDeleteAirdropResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgDeleteAirdropResponse proto.InternalMessageInfo + +func init() { + proto.RegisterType((*MsgSetAirdropAllocations)(nil), "Stridelabs.stride.claim.v1beta1.MsgSetAirdropAllocations") + proto.RegisterType((*MsgSetAirdropAllocationsResponse)(nil), "Stridelabs.stride.claim.v1beta1.MsgSetAirdropAllocationsResponse") + proto.RegisterType((*MsgClaimFreeAmount)(nil), "Stridelabs.stride.claim.v1beta1.MsgClaimFreeAmount") + proto.RegisterType((*MsgClaimFreeAmountResponse)(nil), "Stridelabs.stride.claim.v1beta1.MsgClaimFreeAmountResponse") + proto.RegisterType((*MsgCreateAirdrop)(nil), "Stridelabs.stride.claim.v1beta1.MsgCreateAirdrop") + proto.RegisterType((*MsgCreateAirdropResponse)(nil), "Stridelabs.stride.claim.v1beta1.MsgCreateAirdropResponse") + proto.RegisterType((*MsgDeleteAirdrop)(nil), "Stridelabs.stride.claim.v1beta1.MsgDeleteAirdrop") + proto.RegisterType((*MsgDeleteAirdropResponse)(nil), "Stridelabs.stride.claim.v1beta1.MsgDeleteAirdropResponse") +} + +func init() { proto.RegisterFile("claim/v1beta1/tx.proto", fileDescriptor_2477aa15a389ceb5) } + +var fileDescriptor_2477aa15a389ceb5 = []byte{ + // 618 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x55, 0x31, 0x6f, 0xd3, 0x40, + 0x14, 0x8e, 0x49, 0x0a, 0xe4, 0xaa, 0x16, 0x38, 0x15, 0xe4, 0x5a, 0xd4, 0x8e, 0x3c, 0xa0, 0x48, + 0xa8, 0x36, 0x6d, 0xa7, 0xc2, 0x42, 0xd2, 0x82, 0x84, 0xd4, 0x2e, 0x6e, 0xa7, 0x2e, 0xd5, 0xd9, + 0x3e, 0xdc, 0x13, 0xb6, 0x2f, 0xba, 0xbb, 0x94, 0x76, 0x60, 0xe2, 0x0f, 0x74, 0xe1, 0x07, 0x30, + 0xb0, 0xf0, 0x4b, 0x3a, 0x76, 0x44, 0x0c, 0x01, 0x25, 0xff, 0xa0, 0x13, 0x23, 0xba, 0x3b, 0xc7, + 0x4d, 0xd2, 0x56, 0x84, 0xaa, 0x53, 0xee, 0xde, 0xbd, 0xef, 0x7b, 0xef, 0xbe, 0xfb, 0x5e, 0x0c, + 0x9e, 0x44, 0x29, 0x22, 0x99, 0x7f, 0xb8, 0x12, 0x62, 0x81, 0x56, 0x7c, 0x71, 0xe4, 0x75, 0x18, + 0x15, 0x14, 0x3a, 0x3b, 0x82, 0x91, 0x18, 0xa7, 0x28, 0xe4, 0x1e, 0x57, 0x4b, 0x4f, 0x65, 0x7a, + 0x45, 0xa6, 0xb5, 0x90, 0xd0, 0x84, 0xaa, 0x5c, 0x5f, 0xae, 0x34, 0xcc, 0xb2, 0x23, 0xca, 0x33, + 0xca, 0xfd, 0x10, 0x71, 0x5c, 0x92, 0x46, 0x94, 0xe4, 0xfa, 0xdc, 0xfd, 0x63, 0x00, 0x73, 0x9b, + 0x27, 0x3b, 0x58, 0xb4, 0x08, 0x8b, 0x19, 0xed, 0xb4, 0xd2, 0x94, 0x46, 0x48, 0x10, 0x9a, 0x73, + 0xf8, 0x14, 0xd4, 0x91, 0xde, 0x52, 0x66, 0x1a, 0x0d, 0xa3, 0x59, 0x0f, 0x2e, 0x02, 0x70, 0x0b, + 0x40, 0xa4, 0x31, 0xfb, 0x24, 0xc6, 0xb9, 0x20, 0xef, 0x09, 0x66, 0xe6, 0x1d, 0x99, 0xd6, 0x5e, + 0x3a, 0xef, 0x39, 0x8b, 0xc7, 0x28, 0x4b, 0x5f, 0xba, 0x97, 0x73, 0xdc, 0xe0, 0x51, 0x11, 0x7c, + 0x57, 0xc6, 0xe0, 0x02, 0x98, 0xe9, 0x72, 0xcc, 0xb8, 0x59, 0x6d, 0x54, 0x9b, 0xf5, 0x40, 0x6f, + 0xe0, 0x1e, 0xb8, 0xf7, 0x11, 0x93, 0xe4, 0x40, 0x70, 0xb3, 0x26, 0xe3, 0xed, 0xd7, 0xa7, 0x3d, + 0xa7, 0xf2, 0xb3, 0xe7, 0x3c, 0x4b, 0x88, 0x38, 0xe8, 0x86, 0x5e, 0x44, 0x33, 0xbf, 0xb8, 0xa2, + 0xfe, 0x59, 0xe6, 0xf1, 0x07, 0x5f, 0x1c, 0x77, 0x30, 0xf7, 0x36, 0x71, 0x74, 0xde, 0x73, 0xe6, + 0x75, 0x1b, 0x05, 0x8d, 0x1b, 0x0c, 0x09, 0x5d, 0x17, 0x34, 0xae, 0xbb, 0x79, 0x80, 0x79, 0x87, + 0xe6, 0x1c, 0xbb, 0x87, 0x00, 0x6e, 0xf3, 0x64, 0x43, 0x0a, 0xfd, 0x96, 0x61, 0xdc, 0xca, 0x68, + 0x37, 0x17, 0x10, 0x82, 0x9a, 0x6c, 0xaf, 0x90, 0x44, 0xad, 0x6f, 0x57, 0x0d, 0xf7, 0xc4, 0x00, + 0xd6, 0xe5, 0xc2, 0xc3, 0xb6, 0x20, 0x03, 0xf3, 0xea, 0xf1, 0x71, 0xbc, 0x8f, 0xd4, 0x89, 0x52, + 0x6d, 0x76, 0x75, 0xd1, 0xd3, 0x22, 0x78, 0xf2, 0xb9, 0x87, 0xce, 0xf0, 0x36, 0x28, 0xc9, 0xdb, + 0x2f, 0xa4, 0x70, 0xdf, 0x7f, 0x39, 0xcd, 0x29, 0x84, 0x93, 0x00, 0x1e, 0xcc, 0x15, 0x25, 0x74, + 0x6d, 0xf7, 0x9b, 0x01, 0x1e, 0xca, 0x96, 0x18, 0x46, 0x02, 0x17, 0x92, 0xc1, 0x06, 0x98, 0x8d, + 0x89, 0xb4, 0x63, 0xd8, 0xbd, 0xf0, 0xc8, 0x68, 0x08, 0xda, 0x00, 0x4c, 0xea, 0x11, 0x8c, 0x44, + 0xe0, 0x12, 0x00, 0x5c, 0x20, 0x26, 0xf6, 0x05, 0xc9, 0xb0, 0x59, 0x6d, 0x18, 0xcd, 0x5a, 0x50, + 0x57, 0x91, 0x5d, 0x92, 0x61, 0x68, 0x81, 0xfb, 0x71, 0x97, 0xa9, 0x57, 0x31, 0x6b, 0xea, 0xb0, + 0xdc, 0x4b, 0xcb, 0xc4, 0x38, 0xa7, 0x99, 0x39, 0xa3, 0x58, 0xf5, 0xc6, 0xb5, 0x94, 0xa1, 0xc7, + 0xda, 0x2c, 0x9f, 0x73, 0x57, 0x5d, 0x61, 0x13, 0xa7, 0xf8, 0x16, 0xaf, 0x50, 0x54, 0x1c, 0x63, + 0x1d, 0x56, 0x5c, 0xfd, 0x5a, 0x03, 0xd5, 0x6d, 0x9e, 0xc0, 0x2f, 0x06, 0x78, 0x7c, 0xf5, 0x90, + 0xad, 0x7b, 0xff, 0x98, 0x6c, 0xef, 0x3a, 0x97, 0x5a, 0xad, 0x1b, 0x43, 0x4b, 0x27, 0x7d, 0x36, + 0xc0, 0x83, 0x49, 0x7b, 0xaf, 0x4d, 0x43, 0x3b, 0x01, 0xb2, 0x5e, 0xdd, 0x00, 0x54, 0x76, 0xf1, + 0x09, 0xcc, 0x8d, 0xfb, 0x6a, 0x65, 0x2a, 0xb6, 0x51, 0x88, 0xb5, 0xfe, 0xdf, 0x90, 0xd1, 0xf2, + 0xe3, 0x9e, 0x98, 0xaa, 0xfc, 0x18, 0x64, 0xba, 0xf2, 0x57, 0x7a, 0xa4, 0xfd, 0xe6, 0xb4, 0x6f, + 0x1b, 0x67, 0x7d, 0xdb, 0xf8, 0xdd, 0xb7, 0x8d, 0x93, 0x81, 0x5d, 0x39, 0x1b, 0xd8, 0x95, 0x1f, + 0x03, 0xbb, 0xb2, 0xf7, 0x7c, 0x64, 0x58, 0x35, 0xfd, 0xf2, 0x16, 0x0a, 0xb9, 0xaf, 0xf9, 0xfd, + 0x23, 0x5f, 0x7f, 0x2c, 0xd4, 0xd4, 0x86, 0x77, 0xd5, 0x3f, 0xfa, 0xda, 0xdf, 0x00, 0x00, 0x00, + 0xff, 0xff, 0x26, 0xb8, 0x69, 0x2c, 0x42, 0x06, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// MsgClient is the client API for Msg service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type MsgClient interface { + SetAirdropAllocations(ctx context.Context, in *MsgSetAirdropAllocations, opts ...grpc.CallOption) (*MsgSetAirdropAllocationsResponse, error) + ClaimFreeAmount(ctx context.Context, in *MsgClaimFreeAmount, opts ...grpc.CallOption) (*MsgClaimFreeAmountResponse, error) + CreateAirdrop(ctx context.Context, in *MsgCreateAirdrop, opts ...grpc.CallOption) (*MsgCreateAirdropResponse, error) + DeleteAirdrop(ctx context.Context, in *MsgDeleteAirdrop, opts ...grpc.CallOption) (*MsgDeleteAirdropResponse, error) +} + +type msgClient struct { + cc grpc1.ClientConn +} + +func NewMsgClient(cc grpc1.ClientConn) MsgClient { + return &msgClient{cc} +} + +func (c *msgClient) SetAirdropAllocations(ctx context.Context, in *MsgSetAirdropAllocations, opts ...grpc.CallOption) (*MsgSetAirdropAllocationsResponse, error) { + out := new(MsgSetAirdropAllocationsResponse) + err := c.cc.Invoke(ctx, "/Stridelabs.stride.claim.v1beta1.Msg/SetAirdropAllocations", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *msgClient) ClaimFreeAmount(ctx context.Context, in *MsgClaimFreeAmount, opts ...grpc.CallOption) (*MsgClaimFreeAmountResponse, error) { + out := new(MsgClaimFreeAmountResponse) + err := c.cc.Invoke(ctx, "/Stridelabs.stride.claim.v1beta1.Msg/ClaimFreeAmount", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *msgClient) CreateAirdrop(ctx context.Context, in *MsgCreateAirdrop, opts ...grpc.CallOption) (*MsgCreateAirdropResponse, error) { + out := new(MsgCreateAirdropResponse) + err := c.cc.Invoke(ctx, "/Stridelabs.stride.claim.v1beta1.Msg/CreateAirdrop", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *msgClient) DeleteAirdrop(ctx context.Context, in *MsgDeleteAirdrop, opts ...grpc.CallOption) (*MsgDeleteAirdropResponse, error) { + out := new(MsgDeleteAirdropResponse) + err := c.cc.Invoke(ctx, "/Stridelabs.stride.claim.v1beta1.Msg/DeleteAirdrop", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// MsgServer is the server API for Msg service. +type MsgServer interface { + SetAirdropAllocations(context.Context, *MsgSetAirdropAllocations) (*MsgSetAirdropAllocationsResponse, error) + ClaimFreeAmount(context.Context, *MsgClaimFreeAmount) (*MsgClaimFreeAmountResponse, error) + CreateAirdrop(context.Context, *MsgCreateAirdrop) (*MsgCreateAirdropResponse, error) + DeleteAirdrop(context.Context, *MsgDeleteAirdrop) (*MsgDeleteAirdropResponse, error) +} + +// UnimplementedMsgServer can be embedded to have forward compatible implementations. +type UnimplementedMsgServer struct { +} + +func (*UnimplementedMsgServer) SetAirdropAllocations(ctx context.Context, req *MsgSetAirdropAllocations) (*MsgSetAirdropAllocationsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SetAirdropAllocations not implemented") +} +func (*UnimplementedMsgServer) ClaimFreeAmount(ctx context.Context, req *MsgClaimFreeAmount) (*MsgClaimFreeAmountResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ClaimFreeAmount not implemented") +} +func (*UnimplementedMsgServer) CreateAirdrop(ctx context.Context, req *MsgCreateAirdrop) (*MsgCreateAirdropResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateAirdrop not implemented") +} +func (*UnimplementedMsgServer) DeleteAirdrop(ctx context.Context, req *MsgDeleteAirdrop) (*MsgDeleteAirdropResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteAirdrop not implemented") +} + +func RegisterMsgServer(s grpc1.Server, srv MsgServer) { + s.RegisterService(&_Msg_serviceDesc, srv) +} + +func _Msg_SetAirdropAllocations_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgSetAirdropAllocations) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).SetAirdropAllocations(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/Stridelabs.stride.claim.v1beta1.Msg/SetAirdropAllocations", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).SetAirdropAllocations(ctx, req.(*MsgSetAirdropAllocations)) + } + return interceptor(ctx, in, info, handler) +} + +func _Msg_ClaimFreeAmount_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgClaimFreeAmount) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).ClaimFreeAmount(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/Stridelabs.stride.claim.v1beta1.Msg/ClaimFreeAmount", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).ClaimFreeAmount(ctx, req.(*MsgClaimFreeAmount)) + } + return interceptor(ctx, in, info, handler) +} + +func _Msg_CreateAirdrop_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgCreateAirdrop) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).CreateAirdrop(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/Stridelabs.stride.claim.v1beta1.Msg/CreateAirdrop", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).CreateAirdrop(ctx, req.(*MsgCreateAirdrop)) + } + return interceptor(ctx, in, info, handler) +} + +func _Msg_DeleteAirdrop_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgDeleteAirdrop) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).DeleteAirdrop(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/Stridelabs.stride.claim.v1beta1.Msg/DeleteAirdrop", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).DeleteAirdrop(ctx, req.(*MsgDeleteAirdrop)) + } + return interceptor(ctx, in, info, handler) +} + +var _Msg_serviceDesc = grpc.ServiceDesc{ + ServiceName: "Stridelabs.stride.claim.v1beta1.Msg", + HandlerType: (*MsgServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "SetAirdropAllocations", + Handler: _Msg_SetAirdropAllocations_Handler, + }, + { + MethodName: "ClaimFreeAmount", + Handler: _Msg_ClaimFreeAmount_Handler, + }, + { + MethodName: "CreateAirdrop", + Handler: _Msg_CreateAirdrop_Handler, + }, + { + MethodName: "DeleteAirdrop", + Handler: _Msg_DeleteAirdrop_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "claim/v1beta1/tx.proto", +} + +func (m *MsgSetAirdropAllocations) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgSetAirdropAllocations) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgSetAirdropAllocations) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Weights) > 0 { + for iNdEx := len(m.Weights) - 1; iNdEx >= 0; iNdEx-- { + { + size := m.Weights[iNdEx].Size() + i -= size + if _, err := m.Weights[iNdEx].MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + } + if len(m.Users) > 0 { + for iNdEx := len(m.Users) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Users[iNdEx]) + copy(dAtA[i:], m.Users[iNdEx]) + i = encodeVarintTx(dAtA, i, uint64(len(m.Users[iNdEx]))) + i-- + dAtA[i] = 0x1a + } + } + if len(m.AirdropIdentifier) > 0 { + i -= len(m.AirdropIdentifier) + copy(dAtA[i:], m.AirdropIdentifier) + i = encodeVarintTx(dAtA, i, uint64(len(m.AirdropIdentifier))) + i-- + dAtA[i] = 0x12 + } + if len(m.Allocator) > 0 { + i -= len(m.Allocator) + copy(dAtA[i:], m.Allocator) + i = encodeVarintTx(dAtA, i, uint64(len(m.Allocator))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgSetAirdropAllocationsResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgSetAirdropAllocationsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgSetAirdropAllocationsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *MsgClaimFreeAmount) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgClaimFreeAmount) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgClaimFreeAmount) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.AirdropIdentifier) > 0 { + i -= len(m.AirdropIdentifier) + copy(dAtA[i:], m.AirdropIdentifier) + i = encodeVarintTx(dAtA, i, uint64(len(m.AirdropIdentifier))) + i-- + dAtA[i] = 0x12 + } + if len(m.User) > 0 { + i -= len(m.User) + copy(dAtA[i:], m.User) + i = encodeVarintTx(dAtA, i, uint64(len(m.User))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgClaimFreeAmountResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgClaimFreeAmountResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgClaimFreeAmountResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.ClaimedAmount) > 0 { + for iNdEx := len(m.ClaimedAmount) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.ClaimedAmount[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + return len(dAtA) - i, nil +} + +func (m *MsgCreateAirdrop) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgCreateAirdrop) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgCreateAirdrop) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Denom) > 0 { + i -= len(m.Denom) + copy(dAtA[i:], m.Denom) + i = encodeVarintTx(dAtA, i, uint64(len(m.Denom))) + i-- + dAtA[i] = 0x2a + } + if m.Duration != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.Duration)) + i-- + dAtA[i] = 0x20 + } + if m.StartTime != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.StartTime)) + i-- + dAtA[i] = 0x18 + } + if len(m.Identifier) > 0 { + i -= len(m.Identifier) + copy(dAtA[i:], m.Identifier) + i = encodeVarintTx(dAtA, i, uint64(len(m.Identifier))) + i-- + dAtA[i] = 0x12 + } + if len(m.Distributor) > 0 { + i -= len(m.Distributor) + copy(dAtA[i:], m.Distributor) + i = encodeVarintTx(dAtA, i, uint64(len(m.Distributor))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgCreateAirdropResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgCreateAirdropResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgCreateAirdropResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *MsgDeleteAirdrop) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgDeleteAirdrop) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgDeleteAirdrop) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Identifier) > 0 { + i -= len(m.Identifier) + copy(dAtA[i:], m.Identifier) + i = encodeVarintTx(dAtA, i, uint64(len(m.Identifier))) + i-- + dAtA[i] = 0x12 + } + if len(m.Distributor) > 0 { + i -= len(m.Distributor) + copy(dAtA[i:], m.Distributor) + i = encodeVarintTx(dAtA, i, uint64(len(m.Distributor))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgDeleteAirdropResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgDeleteAirdropResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgDeleteAirdropResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func encodeVarintTx(dAtA []byte, offset int, v uint64) int { + offset -= sovTx(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *MsgSetAirdropAllocations) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Allocator) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.AirdropIdentifier) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + if len(m.Users) > 0 { + for _, s := range m.Users { + l = len(s) + n += 1 + l + sovTx(uint64(l)) + } + } + if len(m.Weights) > 0 { + for _, e := range m.Weights { + l = e.Size() + n += 1 + l + sovTx(uint64(l)) + } + } + return n +} + +func (m *MsgSetAirdropAllocationsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MsgClaimFreeAmount) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.User) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.AirdropIdentifier) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgClaimFreeAmountResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.ClaimedAmount) > 0 { + for _, e := range m.ClaimedAmount { + l = e.Size() + n += 1 + l + sovTx(uint64(l)) + } + } + return n +} + +func (m *MsgCreateAirdrop) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Distributor) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.Identifier) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + if m.StartTime != 0 { + n += 1 + sovTx(uint64(m.StartTime)) + } + if m.Duration != 0 { + n += 1 + sovTx(uint64(m.Duration)) + } + l = len(m.Denom) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgCreateAirdropResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MsgDeleteAirdrop) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Distributor) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.Identifier) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgDeleteAirdropResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func sovTx(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozTx(x uint64) (n int) { + return sovTx(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *MsgSetAirdropAllocations) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgSetAirdropAllocations: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgSetAirdropAllocations: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Allocator", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Allocator = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AirdropIdentifier", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AirdropIdentifier = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Users", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Users = append(m.Users, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Weights", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var v github_com_cosmos_cosmos_sdk_types.Dec + m.Weights = append(m.Weights, v) + if err := m.Weights[len(m.Weights)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgSetAirdropAllocationsResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgSetAirdropAllocationsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgSetAirdropAllocationsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgClaimFreeAmount) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgClaimFreeAmount: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgClaimFreeAmount: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field User", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.User = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AirdropIdentifier", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AirdropIdentifier = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgClaimFreeAmountResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgClaimFreeAmountResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgClaimFreeAmountResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ClaimedAmount", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ClaimedAmount = append(m.ClaimedAmount, types.Coin{}) + if err := m.ClaimedAmount[len(m.ClaimedAmount)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgCreateAirdrop) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgCreateAirdrop: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgCreateAirdrop: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Distributor", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Distributor = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Identifier", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Identifier = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field StartTime", wireType) + } + m.StartTime = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.StartTime |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Duration", wireType) + } + m.Duration = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Duration |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Denom", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Denom = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgCreateAirdropResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgCreateAirdropResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgCreateAirdropResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgDeleteAirdrop) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgDeleteAirdrop: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgDeleteAirdrop: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Distributor", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Distributor = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Identifier", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Identifier = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgDeleteAirdropResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgDeleteAirdropResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgDeleteAirdropResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipTx(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTx + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTx + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTx + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthTx + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupTx + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthTx + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthTx = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowTx = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupTx = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/claim/vesting/client/cli/tx.go b/x/claim/vesting/client/cli/tx.go new file mode 100644 index 0000000000..d4f6418cc5 --- /dev/null +++ b/x/claim/vesting/client/cli/tx.go @@ -0,0 +1,22 @@ +package cli + +import ( + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/client" + + "github.com/Stride-Labs/stride/x/claim/vesting/types" +) + +// GetTxCmd returns stride vesting module's transaction commands. +func GetTxCmd() *cobra.Command { + txCmd := &cobra.Command{ + Use: types.ModuleName, + Short: "Stride vesting transaction subcommands", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + + return txCmd +} diff --git a/x/claim/vesting/client/testutil/cli_test.go b/x/claim/vesting/client/testutil/cli_test.go new file mode 100644 index 0000000000..dd36a6af2d --- /dev/null +++ b/x/claim/vesting/client/testutil/cli_test.go @@ -0,0 +1,17 @@ +// +build norace + +package testutil + +import ( + "testing" + + "github.com/cosmos/cosmos-sdk/testutil/network" + + "github.com/stretchr/testify/suite" +) + +func TestIntegrationTestSuite(t *testing.T) { + cfg := network.DefaultConfig() + cfg.NumValidators = 1 + suite.Run(t, NewIntegrationTestSuite(cfg)) +} diff --git a/x/claim/vesting/client/testutil/suite.go b/x/claim/vesting/client/testutil/suite.go new file mode 100644 index 0000000000..f015f5bd86 --- /dev/null +++ b/x/claim/vesting/client/testutil/suite.go @@ -0,0 +1,32 @@ +package testutil + +import ( + "github.com/stretchr/testify/suite" + + "github.com/cosmos/cosmos-sdk/testutil/network" +) + +type IntegrationTestSuite struct { + suite.Suite + + cfg network.Config + network *network.Network +} + +func NewIntegrationTestSuite(cfg network.Config) *IntegrationTestSuite { + return &IntegrationTestSuite{cfg: cfg} +} + +func (s *IntegrationTestSuite) SetupSuite() { + s.T().Log("setting up integration test suite") + + s.network = network.New(s.T(), s.cfg) + + _, err := s.network.WaitForHeight(1) + s.Require().NoError(err) +} + +func (s *IntegrationTestSuite) TearDownSuite() { + s.T().Log("tearing down integration test suite") + s.network.Cleanup() +} diff --git a/x/claim/vesting/exported/exported.go b/x/claim/vesting/exported/exported.go new file mode 100644 index 0000000000..858e53ed4f --- /dev/null +++ b/x/claim/vesting/exported/exported.go @@ -0,0 +1,42 @@ +package exported + +import ( + "time" + + "github.com/cosmos/cosmos-sdk/x/auth/types" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// VestingAccount defines an account type that vests coins via a vesting schedule. +type VestingAccount interface { + types.AccountI + + // LockedCoins returns the set of coins that are not spendable (i.e. locked), + // defined as the vesting coins that are not delegated. + // + // To get spendable coins of a vesting account, first the total balance must + // be retrieved and the locked tokens can be subtracted from the total balance. + // Note, the spendable balance can be negative. + LockedCoins(blockTime time.Time) sdk.Coins + + // TrackDelegation performs internal vesting accounting necessary when + // delegating from a vesting account. It accepts the current block time, the + // delegation amount and balance of all coins whose denomination exists in + // the account's original vesting balance. + TrackDelegation(blockTime time.Time, balance, amount sdk.Coins) + + // TrackUndelegation performs internal vesting accounting necessary when a + // vesting account performs an undelegation. + TrackUndelegation(amount sdk.Coins) + + GetVestedCoins(blockTime time.Time) sdk.Coins + GetVestingCoins(blockTime time.Time) sdk.Coins + + GetStartTime() int64 + GetEndTime() int64 + + GetOriginalVesting() sdk.Coins + GetDelegatedFree() sdk.Coins + GetDelegatedVesting() sdk.Coins +} diff --git a/x/claim/vesting/handler.go b/x/claim/vesting/handler.go new file mode 100644 index 0000000000..989cb67179 --- /dev/null +++ b/x/claim/vesting/handler.go @@ -0,0 +1,19 @@ +package vesting + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/x/auth/keeper" + + "github.com/Stride-Labs/stride/x/claim/vesting/types" +) + +// NewHandler returns a handler for x/auth message types. +func NewHandler(ak keeper.AccountKeeper, bk types.BankKeeper) sdk.Handler { + return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) { + switch msg := msg.(type) { + default: + return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized %s message type: %T", types.ModuleName, msg) + } + } +} diff --git a/x/claim/vesting/module.go b/x/claim/vesting/module.go new file mode 100644 index 0000000000..a71c92001f --- /dev/null +++ b/x/claim/vesting/module.go @@ -0,0 +1,133 @@ +package vesting + +import ( + "encoding/json" + + "github.com/gorilla/mux" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/spf13/cobra" + abci "github.com/tendermint/tendermint/abci/types" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + "github.com/cosmos/cosmos-sdk/x/auth/keeper" + + "github.com/Stride-Labs/stride/x/claim/vesting/client/cli" + "github.com/Stride-Labs/stride/x/claim/vesting/types" +) + +var ( + _ module.AppModule = AppModule{} + _ module.AppModuleBasic = AppModuleBasic{} +) + +// AppModuleBasic defines the basic application module used by the sub-vesting +// module. The module itself contain no special logic or state other than message +// handling. +type AppModuleBasic struct{} + +// Name returns the module's name. +func (AppModuleBasic) Name() string { + return types.ModuleName +} + +// RegisterCodec registers the module's types with the given codec. +func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { + types.RegisterLegacyAminoCodec(cdc) +} + +// RegisterInterfaces registers the module's interfaces and implementations with +// the given interface registry. +func (AppModuleBasic) RegisterInterfaces(registry codectypes.InterfaceRegistry) { + types.RegisterInterfaces(registry) +} + +// DefaultGenesis returns the module's default genesis state as raw bytes. +func (AppModuleBasic) DefaultGenesis(_ codec.JSONCodec) json.RawMessage { + return []byte("{}") +} + +// ValidateGenesis performs genesis state validation. Currently, this is a no-op. +func (AppModuleBasic) ValidateGenesis(_ codec.JSONCodec, _ client.TxEncodingConfig, bz json.RawMessage) error { + return nil +} + +// RegisterRESTRoutes registers module's REST handlers. Currently, this is a no-op. +func (AppModuleBasic) RegisterRESTRoutes(_ client.Context, _ *mux.Router) {} + +// RegisterGRPCGatewayRoutes registers the module's gRPC Gateway routes. Currently, this +// is a no-op. +func (a AppModuleBasic) RegisterGRPCGatewayRoutes(_ client.Context, _ *runtime.ServeMux) {} + +// GetTxCmd returns the root tx command for the auth module. +func (AppModuleBasic) GetTxCmd() *cobra.Command { + return cli.GetTxCmd() +} + +// GetQueryCmd returns the module's root query command. Currently, this is a no-op. +func (AppModuleBasic) GetQueryCmd() *cobra.Command { + return nil +} + +// AppModule extends the AppModuleBasic implementation by implementing the +// AppModule interface. +type AppModule struct { + AppModuleBasic + + accountKeeper keeper.AccountKeeper + bankKeeper types.BankKeeper +} + +func NewAppModule(ak keeper.AccountKeeper, bk types.BankKeeper) AppModule { + return AppModule{ + AppModuleBasic: AppModuleBasic{}, + accountKeeper: ak, + bankKeeper: bk, + } +} + +// RegisterInvariants performs a no-op; there are no invariants to enforce. +func (AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {} + +// Route returns the module's message router and handler. +func (am AppModule) Route() sdk.Route { + return sdk.NewRoute(types.RouterKey, NewHandler(am.accountKeeper, am.bankKeeper)) +} + +// QuerierRoute returns an empty string as the module contains no query +// functionality. +func (AppModule) QuerierRoute() string { return "" } + +// RegisterServices registers module services. +func (am AppModule) RegisterServices(cfg module.Configurator) { + types.RegisterMsgServer(cfg.MsgServer(), NewMsgServerImpl(am.accountKeeper, am.bankKeeper)) +} + +// LegacyQuerierHandler performs a no-op. +func (am AppModule) LegacyQuerierHandler(_ *codec.LegacyAmino) sdk.Querier { + return nil +} + +// InitGenesis performs a no-op. +func (am AppModule) InitGenesis(_ sdk.Context, _ codec.JSONCodec, _ json.RawMessage) []abci.ValidatorUpdate { + return []abci.ValidatorUpdate{} +} + +// BeginBlock performs a no-op. +func (am AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) {} + +// EndBlock performs a no-op. +func (am AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { + return []abci.ValidatorUpdate{} +} + +// ExportGenesis is always empty, as InitGenesis does nothing either. +func (am AppModule) ExportGenesis(_ sdk.Context, cdc codec.JSONCodec) json.RawMessage { + return am.DefaultGenesis(cdc) +} + +// ConsensusVersion implements AppModule/ConsensusVersion. +func (AppModule) ConsensusVersion() uint64 { return 1 } diff --git a/x/claim/vesting/msg_server.go b/x/claim/vesting/msg_server.go new file mode 100644 index 0000000000..819e8dbf35 --- /dev/null +++ b/x/claim/vesting/msg_server.go @@ -0,0 +1,20 @@ +package vesting + +import ( + "github.com/cosmos/cosmos-sdk/x/auth/keeper" + + "github.com/Stride-Labs/stride/x/claim/vesting/types" +) + +type msgServer struct { + keeper.AccountKeeper + types.BankKeeper +} + +// NewMsgServerImpl returns an implementation of the vesting MsgServer interface, +// wrapping the corresponding AccountKeeper and BankKeeper. +func NewMsgServerImpl(k keeper.AccountKeeper, bk types.BankKeeper) types.MsgServer { + return &msgServer{AccountKeeper: k, BankKeeper: bk} +} + +var _ types.MsgServer = msgServer{} diff --git a/x/claim/vesting/types/codec.go b/x/claim/vesting/types/codec.go new file mode 100644 index 0000000000..9e01e27b70 --- /dev/null +++ b/x/claim/vesting/types/codec.go @@ -0,0 +1,48 @@ +package types + +import ( + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/types/msgservice" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + + "github.com/Stride-Labs/stride/x/claim/vesting/exported" +) + +// RegisterLegacyAminoCodec registers the vesting interfaces and concrete types on the +// provided LegacyAmino codec. These types are used for Amino JSON serialization +func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { + cdc.RegisterInterface((*exported.VestingAccount)(nil), nil) + cdc.RegisterConcrete(&StridePeriodicVestingAccount{}, "cosmos-sdk/StridePeriodicVestingAccount", nil) +} + +// RegisterInterface associates protoName with AccountI and VestingAccount +// Interfaces and creates a registry of it's concrete implementations +func RegisterInterfaces(registry types.InterfaceRegistry) { + registry.RegisterInterface( + "stride.vesting.v1beta1.VestingAccount", + (*exported.VestingAccount)(nil), + &StridePeriodicVestingAccount{}, + ) + + registry.RegisterImplementations( + (*authtypes.AccountI)(nil), + &BaseVestingAccount{}, + &StridePeriodicVestingAccount{}, + ) + + registry.RegisterImplementations( + (*authtypes.GenesisAccount)(nil), + &BaseVestingAccount{}, + &StridePeriodicVestingAccount{}, + ) + + msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) +} + +var amino = codec.NewLegacyAmino() + +func init() { + RegisterLegacyAminoCodec(amino) + amino.Seal() +} diff --git a/x/claim/vesting/types/common_test.go b/x/claim/vesting/types/common_test.go new file mode 100644 index 0000000000..31bcf68627 --- /dev/null +++ b/x/claim/vesting/types/common_test.go @@ -0,0 +1,9 @@ +package types_test + +import ( + strideApp "github.com/Stride-Labs/stride/app" +) + +var ( + app = strideApp.InitStrideTestApp(true) +) diff --git a/x/claim/vesting/types/constants.go b/x/claim/vesting/types/constants.go new file mode 100644 index 0000000000..17f6e91936 --- /dev/null +++ b/x/claim/vesting/types/constants.go @@ -0,0 +1,12 @@ +package types + +const ( + // ModuleName defines the module's name. + ModuleName = "stridevesting" + + // AttributeValueCategory is an alias for the message event value. + AttributeValueCategory = ModuleName + + // RouterKey defines the module's message routing key + RouterKey = ModuleName +) diff --git a/x/claim/vesting/types/expected_keepers.go b/x/claim/vesting/types/expected_keepers.go new file mode 100644 index 0000000000..5705eea30b --- /dev/null +++ b/x/claim/vesting/types/expected_keepers.go @@ -0,0 +1,13 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// BankKeeper defines the expected interface contract the vesting module requires +// for creating vesting accounts with funds. +type BankKeeper interface { + IsSendEnabledCoins(ctx sdk.Context, coins ...sdk.Coin) error + SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) error + BlockedAddr(addr sdk.AccAddress) bool +} diff --git a/x/claim/vesting/types/msgs.go b/x/claim/vesting/types/msgs.go new file mode 100644 index 0000000000..ab1254f4c2 --- /dev/null +++ b/x/claim/vesting/types/msgs.go @@ -0,0 +1 @@ +package types diff --git a/x/claim/vesting/types/period.go b/x/claim/vesting/types/period.go new file mode 100644 index 0000000000..eb686522ea --- /dev/null +++ b/x/claim/vesting/types/period.go @@ -0,0 +1,60 @@ +package types + +import ( + "fmt" + "strings" + "time" + + yaml "gopkg.in/yaml.v2" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// Periods stores all vesting periods passed as part of a StridePeriodicVestingAccount +type Periods []Period + +// Duration is converts the period Length from seconds to a time.Duration +func (p Period) Duration() time.Duration { + return time.Duration(p.Length) * time.Second +} + +// String implements the fmt.Stringer interface +func (p Period) String() string { + out, _ := yaml.Marshal(p) + return string(out) +} + +// TotalLength return the total length in seconds for a period +func (p Periods) TotalLength() int64 { + var total int64 + for _, period := range p { + total += period.Length + } + return total +} + +// TotalDuration returns the total duration of the period +func (p Periods) TotalDuration() time.Duration { + len := p.TotalLength() + return time.Duration(len) * time.Second +} + +// TotalDuration returns the sum of coins for the period +func (p Periods) TotalAmount() sdk.Coins { + total := sdk.Coins{} + for _, period := range p { + total = total.Add(period.Amount...) + } + return total +} + +// String implements the fmt.Stringer interface +func (p Periods) String() string { + periodsListString := make([]string, len(p)) + for _, period := range p { + periodsListString = append(periodsListString, period.String()) + } + + return strings.TrimSpace(fmt.Sprintf(`Vesting Periods: + %s`, strings.Join(periodsListString, ", "))) +} diff --git a/x/claim/vesting/types/test_common.go b/x/claim/vesting/types/test_common.go new file mode 100644 index 0000000000..0e22ea2352 --- /dev/null +++ b/x/claim/vesting/types/test_common.go @@ -0,0 +1,29 @@ +package types + +import ( + "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + "github.com/cosmos/cosmos-sdk/testutil/testdata" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// NewTestMsg generates a test message +func NewTestMsg(addrs ...sdk.AccAddress) *testdata.TestMsg { + return testdata.NewTestMsg(addrs...) +} + +// NewTestCoins coins to more than cover the fee +func NewTestCoins() sdk.Coins { + return sdk.Coins{ + sdk.NewInt64Coin("atom", 10000000), + } +} + +// KeyTestPubAddr generates a test key pair +func KeyTestPubAddr() (cryptotypes.PrivKey, cryptotypes.PubKey, sdk.AccAddress) { + key := secp256k1.GenPrivKey() + pub := key.PubKey() + addr := sdk.AccAddress(pub.Address()) + return key, pub, addr +} diff --git a/x/claim/vesting/types/tx.pb.go b/x/claim/vesting/types/tx.pb.go new file mode 100644 index 0000000000..a1b9ac0b5c --- /dev/null +++ b/x/claim/vesting/types/tx.pb.go @@ -0,0 +1,87 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: vesting/tx.proto + +package types + +import ( + context "context" + fmt "fmt" + _ "github.com/cosmos/cosmos-sdk/types" + _ "github.com/cosmos/cosmos-sdk/x/auth/types" + _ "github.com/gogo/protobuf/gogoproto" + grpc1 "github.com/gogo/protobuf/grpc" + proto "github.com/gogo/protobuf/proto" + grpc "google.golang.org/grpc" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +func init() { proto.RegisterFile("vesting/tx.proto", fileDescriptor_16f610ff571f6d68) } + +var fileDescriptor_16f610ff571f6d68 = []byte{ + // 189 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x28, 0x4b, 0x2d, 0x2e, + 0xc9, 0xcc, 0x4b, 0xd7, 0x2f, 0xa9, 0xd0, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x92, 0x0c, 0x2e, + 0x29, 0xca, 0x4c, 0x49, 0xcd, 0x49, 0x4c, 0x2a, 0xd6, 0x2b, 0x06, 0x33, 0xf5, 0xa0, 0x6a, 0xa4, + 0x44, 0xd2, 0xf3, 0xd3, 0xf3, 0xc1, 0xaa, 0xf4, 0x41, 0x2c, 0x88, 0x06, 0x29, 0xb9, 0xe4, 0xfc, + 0xe2, 0xdc, 0xfc, 0x62, 0xfd, 0xa4, 0xc4, 0xe2, 0x54, 0xfd, 0x32, 0xc3, 0xa4, 0xd4, 0x92, 0x44, + 0x43, 0xfd, 0xe4, 0xfc, 0xcc, 0x3c, 0x34, 0xf9, 0xc4, 0xd2, 0x92, 0x0c, 0xb8, 0x3c, 0x88, 0x03, + 0x91, 0x37, 0x62, 0xe5, 0x62, 0xf6, 0x2d, 0x4e, 0x77, 0xf2, 0x3d, 0xf1, 0x48, 0x8e, 0xf1, 0xc2, + 0x23, 0x39, 0xc6, 0x07, 0x8f, 0xe4, 0x18, 0x27, 0x3c, 0x96, 0x63, 0xb8, 0xf0, 0x58, 0x8e, 0xe1, + 0xc6, 0x63, 0x39, 0x86, 0x28, 0xe3, 0xf4, 0xcc, 0x92, 0x8c, 0xd2, 0x24, 0xbd, 0xe4, 0xfc, 0x5c, + 0x7d, 0x88, 0xe3, 0x74, 0x7d, 0x12, 0x93, 0x8a, 0xf5, 0x21, 0xae, 0xd3, 0xaf, 0xd0, 0x4f, 0xce, + 0x49, 0xcc, 0xcc, 0xd5, 0x87, 0xfb, 0xa4, 0xb2, 0x20, 0xb5, 0x38, 0x89, 0x0d, 0x6c, 0xb8, 0x31, + 0x20, 0x00, 0x00, 0xff, 0xff, 0xb9, 0x67, 0x0a, 0x4d, 0xe1, 0x00, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// MsgClient is the client API for Msg service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type MsgClient interface { +} + +type msgClient struct { + cc grpc1.ClientConn +} + +func NewMsgClient(cc grpc1.ClientConn) MsgClient { + return &msgClient{cc} +} + +// MsgServer is the server API for Msg service. +type MsgServer interface { +} + +// UnimplementedMsgServer can be embedded to have forward compatible implementations. +type UnimplementedMsgServer struct { +} + +func RegisterMsgServer(s grpc1.Server, srv MsgServer) { + s.RegisterService(&_Msg_serviceDesc, srv) +} + +var _Msg_serviceDesc = grpc.ServiceDesc{ + ServiceName: "Stridelabs.stride.vesting.Msg", + HandlerType: (*MsgServer)(nil), + Methods: []grpc.MethodDesc{}, + Streams: []grpc.StreamDesc{}, + Metadata: "vesting/tx.proto", +} diff --git a/x/claim/vesting/types/vesting.pb.go b/x/claim/vesting/types/vesting.pb.go new file mode 100644 index 0000000000..2cb99110a7 --- /dev/null +++ b/x/claim/vesting/types/vesting.pb.go @@ -0,0 +1,1019 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: vesting/vesting.proto + +package types + +import ( + fmt "fmt" + github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" + types1 "github.com/cosmos/cosmos-sdk/types" + types "github.com/cosmos/cosmos-sdk/x/auth/types" + _ "github.com/gogo/protobuf/gogoproto" + proto "github.com/gogo/protobuf/proto" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// BaseVestingAccount implements the VestingAccount interface. It contains all +// the necessary fields needed for any vesting account implementation. +type BaseVestingAccount struct { + *types.BaseAccount `protobuf:"bytes,1,opt,name=base_account,json=baseAccount,proto3,embedded=base_account" json:"base_account,omitempty"` + OriginalVesting github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,2,rep,name=original_vesting,json=originalVesting,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"original_vesting" yaml:"original_vesting"` + DelegatedFree github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,3,rep,name=delegated_free,json=delegatedFree,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"delegated_free" yaml:"delegated_free"` + DelegatedVesting github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,4,rep,name=delegated_vesting,json=delegatedVesting,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"delegated_vesting" yaml:"delegated_vesting"` + EndTime int64 `protobuf:"varint,5,opt,name=end_time,json=endTime,proto3" json:"end_time,omitempty" yaml:"end_time"` +} + +func (m *BaseVestingAccount) Reset() { *m = BaseVestingAccount{} } +func (*BaseVestingAccount) ProtoMessage() {} +func (*BaseVestingAccount) Descriptor() ([]byte, []int) { + return fileDescriptor_50dbe096578ec44c, []int{0} +} +func (m *BaseVestingAccount) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *BaseVestingAccount) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_BaseVestingAccount.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *BaseVestingAccount) XXX_Merge(src proto.Message) { + xxx_messageInfo_BaseVestingAccount.Merge(m, src) +} +func (m *BaseVestingAccount) XXX_Size() int { + return m.Size() +} +func (m *BaseVestingAccount) XXX_DiscardUnknown() { + xxx_messageInfo_BaseVestingAccount.DiscardUnknown(m) +} + +var xxx_messageInfo_BaseVestingAccount proto.InternalMessageInfo + +// Period defines a length of time and amount of coins that will vest. +type Period struct { + StartTime int64 `protobuf:"varint,1,opt,name=start_time,json=startTime,proto3" json:"start_time,omitempty"` + Length int64 `protobuf:"varint,2,opt,name=length,proto3" json:"length,omitempty"` + Amount github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,3,rep,name=amount,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"amount"` +} + +func (m *Period) Reset() { *m = Period{} } +func (*Period) ProtoMessage() {} +func (*Period) Descriptor() ([]byte, []int) { + return fileDescriptor_50dbe096578ec44c, []int{1} +} +func (m *Period) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Period) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Period.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Period) XXX_Merge(src proto.Message) { + xxx_messageInfo_Period.Merge(m, src) +} +func (m *Period) XXX_Size() int { + return m.Size() +} +func (m *Period) XXX_DiscardUnknown() { + xxx_messageInfo_Period.DiscardUnknown(m) +} + +var xxx_messageInfo_Period proto.InternalMessageInfo + +func (m *Period) GetStartTime() int64 { + if m != nil { + return m.StartTime + } + return 0 +} + +func (m *Period) GetLength() int64 { + if m != nil { + return m.Length + } + return 0 +} + +func (m *Period) GetAmount() github_com_cosmos_cosmos_sdk_types.Coins { + if m != nil { + return m.Amount + } + return nil +} + +// StridePeriodicVestingAccount implements the VestingAccount interface. It +// periodically vests by unlocking coins during each specified period. +type StridePeriodicVestingAccount struct { + *BaseVestingAccount `protobuf:"bytes,1,opt,name=base_vesting_account,json=baseVestingAccount,proto3,embedded=base_vesting_account" json:"base_vesting_account,omitempty"` + VestingPeriods []Period `protobuf:"bytes,3,rep,name=vesting_periods,json=vestingPeriods,proto3" json:"vesting_periods" yaml:"vesting_periods"` +} + +func (m *StridePeriodicVestingAccount) Reset() { *m = StridePeriodicVestingAccount{} } +func (*StridePeriodicVestingAccount) ProtoMessage() {} +func (*StridePeriodicVestingAccount) Descriptor() ([]byte, []int) { + return fileDescriptor_50dbe096578ec44c, []int{2} +} +func (m *StridePeriodicVestingAccount) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *StridePeriodicVestingAccount) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_StridePeriodicVestingAccount.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *StridePeriodicVestingAccount) XXX_Merge(src proto.Message) { + xxx_messageInfo_StridePeriodicVestingAccount.Merge(m, src) +} +func (m *StridePeriodicVestingAccount) XXX_Size() int { + return m.Size() +} +func (m *StridePeriodicVestingAccount) XXX_DiscardUnknown() { + xxx_messageInfo_StridePeriodicVestingAccount.DiscardUnknown(m) +} + +var xxx_messageInfo_StridePeriodicVestingAccount proto.InternalMessageInfo + +func init() { + proto.RegisterType((*BaseVestingAccount)(nil), "Stridelabs.stride.vesting.BaseVestingAccount") + proto.RegisterType((*Period)(nil), "Stridelabs.stride.vesting.Period") + proto.RegisterType((*StridePeriodicVestingAccount)(nil), "Stridelabs.stride.vesting.StridePeriodicVestingAccount") +} + +func init() { proto.RegisterFile("vesting/vesting.proto", fileDescriptor_50dbe096578ec44c) } + +var fileDescriptor_50dbe096578ec44c = []byte{ + // 567 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x54, 0x31, 0x6f, 0xd3, 0x40, + 0x14, 0xf6, 0x35, 0x21, 0x94, 0x0b, 0x34, 0xc5, 0xb4, 0xc5, 0xad, 0xc0, 0x0e, 0x9e, 0xb2, 0xc4, + 0xa6, 0xed, 0x96, 0x0d, 0x23, 0x21, 0x55, 0x14, 0x09, 0x19, 0xc4, 0xc0, 0x12, 0x9d, 0xed, 0xc3, + 0x39, 0xb0, 0x7d, 0x91, 0xef, 0x52, 0xd1, 0x7f, 0x80, 0xc4, 0x02, 0x12, 0x03, 0x63, 0xe7, 0xfe, + 0x92, 0x8e, 0x11, 0x13, 0x53, 0x40, 0xc9, 0x3f, 0xe8, 0xca, 0x82, 0x7c, 0x77, 0x4e, 0xc0, 0x15, + 0x44, 0xed, 0x64, 0xdf, 0xbd, 0xf7, 0x7d, 0xef, 0x7b, 0xef, 0xee, 0x3b, 0xb8, 0x79, 0x84, 0x19, + 0x27, 0x59, 0xec, 0xaa, 0xaf, 0x33, 0xcc, 0x29, 0xa7, 0xfa, 0xf6, 0x0b, 0x9e, 0x93, 0x08, 0x27, + 0x28, 0x60, 0x0e, 0x13, 0xbf, 0x8e, 0x4a, 0xd8, 0xd9, 0x88, 0x69, 0x4c, 0x45, 0x96, 0x5b, 0xfc, + 0x49, 0xc0, 0x8e, 0x19, 0x52, 0x96, 0x52, 0xe6, 0x06, 0x88, 0x61, 0xf7, 0x68, 0x37, 0xc0, 0x1c, + 0xed, 0xba, 0x21, 0x25, 0x59, 0x25, 0x8e, 0x46, 0x7c, 0x30, 0x8f, 0x17, 0x0b, 0x19, 0xb7, 0xbf, + 0xd5, 0xa1, 0xee, 0x21, 0x86, 0x5f, 0xc9, 0x2a, 0x8f, 0xc2, 0x90, 0x8e, 0x32, 0xae, 0x1f, 0xc0, + 0x9b, 0x05, 0x63, 0x1f, 0xc9, 0xb5, 0x01, 0xda, 0xa0, 0xd3, 0xdc, 0x6b, 0x3b, 0x92, 0xcd, 0x11, + 0x04, 0x8a, 0xcd, 0x29, 0xe0, 0x0a, 0xe7, 0xd5, 0xc7, 0x13, 0x0b, 0xf8, 0xcd, 0x60, 0xb1, 0xa5, + 0x7f, 0x06, 0x70, 0x9d, 0xe6, 0x24, 0x26, 0x19, 0x4a, 0xfa, 0xaa, 0x19, 0x63, 0xa5, 0x5d, 0xeb, + 0x34, 0xf7, 0xb6, 0x4b, 0xbe, 0x22, 0x7f, 0xce, 0xf7, 0x98, 0x92, 0xcc, 0x7b, 0x7a, 0x36, 0xb1, + 0xb4, 0xf3, 0x89, 0x75, 0xf7, 0x18, 0xa5, 0x49, 0xcf, 0xae, 0x12, 0xd8, 0xa7, 0x3f, 0xac, 0x4e, + 0x4c, 0xf8, 0x60, 0x14, 0x38, 0x21, 0x4d, 0x5d, 0xd5, 0xa5, 0xfc, 0x74, 0x59, 0xf4, 0xce, 0xe5, + 0xc7, 0x43, 0xcc, 0x04, 0x17, 0xf3, 0x5b, 0x25, 0x5c, 0x75, 0xa9, 0x7f, 0x04, 0x70, 0x2d, 0xc2, + 0x09, 0x8e, 0x11, 0xc7, 0x51, 0xff, 0x4d, 0x8e, 0xb1, 0x51, 0x5b, 0xa6, 0xe8, 0x40, 0x29, 0xda, + 0x94, 0x8a, 0xfe, 0x86, 0x5f, 0x4e, 0xcf, 0xad, 0x39, 0xf8, 0x49, 0x8e, 0xb1, 0xfe, 0x05, 0xc0, + 0xdb, 0x0b, 0xba, 0x72, 0x44, 0xf5, 0x65, 0x82, 0x0e, 0x95, 0x20, 0xa3, 0x2a, 0xe8, 0x4a, 0x33, + 0x5a, 0x9f, 0xe3, 0xcb, 0x21, 0x39, 0x70, 0x15, 0x67, 0x51, 0x9f, 0x93, 0x14, 0x1b, 0xd7, 0xda, + 0xa0, 0x53, 0xf3, 0xee, 0x9c, 0x4f, 0xac, 0x96, 0xac, 0x56, 0x46, 0x6c, 0xff, 0x3a, 0xce, 0xa2, + 0x97, 0x24, 0xc5, 0xbd, 0xd5, 0x0f, 0x27, 0x96, 0xf6, 0xf5, 0xc4, 0xd2, 0xec, 0x53, 0x00, 0x1b, + 0xcf, 0x71, 0x4e, 0x68, 0xa4, 0xdf, 0x87, 0x90, 0x71, 0x94, 0x73, 0x49, 0x53, 0x5c, 0xa3, 0x9a, + 0x7f, 0x43, 0xec, 0x14, 0x18, 0x7d, 0x0b, 0x36, 0x12, 0x9c, 0xc5, 0x7c, 0x60, 0xac, 0x88, 0x90, + 0x5a, 0xe9, 0x21, 0x6c, 0xa0, 0x54, 0xdc, 0xbc, 0xa5, 0xe7, 0xf2, 0xb0, 0x18, 0xc3, 0xa5, 0x5a, + 0x55, 0xd4, 0xbd, 0xba, 0x10, 0xfb, 0x0b, 0xc0, 0x7b, 0xd2, 0x75, 0x52, 0x32, 0x09, 0x2b, 0x5e, + 0xc0, 0x70, 0x43, 0x78, 0x41, 0x8d, 0xb5, 0xe2, 0x89, 0xae, 0xf3, 0x4f, 0xcb, 0x3a, 0x17, 0x8d, + 0xa5, 0x0c, 0xa2, 0x07, 0x17, 0x2d, 0xf7, 0x16, 0xb6, 0xca, 0x0a, 0x43, 0x21, 0x84, 0xa9, 0xde, + 0x1f, 0xfc, 0xa7, 0x82, 0x94, 0xec, 0x99, 0xea, 0x2a, 0x6c, 0xc9, 0xc3, 0xa9, 0xf0, 0xd8, 0xfe, + 0x9a, 0xda, 0x91, 0xe9, 0x6c, 0x71, 0x54, 0xde, 0xb3, 0xb3, 0xa9, 0x09, 0xc6, 0x53, 0x13, 0xfc, + 0x9c, 0x9a, 0xe0, 0xd3, 0xcc, 0xd4, 0xc6, 0x33, 0x53, 0xfb, 0x3e, 0x33, 0xb5, 0xd7, 0xfb, 0x7f, + 0xcc, 0x53, 0x0a, 0xe8, 0x1e, 0xa2, 0x80, 0xb9, 0x52, 0x81, 0xfb, 0xde, 0x0d, 0x13, 0x44, 0xd2, + 0xf2, 0xfd, 0x92, 0x03, 0x0e, 0x1a, 0xe2, 0x55, 0xd9, 0xff, 0x1d, 0x00, 0x00, 0xff, 0xff, 0xc1, + 0xeb, 0x7f, 0xdd, 0xdf, 0x04, 0x00, 0x00, +} + +func (m *BaseVestingAccount) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *BaseVestingAccount) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *BaseVestingAccount) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.EndTime != 0 { + i = encodeVarintVesting(dAtA, i, uint64(m.EndTime)) + i-- + dAtA[i] = 0x28 + } + if len(m.DelegatedVesting) > 0 { + for iNdEx := len(m.DelegatedVesting) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.DelegatedVesting[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintVesting(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + } + if len(m.DelegatedFree) > 0 { + for iNdEx := len(m.DelegatedFree) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.DelegatedFree[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintVesting(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + if len(m.OriginalVesting) > 0 { + for iNdEx := len(m.OriginalVesting) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.OriginalVesting[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintVesting(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + if m.BaseAccount != nil { + { + size, err := m.BaseAccount.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintVesting(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *Period) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Period) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Period) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Amount) > 0 { + for iNdEx := len(m.Amount) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Amount[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintVesting(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + if m.Length != 0 { + i = encodeVarintVesting(dAtA, i, uint64(m.Length)) + i-- + dAtA[i] = 0x10 + } + if m.StartTime != 0 { + i = encodeVarintVesting(dAtA, i, uint64(m.StartTime)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *StridePeriodicVestingAccount) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *StridePeriodicVestingAccount) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *StridePeriodicVestingAccount) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.VestingPeriods) > 0 { + for iNdEx := len(m.VestingPeriods) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.VestingPeriods[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintVesting(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + if m.BaseVestingAccount != nil { + { + size, err := m.BaseVestingAccount.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintVesting(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintVesting(dAtA []byte, offset int, v uint64) int { + offset -= sovVesting(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *BaseVestingAccount) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.BaseAccount != nil { + l = m.BaseAccount.Size() + n += 1 + l + sovVesting(uint64(l)) + } + if len(m.OriginalVesting) > 0 { + for _, e := range m.OriginalVesting { + l = e.Size() + n += 1 + l + sovVesting(uint64(l)) + } + } + if len(m.DelegatedFree) > 0 { + for _, e := range m.DelegatedFree { + l = e.Size() + n += 1 + l + sovVesting(uint64(l)) + } + } + if len(m.DelegatedVesting) > 0 { + for _, e := range m.DelegatedVesting { + l = e.Size() + n += 1 + l + sovVesting(uint64(l)) + } + } + if m.EndTime != 0 { + n += 1 + sovVesting(uint64(m.EndTime)) + } + return n +} + +func (m *Period) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.StartTime != 0 { + n += 1 + sovVesting(uint64(m.StartTime)) + } + if m.Length != 0 { + n += 1 + sovVesting(uint64(m.Length)) + } + if len(m.Amount) > 0 { + for _, e := range m.Amount { + l = e.Size() + n += 1 + l + sovVesting(uint64(l)) + } + } + return n +} + +func (m *StridePeriodicVestingAccount) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.BaseVestingAccount != nil { + l = m.BaseVestingAccount.Size() + n += 1 + l + sovVesting(uint64(l)) + } + if len(m.VestingPeriods) > 0 { + for _, e := range m.VestingPeriods { + l = e.Size() + n += 1 + l + sovVesting(uint64(l)) + } + } + return n +} + +func sovVesting(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozVesting(x uint64) (n int) { + return sovVesting(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *BaseVestingAccount) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowVesting + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: BaseVestingAccount: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: BaseVestingAccount: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BaseAccount", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowVesting + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthVesting + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthVesting + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.BaseAccount == nil { + m.BaseAccount = &types.BaseAccount{} + } + if err := m.BaseAccount.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field OriginalVesting", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowVesting + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthVesting + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthVesting + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.OriginalVesting = append(m.OriginalVesting, types1.Coin{}) + if err := m.OriginalVesting[len(m.OriginalVesting)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DelegatedFree", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowVesting + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthVesting + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthVesting + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DelegatedFree = append(m.DelegatedFree, types1.Coin{}) + if err := m.DelegatedFree[len(m.DelegatedFree)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DelegatedVesting", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowVesting + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthVesting + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthVesting + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DelegatedVesting = append(m.DelegatedVesting, types1.Coin{}) + if err := m.DelegatedVesting[len(m.DelegatedVesting)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field EndTime", wireType) + } + m.EndTime = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowVesting + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.EndTime |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipVesting(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthVesting + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Period) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowVesting + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Period: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Period: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field StartTime", wireType) + } + m.StartTime = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowVesting + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.StartTime |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Length", wireType) + } + m.Length = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowVesting + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Length |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Amount", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowVesting + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthVesting + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthVesting + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Amount = append(m.Amount, types1.Coin{}) + if err := m.Amount[len(m.Amount)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipVesting(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthVesting + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *StridePeriodicVestingAccount) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowVesting + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: StridePeriodicVestingAccount: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: StridePeriodicVestingAccount: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BaseVestingAccount", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowVesting + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthVesting + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthVesting + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.BaseVestingAccount == nil { + m.BaseVestingAccount = &BaseVestingAccount{} + } + if err := m.BaseVestingAccount.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field VestingPeriods", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowVesting + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthVesting + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthVesting + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.VestingPeriods = append(m.VestingPeriods, Period{}) + if err := m.VestingPeriods[len(m.VestingPeriods)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipVesting(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthVesting + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipVesting(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowVesting + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowVesting + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowVesting + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthVesting + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupVesting + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthVesting + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthVesting = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowVesting = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupVesting = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/claim/vesting/types/vesting_account.go b/x/claim/vesting/types/vesting_account.go new file mode 100644 index 0000000000..04770fd845 --- /dev/null +++ b/x/claim/vesting/types/vesting_account.go @@ -0,0 +1,356 @@ +package types + +import ( + "errors" + "time" + + yaml "gopkg.in/yaml.v2" + + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + + "github.com/Stride-Labs/stride/utils" + vestexported "github.com/Stride-Labs/stride/x/claim/vesting/exported" +) + +// Compile-time type assertions +var ( + _ authtypes.AccountI = (*BaseVestingAccount)(nil) + _ vestexported.VestingAccount = (*StridePeriodicVestingAccount)(nil) +) + +// Base Vesting Account + +// NewBaseVestingAccount creates a new BaseVestingAccount object. It is the +// callers responsibility to ensure the base account has sufficient funds with +// regards to the original vesting amount. +func NewBaseVestingAccount(baseAccount *authtypes.BaseAccount, originalVesting sdk.Coins, endTime int64) *BaseVestingAccount { + return &BaseVestingAccount{ + BaseAccount: baseAccount, + OriginalVesting: originalVesting, + DelegatedFree: sdk.NewCoins(), + DelegatedVesting: sdk.NewCoins(), + EndTime: endTime, + } +} + +// LockedCoinsFromVesting returns all the coins that are not spendable (i.e. locked) +// for a vesting account given the current vesting coins. If no coins are locked, +// an empty slice of Coins is returned. +// +// CONTRACT: Delegated vesting coins and vestingCoins must be sorted. +func (bva BaseVestingAccount) LockedCoinsFromVesting(vestingCoins sdk.Coins) sdk.Coins { + lockedCoins := vestingCoins.Sub(vestingCoins.Min(bva.DelegatedVesting)) + if lockedCoins == nil { + return sdk.Coins{} + } + return lockedCoins +} + +// TrackDelegation tracks a delegation amount for any given vesting account type +// given the amount of coins currently vesting and the current account balance +// of the delegation denominations. +// +// CONTRACT: The account's coins, delegation coins, vesting coins, and delegated +// vesting coins must be sorted. +func (bva *BaseVestingAccount) TrackDelegation(balance, vestingCoins, amount sdk.Coins) { + for _, coin := range amount { + baseAmt := balance.AmountOf(coin.Denom) + vestingAmt := vestingCoins.AmountOf(coin.Denom) + delVestingAmt := bva.DelegatedVesting.AmountOf(coin.Denom) + + // Panic if the delegation amount is zero or if the base coins does not + // exceed the desired delegation amount. + if coin.Amount.IsZero() || baseAmt.LT(coin.Amount) { + panic("delegation attempt with zero coins or insufficient funds") + } + + // compute x and y per the specification, where: + // X := min(max(V - DV, 0), D) + // Y := D - X + x := sdk.MinInt(sdk.MaxInt(vestingAmt.Sub(delVestingAmt), sdk.ZeroInt()), coin.Amount) + y := coin.Amount.Sub(x) + + if !x.IsZero() { + xCoin := sdk.NewCoin(coin.Denom, x) + bva.DelegatedVesting = bva.DelegatedVesting.Add(xCoin) + } + + if !y.IsZero() { + yCoin := sdk.NewCoin(coin.Denom, y) + bva.DelegatedFree = bva.DelegatedFree.Add(yCoin) + } + } +} + +// TrackUndelegation tracks an undelegation amount by setting the necessary +// values by which delegated vesting and delegated vesting need to decrease and +// by which amount the base coins need to increase. +// +// NOTE: The undelegation (bond refund) amount may exceed the delegated +// vesting (bond) amount due to the way undelegation truncates the bond refund, +// which can increase the validator's exchange rate (tokens/shares) slightly if +// the undelegated tokens are non-integral. +// +// CONTRACT: The account's coins and undelegation coins must be sorted. +func (bva *BaseVestingAccount) TrackUndelegation(amount sdk.Coins) { + for _, coin := range amount { + // panic if the undelegation amount is zero + if coin.Amount.IsZero() { + panic("undelegation attempt with zero coins") + } + delegatedFree := bva.DelegatedFree.AmountOf(coin.Denom) + delegatedVesting := bva.DelegatedVesting.AmountOf(coin.Denom) + + // compute x and y per the specification, where: + // X := min(DF, D) + // Y := min(DV, D - X) + x := sdk.MinInt(delegatedFree, coin.Amount) + y := sdk.MinInt(delegatedVesting, coin.Amount.Sub(x)) + + if !x.IsZero() { + xCoin := sdk.NewCoin(coin.Denom, x) + bva.DelegatedFree = bva.DelegatedFree.Sub(sdk.Coins{xCoin}) + } + + if !y.IsZero() { + yCoin := sdk.NewCoin(coin.Denom, y) + bva.DelegatedVesting = bva.DelegatedVesting.Sub(sdk.Coins{yCoin}) + } + } +} + +// GetOriginalVesting returns a vesting account's original vesting amount +func (bva BaseVestingAccount) GetOriginalVesting() sdk.Coins { + return bva.OriginalVesting +} + +// GetDelegatedFree returns a vesting account's delegation amount that is not +// vesting. +func (bva BaseVestingAccount) GetDelegatedFree() sdk.Coins { + return bva.DelegatedFree +} + +// GetDelegatedVesting returns a vesting account's delegation amount that is +// still vesting. +func (bva BaseVestingAccount) GetDelegatedVesting() sdk.Coins { + return bva.DelegatedVesting +} + +// GetEndTime returns a vesting account's end time +func (bva BaseVestingAccount) GetEndTime() int64 { + return bva.EndTime +} + +// Validate checks for errors on the account fields +func (bva BaseVestingAccount) Validate() error { + if !(bva.DelegatedVesting.IsAllLTE(bva.OriginalVesting)) { + return errors.New("delegated vesting amount cannot be greater than original vesting amount") + } + return bva.BaseAccount.Validate() +} + +type vestingAccountYAML struct { + Address sdk.AccAddress `json:"address" yaml:"address"` + PubKey string `json:"public_key" yaml:"public_key"` + AccountNumber uint64 `json:"account_number" yaml:"account_number"` + Sequence uint64 `json:"sequence" yaml:"sequence"` + OriginalVesting sdk.Coins `json:"original_vesting" yaml:"original_vesting"` + DelegatedFree sdk.Coins `json:"delegated_free" yaml:"delegated_free"` + DelegatedVesting sdk.Coins `json:"delegated_vesting" yaml:"delegated_vesting"` + EndTime int64 `json:"end_time" yaml:"end_time"` + + // custom fields based on concrete vesting type which can be omitted + StartTime int64 `json:"start_time,omitempty" yaml:"start_time,omitempty"` + VestingPeriods Periods `json:"vesting_periods,omitempty" yaml:"vesting_periods,omitempty"` +} + +func (bva BaseVestingAccount) String() string { + out, _ := bva.MarshalYAML() + return out.(string) +} + +// MarshalYAML returns the YAML representation of a BaseVestingAccount. +func (bva BaseVestingAccount) MarshalYAML() (interface{}, error) { + accAddr, err := sdk.AccAddressFromBech32(bva.Address) + if err != nil { + return nil, err + } + + out := vestingAccountYAML{ + Address: accAddr, + AccountNumber: bva.AccountNumber, + PubKey: getPKString(bva), + Sequence: bva.Sequence, + OriginalVesting: bva.OriginalVesting, + DelegatedFree: bva.DelegatedFree, + DelegatedVesting: bva.DelegatedVesting, + EndTime: bva.EndTime, + } + return marshalYaml(out) +} + +// Periodic Vesting Account (only for stride) +// This vesting account works differently from the core periodic vesting account. +var _ vestexported.VestingAccount = (*StridePeriodicVestingAccount)(nil) +var _ authtypes.GenesisAccount = (*StridePeriodicVestingAccount)(nil) + +// NewStridePeriodicVestingAccountRaw creates a new StridePeriodicVestingAccount object from BaseVestingAccount +func NewStridePeriodicVestingAccountRaw(bva *BaseVestingAccount, startTime int64, periods Periods) *StridePeriodicVestingAccount { + return &StridePeriodicVestingAccount{ + BaseVestingAccount: bva, + VestingPeriods: periods, + } +} + +// NewStridePeriodicVestingAccount returns a new StridePeriodicVestingAccount +func NewStridePeriodicVestingAccount(baseAcc *authtypes.BaseAccount, originalVesting sdk.Coins, periods Periods) *StridePeriodicVestingAccount { + if len(periods) == 0 { + return &StridePeriodicVestingAccount{} + } + + endTime := int64(0) + for _, p := range periods { + endTime = utils.Max64(endTime, p.StartTime+p.Length) + } + + baseVestingAcc := &BaseVestingAccount{ + BaseAccount: baseAcc, + OriginalVesting: originalVesting, + EndTime: endTime, + } + + return &StridePeriodicVestingAccount{ + BaseVestingAccount: baseVestingAcc, + VestingPeriods: periods, + } +} + +// AddNewGrant adds a new grant +func (pva *StridePeriodicVestingAccount) AddNewGrant(grantedPeriod Period) { + // Starting time for new period must be greater than original starting time + pva.VestingPeriods = append(pva.VestingPeriods, grantedPeriod) + pva.EndTime = utils.Max64(pva.EndTime, grantedPeriod.Length+grantedPeriod.StartTime) + pva.OriginalVesting = pva.OriginalVesting.Add(grantedPeriod.Amount...) +} + +// GetVestedCoins returns the total number of vested coins. If no coins are vested, +// nil is returned. +func (pva StridePeriodicVestingAccount) GetVestedCoins(blockTime time.Time) sdk.Coins { + var vestedCoins sdk.Coins + + // We must handle the case where the start time for a vesting account has + // been set into the future or when the start of the chain is not exactly + // known. + if len(pva.VestingPeriods) == 0 { + return vestedCoins + } else if blockTime.Unix() <= pva.VestingPeriods[0].StartTime { + return vestedCoins + } else if blockTime.Unix() >= pva.EndTime { + return pva.OriginalVesting + } + + for _, period := range pva.VestingPeriods { + vestedCoins = vestedCoins.Add(utils.GetVestedCoinsAt(blockTime.Unix(), period.StartTime, period.Length, period.Amount)...) + } + + return vestedCoins +} + +// GetVestingCoins returns the total number of vesting coins. If no coins are +// vesting, nil is returned. +func (pva StridePeriodicVestingAccount) GetVestingCoins(blockTime time.Time) sdk.Coins { + return pva.OriginalVesting.Sub(pva.GetVestedCoins(blockTime)) +} + +// LockedCoins returns the set of coins that are not spendable (i.e. locked), +// defined as the vesting coins that are not delegated. +func (pva StridePeriodicVestingAccount) LockedCoins(blockTime time.Time) sdk.Coins { + return pva.BaseVestingAccount.LockedCoinsFromVesting(pva.GetVestingCoins(blockTime)) +} + +// TrackDelegation tracks a desired delegation amount by setting the appropriate +// values for the amount of delegated vesting, delegated free, and reducing the +// overall amount of base coins. +func (pva *StridePeriodicVestingAccount) TrackDelegation(blockTime time.Time, balance, amount sdk.Coins) { + pva.BaseVestingAccount.TrackDelegation(balance, pva.GetVestingCoins(blockTime), amount) +} + +// GetStartTime returns the time when vesting starts for a periodic vesting +// account. +func (pva StridePeriodicVestingAccount) GetStartTime() int64 { + return pva.VestingPeriods[0].StartTime +} + +// GetVestingPeriods returns vesting periods associated with periodic vesting account. +func (pva StridePeriodicVestingAccount) GetVestingPeriods() Periods { + return pva.VestingPeriods +} + +// Validate checks for errors on the account fields +func (pva StridePeriodicVestingAccount) Validate() error { + if pva.GetStartTime() >= pva.GetEndTime() { + return errors.New("vesting start-time cannot be before end-time") + } + endTime := pva.VestingPeriods[0].StartTime + originalVesting := sdk.NewCoins() + for _, p := range pva.VestingPeriods { + endTime += p.Length + originalVesting = originalVesting.Add(p.Amount...) + } + if endTime != pva.EndTime { + return errors.New("vesting end time does not match length of all vesting periods") + } + if !originalVesting.IsEqual(pva.OriginalVesting) { + return errors.New("original vesting coins does not match the sum of all coins in vesting periods") + } + + return pva.BaseVestingAccount.Validate() +} + +func (pva StridePeriodicVestingAccount) String() string { + out, _ := pva.MarshalYAML() + return out.(string) +} + +// MarshalYAML returns the YAML representation of a StridePeriodicVestingAccount. +func (pva StridePeriodicVestingAccount) MarshalYAML() (interface{}, error) { + accAddr, err := sdk.AccAddressFromBech32(pva.Address) + if err != nil { + return nil, err + } + + out := vestingAccountYAML{ + Address: accAddr, + AccountNumber: pva.AccountNumber, + PubKey: getPKString(pva), + Sequence: pva.Sequence, + OriginalVesting: pva.OriginalVesting, + DelegatedFree: pva.DelegatedFree, + DelegatedVesting: pva.DelegatedVesting, + EndTime: pva.EndTime, + StartTime: pva.VestingPeriods[0].StartTime, + VestingPeriods: pva.VestingPeriods, + } + return marshalYaml(out) +} + +type getPK interface { + GetPubKey() cryptotypes.PubKey +} + +func getPKString(g getPK) string { + if pk := g.GetPubKey(); pk != nil { + return pk.String() + } + return "" +} + +func marshalYaml(i interface{}) (interface{}, error) { + bz, err := yaml.Marshal(i) + if err != nil { + return nil, err + } + return string(bz), nil +} diff --git a/x/claim/vesting/types/vesting_account_test.go b/x/claim/vesting/types/vesting_account_test.go new file mode 100644 index 0000000000..cb72503de7 --- /dev/null +++ b/x/claim/vesting/types/vesting_account_test.go @@ -0,0 +1,267 @@ +package types_test + +import ( + "testing" + "time" + + "github.com/stretchr/testify/require" + tmtime "github.com/tendermint/tendermint/types/time" + + "github.com/cosmos/cosmos-sdk/testutil/testdata" + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + + "github.com/Stride-Labs/stride/x/claim/vesting/types" +) + +var ( + stakeDenom = "stake" + feeDenom = "fee" +) + +func TestGetVestedCoinsPeriodicVestingAcc(t *testing.T) { + now := tmtime.Now() + endTime := now.Add(24 * time.Hour) + periods := types.Periods{ + types.Period{StartTime: now.Unix(), Length: int64(12 * 60 * 60), Amount: sdk.Coins{sdk.NewInt64Coin(feeDenom, 500), sdk.NewInt64Coin(stakeDenom, 50)}}, + types.Period{StartTime: now.Unix() + int64(12*60*60), Length: int64(6 * 60 * 60), Amount: sdk.Coins{sdk.NewInt64Coin(feeDenom, 250), sdk.NewInt64Coin(stakeDenom, 25)}}, + types.Period{StartTime: now.Unix() + int64(18*60*60), Length: int64(6 * 60 * 60), Amount: sdk.Coins{sdk.NewInt64Coin(feeDenom, 250), sdk.NewInt64Coin(stakeDenom, 25)}}, + } + + bacc, origCoins := initBaseAccount() + pva := types.NewStridePeriodicVestingAccount(bacc, origCoins, periods) + + // require no coins vested at the beginning of the vesting schedule + vestedCoins := pva.GetVestedCoins(now) + require.Nil(t, vestedCoins) + + // require all coins vested at the end of the vesting schedule + vestedCoins = pva.GetVestedCoins(endTime) + require.Equal(t, origCoins, vestedCoins) + + // require 50% of coins vested after period 1 + vestedCoins = pva.GetVestedCoins(now.Add(12 * time.Hour)) + require.Equal(t, sdk.Coins{sdk.NewInt64Coin(feeDenom, 500), sdk.NewInt64Coin(stakeDenom, 50)}, vestedCoins) + + // require 62.5% of coins vested after 15 hrs passed (in the middle of period 2) + vestedCoins = pva.GetVestedCoins(now.Add(15 * time.Hour)) + require.Equal(t, sdk.Coins{sdk.NewInt64Coin(feeDenom, 625), sdk.NewInt64Coin(stakeDenom, 62)}, vestedCoins) + + // require 75% of coins vested after period 2 + vestedCoins = pva.GetVestedCoins(now.Add(18 * time.Hour)) + require.Equal(t, + sdk.Coins{ + sdk.NewInt64Coin(feeDenom, 750), sdk.NewInt64Coin(stakeDenom, 75)}, vestedCoins) + + // require 100% of coins vested + vestedCoins = pva.GetVestedCoins(now.Add(48 * time.Hour)) + require.Equal(t, origCoins, vestedCoins) +} + +func TestGetVestingCoinsPeriodicVestingAcc(t *testing.T) { + now := tmtime.Now() + endTime := now.Add(24 * time.Hour) + periods := types.Periods{ + types.Period{StartTime: now.Unix(), Length: int64(12 * 60 * 60), Amount: sdk.Coins{sdk.NewInt64Coin(feeDenom, 500), sdk.NewInt64Coin(stakeDenom, 50)}}, + types.Period{StartTime: now.Unix() + int64(12*60*60), Length: int64(6 * 60 * 60), Amount: sdk.Coins{sdk.NewInt64Coin(feeDenom, 250), sdk.NewInt64Coin(stakeDenom, 25)}}, + types.Period{StartTime: now.Unix() + int64(18*60*60), Length: int64(6 * 60 * 60), Amount: sdk.Coins{sdk.NewInt64Coin(feeDenom, 250), sdk.NewInt64Coin(stakeDenom, 25)}}, + } + + bacc, origCoins := initBaseAccount() + pva := types.NewStridePeriodicVestingAccount(bacc, origCoins, periods) + + // require all coins vesting at the beginning of the vesting schedule + vestingCoins := pva.GetVestingCoins(now) + require.Equal(t, origCoins, vestingCoins) + + // require no coins vesting at the end of the vesting schedule + vestingCoins = pva.GetVestingCoins(endTime) + require.Nil(t, vestingCoins) + + // require 50% of coins vesting + vestingCoins = pva.GetVestingCoins(now.Add(12 * time.Hour)) + require.Equal(t, sdk.Coins{sdk.NewInt64Coin(feeDenom, 500), sdk.NewInt64Coin(stakeDenom, 50)}, vestingCoins) + + // require 37.5% of coins vesting after 15 hrs passed (in the middle of period 2) + vestingCoins = pva.GetVestingCoins(now.Add(15 * time.Hour)) + require.Equal(t, sdk.Coins{sdk.NewInt64Coin(feeDenom, 375), sdk.NewInt64Coin(stakeDenom, 38)}, vestingCoins) + + // require 25% of coins vesting after period 2 + vestingCoins = pva.GetVestingCoins(now.Add(18 * time.Hour)) + require.Equal(t, sdk.Coins{sdk.NewInt64Coin(feeDenom, 250), sdk.NewInt64Coin(stakeDenom, 25)}, vestingCoins) + + // require 0% of coins vesting after vesting complete + vestingCoins = pva.GetVestingCoins(now.Add(48 * time.Hour)) + require.Nil(t, vestingCoins) +} + +func TestSpendableCoinsPeriodicVestingAcc(t *testing.T) { + now := tmtime.Now() + endTime := now.Add(24 * time.Hour) + periods := types.Periods{ + types.Period{StartTime: now.Unix(), Length: int64(12 * 60 * 60), Amount: sdk.Coins{sdk.NewInt64Coin(feeDenom, 500), sdk.NewInt64Coin(stakeDenom, 50)}}, + types.Period{StartTime: now.Unix() + int64(12*60*60), Length: int64(6 * 60 * 60), Amount: sdk.Coins{sdk.NewInt64Coin(feeDenom, 250), sdk.NewInt64Coin(stakeDenom, 25)}}, + types.Period{StartTime: now.Unix() + int64(15*60*60), Length: int64(6 * 60 * 60), Amount: sdk.Coins{sdk.NewInt64Coin(feeDenom, 250), sdk.NewInt64Coin(stakeDenom, 25)}}, + } + + bacc, origCoins := initBaseAccount() + pva := types.NewStridePeriodicVestingAccount(bacc, origCoins, periods) + + // require that there exist no spendable coins at the beginning of the + // vesting schedule + lockedCoins := pva.LockedCoins(now) + require.Equal(t, origCoins, lockedCoins) + + // require that all original coins are spendable at the end of the vesting + // schedule + lockedCoins = pva.LockedCoins(endTime) + require.Equal(t, sdk.NewCoins(), lockedCoins) + + // require that vesting coins (50%) are locked + lockedCoins = pva.LockedCoins(now.Add(12 * time.Hour)) + require.Equal(t, sdk.Coins{sdk.NewInt64Coin(feeDenom, 500), sdk.NewInt64Coin(stakeDenom, 50)}, lockedCoins) + + // require that vesting coins (0%) are locked + lockedCoins = pva.LockedCoins(now.Add(21 * time.Hour)) + require.Equal(t, sdk.Coins{}, lockedCoins) +} + +func TestTrackDelegationPeriodicVestingAcc(t *testing.T) { + now := tmtime.Now() + endTime := now.Add(24 * time.Hour) + periods := types.Periods{ + types.Period{StartTime: now.Unix(), Length: int64(12 * 60 * 60), Amount: sdk.Coins{sdk.NewInt64Coin(feeDenom, 500), sdk.NewInt64Coin(stakeDenom, 50)}}, + types.Period{StartTime: now.Unix() + int64(12*60*60), Length: int64(6 * 60 * 60), Amount: sdk.Coins{sdk.NewInt64Coin(feeDenom, 250), sdk.NewInt64Coin(stakeDenom, 25)}}, + types.Period{StartTime: now.Unix() + int64(18*60*60), Length: int64(6 * 60 * 60), Amount: sdk.Coins{sdk.NewInt64Coin(feeDenom, 250), sdk.NewInt64Coin(stakeDenom, 25)}}, + } + + bacc, origCoins := initBaseAccount() + + // require the ability to delegate all vesting coins + pva := types.NewStridePeriodicVestingAccount(bacc, origCoins, periods) + pva.TrackDelegation(now, origCoins, origCoins) + require.Equal(t, origCoins, pva.DelegatedVesting) + require.Nil(t, pva.DelegatedFree) + + // require the ability to delegate all vested coins + pva = types.NewStridePeriodicVestingAccount(bacc, origCoins, periods) + pva.TrackDelegation(endTime, origCoins, origCoins) + require.Nil(t, pva.DelegatedVesting) + require.Equal(t, origCoins, pva.DelegatedFree) + + // delegate half of vesting coins + pva = types.NewStridePeriodicVestingAccount(bacc, origCoins, periods) + pva.TrackDelegation(now, origCoins, periods[0].Amount) + // require that all delegated coins are delegated vesting + require.Equal(t, pva.DelegatedVesting, periods[0].Amount) + require.Nil(t, pva.DelegatedFree) + + // delegate 75% of coins, split between vested and vesting + pva = types.NewStridePeriodicVestingAccount(bacc, origCoins, periods) + pva.TrackDelegation(now.Add(12*time.Hour), origCoins, periods[0].Amount.Add(periods[1].Amount...)) + // require that the maximum possible amount of vesting coins are chosen for delegation. + require.Equal(t, pva.DelegatedFree, periods[1].Amount) + require.Equal(t, pva.DelegatedVesting, periods[0].Amount) + + // require the ability to delegate all vesting coins (50%) and all vested coins (50%) + pva = types.NewStridePeriodicVestingAccount(bacc, origCoins, periods) + pva.TrackDelegation(now.Add(12*time.Hour), origCoins, sdk.Coins{sdk.NewInt64Coin(stakeDenom, 50)}) + require.Equal(t, sdk.Coins{sdk.NewInt64Coin(stakeDenom, 50)}, pva.DelegatedVesting) + require.Nil(t, pva.DelegatedFree) + + pva.TrackDelegation(now.Add(12*time.Hour), origCoins, sdk.Coins{sdk.NewInt64Coin(stakeDenom, 50)}) + require.Equal(t, sdk.Coins{sdk.NewInt64Coin(stakeDenom, 50)}, pva.DelegatedVesting) + require.Equal(t, sdk.Coins{sdk.NewInt64Coin(stakeDenom, 50)}, pva.DelegatedFree) + + // require no modifications when delegation amount is zero or not enough funds + pva = types.NewStridePeriodicVestingAccount(bacc, origCoins, periods) + require.Panics(t, func() { + pva.TrackDelegation(endTime, origCoins, sdk.Coins{sdk.NewInt64Coin(stakeDenom, 1000000)}) + }) + require.Nil(t, pva.DelegatedVesting) + require.Nil(t, pva.DelegatedFree) +} + +func TestTrackUndelegationPeriodicVestingAcc(t *testing.T) { + now := tmtime.Now() + endTime := now.Add(24 * time.Hour) + periods := types.Periods{ + types.Period{StartTime: now.Unix(), Length: int64(12 * 60 * 60), Amount: sdk.Coins{sdk.NewInt64Coin(feeDenom, 500), sdk.NewInt64Coin(stakeDenom, 50)}}, + types.Period{StartTime: now.Unix() + int64(12*60*60), Length: int64(6 * 60 * 60), Amount: sdk.Coins{sdk.NewInt64Coin(feeDenom, 250), sdk.NewInt64Coin(stakeDenom, 25)}}, + types.Period{StartTime: now.Unix() + int64(18*60*60), Length: int64(6 * 60 * 60), Amount: sdk.Coins{sdk.NewInt64Coin(feeDenom, 250), sdk.NewInt64Coin(stakeDenom, 25)}}, + } + + bacc, origCoins := initBaseAccount() + + // require the ability to undelegate all vesting coins at the beginning of vesting + pva := types.NewStridePeriodicVestingAccount(bacc, origCoins, periods) + pva.TrackDelegation(now, origCoins, origCoins) + pva.TrackUndelegation(origCoins) + require.Nil(t, pva.DelegatedFree) + require.Nil(t, pva.DelegatedVesting) + + // require the ability to undelegate all vested coins at the end of vesting + pva = types.NewStridePeriodicVestingAccount(bacc, origCoins, periods) + + pva.TrackDelegation(endTime, origCoins, origCoins) + pva.TrackUndelegation(origCoins) + require.Nil(t, pva.DelegatedFree) + require.Nil(t, pva.DelegatedVesting) + + // require the ability to undelegate half of coins + pva = types.NewStridePeriodicVestingAccount(bacc, origCoins, periods) + pva.TrackDelegation(endTime, origCoins, periods[0].Amount) + pva.TrackUndelegation(periods[0].Amount) + require.Nil(t, pva.DelegatedFree) + require.Nil(t, pva.DelegatedVesting) + + // require no modifications when the undelegation amount is zero + pva = types.NewStridePeriodicVestingAccount(bacc, origCoins, periods) + + require.Panics(t, func() { + pva.TrackUndelegation(sdk.Coins{sdk.NewInt64Coin(stakeDenom, 0)}) + }) + require.Nil(t, pva.DelegatedFree) + require.Nil(t, pva.DelegatedVesting) + + // vest 50% and delegate to two validators + pva = types.NewStridePeriodicVestingAccount(bacc, origCoins, periods) + pva.TrackDelegation(now.Add(12*time.Hour), origCoins, sdk.Coins{sdk.NewInt64Coin(stakeDenom, 50)}) + pva.TrackDelegation(now.Add(12*time.Hour), origCoins, sdk.Coins{sdk.NewInt64Coin(stakeDenom, 50)}) + + // undelegate from one validator that got slashed 50% + pva.TrackUndelegation(sdk.Coins{sdk.NewInt64Coin(stakeDenom, 25)}) + require.Equal(t, sdk.Coins{sdk.NewInt64Coin(stakeDenom, 25)}, pva.DelegatedFree) + require.Equal(t, sdk.Coins{sdk.NewInt64Coin(stakeDenom, 50)}, pva.DelegatedVesting) + + // undelegate from the other validator that did not get slashed + pva.TrackUndelegation(sdk.Coins{sdk.NewInt64Coin(stakeDenom, 50)}) + require.Nil(t, pva.DelegatedFree) + require.Equal(t, sdk.Coins{sdk.NewInt64Coin(stakeDenom, 25)}, pva.DelegatedVesting) +} + +func TestStridePeriodicVestingAccountMarshal(t *testing.T) { + baseAcc, coins := initBaseAccount() + now := tmtime.Now() + acc := types.NewStridePeriodicVestingAccount(baseAcc, coins, types.Periods{types.Period{now.Unix(), 3600, coins}}) + + bz, err := app.AccountKeeper.MarshalAccount(acc) + require.Nil(t, err) + + acc2, err := app.AccountKeeper.UnmarshalAccount(bz) + require.Nil(t, err) + require.IsType(t, &types.StridePeriodicVestingAccount{}, acc2) + require.Equal(t, acc.String(), acc2.String()) + + // error on bad bytes + _, err = app.AccountKeeper.UnmarshalAccount(bz[:len(bz)/2]) + require.NotNil(t, err) +} + +func initBaseAccount() (*authtypes.BaseAccount, sdk.Coins) { + _, _, addr := testdata.KeyTestPubAddr() + origCoins := sdk.Coins{sdk.NewInt64Coin(feeDenom, 1000), sdk.NewInt64Coin(stakeDenom, 100)} + bacc := authtypes.NewBaseAccountWithAddress(addr) + + return bacc, origCoins +} diff --git a/x/stakeibc/keeper/keeper.go b/x/stakeibc/keeper/keeper.go index 450145ae77..13077ddbf7 100644 --- a/x/stakeibc/keeper/keeper.go +++ b/x/stakeibc/keeper/keeper.go @@ -42,8 +42,8 @@ type ( RecordsKeeper recordsmodulekeeper.Keeper StakingKeeper stakingkeeper.Keeper ICACallbacksKeeper icacallbackskeeper.Keeper - - accountKeeper types.AccountKeeper + hooks types.StakeIBCHooks + accountKeeper types.AccountKeeper } ) @@ -91,6 +91,17 @@ func (k Keeper) Logger(ctx sdk.Context) log.Logger { return ctx.Logger().With("module", fmt.Sprintf("x/%s", types.ModuleName)) } +// SetHooks sets the hooks for ibc staking +func (k *Keeper) SetHooks(gh types.StakeIBCHooks) *Keeper { + if k.hooks != nil { + panic("cannot set ibc staking hooks twice") + } + + k.hooks = gh + + return k +} + // ClaimCapability claims the channel capability passed via the OnOpenChanInit callback func (k *Keeper) ClaimCapability(ctx sdk.Context, cap *capabilitytypes.Capability, name string) error { return k.scopedKeeper.ClaimCapability(ctx, cap, name) diff --git a/x/stakeibc/keeper/msg_server_liquid_stake.go b/x/stakeibc/keeper/msg_server_liquid_stake.go index e6c41b9540..e57b76aa91 100644 --- a/x/stakeibc/keeper/msg_server_liquid_stake.go +++ b/x/stakeibc/keeper/msg_server_liquid_stake.go @@ -95,6 +95,7 @@ func (k msgServer) LiquidStake(goCtx context.Context, msg *types.MsgLiquidStake) depositRecord.Amount += msgAmt k.RecordsKeeper.SetDepositRecord(ctx, *depositRecord) + k.hooks.AfterLiquidStake(ctx, sender) return &types.MsgLiquidStakeResponse{}, nil } diff --git a/x/stakeibc/types/expected_keepers.go b/x/stakeibc/types/expected_keepers.go index baf1cef7a6..099fe8b92e 100644 --- a/x/stakeibc/types/expected_keepers.go +++ b/x/stakeibc/types/expected_keepers.go @@ -25,3 +25,12 @@ type BankKeeper interface { SendCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) error MintCoins(ctx sdk.Context, moduleName string, amt sdk.Coins) error } + +// Event Hooks +// These can be utilized to communicate between a stakeibc keeper and another +// keeper which must take particular actions when liquid staking happens + +// StakeIBCHooks event hooks for stakeibc +type StakeIBCHooks interface { + AfterLiquidStake(ctx sdk.Context, addr sdk.AccAddress) // Must be called after liquid stake is completed +} diff --git a/x/stakeibc/types/hooks.go b/x/stakeibc/types/hooks.go new file mode 100644 index 0000000000..6ea6e7c634 --- /dev/null +++ b/x/stakeibc/types/hooks.go @@ -0,0 +1,18 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// combine multiple staking hooks, all hook functions are run in array sequence +type MultiStakeIBCHooks []StakeIBCHooks + +func NewMultiStakeIBCHooks(hooks ...StakeIBCHooks) MultiStakeIBCHooks { + return hooks +} + +func (h MultiStakeIBCHooks) AfterLiquidStake(ctx sdk.Context, addr sdk.AccAddress) { + for i := range h { + h[i].AfterLiquidStake(ctx, addr) + } +}