Compare commits

...

24 Commits

Author SHA1 Message Date
Gustavo Chain
fdb8d4002f
update broken ws endpoint
Some checks failed
release / goreleaser (push) Has been cancelled
2023-03-27 11:34:27 +02:00
Gustavo Chaín
1e149e7a50
Merge pull request #15 from mempool/dependabot/go_modules/github.com/fatih/color-1.14.1
Bump github.com/fatih/color from 1.13.0 to 1.14.1
2023-01-30 16:37:02 +00:00
dependabot[bot]
c85f24abe7
Bump github.com/fatih/color from 1.13.0 to 1.14.1
Bumps [github.com/fatih/color](https://github.com/fatih/color) from 1.13.0 to 1.14.1.
- [Release notes](https://github.com/fatih/color/releases)
- [Commits](https://github.com/fatih/color/compare/v1.13.0...v1.14.1)

---
updated-dependencies:
- dependency-name: github.com/fatih/color
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-24 15:07:00 +00:00
naveensrinivasan
d6320efe88
Updated the release to use go 1.17 2022-05-05 20:13:16 +02:00
naveensrinivasan
7461e85495
Upgraded to go 1.17
- Upgraded to go 1.17 as 1.14 is not supported anymore.
- Pinned the docker file to a hash https://github.com/ossf/scorecard/blob/main/docs/checks.md#pinned-dependencies

Signed-off-by: naveensrinivasan <172697+naveensrinivasan@users.noreply.github.com>
2022-05-05 20:13:13 +02:00
Gustavo Chain
595040d46f
go get -u 2022-05-05 20:12:46 +02:00
Naveen
9b11358fb2
Create dependabot.yml 2022-03-06 10:19:24 -05:00
Gustavo Chain
dc9662b509
Update client's endpoint
Some checks failed
release / goreleaser (push) Has been cancelled
2021-01-22 13:21:33 +01:00
Gustavo Chain
1ac079b082
Add halving banner
Some checks failed
release / goreleaser (push) Has been cancelled
2020-04-10 19:20:14 +02:00
Gustavo Chain
ba84b32f05
rename fee_range to feeRange 2020-04-07 10:21:33 +02:00
Gustavo Chain
5e57b325d9
Add Dockerfile
Some checks failed
release / goreleaser (push) Has been cancelled
This commit also disable the docker building process performed by
 goreleaser. Docker containers are built now by hub.docker.com.
2020-03-31 20:42:03 +02:00
Gustavo Chain
89085c721c
Update Dockefile
Some checks failed
release / goreleaser (push) Has been cancelled
2020-03-29 23:04:56 +02:00
Gustavo Chain
e6b74bc6da
Update README.md and goreleaser 2020-03-29 22:58:52 +02:00
Gustavo Chain
07a4573c46
Rename to mempool/mempool-cli 2020-03-29 22:57:15 +02:00
Gustavo Chain
7d6d22186f
Update README.md 2020-03-29 16:32:14 +02:00
Gustavo Chain
395198c4e7
rename projected to mempool 2020-03-29 16:30:31 +02:00
Gustavo Chain
89f05b151b
drop freebsd releases
Some checks failed
release / goreleaser (push) Has been cancelled
2020-03-29 16:15:02 +02:00
Gustavo Chain
252edaf84b
Update code to use new v2 API 2020-03-29 16:05:20 +02:00
Gustavo Chain
616593ce4d
Rename projected to mempool 2020-03-29 15:50:20 +02:00
Gustavo Chaín
f5cdc20b4f
Update README.md 2020-02-27 23:16:57 +01:00
Gustavo Chain
fd071a4aff
Update README.md 2020-02-27 19:43:56 +01:00
Gustavo Chain
37a40a30f9
Fix docker in actions 2020-02-27 19:39:53 +01:00
Gustavo Chaín
71d5c58193
Update README.md 2020-02-27 19:32:47 +01:00
Gustavo Chain
187d5aa88a
Expand releases
Freebsd and Windows added to the OSs
arm and arm64 added to the Archs
Added Docker
2020-02-27 18:47:30 +01:00
12 changed files with 187 additions and 85 deletions

11
.github/dependabot.yml vendored Normal file
View File

@ -0,0 +1,11 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
- package-ecosystem: "gomod" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "daily"

View File

@ -19,13 +19,15 @@ jobs:
name: Set up Go
uses: actions/setup-go@v1
with:
go-version: 1.13.x
go-version: 1.17.x
-
name: Docker login
run: docker login -u ${{ secrets.DOCKER_USERNAME }} -p ${{ secrets.DOCKER_PASSWORD }}
-
name: Run GoReleaser
uses: goreleaser/goreleaser-action@v1
with:
version: latest
args: release --rm-dist
key: ${{ secrets.YOUR_PRIVATE_KEY }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@ -1,15 +1,30 @@
# This is an example goreleaser.yaml file with some sane defaults.
# Make sure to check the documentation at http://goreleaser.com
builds:
- env:
- CGO_ENABLED=0
-
env:
- CGO_ENABLED=0
goos:
- linux
- darwin
- windows
goarch:
- amd64
- 386
- arm
- arm64
archives:
- replacements:
darwin: Darwin
linux: Linux
freebsd: FreeBSD
darwin: Darwin
windows: Windows
386: i386
amd64: x86_64
checksum:
name_template: 'checksums.txt'
snapshot:

10
Dockerfile Normal file
View File

@ -0,0 +1,10 @@
FROM golang:1.17-alpine@sha256:b35984144ec2c2dfd6200e112a9b8ecec4a8fd9eff0babaff330f1f82f14cb2a
RUN apk --no-cache add ca-certificates
WORKDIR /src
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o mempool-cli .
FROM scratch
COPY --from=0 /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=0 /src/mempool-cli /
ENTRYPOINT ["/mempool-cli"]

View File

@ -1,4 +1,5 @@
# mempool
# mempool-cli
[mempool.space](https://mempool.space/) for the terminal
![mempool screenshot](https://github.com/gchaincl/mempool/raw/master/share/screenshot.png)
@ -11,9 +12,22 @@ Get a pre-built [release](https://github.com/gchaincl/mempool/releases/latest)
### development version
```bash
go get -u github.com/gchaincl/mempool
go get -u github.com/mempool/mempool-cli
```
### Docker
```bash
docker run -it mempool/mempool-cli
```
# Usage
### Key bindings
Key | Description
------------------|--------------------------------------
<kbd>Ctrl+c</kbd> | Quit
<kbd>f</kbd> | Opens Tx search
<kbd>click</kbd> | Opens info for a selected block
# TODO
- [x] Transaction Tracking (by Tx ID) (using 'f' key)
- [x] Block details on click

View File

@ -10,7 +10,7 @@ import (
)
const (
API_URL = "https://mempool.space/api/v1/"
API_URL = "https://mempool.space/api/v1/ws"
)
type MempoolInfo struct {
@ -19,29 +19,25 @@ type MempoolInfo struct {
}
type Block struct {
Hash string `json:"hash"`
Height int `json:"height"`
NTx int `json:"nTx"`
Size int `json:"size"`
Time int `json:"time"`
Weight int `json:"weight"`
Fees float64 `json:"fees"`
MinFee float64 `json:"minFee"`
MaxFee float64 `json:"maxFee"`
MedianFee float64 `json:"medianFee"`
ID string `json:"id"`
Height int `json:"height"`
TxCount int `json:"tx_count"`
Size int `json:"size"`
Time int `json:"timestamp"`
Weight int `json:"weight"`
FeeRange []float64 `json:"feeRange"`
MedianFee float64 `json:"medianFee"`
}
type ProjectedBlock struct {
BlockSize int `json:"blockSize"`
BlockWeight int `json:"blockWeight"`
NTx int `json:"nTx"`
MinFee float64 `json:"minFee"`
MaxFee float64 `json:"maxFee"`
MinWeigthFee float64 `json:"minWeigthFee"`
MaxWeigthFee float64 `json:"maxWeigthFee"`
MedianFee float64 `json:"medianFee"`
Fees float64 `json:"fees"`
HasMyTx bool `json:"hasMytx"`
type MempoolBlock struct {
BlockSize int `json:"blockSize"`
BlockWeight float64 `json:"blockVSize"`
NTx int `json:"nTx"`
MinWeigthFee float64 `json:"minWeigthFee"`
MaxWeigthFee float64 `json:"maxWeigthFee"`
MedianFee float64 `json:"medianFee"`
FeeRange []float64 `json:"feeRange"`
HasMyTx bool `json:"hasMytx"`
}
type TrackTx struct {
@ -61,8 +57,8 @@ type Response struct {
Block *Block `json:"block"`
Blocks []Block `json:"blocks"`
ProjectedBlocks []ProjectedBlock `json:"projectedBlocks"`
TrackTx TrackTx `json:"track-tx"`
MempoolBlocks []MempoolBlock `json:"mempool-blocks"`
TrackTx TrackTx `json:"track-tx"`
TxPerSecond float64 `json:"txPerSecond"`
VBytesPerSecond int `json:"vBytesPerSecond"`
@ -78,10 +74,15 @@ type Client struct {
func New() (*Client, error) {
dialer := websocket.Dialer{}
conn, _, err := dialer.Dial("wss://mempool.space/ws", nil)
conn, _, err := dialer.Dial("wss://mempool.space/api/v1/ws", nil)
if err != nil {
return nil, err
}
conn.WriteMessage(websocket.TextMessage, []byte(
`{"action": "init"}`,
))
return &Client{conn: conn}, nil
}
@ -95,7 +96,7 @@ func (c *Client) Read() (*Response, error) {
func (c *Client) Want() error {
return c.conn.WriteMessage(websocket.TextMessage, []byte(
`{"action":"want","data":["stats","blocks","projected-blocks"]}`,
`{"action":"want","data":["stats","blocks","mempool-blocks"]}`,
))
}
@ -134,9 +135,9 @@ func Get(ctx context.Context, path string, v interface{}) error {
return json.NewDecoder(r.Body).Decode(v)
}
func GetProjectedFee(ctx context.Context, n int) (Fees, error) {
func GetMempoolFee(ctx context.Context, n int) (Fees, error) {
var fees Fees
if err := Get(ctx, fmt.Sprintf("transactions/projected/%d", n), &fees); err != nil {
if err := Get(ctx, fmt.Sprintf("transactions/mempool/%d", n), &fees); err != nil {
return nil, err
}
return fees, nil

21
go.mod
View File

@ -1,11 +1,18 @@
module github.com/gchaincl/mempool
module github.com/mempool/mempool-cli
go 1.13
go 1.17
require (
github.com/fatih/color v1.9.0
github.com/gorilla/websocket v1.4.1
github.com/jroimartin/gocui v0.4.0
github.com/mattn/go-runewidth v0.0.8 // indirect
github.com/nsf/termbox-go v0.0.0-20200204031403-4d2b513ad8be // indirect
github.com/fatih/color v1.14.1
github.com/gorilla/websocket v1.5.0
github.com/jroimartin/gocui v0.5.0
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-runewidth v0.0.13 // indirect
golang.org/x/sys v0.3.0 // indirect
)
require (
github.com/mattn/go-isatty v0.0.17 // indirect
github.com/nsf/termbox-go v1.1.1 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
)

38
go.sum
View File

@ -1,17 +1,21 @@
github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s=
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/jroimartin/gocui v0.4.0 h1:52jnalstgmc25FmtGcWqa0tcbMEWS6RpFLsOIO+I+E8=
github.com/jroimartin/gocui v0.4.0/go.mod h1:7i7bbj99OgFHzo7kB2zPb8pXLqMBSQegY7azfqXMkyY=
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.11 h1:FxPOTFNqGkuDUGi3H/qkUbQO4ZiBa2brKq5r0l8TGeM=
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
github.com/mattn/go-runewidth v0.0.8 h1:3tS41NlGYSmhhe/8fhGRzc+z3AYCw1Fe1WAyLuujKs0=
github.com/mattn/go-runewidth v0.0.8/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/nsf/termbox-go v0.0.0-20200204031403-4d2b513ad8be h1:yzmWtPyxEUIKdZg4RcPq64MfS8NA6A5fNOJgYhpR9EQ=
github.com/nsf/termbox-go v0.0.0-20200204031403-4d2b513ad8be/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
github.com/fatih/color v1.14.1 h1:qfhVLaG5s+nCROl1zJsZRxFeYrHLqWroPOQ8BWiNb4w=
github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/jroimartin/gocui v0.5.0 h1:DCZc97zY9dMnHXJSJLLmx9VqiEnAj0yh0eTNpuEtG/4=
github.com/jroimartin/gocui v0.5.0/go.mod h1:l7Hz8DoYoL6NoYnlnaX6XCNR62G7J5FfSW5jEogzaxE=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/nsf/termbox-go v1.1.1 h1:nksUPLCb73Q++DwbYUBEglYBRPZyoXJdrj5L+TkjyZY=
github.com/nsf/termbox-go v1.1.1/go.mod h1:T0cTdVuOwf7pHQNtfhnEbzHbcNyCEcVU4YPpouCbVxo=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ=
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=

View File

@ -3,7 +3,7 @@ package main
import (
"log"
"github.com/gchaincl/mempool/ui"
"github.com/mempool/mempool-cli/ui"
)
func main() {

View File

@ -7,7 +7,7 @@ import (
"time"
"github.com/fatih/color"
"github.com/gchaincl/mempool/client"
"github.com/mempool/mempool-cli/client"
)
type Box struct {
@ -48,9 +48,9 @@ func (b *Box) Render(full int, bg color.Attribute) []byte {
return buf.Bytes()
}
type ProjectedBlock client.ProjectedBlock
type MempoolBlock client.MempoolBlock
func (b ProjectedBlock) Print(n int, x, _y int) []byte {
func (b MempoolBlock) Print(n int, x, _y int) []byte {
var footer string
// Attach ETA to the first 3 blocks
if n < 3 {
@ -60,9 +60,13 @@ func (b ProjectedBlock) Print(n int, x, _y int) []byte {
footer = fmt.Sprintf("+%d blocks", n)
}
var min, max float64
if len(b.FeeRange) > 2 {
min, max = b.FeeRange[0], b.FeeRange[len(b.FeeRange)-1]
}
box := &Box{x: x}
box.Printf(color.FgWhite, "~%d sat/vB", ceil(b.MedianFee)).
Printf(color.FgYellow, "%d-%d sat/vB", ceil(b.MinFee), ceil(b.MaxFee)).
Printf(color.FgYellow, "%d-%d sat/vB", ceil(min), ceil(max)).
Append("").
Printf(color.FgWhite, "%.2f MB", float64(b.BlockSize)/(1000*1000)).
Printf(color.FgWhite, "%4d transactions", b.NTx).
@ -75,7 +79,7 @@ func (b ProjectedBlock) Print(n int, x, _y int) []byte {
var full int
if n < 3 {
full = int(
float64(b.BlockWeight) / 4_000_000 * 10,
float64(b.BlockWeight) / 1_000_000 * 10,
)
}
@ -88,11 +92,15 @@ func (b Block) Print(n int, x, _y int) []byte {
ago := time.Now().Unix() - int64(b.Time)
box := &Box{x: x}
var min, max float64
if len(b.FeeRange) > 2 {
min, max = b.FeeRange[0], b.FeeRange[len(b.FeeRange)-1]
}
box.Printf(color.FgWhite, "~%d sat/Vb", ceil(b.MedianFee)).
Printf(color.FgYellow, "%d-%d sat/vB", ceil(b.MinFee), ceil(b.MaxFee)).
Printf(color.FgYellow, "%d-%d sat/vB", ceil(min), ceil(max)).
Append("").
Printf(color.FgWhite, "%.2f MB", float64(b.Size)/(1000*1000)).
Printf(color.FgWhite, " %4d transactions", b.NTx).
Printf(color.FgWhite, " %4d transactions", b.TxCount).
Append("").
Append("").
Append("").

View File

@ -7,8 +7,9 @@ import (
"sync"
"github.com/fatih/color"
"github.com/gchaincl/mempool/client"
"github.com/jroimartin/gocui"
"github.com/mempool/mempool-cli/client"
)
type FeeDistribution struct {
@ -34,7 +35,7 @@ func (fd *FeeDistribution) newCtx() context.Context {
func (fd *FeeDistribution) FetchProjection(n int) error {
fn := func(ctx context.Context) (client.Fees, error) {
return client.GetProjectedFee(ctx, n)
return client.GetMempoolFee(ctx, n)
}
return fd.fetch(fn)
}

View File

@ -7,18 +7,20 @@ import (
"strings"
"github.com/fatih/color"
"github.com/gchaincl/mempool/client"
"github.com/jroimartin/gocui"
"github.com/mempool/mempool-cli/client"
)
const (
BLOCK_WIDTH = 22
BLOCK_WIDTH = 22
NEXT_HALVING = 630_000
)
type state struct {
loaded bool
blocks []client.Block
projected []client.ProjectedBlock
mempool []client.MempoolBlock
vBytesPerSecond int
info *client.MempoolInfo
tracking *client.TrackTx
@ -105,8 +107,8 @@ func (ui *UI) Render(resp *client.Response) {
ui.state.blocks = bs
}
if bs := resp.ProjectedBlocks; len(bs) != 0 {
ui.state.projected = bs
if bs := resp.MempoolBlocks; len(bs) != 0 {
ui.state.mempool = bs
}
if b := resp.Block; b != nil {
@ -143,9 +145,9 @@ func (ui *UI) Layout(g *gocui.Gui) error {
track := ui.state.tracking
// draw projected blocks (mempool)
for i, _ := range ui.state.projected {
name := fmt.Sprintf("projected-block-%d", i)
// draw mempool blocks
for i, _ := range ui.state.mempool {
name := fmt.Sprintf("mempool-block-%d", i)
var x0, x1, y0, y1 int
if vertical {
x0 = x - (BLOCK_WIDTH+2)*(i+1)
@ -177,7 +179,7 @@ func (ui *UI) Layout(g *gocui.Gui) error {
}
v.Clear()
if _, err := v.Write(ui.printProjectedBlock(i, x1-x0, y1-y0)); err != nil {
if _, err := v.Write(ui.printMempoolBlock(i, x1-x0, y1-y0)); err != nil {
return err
}
}
@ -230,6 +232,11 @@ func (ui *UI) Layout(g *gocui.Gui) error {
return err
}
// halving
if err := ui.halvingBanner(); err != nil {
return err
}
return nil
}
@ -245,9 +252,9 @@ func (ui *UI) loading(g *gocui.Gui, x, y int) error {
return nil
}
func (ui *UI) printProjectedBlock(n int, x, y int) []byte {
b := ui.state.projected[n]
return ProjectedBlock(b).Print(n, x, y)
func (ui *UI) printMempoolBlock(n int, x, y int) []byte {
b := ui.state.mempool[n]
return MempoolBlock(b).Print(n, x, y)
}
func (ui *UI) printBlock(n int, x, y int) []byte {
@ -306,14 +313,14 @@ func (ui *UI) info(g *gocui.Gui, x, y int) error {
}
var mSize int
for _, b := range ui.state.projected {
for _, b := range ui.state.mempool {
mSize += b.BlockSize
}
// Compute the total number of blocks on the mempool
// We use the total BlockWeight / 4mm
var w float64
for _, b := range ui.state.projected {
for _, b := range ui.state.mempool {
w += float64(b.BlockWeight)
}
@ -325,10 +332,32 @@ func (ui *UI) info(g *gocui.Gui, x, y int) error {
return nil
}
func (ui *UI) halvingBanner() error {
blocks := ui.state.blocks
if len(blocks) == 0 {
return nil
}
height := blocks[0].Height
if height >= NEXT_HALVING {
return nil
}
in := NEXT_HALVING - height
msg := fmt.Sprintf("Quantitative Hardening in %d blocks", in)
v, err := ui.gui.SetView("halving", 1, 1, len(msg)+2, 3)
if err != nil {
if err != gocui.ErrUnknownView {
return err
}
}
_, err = fmt.Fprintf(v, msg)
return err
}
func (ui *UI) onBlockClick(g *gocui.Gui, v *gocui.View) error {
name := v.Name()
if strings.HasPrefix(name, "projected-block-") {
id := strings.TrimPrefix(name, "projected-block-")
if strings.HasPrefix(name, "mempool-block-") {
id := strings.TrimPrefix(name, "mempool-block-")
n, _ := strconv.Atoi(id)
return ui.fd.FetchProjection(n)
}