Skip to content

Commit

Permalink
Migrate the Cosmos [Registry, Validator] Client to use Tessellated's …
Browse files Browse the repository at this point in the history
…Planetarium (#32)

* Change out the chain registry url

* write a quick test

* pickup files

* rework chain registry

* mess with paths

* put registry client onto planetarium

* add test for validator

* run linter
  • Loading branch information
keefertaylor authored Jan 23, 2024
1 parent 7e013e8 commit 14ebc5e
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 46 deletions.
50 changes: 19 additions & 31 deletions cosmos/chain-registry/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ import (
"github.com/tessellated-io/pickaxe/log"
)

/**
* A chain registry client.
*
* This class is made to be compatible with Planetarium (https://github.com/tessellated-io/planetarium), which is a hosted version
* of the Chain Registry provided by Tessellated, although it should be compatible with other services by providing custom base urls.
*/

// Default implementation
type chainRegistryClient struct {
// Cache of all chain names
Expand All @@ -19,7 +26,8 @@ type chainRegistryClient struct {
chainNameToChainID map[string]string

// Base url of an API service
baseURL string
chainRegistryBaseUrl string
validatorRegistryBaseUrl string

log *log.Logger
}
Expand All @@ -28,13 +36,14 @@ type chainRegistryClient struct {
var _ ChainRegistryClient = (*chainRegistryClient)(nil)

// NewRegistryClient makes a new default registry client.
func NewChainRegistryClient(log *log.Logger, baseURL string) *chainRegistryClient {
func NewChainRegistryClient(log *log.Logger, chainRegistryBaseUrl, validatorRegistryBaseUrl string) *chainRegistryClient {
return &chainRegistryClient{
// Initially empty chain name cache
chainNames: []string{},
chainNameToChainID: make(map[string]string),

baseURL: baseURL,
chainRegistryBaseUrl: chainRegistryBaseUrl,
validatorRegistryBaseUrl: validatorRegistryBaseUrl,

log: log,
}
Expand All @@ -43,7 +52,7 @@ func NewChainRegistryClient(log *log.Logger, baseURL string) *chainRegistryClien
// ChainRegistryClient interface

func (rc *chainRegistryClient) ChainInfo(ctx context.Context, chainName string) (*ChainInfo, error) {
url := fmt.Sprintf("%s/v1/chain/%s", rc.baseURL, chainName)
url := fmt.Sprintf("%s/%s/chain.json", rc.chainRegistryBaseUrl, chainName)

bytes, err := rc.makeRequest(ctx, url)
if err != nil {
Expand All @@ -62,7 +71,7 @@ func (rc *chainRegistryClient) ChainInfo(ctx context.Context, chainName string)
}

func (rc *chainRegistryClient) AssetList(ctx context.Context, chainName string) (*AssetList, error) {
url := fmt.Sprintf("%s/v1/chain/%s/assets", rc.baseURL, chainName)
url := fmt.Sprintf("%s/%s/assetlist.json", rc.chainRegistryBaseUrl, chainName)

bytes, err := rc.makeRequest(ctx, url)
if err != nil {
Expand Down Expand Up @@ -134,7 +143,7 @@ func (rc *chainRegistryClient) ChainNameForChainID(ctx context.Context, targetCh

func (rc *chainRegistryClient) AllChainNames(ctx context.Context) ([]string, error) {
// Get all chain names
url := fmt.Sprintf("%s/v1/chains", rc.baseURL)
url := fmt.Sprintf("%s/all", rc.chainRegistryBaseUrl)
bytes, err := rc.makeRequest(ctx, url)
if err != nil {
return nil, err
Expand All @@ -149,29 +158,17 @@ func (rc *chainRegistryClient) AllChainNames(ctx context.Context) ([]string, err
}

func (rc *chainRegistryClient) Validator(ctx context.Context, targetValidator string) (*Validator, error) {
validators, err := rc.Validators(ctx)
if err != nil {
return nil, err
}

validator, err := rc.extractValidator(targetValidator, validators)
if err != nil {
return nil, err
}
return validator, nil
}

func (rc *chainRegistryClient) Validators(ctx context.Context) ([]Validator, error) {
bytes, err := rc.makeRequest(ctx, "https://validators.cosmos.directory/")
url := fmt.Sprintf("%s/%s/chains.json", rc.validatorRegistryBaseUrl, targetValidator)
bytes, err := rc.makeRequest(ctx, url)
if err != nil {
return nil, err
}

response, err := parseValidatorRegistryResponse(bytes)
response, err := parseValidator(bytes)
if err != nil {
return nil, err
}
return response.Validators, nil
return response, nil
}

// Private helpers
Expand Down Expand Up @@ -209,12 +206,3 @@ func (rc *chainRegistryClient) makeRequest(ctx context.Context, url string) ([]b
return nil, fmt.Errorf("received non-OK HTTP status: %d", resp.StatusCode)
}
}

func (rc *chainRegistryClient) extractValidator(targetValidator string, validators []Validator) (*Validator, error) {
for _, validator := range validators {
if strings.EqualFold(targetValidator, validator.Name) {
return &validator, nil
}
}
return nil, fmt.Errorf("unable to find a validator with name \"%s\"", targetValidator)
}
16 changes: 13 additions & 3 deletions cosmos/chain-registry/registry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@ import (
"github.com/tessellated-io/pickaxe/log"
)

const chainsBaseUrl = "https://planetarium.tessellated.io/v1/chains"
const validatorsBaseUrl = "https://planetarium.tessellated.io/v1/validators"

func TestCanRetrieveChain(t *testing.T) {
client := registry.NewChainRegistryClient(log.NewLogger(zerolog.FatalLevel), "https://chain-registry.tessellated.io")
client := registry.NewChainRegistryClient(log.NewLogger(zerolog.FatalLevel), chainsBaseUrl, validatorsBaseUrl)

hubInfo, err := client.ChainInfo(context.Background(), "cosmoshub")
assert.Nil(t, err, "error should be nil")
Expand All @@ -20,15 +23,22 @@ func TestCanRetrieveChain(t *testing.T) {
}

func TestCanRetrieveAssets(t *testing.T) {
client := registry.NewChainRegistryClient(log.NewLogger(zerolog.FatalLevel), "https://chain-registry.tessellated.io")
client := registry.NewChainRegistryClient(log.NewLogger(zerolog.FatalLevel), chainsBaseUrl, validatorsBaseUrl)

_, err := client.AssetList(context.Background(), "cosmoshub")
assert.Nil(t, err, "error should be nil")
}

func TestCanRetrieveAllChains(t *testing.T) {
client := registry.NewChainRegistryClient(log.NewLogger(zerolog.FatalLevel), "https://chain-registry.tessellated.io")
client := registry.NewChainRegistryClient(log.NewLogger(zerolog.FatalLevel), chainsBaseUrl, validatorsBaseUrl)

_, err := client.AllChainNames(context.Background())
assert.Nil(t, err, "error should be nil")
}

func TestCanRetrieveValidator(t *testing.T) {
client := registry.NewChainRegistryClient(log.NewLogger(zerolog.FatalLevel), chainsBaseUrl, validatorsBaseUrl)

_, err := client.Validator(context.Background(), "tessellated")
assert.Nil(t, err, "error should be nil")
}
16 changes: 4 additions & 12 deletions cosmos/chain-registry/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,21 +179,13 @@ type RestakeInfo struct {
}

type Validator struct {
Path string `json:"path"`
Name string `json:"name"`
Identity string `json:"identity"`
TotalUSD float64 `json:"total_usd"`
TotalUsers int `json:"total_users"`
Chains []RestakeInfo `json:"chains"`
Name string `json:"name"`
Chains []RestakeInfo `json:"chains"`
}

type Response struct {
Validators []Validator `json:"validators"`
}

func parseValidatorRegistryResponse(responseBytes []byte) (*Response, error) {
func parseValidator(responseBytes []byte) (*Validator, error) {
// Unmarshal JSON data
var response Response
var response Validator
if err := json.Unmarshal(responseBytes, &response); err != nil {
return nil, err
}
Expand Down

0 comments on commit 14ebc5e

Please sign in to comment.