views: transactions

pull/10/head
Edouard Paris 5 years ago
parent 7099391f78
commit f81b46d07b

@ -35,4 +35,6 @@ type Backend interface {
DecodePayReq(context.Context, string) (*models.PayReq, error)
SendPayment(context.Context, *models.PayReq) (*models.Payment, error)
GetTransactions(context.Context) ([]*models.Transaction, error)
}

@ -134,6 +134,23 @@ func (l Backend) NewClientConn() (*grpc.ClientConn, error) {
return newClientConn(l.cfg)
}
func (l Backend) GetTransactions(ctx context.Context) ([]*models.Transaction, error) {
l.logger.Debug("Get transactions...")
clt, err := l.Client(ctx)
if err != nil {
return nil, err
}
defer clt.Close()
req := &lnrpc.GetTransactionsRequest{}
resp, err := clt.GetTransactions(ctx, req)
if err != nil {
return nil, errors.WithStack(err)
}
return protoToTransactions(resp), nil
}
func (l Backend) GetWalletBalance(ctx context.Context) (*models.WalletBalance, error) {
l.logger.Debug("Retrieve wallet balance...")

@ -284,3 +284,24 @@ func protoToRoutingPolicy(resp *lnrpc.RoutingPolicy) *models.RoutingPolicy {
Disabled: resp.Disabled,
}
}
func protoToTransactions(resp *lnrpc.TransactionDetails) []*models.Transaction {
if resp == nil {
return nil
}
transactions := make([]*models.Transaction, len(resp.Transactions))
for i := range resp.Transactions {
transactions[i] = &models.Transaction{
TxHash: resp.Transactions[i].TxHash,
Amount: resp.Transactions[i].Amount,
NumConfirmations: resp.Transactions[i].NumConfirmations,
BlockHash: resp.Transactions[i].BlockHash,
BlockHeight: resp.Transactions[i].BlockHeight,
TimeStamp: resp.Transactions[i].TimeStamp,
TotalFees: resp.Transactions[i].TotalFees,
DestAddresses: resp.Transactions[i].DestAddresses,
}
}
return transactions
}

@ -54,6 +54,10 @@ func (b *Backend) GetWalletBalance(ctx context.Context) (*models.WalletBalance,
return &models.WalletBalance{}, nil
}
func (b *Backend) GetTransactions(ctx context.Context) ([]*models.Transaction, error) {
return []*models.Transaction{}, nil
}
func (b *Backend) GetChannelsBalance(ctx context.Context) (*models.ChannelsBalance, error) {
return &models.ChannelsBalance{}, nil
}

@ -0,0 +1,20 @@
package models
type Transaction struct {
// / The transaction hash
TxHash string
// / The transaction amount, denominated in satoshis
Amount int64
// / The number of confirmations
NumConfirmations int32
// / The hash of the block this transaction was included in
BlockHash string
// / The height of the block this transaction was included in
BlockHeight int32
// / Timestamp of this transaction
TimeStamp int64
// / Fees paid for this transaction
TotalFees int64
// / Addresses that received funds for this transaction
DestAddresses []string
}

@ -243,6 +243,17 @@ func (c *controller) OnEnter(g *gocui.Gui, v *gocui.View) error {
if err != nil {
return err
}
case views.MENU:
err := c.models.RefreshTransactions(context.Background())
if err != nil {
return err
}
c.views.Main = c.views.Transactions
err = c.views.Transactions.Set(g, 11, 6, maxX-1, maxY)
if err != nil {
return err
}
}
return nil
}

@ -18,6 +18,7 @@ type Models struct {
CurrentChannel *Channel
WalletBalance *WalletBalance
ChannelsBalance *ChannelsBalance
Transactions *Transactions
}
func New(app *app.App) *Models {
@ -29,6 +30,7 @@ func New(app *app.App) *Models {
WalletBalance: &WalletBalance{},
ChannelsBalance: &ChannelsBalance{},
CurrentChannel: &Channel{},
Transactions: &Transactions{},
}
}

@ -0,0 +1,24 @@
package models
import (
"context"
"github.com/edouardparis/lntop/network/models"
)
type Transactions struct {
list []*models.Transaction
}
func (t Transactions) List() []*models.Transaction {
return t.list
}
func (m *Models) RefreshTransactions(ctx context.Context) error {
transactions, err := m.network.GetTransactions(ctx)
if err != nil {
return err
}
*m.Transactions = Transactions{list: transactions}
return nil
}

@ -0,0 +1,194 @@
package views
import (
"bytes"
"fmt"
"github.com/jroimartin/gocui"
"golang.org/x/text/language"
"golang.org/x/text/message"
netmodels "github.com/edouardparis/lntop/network/models"
"github.com/edouardparis/lntop/ui/color"
"github.com/edouardparis/lntop/ui/models"
)
const (
TRANSACTIONS = "transactions"
TRANSACTIONS_COLUMNS = "transactions_columns"
TRANSACTIONS_FOOTER = "transactions_footer"
)
var DefaultTransactionsColumns = []string{
"TXHASH",
"AMOUNT",
}
type Transactions struct {
columns []transactionsColumn
columnsView *gocui.View
view *gocui.View
transactions *models.Transactions
}
type transactionsColumn struct {
name string
display func(*netmodels.Transaction) string
}
func (c Transactions) Name() string {
return TRANSACTIONS
}
func (c *Transactions) Wrap(v *gocui.View) view {
c.view = v
return c
}
func (c *Transactions) CursorDown() error {
return cursorDown(c.view, 1)
}
func (c *Transactions) CursorUp() error {
return cursorUp(c.view, 1)
}
func (c *Transactions) CursorRight() error {
err := cursorRight(c.columnsView, 2)
if err != nil {
return err
}
return cursorRight(c.view, 2)
}
func (c *Transactions) CursorLeft() error {
err := cursorLeft(c.columnsView, 2)
if err != nil {
return err
}
return cursorLeft(c.view, 2)
}
func (c Transactions) Delete(g *gocui.Gui) error {
err := g.DeleteView(TRANSACTIONS_COLUMNS)
if err != nil {
return err
}
err = g.DeleteView(TRANSACTIONS)
if err != nil {
return err
}
return g.DeleteView(TRANSACTIONS_FOOTER)
}
func (c *Transactions) Set(g *gocui.Gui, x0, y0, x1, y1 int) error {
var err error
c.columnsView, err = g.SetView(TRANSACTIONS_COLUMNS, x0-1, y0, x1+2, y0+2)
if err != nil {
if err != gocui.ErrUnknownView {
return err
}
}
c.columnsView.Frame = false
c.columnsView.BgColor = gocui.ColorGreen
c.columnsView.FgColor = gocui.ColorBlack
c.view, err = g.SetView(TRANSACTIONS, x0-1, y0+1, x1+2, y1-1)
if err != nil {
if err != gocui.ErrUnknownView {
return err
}
_, err = g.SetCurrentView(TRANSACTIONS)
if err != nil {
return err
}
}
c.view.Frame = false
c.view.Autoscroll = false
c.view.SelBgColor = gocui.ColorCyan
c.view.SelFgColor = gocui.ColorBlack
c.view.Highlight = true
c.display()
footer, err := g.SetView(TRANSACTIONS_FOOTER, x0-1, y1-2, x1+2, y1)
if err != nil {
if err != gocui.ErrUnknownView {
return err
}
}
footer.Frame = false
footer.BgColor = gocui.ColorCyan
footer.FgColor = gocui.ColorBlack
footer.Clear()
fmt.Fprintln(footer, fmt.Sprintf("%s%s %s%s %s%s %s%s",
color.BlackBg("F1"), "Help",
color.BlackBg("F2"), "Menu",
color.BlackBg("Enter"), "Transaction",
color.BlackBg("F10"), "Quit",
))
return nil
}
func (c *Transactions) display() {
c.columnsView.Clear()
var buffer bytes.Buffer
for i := range c.columns {
buffer.WriteString(c.columns[i].name)
buffer.WriteString(" ")
}
fmt.Fprintln(c.columnsView, buffer.String())
c.view.Clear()
for _, item := range c.transactions.List() {
var buffer bytes.Buffer
for i := range c.columns {
buffer.WriteString(c.columns[i].display(item))
buffer.WriteString(" ")
}
fmt.Fprintln(c.view, buffer.String())
}
}
func NewTransactions(txs *models.Transactions) *Transactions {
transactions := &Transactions{
transactions: txs,
}
printer := message.NewPrinter(language.English)
columns := DefaultTransactionsColumns
transactions.columns = make([]transactionsColumn, len(columns))
for i := range columns {
switch columns[i] {
case "TXHASH":
transactions.columns[i] = transactionsColumn{
name: fmt.Sprintf("%-13s", columns[i]),
display: func(tx *netmodels.Transaction) string {
return fmt.Sprintf("%13s", tx.TxHash)
},
}
case "AMOUNT":
transactions.columns[i] = transactionsColumn{
name: fmt.Sprintf("%-13s", columns[i]),
display: func(tx *netmodels.Transaction) string {
return printer.Sprintf("%13d", tx.Amount)
},
}
default:
transactions.columns[i] = transactionsColumn{
name: fmt.Sprintf("%-21s", columns[i]),
display: func(tx *netmodels.Transaction) string {
return "column does not exist"
},
}
}
}
return transactions
}

@ -20,12 +20,13 @@ type Views struct {
Previous view
Main view
Help *Help
Header *Header
Menu *Menu
Summary *Summary
Channels *Channels
Channel *Channel
Help *Help
Header *Header
Menu *Menu
Summary *Summary
Channels *Channels
Channel *Channel
Transactions *Transactions
}
func (v Views) Get(vi *gocui.View) view {
@ -41,6 +42,8 @@ func (v Views) Get(vi *gocui.View) view {
return v.Menu.Wrap(vi)
case CHANNEL:
return v.Channel.Wrap(vi)
case TRANSACTIONS:
return v.Transactions.Wrap(vi)
default:
return nil
}
@ -86,12 +89,13 @@ func (v *Views) Layout(g *gocui.Gui, maxX, maxY int) error {
func New(cfg config.Views, m *models.Models) *Views {
main := NewChannels(cfg.Channels, m.Channels)
return &Views{
Header: NewHeader(m.Info),
Help: NewHelp(),
Menu: NewMenu(),
Summary: NewSummary(m.Info, m.ChannelsBalance, m.WalletBalance, m.Channels),
Channels: main,
Channel: NewChannel(m.CurrentChannel),
Main: main,
Header: NewHeader(m.Info),
Help: NewHelp(),
Menu: NewMenu(),
Summary: NewSummary(m.Info, m.ChannelsBalance, m.WalletBalance, m.Channels),
Channels: main,
Channel: NewChannel(m.CurrentChannel),
Transactions: NewTransactions(m.Transactions),
Main: main,
}
}

Loading…
Cancel
Save