listen to mempool.space websocket
This commit is contained in:
+92
-19
@@ -5,6 +5,8 @@ import (
|
||||
"fmt"
|
||||
"image/color"
|
||||
"log"
|
||||
"net/http"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"git.dvdt.dev/david/bitcoin-ticker-pi/display"
|
||||
@@ -14,8 +16,8 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
RefreshRateHz = 60
|
||||
MempoolURL = "wss://mempool.dvdt.dev/v1/api/ws"
|
||||
RefreshRateHz = 1
|
||||
MempoolURL = "mempool.space"
|
||||
)
|
||||
|
||||
func main() {
|
||||
@@ -31,38 +33,92 @@ func main() {
|
||||
display.NewSlot(5, 5, 4, 44, 0),
|
||||
display.NewSlot(7, 13, 8, 5, 9),
|
||||
display.NewSlot(12, 5, 4, 7, 27),
|
||||
display.NewSlot(8, 5, 4, 28, 27),
|
||||
)
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
ticker := time.NewTicker(time.Second / RefreshRateHz)
|
||||
tdone := make(chan struct{})
|
||||
mdone := make(chan struct{})
|
||||
blocks := make(chan mempool.Block)
|
||||
msgs := make(chan mempool.Message)
|
||||
errs := make(chan error)
|
||||
|
||||
mp := mempool.New(MempoolURL)
|
||||
mp := mempool.New(MempoolURL, &http.Client{
|
||||
Timeout: 5 * time.Second,
|
||||
})
|
||||
err := mp.Init()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
go func(done chan struct{}, t *time.Ticker) {
|
||||
currentBlockHeight, err := mp.CurrentBlockHeight()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
highfee, medfee, lowfee, err := mp.CurrentFees()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
var blockHeight int
|
||||
blockHeightMutex := &sync.Mutex{}
|
||||
var fees mempool.Fees
|
||||
feesMutex := &sync.Mutex{}
|
||||
var price int
|
||||
priceMutex := &sync.Mutex{}
|
||||
|
||||
blockHeight = currentBlockHeight
|
||||
fees.FastestFee = highfee
|
||||
fees.HalfHourFee = medfee
|
||||
fees.HourFee = lowfee
|
||||
|
||||
go mp.Listen(ctx, msgs, errs, mdone)
|
||||
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
case <-done:
|
||||
return
|
||||
case <-ticker.C:
|
||||
updateSlots(d, 44000, 821000, 100, 200, 300)
|
||||
case m := <-msgs:
|
||||
fmt.Printf("%+v\n", m)
|
||||
if m.Fees != nil {
|
||||
feesMutex.Lock()
|
||||
fees = *m.Fees
|
||||
feesMutex.Unlock()
|
||||
}
|
||||
if m.Block != nil {
|
||||
blockHeightMutex.Lock()
|
||||
blockHeight = int(m.Block.Height)
|
||||
blockHeightMutex.Unlock()
|
||||
}
|
||||
if m.Conversions != nil {
|
||||
priceMutex.Lock()
|
||||
price = m.Conversions.USD
|
||||
priceMutex.Unlock()
|
||||
}
|
||||
}
|
||||
}
|
||||
}(tdone, ticker)
|
||||
}()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-tdone:
|
||||
return
|
||||
case <-ticker.C:
|
||||
d.Clear()
|
||||
d.Render()
|
||||
err = updateSlots(d, price, blockHeight, fees.HourFee, fees.HalfHourFee, fees.FastestFee)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func updateSlots(d *display.Display, price, height, lfee, mfee, hfee int) error {
|
||||
priceStr := fmt.Sprintf("%d", price)
|
||||
d.Clear()
|
||||
|
||||
var priceSegments []display.Segment
|
||||
priceSegments = append(priceSegments, strToDisplaySegments("dollar", fonts.Green)...)
|
||||
priceSegments = append(priceSegments, display.Segment{Text: "dollar", Color: fonts.Green})
|
||||
priceSegments = append(priceSegments, strToDisplaySegments(fmt.Sprintf("%d", price), fonts.White)...)
|
||||
|
||||
err := d.UpdateTopLeft(priceSegments)
|
||||
@@ -71,8 +127,12 @@ func updateSlots(d *display.Display, price, height, lfee, mfee, hfee int) error
|
||||
}
|
||||
|
||||
var moscowTimeSegments []display.Segment
|
||||
moscowTimeSegments = append(moscowTimeSegments, strToDisplaySegments("satoshi", fonts.Orange)...)
|
||||
moscowTimeSegments = append(moscowTimeSegments, strToDisplaySegments(fmt.Sprintf("%d", 100000000/price), fonts.White)...)
|
||||
moscowTime := 0
|
||||
if price > 0 {
|
||||
moscowTime = 100000000 / price
|
||||
}
|
||||
moscowTimeSegments = append(moscowTimeSegments, display.Segment{Text: "satoshi", Color: fonts.Orange})
|
||||
moscowTimeSegments = append(moscowTimeSegments, strToDisplaySegments(fmt.Sprintf("%d", moscowTime), fonts.White)...)
|
||||
|
||||
err = d.UpdateTopRight(moscowTimeSegments)
|
||||
if err != nil {
|
||||
@@ -80,18 +140,31 @@ func updateSlots(d *display.Display, price, height, lfee, mfee, hfee int) error
|
||||
}
|
||||
|
||||
var heightSegments []display.Segment
|
||||
heightSegments = append(heightSegments, strToDisplaySegments("height", fonts.Blue)...)
|
||||
heightSegments = append(heightSegments, display.Segment{Text: "height", Color: fonts.Blue})
|
||||
heightSegments = append(heightSegments, strToDisplaySegments(fmt.Sprintf("%d", height), fonts.White)...)
|
||||
|
||||
err = d.UpdateCenter(heightSegments)
|
||||
err = d.UpdateMain(heightSegments)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
var feeSegments []display.Segment
|
||||
feeSegments = append(feeSegments, display.Segment{Text: "low", Color: fonts.Green})
|
||||
feeSegments = append(feeSegments, strToDisplaySegments(fmt.Sprintf("%d", lfee), fonts.White)...)
|
||||
feeSegments = append(feeSegments, display.Segment{Text: "medium", Color: fonts.Orange})
|
||||
feeSegments = append(feeSegments, strToDisplaySegments(fmt.Sprintf("%d", mfee), fonts.White)...)
|
||||
feeSegments = append(feeSegments, display.Segment{Text: "high", Color: fonts.Red})
|
||||
feeSegments = append(feeSegments, strToDisplaySegments(fmt.Sprintf("%d", hfee), fonts.White)...)
|
||||
|
||||
err = d.UpdateBottom(feeSegments)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return d.Render()
|
||||
}
|
||||
|
||||
func strToDisplaySegments(s string, c color.Color) []display.Segment {
|
||||
func strToDisplaySegments(s string, c color.RGBA) []display.Segment {
|
||||
var segs []display.Segment
|
||||
for _, r := range s {
|
||||
segs = append(segs, display.Segment{Text: string(r), Color: c})
|
||||
|
||||
Reference in New Issue
Block a user