Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Feature / Bet Bonus Reward #368

Merged
merged 9 commits into from
Mar 18, 2024
7 changes: 3 additions & 4 deletions proto/sge/reward/campaign.proto
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,12 @@ message Campaign {
// is_active is the flag to check if the campaign is active or not.
bool is_active = 11;

// claims_per_category is the number of times a user can claim a
// reward for category of this campaign.
uint64 claims_per_category = 12;

// meta is the metadata of the campaign.
// It is a stringified base64 encoded json.
string meta = 13;

// cap_count is the maximum allowed grant for a certain account.
uint64 cap_count = 14;
}

// Pool tracks funds assigned and spent to/for a campaign.
Expand Down
5 changes: 5 additions & 0 deletions proto/sge/reward/genesis.proto
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import "gogoproto/gogo.proto";
import "sge/reward/params.proto";
import "sge/reward/campaign.proto";
import "sge/reward/reward.proto";
import "sge/reward/promoter.proto";

option go_package = "github.com/sge-network/sge/x/reward/types";

Expand All @@ -18,4 +19,8 @@ message GenesisState {
[ (gogoproto.nullable) = false ];
repeated RewardByCampaign reward_by_campaign_list = 5
[ (gogoproto.nullable) = false ];
repeated Promoter promoter_list = 6
[ (gogoproto.nullable) = false ];
repeated PromoterByAddress promoter_by_address_list = 7
[ (gogoproto.nullable) = false ];
}
51 changes: 51 additions & 0 deletions proto/sge/reward/promoter.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
syntax = "proto3";
package sgenetwork.sge.reward;

import "gogoproto/gogo.proto";

import "sge/reward/reward.proto";

option go_package = "github.com/sge-network/sge/x/reward/types";

// Promoter is type for defining the reward promoter properties and configuration.
message Promoter {
// creator is the address of promoter.
string creator = 1;

// uid is the unique identifier of a promoter.
string uid = 2 [
(gogoproto.customname) = "UID",
(gogoproto.jsontag) = "uid",
json_name = "uid"
];

// addresses is the list of account addresses of promoter.
repeated string addresses = 3;

// conf is the configurations of the current promoter for the reward grant.
PromoterConf conf = 4 [ (gogoproto.nullable) = false ];
}

// PromoterConf is type for defining the promoter specific configurations.
message PromoterConf {
// category_cap is the maximium allowed cap for each category.
repeated CategoryCap category_cap = 1 [ (gogoproto.nullable) = false ];
}

// CategoryCap is type to define category and its maximum cap.
message CategoryCap {
RewardCategory category = 1;
int32 cap_per_acc = 2;
}

// PromoterByAddress is type for defining the promoter by address.
message PromoterByAddress {
// promoter_uid is the unique identifier of a certain promoter.
string promoter_uid = 1 [
(gogoproto.customname) = "PromoterUID",
(gogoproto.jsontag) = "promoter_uid",
json_name = "promoter_uid"
];
// address is the address of the promoter account.
string address = 2;
}
6 changes: 4 additions & 2 deletions proto/sge/reward/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,15 @@ service Query {
// Queries list of all Reward items by user address.
rpc RewardsByAddress(QueryRewardsByAddressRequest)
returns (QueryRewardsByAddressResponse) {
option (google.api.http).get = "/sge-network/sge/reward/rewards/{address}";
option (google.api.http).get = "/sge-network/sge/reward/rewards/{promoter_uid}/{address}";
}

// Queries list of all Reward items by user address and reward type
// endpoint.
rpc RewardsByAddressAndCategory(QueryRewardsByAddressAndCategoryRequest)
returns (QueryRewardsByAddressAndCategoryResponse) {
option (google.api.http).get =
"/sge-network/sge/reward/rewards/{address}/{category}";
"/sge-network/sge/reward/rewards/{promoter_uid}/{address}/{category}";
}

// Queries list of all Reward items by campaign endpoint.
Expand Down Expand Up @@ -114,6 +114,7 @@ message QueryRewardsResponse {
message QueryRewardsByAddressRequest {
cosmos.base.query.v1beta1.PageRequest pagination = 1;
string address = 2;
string promoter_uid = 3;
}

// QueryRewardsByAddressResponse is response body of the query all rewards by
Expand All @@ -129,6 +130,7 @@ message QueryRewardsByAddressAndCategoryRequest {
cosmos.base.query.v1beta1.PageRequest pagination = 1;
string address = 2;
RewardCategory category = 3;
string promoter_uid = 4;
}

// QueryRewardsByAddressAndCategoryResponse is response body of the query all
Expand Down
27 changes: 23 additions & 4 deletions proto/sge/reward/ticket.proto
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package sgenetwork.sge.reward;
import "gogoproto/gogo.proto";
import "sge/type/kyc.proto";
import "sge/reward/reward.proto";
import "sge/reward/promoter.proto";

option go_package = "github.com/sge-network/sge/x/reward/types";

Expand Down Expand Up @@ -34,13 +35,12 @@ message CreateCampaignPayload {
// is_active is the flag to check if the campaign is active or not.
bool is_active = 8;

// claims_per_category is the number of times a user can claim a reward for
// category of this campaign.
uint64 claims_per_category = 9;

// meta is the metadata of the campaign.
// It is a stringified base64 encoded json.
string meta = 10;

// cap_count is the maximum allowed grant for a certain account.
uint64 cap_count = 11;
}

// UpdateCampaignPayload is the type for campaign update payload.
Expand Down Expand Up @@ -109,4 +109,23 @@ message GrantSignupAffiliatorRewardPayload {
// affiliatee is the address of the account that used this affiliator's
// address as source_uid
string affiliatee = 2;
}

// GrantBetBonusRewardPayload is the type for bet bonus reward
// grant payload.
message GrantBetBonusRewardPayload {
// common is the common properties of a reward
RewardPayloadCommon common = 1 [ (gogoproto.nullable) = false ];

// bet_uid is the list of uids
string bet_uid = 2 [
(gogoproto.customname) = "BetUID",
(gogoproto.jsontag) = "bet_uid",
json_name = "bet_uid"
];
}

// SetPromoterConfPayload is the payload for the promoter configuration change.
message SetPromoterConfPayload {
PromoterConf conf = 1 [ (gogoproto.nullable) = false ];
}
15 changes: 15 additions & 0 deletions proto/sge/reward/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ option go_package = "github.com/sge-network/sge/x/reward/types";

// Msg defines the Msg service.
service Msg {
// SetPromoterConf is a method to set the configurations of a promoter.
rpc SetPromoterConf(MsgSetPromoterConf) returns (MsgSetPromoterConfResponse);
// CreateCampaign is a method to create a campaign
rpc CreateCampaign(MsgCreateCampaign) returns (MsgCreateCampaignResponse);
// UpdateCampaign is a method to update campaign
Expand All @@ -18,6 +20,19 @@ service Msg {
rpc GrantReward(MsgGrantReward) returns (MsgGrantRewardResponse);
}

// MsgSetPromoterConf is msg to set promoter configuration.
message MsgSetPromoterConf {
// creator is the address of message signer account.
string creator = 1;
// uid is the unique identifier of the promoter.
string uid = 2;
// ticket is the payload data.
string ticket = 3;
}

// MsgCreateCampaignResponse campaign create message response type.
message MsgSetPromoterConfResponse {}

// MsgCreateCampaign is msg to create a reward campaign
message MsgCreateCampaign {
// creator is the address of campaign creator account.
Expand Down
1 change: 1 addition & 0 deletions x/reward/client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ func GetTxCmd() *cobra.Command {
RunE: client.ValidateCmd,
}

cmd.AddCommand(CmdSetPromoterConf())
cmd.AddCommand(CmdCreateCampaign())
cmd.AddCommand(CmdUpdateCampaign())
cmd.AddCommand(CmdWithdrawFunds())
Expand Down
46 changes: 46 additions & 0 deletions x/reward/client/cli/tx_promoter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package cli

import (
"github.com/spf13/cobra"

"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/client/tx"

"github.com/sge-network/sge/x/reward/types"
)

func CmdSetPromoterConf() *cobra.Command {
cmd := &cobra.Command{
Use: "set-promoter-conf [uid] [ticket]",
Short: "Set promoter config",
Long: "Set promoter config of a promoter by uid and the ticket",
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) (err error) {
// Get indexes
argUID := args[0]

// Get value arguments
argTicket := args[1]

clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}

msg := types.NewMsgSetPromoterConfig(
clientCtx.GetFromAddress().String(),
argUID,
argTicket,
)
if err := msg.ValidateBasic(); err != nil {
return err
}
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
},
}

flags.AddTxFlagsToCmd(cmd)

return cmd
}
22 changes: 21 additions & 1 deletion x/reward/genesis.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package reward

import (
"fmt"

sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/sge-network/sge/x/reward/keeper"
Expand All @@ -9,6 +11,12 @@ import (

// InitGenesis initializes the module's state from a provided genesis state.
func InitGenesis(ctx sdk.Context, k keeper.Keeper, genState types.GenesisState) {
for _, elem := range genState.PromoterList {
k.SetPromoter(ctx, elem)
}
for _, elem := range genState.PromoterByAddressList {
k.SetPromoterByAddress(ctx, elem)
}
// Set all the campaign
for _, elem := range genState.CampaignList {
k.SetCampaign(ctx, elem)
Expand All @@ -17,7 +25,19 @@ func InitGenesis(ctx sdk.Context, k keeper.Keeper, genState types.GenesisState)
k.SetReward(ctx, elem)
}
for _, elem := range genState.RewardByCategoryList {
k.SetRewardByReceiver(ctx, elem)
reward, found := k.GetReward(ctx, elem.UID)
if !found {
panic(fmt.Errorf("reward is not valid %s", elem.UID))
}
camp, found := k.GetCampaign(ctx, reward.CampaignUID)
if !found {
panic(fmt.Errorf("campaign is not valid %s", reward.CampaignUID))
}
promoter, found := k.GetPromoterByAddress(ctx, camp.Promoter)
if !found {
panic(fmt.Errorf("promoter is not valid %s", camp.Promoter))
}
k.SetRewardOfReceiverByPromoterAndCategory(ctx, promoter.PromoterUID, elem)
}
for _, elem := range genState.RewardByCampaignList {
k.SetRewardByCampaign(ctx, elem)
Expand Down
52 changes: 44 additions & 8 deletions x/reward/genesis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,39 +13,75 @@ import (
)

func TestGenesis(t *testing.T) {
promoterAddr := "promoter"
promoterUID := uuid.NewString()

campaignUID1 := uuid.NewString()
campaignUID2 := uuid.NewString()

rewardID1 := uuid.NewString()
rewardID2 := uuid.NewString()

genesisState := types.GenesisState{
Params: types.DefaultParams(),

PromoterList: []types.Promoter{
{
Creator: promoterAddr,
UID: promoterUID,
Addresses: []string{promoterAddr},
Conf: types.PromoterConf{
CategoryCap: []types.CategoryCap{
{
Category: types.RewardCategory_REWARD_CATEGORY_SIGNUP,
CapPerAcc: 1,
},
},
},
},
},
PromoterByAddressList: []types.PromoterByAddress{
{
PromoterUID: promoterUID,
Address: promoterAddr,
},
},
CampaignList: []types.Campaign{
{
UID: uuid.NewString(),
UID: campaignUID1,
Promoter: promoterAddr,
},
{
UID: uuid.NewString(),
UID: campaignUID2,
Promoter: promoterAddr,
},
},
RewardList: []types.Reward{
{
UID: uuid.NewString(),
UID: rewardID1,
CampaignUID: campaignUID1,
},
{
UID: uuid.NewString(),
UID: rewardID2,
CampaignUID: campaignUID2,
},
},
RewardByCategoryList: []types.RewardByCategory{
{
UID: uuid.NewString(),
UID: rewardID1,
},
{
UID: uuid.NewString(),
UID: rewardID2,
},
},
RewardByCampaignList: []types.RewardByCampaign{
{
UID: uuid.NewString(),
UID: rewardID1,
CampaignUID: campaignUID1,
},
{
UID: uuid.NewString(),
UID: rewardID1,
CampaignUID: campaignUID2,
},
},
}
Expand Down
4 changes: 1 addition & 3 deletions x/reward/keeper/campaign.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@ import (
func (k Keeper) SetCampaign(ctx sdk.Context, campaign types.Campaign) {
store := k.getCampaignStore(ctx)
b := k.cdc.MustMarshal(&campaign)
store.Set(types.GetCampaignKey(
campaign.UID,
), b)
store.Set(types.GetCampaignKey(campaign.UID), b)
}

// GetCampaign returns a campaign from its index
Expand Down
Loading
Loading