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

feat: add Neutron votes fetching #66

Merged
merged 2 commits into from
Dec 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ Go to your PagerDuty page, then go to Services. Create a service if you haven't

## Which networks this is guaranteed to work?

In theory, it should work on a Cosmos-based blockchains that expose a REST server.
In theory, it should work on a Cosmos-based blockchains that expose a REST server, and also on Neutron.

## How can I contribute?

Expand Down
6 changes: 6 additions & 0 deletions config.example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ wallets = [
{ address = "bitsong14rvn7anf22e00vj5x3al4w50ns78s7n4t8yxcy", alias = "Validator wallet" },
{ address = "bitsong125hdkukw4pu2urhj4nv366q0avdqv24t0vprxs" },
]
# Type. Currently can be either "cosmos" or "neutron". Optional, defaults to "cosmos.
type = "cosmos"
# Neutron smart contract address. Defaults to "neutron1436kxs0w2es6xlqpp9rd35e3d0cjnw4sv8j3a7483sgks29jqwgshlt6zh"
# (mainnet contract address).
neutron-smart-contract = "neutron1436kxs0w2es6xlqpp9rd35e3d0cjnw4sv8j3a7483sgks29jqwgshlt6zh"

# Some chains have a new proposals structure (v1) compared to an older one (v1beta1),
# when there are 2 or more actual proposals inside a single one (namely, Quicksilver).
# On such chains, querying proposals with an older endpoint when there are proposals
Expand Down
21 changes: 21 additions & 0 deletions pkg/fetchers/neutron/fetcher.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package neutron

import (
"encoding/base64"
"fmt"
"main/pkg/http"
"main/pkg/types"

Expand All @@ -20,3 +22,22 @@ func NewFetcher(chainConfig *types.Chain, logger zerolog.Logger) *Fetcher {
Client: http.NewClient(chainConfig.Name, chainConfig.LCDEndpoints, logger),
}
}

func (fetcher *Fetcher) GetSmartContractState(queryString string, output interface{}) *types.QueryError {
query := base64.StdEncoding.EncodeToString([]byte(queryString))

url := fmt.Sprintf(
"/cosmwasm/wasm/v1/contract/%s/smart/%s",
fetcher.ChainConfig.NeutronSmartContract,
query,
)

if errs := fetcher.Client.Get(url, &output); len(errs) > 0 {
return &types.QueryError{
QueryError: nil,
NodeErrors: errs,
}
}

return nil
}
17 changes: 3 additions & 14 deletions pkg/fetchers/neutron/proposals.go
Original file line number Diff line number Diff line change
@@ -1,27 +1,16 @@
package neutron

import (
"encoding/base64"
"fmt"
"main/pkg/fetchers/neutron/responses"
"main/pkg/types"
)

func (fetcher *Fetcher) GetAllProposals() ([]types.Proposal, *types.QueryError) {
query := base64.StdEncoding.EncodeToString([]byte("{\"list_proposals\": {}}"))

url := fmt.Sprintf(
"/cosmwasm/wasm/v1/contract/%s/smart/%s",
fetcher.ChainConfig.NeutronSmartContract,
query,
)
query := "{\"list_proposals\": {}}"

var proposals responses.ProposalsResponse
if errs := fetcher.Client.Get(url, &proposals); len(errs) > 0 {
return nil, &types.QueryError{
QueryError: nil,
NodeErrors: errs,
}
if err := fetcher.GetSmartContractState(query, &proposals); err != nil {
return nil, err
}

proposalsParsed, err := proposals.ToProposals()
Expand Down
44 changes: 44 additions & 0 deletions pkg/fetchers/neutron/responses/vote.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package responses

import (
"main/pkg/types"
)

type Vote struct {
Voter string `json:"voter"`
Vote string `json:"vote"`
}

func (v Vote) GetOption() string {
options := map[string]string{
"yes": "Yes",
"no": "No",
"abstain": "Abstain",
}

if option, ok := options[v.Vote]; ok {
return option
}

return v.Vote
}

type VoteResponse struct {
Data struct {
Vote *Vote `json:"vote"`
} `json:"data"`
}

func (v VoteResponse) ToVote(proposalID string) *types.Vote {
if v.Data.Vote == nil {
return nil
}

return &types.Vote{
ProposalID: proposalID,
Voter: v.Data.Vote.Voter,
Options: []types.VoteOption{
{Option: v.Data.Vote.GetOption(), Weight: 1},
},
}
}
17 changes: 3 additions & 14 deletions pkg/fetchers/neutron/tally.go
Original file line number Diff line number Diff line change
@@ -1,27 +1,16 @@
package neutron

import (
"encoding/base64"
"fmt"
"main/pkg/fetchers/neutron/responses"
"main/pkg/types"
)

func (fetcher *Fetcher) GetTallies() (types.ChainTallyInfos, error) {
query := base64.StdEncoding.EncodeToString([]byte("{\"list_proposals\": {}}"))

url := fmt.Sprintf(
"/cosmwasm/wasm/v1/contract/%s/smart/%s",
fetcher.ChainConfig.NeutronSmartContract,
query,
)
query := "{\"list_proposals\": {}}"

var proposals responses.ProposalsResponse
if errs := fetcher.Client.Get(url, &proposals); len(errs) > 0 {
return types.ChainTallyInfos{}, &types.QueryError{
QueryError: nil,
NodeErrors: errs,
}
if err := fetcher.GetSmartContractState(query, &proposals); err != nil {
return types.ChainTallyInfos{}, err
}

tallyInfos, err := proposals.ToTally()
Expand Down
21 changes: 18 additions & 3 deletions pkg/fetchers/neutron/vote.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,23 @@
package neutron

import "main/pkg/types"
import (
"fmt"
"main/pkg/fetchers/neutron/responses"
"main/pkg/types"
)

func (fetcher *Fetcher) GetVote(proposal, voter string) (*types.Vote, *types.QueryError) {
// TODO: fix
return nil, nil
query := fmt.Sprintf(
"{\"get_vote\":{\"proposal_id\":%s,\"voter\":\"%s\"}}",
proposal,
voter,
)

var vote responses.VoteResponse
if err := fetcher.GetSmartContractState(query, &vote); err != nil {
return nil, err
}

voteParsed := vote.ToVote(proposal)
return voteParsed, nil
}
8 changes: 2 additions & 6 deletions pkg/types/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,18 +108,14 @@ func (c Chain) GetProposalLink(proposal Proposal) Link {

func (c Chain) GetWalletLink(wallet *Wallet) Link {
if c.Explorer == nil || c.Explorer.WalletLinkPattern == "" {
return Link{Name: wallet.Address}
return Link{Name: wallet.AddressOrAlias()}
}

link := Link{
Name: wallet.Address,
Name: wallet.AddressOrAlias(),
Href: fmt.Sprintf(c.Explorer.WalletLinkPattern, wallet.Address),
}

if wallet.Alias != "" {
link.Name = wallet.Alias
}

return link
}

Expand Down
Loading