Skip to content

Commit

Permalink
add specific handling for stargaze; make getAPR more generic; make qu…
Browse files Browse the repository at this point in the history
…eries parallel
  • Loading branch information
Joe Bowman committed Apr 15, 2024
1 parent d304d6f commit 249e43d
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 56 deletions.
157 changes: 112 additions & 45 deletions apr.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import (
"io"
"math"
"net/http"
"strconv"

sdkmath "cosmossdk.io/math"
)

type Chain struct {
Expand All @@ -22,66 +23,132 @@ type APRResponse struct {
Chains []ChainAPR `json:"chains"`
}

type SOMMAPYResponse struct {
APY string `json:"apy"`
}

type ChainAPR struct {
ChainID string `json:"chain_id"`
APR float64 `json:"apr"`
}

func getAPRquery(baseurl string, chainname string) (ChainAPR, error) {
url := baseurl + chainname
if chainname == "sommelier" {
url = "https://lcd.sommelier-3.quicksilver.zone/sommelier/incentives/v1/apy"
func getAPRquery(cfg Config, chainName string) (ChainAPR, error) {

var apr float64
var chainID string
var err error

switch chainName {
case "sommelier":
chainID, apr, err = SommelierApr(cfg, chainName)
case "stargaze":
chainID, apr, err = StargazeApr(cfg, chainName)
default:
chainID, apr, err = BasicApr(cfg, chainName)
}
if err != nil {
return ChainAPR{}, err
}

if chainName != "quicksilver" {
feeadjustedAPR := (apr) * (0.965)
compoundedAPR := math.Pow(1+feeadjustedAPR/121.66, 121.66) - 1
return ChainAPR{ChainID: chainID, APR: compoundedAPR}, nil
}
return ChainAPR{ChainID: chainID, APR: apr}, nil
}

func BasicApr(cfg Config, chainName string) (string, float64, error) {
url := fmt.Sprintf("%s/%s", cfg.APRURL, chainName)

resp, err := http.Get(url)
if err != nil {
return ChainAPR{}, err
return "", 0, err
}

defer resp.Body.Close()

var result map[string]json.RawMessage
var apr float64
var chain Chain

if chainname == "sommelier" {
body, err := io.ReadAll(resp.Body)
if err != nil {
fmt.Println("Error:", err)
return ChainAPR{}, err
}
var aprResp SOMMAPYResponse
err = json.Unmarshal(body, &aprResp)
if err != nil {
return ChainAPR{}, err
}
chain.ChainID = "sommelier-3"
apr, err = strconv.ParseFloat(aprResp.APY, 64)
if err != nil {
fmt.Println("Error:", err)
return ChainAPR{}, err
}
} else {
err = json.NewDecoder(resp.Body).Decode(&result)
if err != nil {
return ChainAPR{}, err
}
err = json.Unmarshal(result["chain"], &chain)
if err != nil {
return ChainAPR{}, err
}
apr = chain.Params.EstimatedApr
}

if chainname != "quicksilver" {
feeadjustedAPR := (apr) * (0.965)
compoundedAPR := math.Pow(1+feeadjustedAPR/121.66, 121.66) - 1
return ChainAPR{ChainID: chain.ChainID, APR: compoundedAPR}, nil
err = json.NewDecoder(resp.Body).Decode(&result)
if err != nil {
return "", 0, err
}
err = json.Unmarshal(result["chain"], &chain)
if err != nil {
return "", 0, err
}

return chain.ChainID, chain.Params.EstimatedApr, nil
}

func StargazeApr(cfg Config, chainname string) (string, float64, error) {
provisionsUrl := "https://lcd.stargaze-1.quicksilver.zone/stargaze/mint/v1beta1/annual_provisions"
bondedUrl := "https://lcd.stargaze-1.quicksilver.zone/cosmos/staking/v1beta1/pool"

provisionQuery, err := http.Get(provisionsUrl)
if err != nil {
return "", 0, err
}

defer provisionQuery.Body.Close()

var provisionsResult map[string]sdkmath.LegacyDec
provisionsResponse, err := io.ReadAll(provisionQuery.Body)
if err != nil {
fmt.Println("Error:", err)
return "", 0, err
}
err = json.Unmarshal(provisionsResponse, &provisionsResult)
if err != nil {
return "", 0, err
}

provisions, err := provisionsResult["annual_provisions"].Float64()
if err != nil {
return "", 0, err
}
return ChainAPR{ChainID: chain.ChainID, APR: apr}, nil

bondedQuery, err := http.Get(bondedUrl)
if err != nil {
return "", 0, err
}

defer bondedQuery.Body.Close()

var bondedResult map[string]map[string]sdkmath.Int
bondedResponse, err := io.ReadAll(bondedQuery.Body)
if err != nil {
fmt.Println("Error:", err)
return "", 0, err
}
err = json.Unmarshal(bondedResponse, &bondedResult)
if err != nil {
return "", 0, err
}

bonded := float64(bondedResult["pool"]["bonded_tokens"].Int64())

return "stargaze-1", provisions / bonded, nil
}

func SommelierApr(cfg Config, chainname string) (string, float64, error) {
url := "https://lcd.sommelier-3.quicksilver.zone/sommelier/incentives/v1/apy"
query, err := http.Get(url)
if err != nil {
return "", 0, err
}
var result map[string]sdkmath.LegacyDec
response, err := io.ReadAll(query.Body)
if err != nil {
fmt.Println("Error:", err)
return "", 0, err
}
err = json.Unmarshal(response, &result)
if err != nil {
return "", 0, err
}

apy, err := result["apy"].Float64()
if err != nil {
return "", 0, err
}
return "sommelier-3", apy, nil
}
6 changes: 4 additions & 2 deletions conf.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
lcd_endpoint: "https://lcd.quicksilver.zone"
rpc_endpoint: "https://rpc.test.quicksilver.zone:443"
chain_rpc_endpoint: "https://rpc.%s.test.quicksilver.zone:443"
rpc_endpoint: "https://rpc.quicksilver.zone:443"
chain_rpc_endpoint: "https://rpc.%s.quicksilver.zone:443"
chains:
- quicksilver
- cosmoshub
Expand All @@ -10,6 +10,8 @@ chains:
- sommelier
- juno
- composable
- dydx
- saga
apr_url: "https://chains.cosmos.directory"
apr_cache_minutes: 15
supply_cache_minutes: 180
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ module github.com/ingenuity-build/evince
go 1.19

require (
cosmossdk.io/math v1.0.0-beta.4
github.com/cosmos/cosmos-sdk v0.46.12
github.com/dgraph-io/ristretto v0.1.1
github.com/disintegration/imaging v1.6.2
github.com/ingenuity-build/quicksilver v1.2.9-hotfix.0
github.com/labstack/echo-contrib v0.13.0
github.com/labstack/echo/v4 v4.10.0
Expand All @@ -15,7 +17,6 @@ require (

require (
cosmossdk.io/errors v1.0.0-beta.7 // indirect
cosmossdk.io/math v1.0.0-beta.4 // indirect
filippo.io/edwards25519 v1.0.0-rc.1 // indirect
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect
github.com/99designs/keyring v1.2.1 // indirect
Expand All @@ -39,7 +40,6 @@ require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect
github.com/dgraph-io/badger/v3 v3.2103.2 // indirect
github.com/disintegration/imaging v1.6.2 // indirect
github.com/dustin/go-humanize v1.0.1-0.20200219035652-afde56e7acac // indirect
github.com/dvsekhvalnov/jose2go v1.5.0 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
Expand Down
23 changes: 16 additions & 7 deletions handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"math"
"net/http"
"strconv"
"sync"
"time"

sdkmath "cosmossdk.io/math"
Expand Down Expand Up @@ -324,15 +325,23 @@ func (s *Service) getAPR(ctx echov4.Context, key string) error {

chains := s.Config.Chains
aprResp := APRResponse{}
for _, chain := range chains {
chainAPR, err := getAPRquery(s.Config.APRURL+"/", chain)
if err != nil {
s.Echo.Logger.Errorf("getAPR: %v - %v", ErrUnableToGetAPR, err)
return ErrUnableToGetAPR
}

aprResp.Chains = append(aprResp.Chains, chainAPR)
// WaitGroup to synchronize goroutines
var wg sync.WaitGroup
wg.Add(len(s.Config.Chains))

for _, chain := range chains {
go func(chainname string) {
defer wg.Done()
chainAPR, err := getAPRquery(s.Config, chainname)
if err != nil {
s.Echo.Logger.Errorf("unable to retrieve apy for %s: %s", chainname, err.Error())
}
aprResp.Chains = append(aprResp.Chains, chainAPR)
}(chain)
}
// Wait for goroutines to complete
wg.Wait()

respdata, err := json.Marshal(aprResp)
if err != nil {
Expand Down

0 comments on commit 249e43d

Please sign in to comment.