Skip to content

Open-Ranking/go-sdk

Repository files navigation

Open Ranking Go SDK

The official Go SDK for the Open Ranking protocol.

Install

go get github.com/Open-Ranking/go-sdk

Quick start

import (
    openranking "github.com/Open-Ranking/go-sdk"
)

client, err := openranking.NewClient("https://example-provider.com", http.DefaultClient)
if err != nil {
    log.Fatal(err)
}

NewClient fetches and validates the provider's capability document once and caches it. All subsequent calls use the cached capabilities without any extra round-trips.

Usage

Rank pubkeys

resp, err := client.RankPubkeys(ctx, openranking.RankPubkeysRequest{
    Pubkeys: []string{alicePubkey, bobPubkey},
    POV:     myPubkey, // rank relative to my social graph
})
if err != nil {
    return err
}
for _, r := range resp.Results {
    fmt.Printf("%s → %.4f\n", r.Pubkey, r.Rank)
}

Get stats for a pubkey

resp, err := client.StatsPubkey(ctx, openranking.StatsPubkeyRequest{
    Pubkey: alicePubkey,
})
fmt.Printf("rank=%.4f followers=%d\n", resp.Rank, *resp.Followers)

Recommend pubkeys

resp, err := client.RecommendPubkeys(ctx, openranking.RecommendPubkeysRequest{
    POV:   myPubkey,
    Topic: "bitcoin",
    Limit: 20,
})

Search pubkeys

resp, err := client.SearchPubkeys(ctx, openranking.SearchPubkeysRequest{
    Query: "fiatjaf",
    Limit: 10,
})

Top Followers / Muters

followers, err := client.Followers(ctx, openranking.FollowersRequest{
    Pubkey: alicePubkey,
    Limit:  50,
})

muters, err := client.Muters(ctx, openranking.MutersRequest{
    Pubkey: alicePubkey,
})

Check compromised pubkeys

resp, err := client.CompromisedPubkeys(ctx, openranking.CompromisedPubkeysRequest{
    Pubkeys: []string{alicePubkey, bobPubkey},
})
for pk, result := range resp {
    fmt.Printf("%s is compromised: %v\n", pk, result)
}

Authentication

Every method accepts optional Option arguments appended after the request struct. Use WithAuth to attach a NWT token to the request:

resp, err := client.RankPubkeys(ctx, openranking.RankPubkeysRequest{
    Pubkeys: []string{alicePubkey},
    POV:     myPubkey,
}, openranking.WithAuth(mySignedEvent))

You can also compose multiple options:

resp, err := client.RecommendPubkeys(ctx, req,
    openranking.WithAuth(mySignedEvent),
    myCustomHeaderOption,
)

Option is just func(*http.Request) error, so it's easy to write your own:

func WithAPIKey(key string) openranking.Option {
    return func(r *http.Request) error {
        r.Header.Set("X-API-Key", key)
        return nil
    }
}

Algorithms

Providers expose one or more algorithms per endpoint. To use a specific one, set the Algorithm field on any request. Leave it empty to use the provider's default.

resp, err := client.RankPubkeys(ctx, openranking.RankPubkeysRequest{
    Pubkeys:   []string{alicePubkey},
    Algorithm: "pagerank-v2",
})

Inspect available algorithms from the cached capability document:

caps := client.Capabilities()
for _, algo := range caps.RankPubkeys {
    fmt.Printf("id=%-20s pov=%v  %s\n", algo.ID, algo.POV, algo.Description)
}

To refresh capabilities (e.g. on a schedule):

if err := client.RefreshCapabilities(ctx); err != nil {
    log.Println("capabilities refresh failed:", err)
}

Testing

The mock sub-package provides a test Open Ranking server backed by net/http/httptest. Import it in your tests to spin up a real HTTP server without any external dependencies:

import (
    openranking "github.com/Open-Ranking/go-sdk"
    "github.com/Open-Ranking/go-sdk/mock"
)

func TestMyCode(t *testing.T) {
    caps := openranking.CapabilityDoc{
        StatsPubkey: []openranking.Algorithm{{ID: "algo-v1"}},
        RankPubkeys: []openranking.Algorithm{{ID: "algo-v1"}},
    }
    srv := mock.NewServer(caps)
    defer srv.Close()

    srv.OnRankPubkeys = func(r openranking.RankPubkeysRequest) (openranking.RankPubkeysResponse, error) {
        return openranking.RankPubkeysResponse{
            Results: []openranking.RankedPubkey{{Pubkey: r.Pubkeys[0], Rank: 1.0}},
        }, nil
    }

    client, err := openranking.NewClient(srv.URL, srv.Client())
    // ...
}

Endpoints with a nil On* handler return 501 Not Implemented. Handlers can return any *openranking.Error or openranking.Retry value and the mock will write the correct HTTP response.

Error handling

resp, err := client.StatsPubkey(ctx, req)
var httpErr openranking.Error
var retry openranking.Retry

switch {
case errors.As(err, &httpErr):
    fmt.Println("HTTP error", httpErr.Code, httpErr.Reason)
case errors.As(err, &retry):
    // result not ready yet — try again after retry.After
    time.Sleep(retry.After)
default:
    // network or validation error
}

About

The official Open Ranking sdk for golang.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages