openranking

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 17, 2026 License: MIT Imports: 14 Imported by: 0

README

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
}

Documentation

Index

Constants

View Source
const (
	EndpointCapabilities       = "/.well-known/open-ranking.json"
	EndpointStatsPubkey        = "/stats/pubkey"
	EndpointRankPubkeys        = "/rank/pubkeys"
	EndpointRecommendPubkeys   = "/recommend/pubkeys"
	EndpointSearchPubkeys      = "/search/pubkeys"
	EndpointFollowers          = "/followers"
	EndpointMuters             = "/muters"
	EndpointCompromisedPubkeys = "/compromised/pubkeys"
)

Variables

Endpoints is a list of all supported endpoints.

View Source
var ErrAlgorithmNotFound = errors.New("algorithm not found")

Functions

func ValidatePubkey

func ValidatePubkey(s string) error

ValidatePubkey validates a public key string.

func WriteError

func WriteError(w http.ResponseWriter, e *Error)

WriteError writes the error to the http response. If the reason is non-empty, it writes it to the "X-Reason" header as per ORE-00.

func WriteRetry

func WriteRetry(w http.ResponseWriter, after time.Duration)

WriteRetry writes a 202 Accepted response with a Retry-After header.

Types

type Algorithm

type Algorithm struct {
	ID          AlgorithmID `json:"id"`
	POV         bool        `json:"pov,omitempty"`
	Topic       bool        `json:"topic,omitempty"`
	Name        string      `json:"name,omitempty"`
	Description string      `json:"description,omitempty"`
	Icon        string      `json:"icon,omitempty"`
	LearnMore   string      `json:"learn_more,omitempty"`
}

Algorithm is a provider-defined ranking or search strategy. It is identified by an AlgorithmID and may have additional metadata.

func (Algorithm) Support

func (a Algorithm) Support(pov, topic string) error

support checks whether the given pov and topic are compatible with the algorithm's flags.

type AlgorithmID

type AlgorithmID string

AlgorithmID is an opaque algorithm identifier. It must be lowercase and use only alphanumeric characters, hyphens, and dots.

const SignatureProofAlgorithm AlgorithmID = "signature-proof"

The AlgorithmID defined in ORE-08.

func (AlgorithmID) Validate

func (a AlgorithmID) Validate() error

type CapabilityDoc

type CapabilityDoc struct {
	StatsPubkey        []Algorithm
	RankPubkeys        []Algorithm
	RecommendPubkeys   []Algorithm
	SearchPubkeys      []Algorithm
	Followers          []Algorithm
	Muters             []Algorithm
	CompromisedPubkeys []Algorithm
}

CapabilityDoc is a document that describes the capabilities of a provider. It contains a list of algorithms for each supported endpoint. If the list of algorithms for an endpoint is empty or nil, the endpoint is not supported.

func GetCapabilities

func GetCapabilities(ctx context.Context, c *http.Client, providerURL string) (CapabilityDoc, error)

GetCapabilities fetches the capabilities of the provider at the given URL. It does not validate the returned CapabilityDoc.

func (CapabilityDoc) Algorithm

func (c CapabilityDoc) Algorithm(endpoint string, ID AlgorithmID) (Algorithm, error)

Algorithm returns the algorithm for the given endpoint and ID, or an error if not found. If the ID is empty, the provider's default algorithm for the endpoint is returned.

func (CapabilityDoc) MarshalJSON

func (c CapabilityDoc) MarshalJSON() ([]byte, error)

func (*CapabilityDoc) UnmarshalJSON

func (c *CapabilityDoc) UnmarshalJSON(data []byte) error

func (CapabilityDoc) Validate

func (c CapabilityDoc) Validate() error

Validate the capability document, which must: - have at least one algorithm registered in all mandatory endpoints (stats/pubkey, rank/pubkeys) - have all valid algorithm IDs

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client is a simple Open Ranking client, that caches the provider CapabilityDoc at construction time. The cached capabilities are used to perform validation before firing the request. All client methods are safe for concurrent use.

func NewClient

func NewClient(providerURL string, httpClient *http.Client) (*Client, error)

NewClient creates a new OpenRanking client with the given provider URL and HTTP client. It returns an error if the capability document cannot be fetched or is invalid.

func (*Client) Capabilities

func (c *Client) Capabilities() CapabilityDoc

Capabilities returns the cached capabilities of the provider.

func (*Client) CompromisedPubkeys

func (c *Client) CompromisedPubkeys(ctx context.Context, r CompromisedPubkeysRequest, opts ...Option) (CompromisedPubkeysResponse, error)

CompromisedPubkeys checks whether any of the given pubkeys are known or suspected to be compromised, by calling the provider's /compromised/pubkeys endpoint.

func (*Client) Followers

func (c *Client) Followers(ctx context.Context, r FollowersRequest, opts ...Option) (FollowersResponse, error)

Followers returns the followers of the given pubkey by calling the provider's /followers endpoint.

func (*Client) Muters

func (c *Client) Muters(ctx context.Context, r MutersRequest, opts ...Option) (MutersResponse, error)

Muters returns the muters of the given pubkey by calling the provider's /muters endpoint.

func (*Client) RankPubkeys

func (c *Client) RankPubkeys(ctx context.Context, r RankPubkeysRequest, opts ...Option) (RankPubkeysResponse, error)

RankPubkeys ranks the given pubkeys by calling the provider's /rank/pubkeys endpoint.

func (*Client) RecommendPubkeys

func (c *Client) RecommendPubkeys(ctx context.Context, r RecommendPubkeysRequest, opts ...Option) (RecommendPubkeysResponse, error)

RecommendPubkeys returns recommended pubkeys by calling the provider's /recommend/pubkeys endpoint.

func (*Client) RefreshCapabilities

func (c *Client) RefreshCapabilities(ctx context.Context) error

RefreshCapabilities refreshes the cached capability document of the client. It returns an error if the capabilities cannot be fetched or are invalid.

func (*Client) SearchPubkeys

func (c *Client) SearchPubkeys(ctx context.Context, r SearchPubkeysRequest, opts ...Option) (SearchPubkeysResponse, error)

SearchPubkeys searches for pubkeys matching the query by calling the provider's /search/pubkeys endpoint.

func (*Client) StatsPubkey

func (c *Client) StatsPubkey(ctx context.Context, r StatsPubkeyRequest, opts ...Option) (StatsPubkeyResponse, error)

StatsPubkey returns the stats for the given pubkey by calling the provider's /stats/pubkey endpoint.

type CompromisedPubkeysRequest

type CompromisedPubkeysRequest struct {
	Pubkeys   []string    `json:"pubkeys"`
	Algorithm AlgorithmID `json:"algorithm,omitempty"`
	POV       string      `json:"pov,omitempty"`
}

func (CompromisedPubkeysRequest) Validate

func (r CompromisedPubkeysRequest) Validate() error

type CompromisedPubkeysResponse

type CompromisedPubkeysResponse map[string]compromise.Result

CompromisedPubkeysResponse maps each compromised pubkey to its compromise.Result. Pubkeys with no known compromise are absent from the map.

func (*CompromisedPubkeysResponse) UnmarshalJSON

func (r *CompromisedPubkeysResponse) UnmarshalJSON(data []byte) error

type Error

type Error struct {
	Code   int
	Reason string
}

Error represent an HTTP error with the specified code and reason. If the reason is not empty, it is written in the "X-Reason" header as per ORE-00.

func ErrBadRequest

func ErrBadRequest(reason string) *Error

ErrBadRequest returns a 400 Bad Request error with the given reason.

func ErrForbidden

func ErrForbidden(reason string) *Error

ErrForbidden returns a 403 Forbidden error with the given reason.

func ErrInternal

func ErrInternal(reason string) *Error

ErrInternal returns a 500 Internal Server Error with the given reason.

func ErrNotAllowed

func ErrNotAllowed(reason string) *Error

ErrNotAllowed returns a 405 Method Not Allowed error with the given reason.

func ErrNotFound

func ErrNotFound(reason string) *Error

ErrNotFound returns a 404 Not Found error with the given reason.

func ErrNotImplemented

func ErrNotImplemented(reason string) *Error

ErrNotImplemented returns a 501 Not Implemented error with the given reason.

func ErrPaymentRequired

func ErrPaymentRequired(reason string) *Error

ErrPaymentRequired returns a 402 Payment Required error with the given reason.

func ErrTooLarge

func ErrTooLarge(reason string) *Error

ErrTooLarge returns a 413 Payload Too Large error with the given reason.

func ErrTooMany

func ErrTooMany(reason string) *Error

ErrTooMany returns a 429 Too Many Requests error with the given reason.

func ErrUnauthorized

func ErrUnauthorized(reason string) *Error

ErrUnauthorized returns a 401 Unauthorized error with the given reason.

func ErrUnavailable

func ErrUnavailable(reason string) *Error

ErrUnavailable returns a 503 Service Unavailable error with the given reason.

func ErrUnsupportedMedia

func ErrUnsupportedMedia(reason string) *Error

ErrUnsupportedMedia returns a 415 Unsupported Media Type error with the given reason.

func (Error) Error

func (e Error) Error() string

func (*Error) Is

func (e *Error) Is(target error) bool

func (Error) String

func (e Error) String() string

type FollowersRequest

type FollowersRequest struct {
	Pubkey    string      `json:"pubkey"`
	Algorithm AlgorithmID `json:"algorithm,omitempty"`
	POV       string      `json:"pov,omitempty"`
	Limit     int         `json:"limit,omitempty"`
}

func (FollowersRequest) Validate

func (r FollowersRequest) Validate() error

type FollowersResponse

type FollowersResponse struct {
	Results []RankedPubkey `json:"results"`
	Total   *int           `json:"total,omitempty"`
	TTL     *int           `json:"ttl,omitempty"`
}

FollowersResponse is the response to a FollowersRequest.

type MutersRequest

type MutersRequest struct {
	Pubkey    string      `json:"pubkey"`
	Algorithm AlgorithmID `json:"algorithm,omitempty"`
	POV       string      `json:"pov,omitempty"`
	Limit     int         `json:"limit,omitempty"`
}

func (MutersRequest) Validate

func (r MutersRequest) Validate() error

type MutersResponse

type MutersResponse struct {
	Results []RankedPubkey `json:"results"`
	Total   *int           `json:"total,omitempty"`
	TTL     *int           `json:"ttl,omitempty"`
}

MutersResponse is the response to a MutersRequest.

type Option

type Option func(r *http.Request) error

Option is a function that modifies an http.Request, allowing for client methods to customize the request before it is sent.

func WithAuth

func WithAuth(e nostr.Event) Option

WithAuth returns an Option that sets the Authorization header with the given NWT.

type RankPubkeysRequest

type RankPubkeysRequest struct {
	Pubkeys   []string    `json:"pubkeys"`
	Algorithm AlgorithmID `json:"algorithm,omitempty"`
	POV       string      `json:"pov,omitempty"`
	Limit     int         `json:"limit,omitempty"`
}

func (RankPubkeysRequest) Validate

func (r RankPubkeysRequest) Validate() error

type RankPubkeysResponse

type RankPubkeysResponse struct {
	Results []RankedPubkey `json:"results"`
	TTL     *int           `json:"ttl,omitempty"`
}

RankPubkeysResponse is the response to the /rank/pubkeys endpoint.

type RankedPubkey

type RankedPubkey struct {
	Pubkey string  `json:"pubkey"`
	Rank   float64 `json:"rank"`
}

RankedPubkey represents a pubkey with its associated rank.

type RecommendPubkeysRequest

type RecommendPubkeysRequest struct {
	Algorithm AlgorithmID `json:"algorithm,omitempty"`
	POV       string      `json:"pov,omitempty"`
	Topic     string      `json:"topic,omitempty"`
	Limit     int         `json:"limit,omitempty"`
}

func (RecommendPubkeysRequest) Validate

func (r RecommendPubkeysRequest) Validate() error

type RecommendPubkeysResponse

type RecommendPubkeysResponse struct {
	Results []RankedPubkey `json:"results"`
	TTL     *int           `json:"ttl,omitempty"`
}

RecommendPubkeysResponse is the response to the /recommend/pubkeys endpoint.

type Retry

type Retry struct {
	After time.Duration
}

Retry is returned when the provider responds with 202 Accepted. The result is not yet ready. Retry the identical request after After.

func (Retry) Error

func (r Retry) Error() string

func (*Retry) Is

func (r *Retry) Is(target error) bool

type SearchPubkeysRequest

type SearchPubkeysRequest struct {
	Query     string      `json:"query"`
	Algorithm AlgorithmID `json:"algorithm,omitempty"`
	POV       string      `json:"pov,omitempty"`
	Limit     int         `json:"limit,omitempty"`
}

func (SearchPubkeysRequest) Validate

func (r SearchPubkeysRequest) Validate() error

type SearchPubkeysResponse

type SearchPubkeysResponse struct {
	Results []RankedPubkey `json:"results"`
	TTL     *int           `json:"ttl,omitempty"`
}

SearchPubkeysResponse is the response to the /search/pubkeys endpoint.

type StatsPubkeyRequest

type StatsPubkeyRequest struct {
	Pubkey    string      `json:"pubkey"`
	Algorithm AlgorithmID `json:"algorithm,omitempty"`
	POV       string      `json:"pov,omitempty"`
}

func (StatsPubkeyRequest) Validate

func (r StatsPubkeyRequest) Validate() error

type StatsPubkeyResponse

type StatsPubkeyResponse struct {
	Pubkey      string  `json:"pubkey"`
	Rank        float64 `json:"rank"`
	Follows     *int    `json:"follows,omitempty"`
	Followers   *int    `json:"followers,omitempty"`
	Mutes       *int    `json:"mutes,omitempty"`
	Muters      *int    `json:"muters,omitempty"`
	Reports     *int    `json:"reports,omitempty"`
	Reporters   *int    `json:"reporters,omitempty"`
	FirstSeenAt *int64  `json:"first_seen_at,omitempty"`
	TTL         *int    `json:"ttl,omitempty"`
}

StatsPubkeyResponse is the response to a /stats/pubkey request.

Directories

Path Synopsis
Package mock provides a test Open Ranking server backed by net/http/httptest.
Package mock provides a test Open Ranking server backed by net/http/httptest.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL