Compare commits

...

1 Commits

Author SHA1 Message Date
Gustavo Chain
b1715a7401
allow user to specify a custom endpoint 2022-05-05 20:34:00 +02:00
4 changed files with 40 additions and 24 deletions

View File

@ -5,14 +5,11 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"net/http" "net/http"
"strings"
"github.com/gorilla/websocket" "github.com/gorilla/websocket"
) )
const (
API_URL = "https://mempool.space/api/v1/ws"
)
type MempoolInfo struct { type MempoolInfo struct {
Size int `json:"size"` Size int `json:"size"`
Bytes int `json:"bytes"` Bytes int `json:"bytes"`
@ -69,12 +66,22 @@ type Response struct {
} }
type Client struct { type Client struct {
conn *websocket.Conn conn *websocket.Conn
endpoint string
} }
func New() (*Client, error) { func New() (*Client, error) {
return NewWithEndpoint("mempool.space")
}
func NewWithEndpoint(endpoint string) (*Client, error) {
if !strings.HasSuffix(endpoint, "/") {
endpoint = endpoint + "/"
}
endpoint = endpoint + "api/v1/ws"
dialer := websocket.Dialer{} dialer := websocket.Dialer{}
conn, _, err := dialer.Dial("wss://mempool.space/ws", nil) conn, _, err := dialer.Dial("wss://"+endpoint, nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -83,7 +90,10 @@ func New() (*Client, error) {
`{"action": "init"}`, `{"action": "init"}`,
)) ))
return &Client{conn: conn}, nil return &Client{
conn: conn,
endpoint: endpoint,
}, nil
} }
func (c *Client) Read() (*Response, error) { func (c *Client) Read() (*Response, error) {
@ -114,8 +124,8 @@ func (f Fees) Len() int { return len(f) }
func (f Fees) Less(i, j int) bool { return f[i].FPV < f[j].FPV } func (f Fees) Less(i, j int) bool { return f[i].FPV < f[j].FPV }
func (f Fees) Swap(i, j int) { f[i], f[j] = f[j], f[i] } func (f Fees) Swap(i, j int) { f[i], f[j] = f[j], f[i] }
func Get(ctx context.Context, path string, v interface{}) error { func (c *Client) Get(ctx context.Context, path string, v interface{}) error {
req, err := http.NewRequest("GET", API_URL+path, nil) req, err := http.NewRequest("GET", "https://"+c.endpoint+path, nil)
if err != nil { if err != nil {
return err return err
} }
@ -135,17 +145,17 @@ func Get(ctx context.Context, path string, v interface{}) error {
return json.NewDecoder(r.Body).Decode(v) return json.NewDecoder(r.Body).Decode(v)
} }
func GetMempoolFee(ctx context.Context, n int) (Fees, error) { func (c *Client) GetMempoolFee(ctx context.Context, n int) (Fees, error) {
var fees Fees var fees Fees
if err := Get(ctx, fmt.Sprintf("transactions/mempool/%d", n), &fees); err != nil { if err := c.Get(ctx, fmt.Sprintf("/transactions/mempool/%d", n), &fees); err != nil {
return nil, err return nil, err
} }
return fees, nil return fees, nil
} }
func GetBlockFee(ctx context.Context, n int) (Fees, error) { func (c *Client) GetBlockFee(ctx context.Context, n int) (Fees, error) {
var fees Fees var fees Fees
if err := Get(ctx, fmt.Sprintf("transactions/height/%d", n), &fees); err != nil { if err := c.Get(ctx, fmt.Sprintf("/transactions/height/%d", n), &fees); err != nil {
return nil, err return nil, err
} }
return fees, nil return fees, nil

View File

@ -1,13 +1,17 @@
package main package main
import ( import (
"flag"
"log" "log"
"github.com/mempool/mempool-cli/ui" "github.com/mempool/mempool-cli/ui"
) )
func main() { func main() {
gui, err := ui.New() endpoint := flag.String("endpoint", "mempool.space", "The API endpoint")
flag.Parse()
gui, err := ui.New(*endpoint)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }

View File

@ -21,10 +21,11 @@ type FeeDistribution struct {
cancelFn context.CancelFunc cancelFn context.CancelFunc
fees client.Fees fees client.Fees
title string title string
client *client.Client
} }
func NewFeeDistribution(g *gocui.Gui) *FeeDistribution { func NewFeeDistribution(g *gocui.Gui, c *client.Client) *FeeDistribution {
return &FeeDistribution{gui: g} return &FeeDistribution{gui: g, client: c}
} }
func (fd *FeeDistribution) newCtx() context.Context { func (fd *FeeDistribution) newCtx() context.Context {
@ -35,14 +36,14 @@ func (fd *FeeDistribution) newCtx() context.Context {
func (fd *FeeDistribution) FetchProjection(n int) error { func (fd *FeeDistribution) FetchProjection(n int) error {
fn := func(ctx context.Context) (client.Fees, error) { fn := func(ctx context.Context) (client.Fees, error) {
return client.GetMempoolFee(ctx, n) return fd.client.GetMempoolFee(ctx, n)
} }
return fd.fetch(fn) return fd.fetch(fn)
} }
func (fd *FeeDistribution) FetchBlock(n int) error { func (fd *FeeDistribution) FetchBlock(n int) error {
fn := func(ctx context.Context) (client.Fees, error) { fn := func(ctx context.Context) (client.Fees, error) {
return client.GetBlockFee(ctx, n) return fd.client.GetBlockFee(ctx, n)
} }
return fd.fetch(fn) return fd.fetch(fn)
} }

View File

@ -34,14 +34,19 @@ type UI struct {
state state state state
} }
func New() (*UI, error) { func New(endpoint string) (*UI, error) {
c, err := client.NewWithEndpoint(endpoint)
if err != nil {
log.Fatal(err)
}
gui, err := gocui.NewGui(gocui.Output256) gui, err := gocui.NewGui(gocui.Output256)
if err != nil { if err != nil {
return nil, err return nil, err
} }
ui := &UI{gui: gui} ui := &UI{gui: gui}
ui.fd = NewFeeDistribution(gui) ui.fd = NewFeeDistribution(gui, c)
ui.ts = NewTXSearch(gui) ui.ts = NewTXSearch(gui)
gui.SetManager(ui, ui.fd, ui.ts) gui.SetManager(ui, ui.fd, ui.ts)
@ -54,10 +59,6 @@ func New() (*UI, error) {
gui.SelFgColor = gocui.ColorWhite gui.SelFgColor = gocui.ColorWhite
go func() { go func() {
c, err := client.New()
if err != nil {
log.Fatal(err)
}
if err := c.Want(); err != nil { if err := c.Want(); err != nil {
log.Fatal(err) log.Fatal(err)
} }