From 689e4e6413ee66e243807779a792ebed357b8a0b Mon Sep 17 00:00:00 2001 From: Kay Date: Fri, 26 Jan 2024 12:08:02 +0000 Subject: [PATCH 1/5] feat: adding claim command to bot --- client/client.go | 16 ++++++---------- engine/engine.go | 14 ++++++++------ engine/engine_test.go | 28 ++++++++++++++++------------ store/interface.go | 9 +++++---- store/mock.go | 16 ++++++++-------- store/store.go | 8 ++++---- store/store_test.go | 16 ++++++++++++---- store/test/store_example.json | 24 ++++++++++++++++-------- 8 files changed, 75 insertions(+), 56 deletions(-) diff --git a/client/client.go b/client/client.go index 3dcb4b05..948cc8ab 100644 --- a/client/client.go +++ b/client/client.go @@ -5,8 +5,6 @@ import ( "errors" "github.com/kehiy/RoboPac/log" - "github.com/pactus-project/pactus/crypto" - "github.com/pactus-project/pactus/crypto/bls" pactus "github.com/pactus-project/pactus/www/grpc/gen/go" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" @@ -61,22 +59,20 @@ func (c *Client) GetNetworkInfo() (*pactus.GetNetworkInfoResponse, error) { return networkInfo, nil } -func (c *Client) GetPeerInfo(address string) (*pactus.PeerInfo, *bls.PublicKey, error) { +func (c *Client) GetPeerInfo(address string) (*pactus.PeerInfo, error) { networkInfo, _ := c.GetNetworkInfo() - crypto.PublicKeyHRP = "tpublic" if networkInfo != nil { for _, p := range networkInfo.ConnectedPeers { - for _, key := range p.ConsensusKeys { - pub, _ := bls.PublicKeyFromString(key) - if pub != nil { - if pub.ValidatorAddress().String() == address { - return p, pub, nil + for _, addr := range p.ConsensusAddress { + if addr != "" { + if addr == address { + return p, nil } } } } } - return nil, nil, errors.New("peer does not exist") + return nil, errors.New("peer does not exist") } func (c *Client) IsValidator(address string) (bool, error) { diff --git a/engine/engine.go b/engine/engine.go index f2091200..b17608e2 100644 --- a/engine/engine.go +++ b/engine/engine.go @@ -140,16 +140,17 @@ func (be *BotEngine) Claim(tokens []string) (*store.ClaimTransaction, error) { be.Lock() defer be.Unlock() - if len(tokens) != 2 { + if len(tokens) != 3 { return nil, errors.New("missing argument: validator address") } valAddr := tokens[0] - discordID := tokens[1] + testNetValAddr := tokens[1] + discordID := tokens[2] - be.logger.Info("new claim request", "valAddr", valAddr, "discordID", discordID) + be.logger.Info("new claim request", "valAddr", valAddr, "testNetValAddr", testNetValAddr, "discordID", discordID) - claimer := be.Store.ClaimerInfo(discordID) + claimer := be.Store.ClaimerInfo(testNetValAddr) if claimer == nil { return nil, errors.New("claimer not found") } @@ -185,12 +186,13 @@ func (be *BotEngine) Claim(tokens []string) (*store.ClaimTransaction, error) { return nil, err } - err = be.Store.AddClaimTransaction(txID, util.ChangeToCoin(txData.Transaction.Value), int64(txData.BlockTime), discordID) + err = be.Store.AddClaimTransaction(util.ChangeToCoin(txData.Transaction.Value), + int64(txData.BlockTime), txID, discordID, testNetValAddr) if err != nil { return nil, err } - claimer = be.Store.ClaimerInfo(discordID) + claimer = be.Store.ClaimerInfo(testNetValAddr) if claimer == nil { return nil, errors.New("can't save claim info") } diff --git a/engine/engine_test.go b/engine/engine_test.go index 5475c3d5..33ffe4be 100644 --- a/engine/engine_test.go +++ b/engine/engine_test.go @@ -156,16 +156,17 @@ func TestClaim(t *testing.T) { t.Run("everything normal and good", func(t *testing.T) { valAddress := "pc1p74scge5dyzjktv9q70xtr0pjmyqcqk7nuh8nzp" + testNetValAddr := "tpc1pqn7uaeduklpg00rqt6uq0m9wy5txnyt0kmxmgf" discordID := "123456789" txID := "0x123456789" - amount := 74.68 + amount := float64(74) time := time.Now().Unix() client.EXPECT().IsValidator(valAddress).Return( true, nil, ) - store.EXPECT().ClaimerInfo(discordID).Return( + store.EXPECT().ClaimerInfo(testNetValAddr).Return( &rpstore.Claimer{ DiscordID: discordID, TotalReward: amount, @@ -189,11 +190,11 @@ func TestClaim(t *testing.T) { }, nil, ) - store.EXPECT().AddClaimTransaction(txID, amount, time, discordID).Return( + store.EXPECT().AddClaimTransaction(amount, time, txID, discordID, testNetValAddr).Return( nil, ) - store.EXPECT().ClaimerInfo(discordID).Return( + store.EXPECT().ClaimerInfo(testNetValAddr).Return( &rpstore.Claimer{ DiscordID: discordID, TotalReward: amount, @@ -205,7 +206,7 @@ func TestClaim(t *testing.T) { }, ).AnyTimes() - claimTx, err := eng.Claim([]string{valAddress, discordID}) + claimTx, err := eng.Claim([]string{valAddress, testNetValAddr, discordID}) assert.NoError(t, err) assert.NotNil(t, claimTx) @@ -214,7 +215,7 @@ func TestClaim(t *testing.T) { assert.Equal(t, time, claimTx.Time) //! can't claim twice. - claimTx, err = eng.Claim([]string{valAddress, discordID}) + claimTx, err = eng.Claim([]string{valAddress, testNetValAddr, discordID}) assert.EqualError(t, err, "this claimer have already claimed rewards") assert.Nil(t, claimTx) }) @@ -227,23 +228,25 @@ func TestClaim(t *testing.T) { t.Run("claimer not found", func(t *testing.T) { valAddress := "pc1p74scge5dyzjktv9q70xtr0pjmyqcqk7nuh8nzp" + testNetValAddr := "tpc1peaeyzmwjqu6nz93c27hr8ad2l265tx4s9v6zhw" discordID := "987654321" - store.EXPECT().ClaimerInfo(discordID).Return( + store.EXPECT().ClaimerInfo(testNetValAddr).Return( nil, ) - claimTx, err := eng.Claim([]string{valAddress, discordID}) + claimTx, err := eng.Claim([]string{valAddress, testNetValAddr, discordID}) assert.EqualError(t, err, "claimer not found") assert.Nil(t, claimTx) }) t.Run("not validator address", func(t *testing.T) { valAddress := "pc1p74scge5dyzjktv9q70xtr0pjmyqcqk7nuh8nzp" + testNetValAddr := "tpc1p2vx5t8sglhvncmp3en0qhgtxyc59w0gfgnaqe7" discordID := "1234567890" amount := 74.68 - store.EXPECT().ClaimerInfo(discordID).Return( + store.EXPECT().ClaimerInfo(testNetValAddr).Return( &rpstore.Claimer{ DiscordID: discordID, TotalReward: amount, @@ -254,13 +257,14 @@ func TestClaim(t *testing.T) { false, nil, ) - claimTx, err := eng.Claim([]string{valAddress, discordID}) + claimTx, err := eng.Claim([]string{valAddress, testNetValAddr, discordID}) assert.EqualError(t, err, "invalid argument: validator address") assert.Nil(t, claimTx) }) t.Run("empty transaction ID", func(t *testing.T) { valAddress := "pc1p74scge5dyzjktv9q70xtr0pjmyqcqk7nuh8nzp" + testNetValAddr := "tpc1pvmundkkp83u5cfz04sem5r7688dc0lef5u0mmv" discordID := "1234567890" amount := 74.68 @@ -268,7 +272,7 @@ func TestClaim(t *testing.T) { true, nil, ) - store.EXPECT().ClaimerInfo(discordID).Return( + store.EXPECT().ClaimerInfo(testNetValAddr).Return( &rpstore.Claimer{ DiscordID: discordID, TotalReward: amount, @@ -281,7 +285,7 @@ func TestClaim(t *testing.T) { "", nil, ) - claimTx, err := eng.Claim([]string{valAddress, discordID}) + claimTx, err := eng.Claim([]string{valAddress, testNetValAddr, discordID}) assert.EqualError(t, err, "can't send bond transaction") assert.Nil(t, claimTx) }) diff --git a/store/interface.go b/store/interface.go index d991aef8..e099806c 100644 --- a/store/interface.go +++ b/store/interface.go @@ -7,8 +7,9 @@ type ClaimTransaction struct { } type Claimer struct { - DiscordID string `json:"discord_id"` - TotalReward float64 `json:"total_reward"` + DiscordID string `json:"did"` + // ValAddr string `json:"main_net_validator_address"` + TotalReward float64 `json:"r"` ClaimTransaction *ClaimTransaction `json:"claim_transaction"` } @@ -17,6 +18,6 @@ func (c *Claimer) IsClaimed() bool { } type IStore interface { - ClaimerInfo(discordID string) *Claimer - AddClaimTransaction(TxID string, Amount float64, Time int64, discordID string) error + ClaimerInfo(testNetValAddr string) *Claimer + AddClaimTransaction(amount float64, time int64, txID, discordID, testNetValAddr string) error } diff --git a/store/mock.go b/store/mock.go index 59faf76f..52e4a2eb 100644 --- a/store/mock.go +++ b/store/mock.go @@ -39,29 +39,29 @@ func (m *MockIStore) EXPECT() *MockIStoreMockRecorder { } // AddClaimTransaction mocks base method. -func (m *MockIStore) AddClaimTransaction(TxID string, Amount float64, Time int64, discordID string) error { +func (m *MockIStore) AddClaimTransaction(amount float64, time int64, txID, discordID, testNetValAddr string) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AddClaimTransaction", TxID, Amount, Time, discordID) + ret := m.ctrl.Call(m, "AddClaimTransaction", amount, time, txID, discordID, testNetValAddr) ret0, _ := ret[0].(error) return ret0 } // AddClaimTransaction indicates an expected call of AddClaimTransaction. -func (mr *MockIStoreMockRecorder) AddClaimTransaction(TxID, Amount, Time, discordID any) *gomock.Call { +func (mr *MockIStoreMockRecorder) AddClaimTransaction(amount, time, txID, discordID, testNetValAddr any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddClaimTransaction", reflect.TypeOf((*MockIStore)(nil).AddClaimTransaction), TxID, Amount, Time, discordID) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddClaimTransaction", reflect.TypeOf((*MockIStore)(nil).AddClaimTransaction), amount, time, txID, discordID, testNetValAddr) } // ClaimerInfo mocks base method. -func (m *MockIStore) ClaimerInfo(discordID string) *Claimer { +func (m *MockIStore) ClaimerInfo(testNetValAddr string) *Claimer { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ClaimerInfo", discordID) + ret := m.ctrl.Call(m, "ClaimerInfo", testNetValAddr) ret0, _ := ret[0].(*Claimer) return ret0 } // ClaimerInfo indicates an expected call of ClaimerInfo. -func (mr *MockIStoreMockRecorder) ClaimerInfo(discordID any) *gomock.Call { +func (mr *MockIStoreMockRecorder) ClaimerInfo(testNetValAddr any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClaimerInfo", reflect.TypeOf((*MockIStore)(nil).ClaimerInfo), discordID) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClaimerInfo", reflect.TypeOf((*MockIStore)(nil).ClaimerInfo), testNetValAddr) } diff --git a/store/store.go b/store/store.go index 943f2f22..a9162074 100644 --- a/store/store.go +++ b/store/store.go @@ -43,8 +43,8 @@ func LoadStore(cfg *config.Config, logger *log.SubLogger) (IStore, error) { return ss, nil } -func (s *Store) ClaimerInfo(discordID string) *Claimer { - entry, found := s.syncMap.Load(discordID) +func (s *Store) ClaimerInfo(testNetValAddr string) *Claimer { + entry, found := s.syncMap.Load(testNetValAddr) if !found { return nil } @@ -53,8 +53,8 @@ func (s *Store) ClaimerInfo(discordID string) *Claimer { return claimerInfo } -func (s *Store) AddClaimTransaction(txID string, amount float64, time int64, discordID string) error { - s.syncMap.Store(discordID, &Claimer{ +func (s *Store) AddClaimTransaction(amount float64, time int64, txID, discordID, testNetValAddr string) error { + s.syncMap.Store(testNetValAddr, &Claimer{ DiscordID: discordID, ClaimTransaction: &ClaimTransaction{ TxID: txID, diff --git a/store/store_test.go b/store/store_test.go index 0e245189..32642770 100644 --- a/store/store_test.go +++ b/store/store_test.go @@ -35,7 +35,7 @@ func TestStore(t *testing.T) { store, path := setup(t) t.Run("get claimer", func(t *testing.T) { - claimer := store.ClaimerInfo("123456789") + claimer := store.ClaimerInfo("tpc1pqn7uaeduklpg00rqt6uq0m9wy5txnyt0kmxmgf") assert.Equal(t, float64(100), claimer.TotalReward) assert.Equal(t, "123456789", claimer.DiscordID) }) @@ -44,16 +44,17 @@ func TestStore(t *testing.T) { txID := "0x123456789" time := time.Now() discordID := "123456789" + testNetValAddr := "tpc1pqn7uaeduklpg00rqt6uq0m9wy5txnyt0kmxmgf" - claimer := store.ClaimerInfo(discordID) + claimer := store.ClaimerInfo(testNetValAddr) isClaimed := claimer.IsClaimed() assert.False(t, isClaimed) - err := store.AddClaimTransaction(txID, claimer.TotalReward, time.Unix(), discordID) + err := store.AddClaimTransaction(claimer.TotalReward, time.Unix(), txID, discordID, testNetValAddr) assert.NoError(t, err) - claimedInfo := store.ClaimerInfo(discordID) + claimedInfo := store.ClaimerInfo(testNetValAddr) assert.Equal(t, discordID, claimedInfo.DiscordID) assert.Equal(t, float64(100), claimedInfo.ClaimTransaction.Amount) assert.Equal(t, txID, claimedInfo.ClaimTransaction.TxID) @@ -65,6 +66,13 @@ func TestStore(t *testing.T) { assert.True(t, isClaimed) }) + t.Run("is claimed test", func(t *testing.T) { + claimer := store.ClaimerInfo("tpc1pesz6kuv7jts6al6la3794fyj5xaj7wm93k7z6y") + assert.Equal(t, float64(12), claimer.TotalReward) + assert.Equal(t, "964550933793103912", claimer.DiscordID) + assert.True(t, claimer.IsClaimed()) + }) + err := os.Remove(path) assert.NoError(t, err) diff --git a/store/test/store_example.json b/store/test/store_example.json index dfbdaf96..5f2321f7 100644 --- a/store/test/store_example.json +++ b/store/test/store_example.json @@ -1,11 +1,19 @@ { - "123456789": { - "discord_id": "123456789", - "total_reward": 100 + "tpc1pqn7uaeduklpg00rqt6uq0m9wy5txnyt0kmxmgf": { + "did": "123456789", + "r": 100 }, - "987654321": { - "discord_id": "987654321", - "total_reward": 62, - "claim_transaction": null + "tpc1ppuh60th5cu9qccj6vjurx2zvd7vngcrztzycfg": { + "did": "1111030757700419636", + "r": 10 + }, + "tpc1pesz6kuv7jts6al6la3794fyj5xaj7wm93k7z6y": { + "did": "964550933793103912", + "r": 12, + "claim_transaction": { + "transaction_id": "", + "amount": 0, + "time": 0 + } } -} \ No newline at end of file +} From f67c475dd6d77c5591e2d3711cc1164748e2412c Mon Sep 17 00:00:00 2001 From: Kay Date: Fri, 26 Jan 2024 17:37:41 +0000 Subject: [PATCH 2/5] feat: adding discord bot --- discord/discord.go | 40 +++++++++++++++++++++++++++++++++++++++- go.mod | 3 +++ go.sum | 11 +++++++++++ 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/discord/discord.go b/discord/discord.go index 86ccf7af..60d198e1 100644 --- a/discord/discord.go +++ b/discord/discord.go @@ -1,3 +1,41 @@ package discord -// need implementation. +import ( + "github.com/bwmarrin/discordgo" + "github.com/kehiy/RoboPac/engine" + "github.com/kehiy/RoboPac/log" +) + +type DiscordBot struct { + Session *discordgo.Session + BotEngine engine.Engine + GuildID string +} + +func NewDiscordBot(botEngine engine.Engine, token, guildID string) (*DiscordBot, error) { + s, err := discordgo.New(token) + if err != nil { + return nil, err + } + + return &DiscordBot{ + Session: s, + BotEngine: botEngine, + GuildID: guildID, + }, nil +} + +func (db *DiscordBot) Start() { + log.Info("starting Discord Bot...") + + err := db.Session.Open() + if err != nil { + log.Panic("can't open discord session", "err", err) + } +} + +func (db *DiscordBot) Stop() { + log.Info("shutting down Discord Bot...") + + _ = db.Session.Close() +} diff --git a/go.mod b/go.mod index 478d3c85..f45d0f00 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,10 @@ require ( google.golang.org/grpc v1.58.3 ) +require github.com/gorilla/websocket v1.5.1 // indirect + require ( + github.com/bwmarrin/discordgo v0.27.1 github.com/davecgh/go-spew v1.1.1 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect github.com/fxamacker/cbor/v2 v2.5.0 // indirect diff --git a/go.sum b/go.sum index 435bbf54..708b4f54 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +github.com/bwmarrin/discordgo v0.27.1 h1:ib9AIc/dom1E/fSIulrBwnez0CToJE113ZGt4HoliGY= +github.com/bwmarrin/discordgo v0.27.1/go.mod h1:NJZpH+1AfhIcyQsPeuBKsUtYrRnjkyu0kIVMCHkZtRY= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= @@ -20,6 +22,9 @@ github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= +github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0 h1:RtRsiaGvWxcwd8y3BiRZxsylPT8hLWZ5SPcfI+3IDNk= github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0/go.mod h1:TzP6duP4Py2pHLVPPQp42aoYI92+PCrVotyR5e8Vqlk= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= @@ -91,25 +96,31 @@ go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ= golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.18.0 h1:mIYleuAkSbHh0tCv7RvjL3F6ZVbLjq4+R7zbOn3Kokg= golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201101102859-da207088b7d1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5 h1:L6iMMGrtzgHsWofoFcihmDEMYeDR9KN/ThbPWGrh++g= google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5/go.mod h1:oH/ZOT02u4kWEp7oYBGYFFkCdKS/uYR9Z7+0/xuuFp8= From b6f84ef52af3266508d48e4f73a649cd4f6ae27d Mon Sep 17 00:00:00 2001 From: Kay Date: Sat, 27 Jan 2024 14:42:21 +0000 Subject: [PATCH 3/5] fix: pipeline lint issues --- discord/discord.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/discord/discord.go b/discord/discord.go index 60d198e1..46bdd915 100644 --- a/discord/discord.go +++ b/discord/discord.go @@ -19,9 +19,9 @@ func NewDiscordBot(botEngine engine.Engine, token, guildID string) (*DiscordBot, } return &DiscordBot{ - Session: s, + Session: s, BotEngine: botEngine, - GuildID: guildID, + GuildID: guildID, }, nil } From a288692b11576228a6025c80d81fc6bcdfe81cf6 Mon Sep 17 00:00:00 2001 From: Kay Date: Sat, 27 Jan 2024 15:40:25 +0000 Subject: [PATCH 4/5] feat: adding discord slash commands --- client/client_mgr.go | 2 +- cmd/commands/run.go | 15 ++++++++++++--- discord/commands.go | 14 ++++++++++++++ discord/discord.go | 17 ++++++++++++++++- discord/embeds.go | 16 ++++++++++++++++ discord/handlers.go | 7 +++++++ 6 files changed, 66 insertions(+), 5 deletions(-) create mode 100644 discord/commands.go create mode 100644 discord/embeds.go create mode 100644 discord/handlers.go diff --git a/client/client_mgr.go b/client/client_mgr.go index 08cac960..573ccb9e 100644 --- a/client/client_mgr.go +++ b/client/client_mgr.go @@ -175,7 +175,7 @@ func (cm *Mgr) GetTransactionData(txID string) (*pactus.GetTransactionResponse, return nil, errors.New("unable to get transaction data") } -func (cm *Mgr) Close() { +func (cm *Mgr) Stop() { for addr, c := range cm.clients { if err := c.Close(); err != nil { log.Error("could not close connection to RPC node", "err", err, "RPCAddr", addr) diff --git a/cmd/commands/run.go b/cmd/commands/run.go index 87ba2bc4..11047973 100644 --- a/cmd/commands/run.go +++ b/cmd/commands/run.go @@ -7,6 +7,7 @@ import ( "github.com/kehiy/RoboPac/client" "github.com/kehiy/RoboPac/config" + "github.com/kehiy/RoboPac/discord" "github.com/kehiy/RoboPac/engine" "github.com/kehiy/RoboPac/log" "github.com/kehiy/RoboPac/store" @@ -21,7 +22,7 @@ func RunCommand(parentCmd *cobra.Command) { } parentCmd.AddCommand(run) - run.Run = func(cmd *cobra.Command, args []string) { + run.Run = func(_ *cobra.Command, _ []string) { // load configuration. config, err := config.Load() if err != nil { @@ -72,16 +73,24 @@ func RunCommand(parentCmd *cobra.Command) { // starting botEngine. botEngine, err := engine.NewBotEngine(eSl, cm, wallet, store) if err != nil { - log.Panic("could not start discord bot", "err", err) + log.Panic("could not start bot engine", "err", err) } botEngine.Start() + discordBot, err := discord.NewDiscordBot(botEngine, config.DiscordBotCfg.DiscordToken, + config.DiscordBotCfg.DiscordGuildID) + if err != nil { + log.Panic("could not start discord bot", "err", err) + } + discordBot.Start() + sigChan := make(chan os.Signal, 1) signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM, os.Interrupt) <-sigChan // gracefully shutdown the bot. + discordBot.Stop() + cm.Stop() botEngine.Stop() - cm.Close() } } diff --git a/discord/commands.go b/discord/commands.go new file mode 100644 index 00000000..e514a075 --- /dev/null +++ b/discord/commands.go @@ -0,0 +1,14 @@ +package discord + +import "github.com/bwmarrin/discordgo" + +var commands = []*discordgo.ApplicationCommand{ + { + Name: "help", + Description: "Help command for RoboPac", + }, +} + +var commandHandlers = map[string]func(s *discordgo.Session, i *discordgo.InteractionCreate){ + "help": helpCommandHandler, +} diff --git a/discord/discord.go b/discord/discord.go index 46bdd915..2f21e712 100644 --- a/discord/discord.go +++ b/discord/discord.go @@ -13,7 +13,7 @@ type DiscordBot struct { } func NewDiscordBot(botEngine engine.Engine, token, guildID string) (*DiscordBot, error) { - s, err := discordgo.New(token) + s, err := discordgo.New("Bot " + token) if err != nil { return nil, err } @@ -28,10 +28,25 @@ func NewDiscordBot(botEngine engine.Engine, token, guildID string) (*DiscordBot, func (db *DiscordBot) Start() { log.Info("starting Discord Bot...") + db.Session.AddHandler(func(s *discordgo.Session, i *discordgo.InteractionCreate) { + if h, ok := commandHandlers[i.ApplicationCommandData().Name]; ok { + h(s, i) + } + }) + err := db.Session.Open() if err != nil { log.Panic("can't open discord session", "err", err) } + + registeredCommands := make([]*discordgo.ApplicationCommand, len(commands)) + for i, v := range commands { + cmd, err := db.Session.ApplicationCommandCreate(db.Session.State.User.ID, db.GuildID, v) + if err != nil { + log.Panic("can not register discord command", "name", v.Name, "err", err) + } + registeredCommands[i] = cmd + } } func (db *DiscordBot) Stop() { diff --git a/discord/embeds.go b/discord/embeds.go new file mode 100644 index 00000000..bae27ea3 --- /dev/null +++ b/discord/embeds.go @@ -0,0 +1,16 @@ +package discord + +import "github.com/bwmarrin/discordgo" + +func helpEmbed(s *discordgo.Session) *discordgo.MessageEmbed { + return &discordgo.MessageEmbed{ + Title: "RoboPac Help", + URL: "https://pactus.org", + Author: &discordgo.MessageEmbedAuthor{ + URL: "https://pactus.org", + IconURL: s.State.User.AvatarURL(""), + Name: s.State.User.Username, + }, + Description: "RoboPac is a robot that provides support and information about the Pactus Blockchain.", + } +} diff --git a/discord/handlers.go b/discord/handlers.go new file mode 100644 index 00000000..3ce227e4 --- /dev/null +++ b/discord/handlers.go @@ -0,0 +1,7 @@ +package discord + +import "github.com/bwmarrin/discordgo" + +func helpCommandHandler(s *discordgo.Session, i *discordgo.InteractionCreate) { + s.ChannelMessageSendEmbedReply(i.ChannelID, helpEmbed(s), i.Message.Reference()) +} From b55e9a47c60d1502eb4c8c6b85bba38a94c50c5c Mon Sep 17 00:00:00 2001 From: Kay Date: Sat, 27 Jan 2024 15:41:07 +0000 Subject: [PATCH 5/5] fix: pipeline lint issues --- discord/embeds.go | 2 +- discord/handlers.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/discord/embeds.go b/discord/embeds.go index bae27ea3..c7c91e62 100644 --- a/discord/embeds.go +++ b/discord/embeds.go @@ -5,7 +5,7 @@ import "github.com/bwmarrin/discordgo" func helpEmbed(s *discordgo.Session) *discordgo.MessageEmbed { return &discordgo.MessageEmbed{ Title: "RoboPac Help", - URL: "https://pactus.org", + URL: "https://pactus.org", Author: &discordgo.MessageEmbedAuthor{ URL: "https://pactus.org", IconURL: s.State.User.AvatarURL(""), diff --git a/discord/handlers.go b/discord/handlers.go index 3ce227e4..50d338b6 100644 --- a/discord/handlers.go +++ b/discord/handlers.go @@ -3,5 +3,5 @@ package discord import "github.com/bwmarrin/discordgo" func helpCommandHandler(s *discordgo.Session, i *discordgo.InteractionCreate) { - s.ChannelMessageSendEmbedReply(i.ChannelID, helpEmbed(s), i.Message.Reference()) + _, _ = s.ChannelMessageSendEmbedReply(i.ChannelID, helpEmbed(s), i.Message.Reference()) }