Skip to content

Commit 01bb8e0

Browse files
authored
feat: adding claim command to bot (#25)
1 parent 9df1e1a commit 01bb8e0

File tree

16 files changed

+193
-61
lines changed

16 files changed

+193
-61
lines changed

client/client.go

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ import (
55
"errors"
66

77
"github.com/kehiy/RoboPac/log"
8-
"github.com/pactus-project/pactus/crypto"
9-
"github.com/pactus-project/pactus/crypto/bls"
108
pactus "github.com/pactus-project/pactus/www/grpc/gen/go"
119
"google.golang.org/grpc"
1210
"google.golang.org/grpc/credentials/insecure"
@@ -61,22 +59,20 @@ func (c *Client) GetNetworkInfo() (*pactus.GetNetworkInfoResponse, error) {
6159
return networkInfo, nil
6260
}
6361

64-
func (c *Client) GetPeerInfo(address string) (*pactus.PeerInfo, *bls.PublicKey, error) {
62+
func (c *Client) GetPeerInfo(address string) (*pactus.PeerInfo, error) {
6563
networkInfo, _ := c.GetNetworkInfo()
66-
crypto.PublicKeyHRP = "tpublic"
6764
if networkInfo != nil {
6865
for _, p := range networkInfo.ConnectedPeers {
69-
for _, key := range p.ConsensusKeys {
70-
pub, _ := bls.PublicKeyFromString(key)
71-
if pub != nil {
72-
if pub.ValidatorAddress().String() == address {
73-
return p, pub, nil
66+
for _, addr := range p.ConsensusAddress {
67+
if addr != "" {
68+
if addr == address {
69+
return p, nil
7470
}
7571
}
7672
}
7773
}
7874
}
79-
return nil, nil, errors.New("peer does not exist")
75+
return nil, errors.New("peer does not exist")
8076
}
8177

8278
func (c *Client) IsValidator(address string) (bool, error) {

client/client_mgr.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ func (cm *Mgr) GetTransactionData(txID string) (*pactus.GetTransactionResponse,
175175
return nil, errors.New("unable to get transaction data")
176176
}
177177

178-
func (cm *Mgr) Close() {
178+
func (cm *Mgr) Stop() {
179179
for addr, c := range cm.clients {
180180
if err := c.Close(); err != nil {
181181
log.Error("could not close connection to RPC node", "err", err, "RPCAddr", addr)

cmd/commands/run.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77

88
"github.com/kehiy/RoboPac/client"
99
"github.com/kehiy/RoboPac/config"
10+
"github.com/kehiy/RoboPac/discord"
1011
"github.com/kehiy/RoboPac/engine"
1112
"github.com/kehiy/RoboPac/log"
1213
"github.com/kehiy/RoboPac/store"
@@ -21,7 +22,7 @@ func RunCommand(parentCmd *cobra.Command) {
2122
}
2223
parentCmd.AddCommand(run)
2324

24-
run.Run = func(cmd *cobra.Command, args []string) {
25+
run.Run = func(_ *cobra.Command, _ []string) {
2526
// load configuration.
2627
config, err := config.Load()
2728
if err != nil {
@@ -72,16 +73,24 @@ func RunCommand(parentCmd *cobra.Command) {
7273
// starting botEngine.
7374
botEngine, err := engine.NewBotEngine(eSl, cm, wallet, store)
7475
if err != nil {
75-
log.Panic("could not start discord bot", "err", err)
76+
log.Panic("could not start bot engine", "err", err)
7677
}
7778
botEngine.Start()
7879

80+
discordBot, err := discord.NewDiscordBot(botEngine, config.DiscordBotCfg.DiscordToken,
81+
config.DiscordBotCfg.DiscordGuildID)
82+
if err != nil {
83+
log.Panic("could not start discord bot", "err", err)
84+
}
85+
discordBot.Start()
86+
7987
sigChan := make(chan os.Signal, 1)
8088
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM, os.Interrupt)
8189
<-sigChan
8290

8391
// gracefully shutdown the bot.
92+
discordBot.Stop()
93+
cm.Stop()
8494
botEngine.Stop()
85-
cm.Close()
8695
}
8796
}

discord/commands.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package discord
2+
3+
import "github.com/bwmarrin/discordgo"
4+
5+
var commands = []*discordgo.ApplicationCommand{
6+
{
7+
Name: "help",
8+
Description: "Help command for RoboPac",
9+
},
10+
}
11+
12+
var commandHandlers = map[string]func(s *discordgo.Session, i *discordgo.InteractionCreate){
13+
"help": helpCommandHandler,
14+
}

discord/discord.go

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,56 @@
11
package discord
22

3-
// need implementation.
3+
import (
4+
"github.com/bwmarrin/discordgo"
5+
"github.com/kehiy/RoboPac/engine"
6+
"github.com/kehiy/RoboPac/log"
7+
)
8+
9+
type DiscordBot struct {
10+
Session *discordgo.Session
11+
BotEngine engine.Engine
12+
GuildID string
13+
}
14+
15+
func NewDiscordBot(botEngine engine.Engine, token, guildID string) (*DiscordBot, error) {
16+
s, err := discordgo.New("Bot " + token)
17+
if err != nil {
18+
return nil, err
19+
}
20+
21+
return &DiscordBot{
22+
Session: s,
23+
BotEngine: botEngine,
24+
GuildID: guildID,
25+
}, nil
26+
}
27+
28+
func (db *DiscordBot) Start() {
29+
log.Info("starting Discord Bot...")
30+
31+
db.Session.AddHandler(func(s *discordgo.Session, i *discordgo.InteractionCreate) {
32+
if h, ok := commandHandlers[i.ApplicationCommandData().Name]; ok {
33+
h(s, i)
34+
}
35+
})
36+
37+
err := db.Session.Open()
38+
if err != nil {
39+
log.Panic("can't open discord session", "err", err)
40+
}
41+
42+
registeredCommands := make([]*discordgo.ApplicationCommand, len(commands))
43+
for i, v := range commands {
44+
cmd, err := db.Session.ApplicationCommandCreate(db.Session.State.User.ID, db.GuildID, v)
45+
if err != nil {
46+
log.Panic("can not register discord command", "name", v.Name, "err", err)
47+
}
48+
registeredCommands[i] = cmd
49+
}
50+
}
51+
52+
func (db *DiscordBot) Stop() {
53+
log.Info("shutting down Discord Bot...")
54+
55+
_ = db.Session.Close()
56+
}

discord/embeds.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package discord
2+
3+
import "github.com/bwmarrin/discordgo"
4+
5+
func helpEmbed(s *discordgo.Session) *discordgo.MessageEmbed {
6+
return &discordgo.MessageEmbed{
7+
Title: "RoboPac Help",
8+
URL: "https://pactus.org",
9+
Author: &discordgo.MessageEmbedAuthor{
10+
URL: "https://pactus.org",
11+
IconURL: s.State.User.AvatarURL(""),
12+
Name: s.State.User.Username,
13+
},
14+
Description: "RoboPac is a robot that provides support and information about the Pactus Blockchain.",
15+
}
16+
}

discord/handlers.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package discord
2+
3+
import "github.com/bwmarrin/discordgo"
4+
5+
func helpCommandHandler(s *discordgo.Session, i *discordgo.InteractionCreate) {
6+
_, _ = s.ChannelMessageSendEmbedReply(i.ChannelID, helpEmbed(s), i.Message.Reference())
7+
}

engine/engine.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -140,16 +140,17 @@ func (be *BotEngine) Claim(tokens []string) (*store.ClaimTransaction, error) {
140140
be.Lock()
141141
defer be.Unlock()
142142

143-
if len(tokens) != 2 {
143+
if len(tokens) != 3 {
144144
return nil, errors.New("missing argument: validator address")
145145
}
146146

147147
valAddr := tokens[0]
148-
discordID := tokens[1]
148+
testNetValAddr := tokens[1]
149+
discordID := tokens[2]
149150

150-
be.logger.Info("new claim request", "valAddr", valAddr, "discordID", discordID)
151+
be.logger.Info("new claim request", "valAddr", valAddr, "testNetValAddr", testNetValAddr, "discordID", discordID)
151152

152-
claimer := be.Store.ClaimerInfo(discordID)
153+
claimer := be.Store.ClaimerInfo(testNetValAddr)
153154
if claimer == nil {
154155
return nil, errors.New("claimer not found")
155156
}
@@ -185,12 +186,13 @@ func (be *BotEngine) Claim(tokens []string) (*store.ClaimTransaction, error) {
185186
return nil, err
186187
}
187188

188-
err = be.Store.AddClaimTransaction(txID, util.ChangeToCoin(txData.Transaction.Value), int64(txData.BlockTime), discordID)
189+
err = be.Store.AddClaimTransaction(util.ChangeToCoin(txData.Transaction.Value),
190+
int64(txData.BlockTime), txID, discordID, testNetValAddr)
189191
if err != nil {
190192
return nil, err
191193
}
192194

193-
claimer = be.Store.ClaimerInfo(discordID)
195+
claimer = be.Store.ClaimerInfo(testNetValAddr)
194196
if claimer == nil {
195197
return nil, errors.New("can't save claim info")
196198
}

engine/engine_test.go

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -156,16 +156,17 @@ func TestClaim(t *testing.T) {
156156

157157
t.Run("everything normal and good", func(t *testing.T) {
158158
valAddress := "pc1p74scge5dyzjktv9q70xtr0pjmyqcqk7nuh8nzp"
159+
testNetValAddr := "tpc1pqn7uaeduklpg00rqt6uq0m9wy5txnyt0kmxmgf"
159160
discordID := "123456789"
160161
txID := "0x123456789"
161-
amount := 74.68
162+
amount := float64(74)
162163
time := time.Now().Unix()
163164

164165
client.EXPECT().IsValidator(valAddress).Return(
165166
true, nil,
166167
)
167168

168-
store.EXPECT().ClaimerInfo(discordID).Return(
169+
store.EXPECT().ClaimerInfo(testNetValAddr).Return(
169170
&rpstore.Claimer{
170171
DiscordID: discordID,
171172
TotalReward: amount,
@@ -189,11 +190,11 @@ func TestClaim(t *testing.T) {
189190
}, nil,
190191
)
191192

192-
store.EXPECT().AddClaimTransaction(txID, amount, time, discordID).Return(
193+
store.EXPECT().AddClaimTransaction(amount, time, txID, discordID, testNetValAddr).Return(
193194
nil,
194195
)
195196

196-
store.EXPECT().ClaimerInfo(discordID).Return(
197+
store.EXPECT().ClaimerInfo(testNetValAddr).Return(
197198
&rpstore.Claimer{
198199
DiscordID: discordID,
199200
TotalReward: amount,
@@ -205,7 +206,7 @@ func TestClaim(t *testing.T) {
205206
},
206207
).AnyTimes()
207208

208-
claimTx, err := eng.Claim([]string{valAddress, discordID})
209+
claimTx, err := eng.Claim([]string{valAddress, testNetValAddr, discordID})
209210
assert.NoError(t, err)
210211
assert.NotNil(t, claimTx)
211212

@@ -214,7 +215,7 @@ func TestClaim(t *testing.T) {
214215
assert.Equal(t, time, claimTx.Time)
215216

216217
//! can't claim twice.
217-
claimTx, err = eng.Claim([]string{valAddress, discordID})
218+
claimTx, err = eng.Claim([]string{valAddress, testNetValAddr, discordID})
218219
assert.EqualError(t, err, "this claimer have already claimed rewards")
219220
assert.Nil(t, claimTx)
220221
})
@@ -227,23 +228,25 @@ func TestClaim(t *testing.T) {
227228

228229
t.Run("claimer not found", func(t *testing.T) {
229230
valAddress := "pc1p74scge5dyzjktv9q70xtr0pjmyqcqk7nuh8nzp"
231+
testNetValAddr := "tpc1peaeyzmwjqu6nz93c27hr8ad2l265tx4s9v6zhw"
230232
discordID := "987654321"
231233

232-
store.EXPECT().ClaimerInfo(discordID).Return(
234+
store.EXPECT().ClaimerInfo(testNetValAddr).Return(
233235
nil,
234236
)
235237

236-
claimTx, err := eng.Claim([]string{valAddress, discordID})
238+
claimTx, err := eng.Claim([]string{valAddress, testNetValAddr, discordID})
237239
assert.EqualError(t, err, "claimer not found")
238240
assert.Nil(t, claimTx)
239241
})
240242

241243
t.Run("not validator address", func(t *testing.T) {
242244
valAddress := "pc1p74scge5dyzjktv9q70xtr0pjmyqcqk7nuh8nzp"
245+
testNetValAddr := "tpc1p2vx5t8sglhvncmp3en0qhgtxyc59w0gfgnaqe7"
243246
discordID := "1234567890"
244247
amount := 74.68
245248

246-
store.EXPECT().ClaimerInfo(discordID).Return(
249+
store.EXPECT().ClaimerInfo(testNetValAddr).Return(
247250
&rpstore.Claimer{
248251
DiscordID: discordID,
249252
TotalReward: amount,
@@ -254,21 +257,22 @@ func TestClaim(t *testing.T) {
254257
false, nil,
255258
)
256259

257-
claimTx, err := eng.Claim([]string{valAddress, discordID})
260+
claimTx, err := eng.Claim([]string{valAddress, testNetValAddr, discordID})
258261
assert.EqualError(t, err, "invalid argument: validator address")
259262
assert.Nil(t, claimTx)
260263
})
261264

262265
t.Run("empty transaction ID", func(t *testing.T) {
263266
valAddress := "pc1p74scge5dyzjktv9q70xtr0pjmyqcqk7nuh8nzp"
267+
testNetValAddr := "tpc1pvmundkkp83u5cfz04sem5r7688dc0lef5u0mmv"
264268
discordID := "1234567890"
265269
amount := 74.68
266270

267271
client.EXPECT().IsValidator(valAddress).Return(
268272
true, nil,
269273
)
270274

271-
store.EXPECT().ClaimerInfo(discordID).Return(
275+
store.EXPECT().ClaimerInfo(testNetValAddr).Return(
272276
&rpstore.Claimer{
273277
DiscordID: discordID,
274278
TotalReward: amount,
@@ -281,7 +285,7 @@ func TestClaim(t *testing.T) {
281285
"", nil,
282286
)
283287

284-
claimTx, err := eng.Claim([]string{valAddress, discordID})
288+
claimTx, err := eng.Claim([]string{valAddress, testNetValAddr, discordID})
285289
assert.EqualError(t, err, "can't send bond transaction")
286290
assert.Nil(t, claimTx)
287291
})

go.mod

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@ require (
1010
google.golang.org/grpc v1.58.3
1111
)
1212

13+
require github.com/gorilla/websocket v1.5.1 // indirect
14+
1315
require (
16+
github.com/bwmarrin/discordgo v0.27.1
1417
github.com/davecgh/go-spew v1.1.1 // indirect
1518
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect
1619
github.com/fxamacker/cbor/v2 v2.5.0 // indirect

0 commit comments

Comments
 (0)