Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: invoice payment component #30

Merged
merged 9 commits into from
Feb 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ module github.com/ardevd/flash
go 1.21.1

require (
github.com/btcsuite/btcd/btcutil v1.1.4-0.20230904040416-d4f519f5dc05
github.com/btcsuite/btcd/btcutil v1.1.5
github.com/charmbracelet/bubbles v0.17.1
github.com/charmbracelet/bubbletea v0.25.0
github.com/charmbracelet/huh v0.2.3
github.com/charmbracelet/lipgloss v0.9.1
github.com/charmbracelet/log v0.3.1
github.com/google/tink/go v1.7.0
github.com/lightninglabs/lndclient v1.0.1-0.20240116101412-67d851af8b54
github.com/lightningnetwork/lnd v0.17.3-beta.rc1
github.com/lightningnetwork/lnd v0.17.4-beta.rc1
github.com/muesli/termenv v0.15.2
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
github.com/stretchr/testify v1.8.4
Expand All @@ -26,12 +26,12 @@ require (
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
github.com/aymerick/douceur v0.2.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/btcsuite/btcd v0.23.5-0.20230905170901-80f5a0ffdf36 // indirect
github.com/btcsuite/btcd v0.24.1-0.20240123000108-62e6af035ec5 // indirect
github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect
github.com/btcsuite/btcd/btcutil/psbt v1.1.8 // indirect
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.2 // indirect
github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 // indirect
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f // indirect
github.com/btcsuite/btcwallet v0.16.10-0.20231129183218-5df09dd43358 // indirect
github.com/btcsuite/btcwallet v0.16.10-0.20240127010340-16b422a2e8bf // indirect
github.com/btcsuite/btcwallet/wallet/txauthor v1.3.2 // indirect
github.com/btcsuite/btcwallet/wallet/txrules v1.2.0 // indirect
github.com/btcsuite/btcwallet/wallet/txsizes v1.2.3 // indirect
Expand Down Expand Up @@ -68,7 +68,7 @@ require (
github.com/google/btree v1.0.1 // indirect
github.com/google/uuid v1.3.1 // indirect
github.com/gorilla/css v1.0.0 // indirect
github.com/gorilla/websocket v1.4.2 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect
github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect
Expand Down
26 changes: 13 additions & 13 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,10 @@ github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6r
github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
github.com/btcsuite/btcd v0.22.0-beta.0.20220111032746-97732e52810c/go.mod h1:tjmYdS6MLJ5/s0Fj4DbLgSbDHbEqLJrtnHecBFkdz5M=
github.com/btcsuite/btcd v0.22.0-beta.0.20220204213055-eaf0459ff879/go.mod h1:osu7EoKiL36UThEgzYPqdRaxeo0NU8VoXqgcnwpey0g=
github.com/btcsuite/btcd v0.23.0/go.mod h1:0QJIIN1wwIXF/3G/m87gIwGniDMDQqjVn4SZgnFpsYY=
github.com/btcsuite/btcd v0.23.1/go.mod h1:0QJIIN1wwIXF/3G/m87gIwGniDMDQqjVn4SZgnFpsYY=
github.com/btcsuite/btcd v0.23.5-0.20230905170901-80f5a0ffdf36 h1:g/UbZ6iSzcUH9kEvC+rB8UBCqahmt69e8y6nCegczbg=
github.com/btcsuite/btcd v0.23.5-0.20230905170901-80f5a0ffdf36/go.mod h1:0QJIIN1wwIXF/3G/m87gIwGniDMDQqjVn4SZgnFpsYY=
github.com/btcsuite/btcd v0.23.5-0.20231215221805-96c9fd8078fd/go.mod h1:nm3Bko6zh6bWP60UxwoT5LzdGJsQJaPo6HjduXq9p6A=
github.com/btcsuite/btcd v0.24.1-0.20240123000108-62e6af035ec5 h1:8BHBWvtP6kkzvmCpyWEznq4eS0gfLOSVuXLesv413Xs=
github.com/btcsuite/btcd v0.24.1-0.20240123000108-62e6af035ec5/go.mod h1:5C8ChTkl5ejr3WHj8tkQSCmydiMEPB0ZhQhehpq7Dgg=
github.com/btcsuite/btcd/btcec/v2 v2.1.0/go.mod h1:2VzYrv4Gm4apmbVVsSq5bqf1Ec8v56E48Vt0Y/umPgA=
github.com/btcsuite/btcd/btcec/v2 v2.1.1/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE=
github.com/btcsuite/btcd/btcec/v2 v2.1.3/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE=
Expand All @@ -82,19 +82,19 @@ github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY
github.com/btcsuite/btcd/btcutil v1.0.0/go.mod h1:Uoxwv0pqYWhD//tfTiipkxNfdhG9UrLwaeswfjfdF0A=
github.com/btcsuite/btcd/btcutil v1.1.0/go.mod h1:5OapHB7A2hBBWLm48mmw4MOHNJCcUBTwmWH/0Jn8VHE=
github.com/btcsuite/btcd/btcutil v1.1.1/go.mod h1:nbKlBMNm9FGsdvKvu0essceubPiAcI57pYBNnsLAa34=
github.com/btcsuite/btcd/btcutil v1.1.4-0.20230904040416-d4f519f5dc05 h1:aemxF+69pT9sYC5E6Qj71zQVHcF72m0BNcVhCl3/thU=
github.com/btcsuite/btcd/btcutil v1.1.4-0.20230904040416-d4f519f5dc05/go.mod h1:UR7dsSJzJUfMmFiiLlIrMq1lS9jh9EdCV7FStZSnpi0=
github.com/btcsuite/btcd/btcutil v1.1.5 h1:+wER79R5670vs/ZusMTF1yTcRYE5GUsFbdjdisflzM8=
github.com/btcsuite/btcd/btcutil v1.1.5/go.mod h1:PSZZ4UitpLBWzxGd5VGOrLnmOjtPP/a6HaFo12zMs00=
github.com/btcsuite/btcd/btcutil/psbt v1.1.8 h1:4voqtT8UppT7nmKQkXV+T9K8UyQjKOn2z/ycpmJK8wg=
github.com/btcsuite/btcd/btcutil/psbt v1.1.8/go.mod h1:kA6FLH/JfUx++j9pYU0pyu+Z8XGBQuuTmuKYUf6q7/U=
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc=
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc=
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.2 h1:KdUfX2zKommPRa+PD0sWZUyXe9w277ABlgELO7H04IM=
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.2/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc=
github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 h1:59Kx4K6lzOW5w6nFlA0v5+lk/6sjybR934QNHSJZPTQ=
github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc=
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f h1:bAs4lUbRJpnnkd9VhRV3jjAVU7DJVjMaK+IsvSeZvFo=
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
github.com/btcsuite/btcwallet v0.16.10-0.20231129183218-5df09dd43358 h1:lZUSo6TISHUJQxpn/AniW5gqaN1iRNS87SDWvV3AHfg=
github.com/btcsuite/btcwallet v0.16.10-0.20231129183218-5df09dd43358/go.mod h1:WSKhOJWUmUOHKCKEzdt+jWAHFAE/t4RqVbCwL2pEdiU=
github.com/btcsuite/btcwallet v0.16.10-0.20240127010340-16b422a2e8bf h1:eNjj5R0tKP48NQxDkuKr+C9frZsdzTAemEwu75ZDQg0=
github.com/btcsuite/btcwallet v0.16.10-0.20240127010340-16b422a2e8bf/go.mod h1:LzcW/LYkQLgDufv6Ouw4cOIW0YsY+A60MTtc61/OZTU=
github.com/btcsuite/btcwallet/wallet/txauthor v1.3.2 h1:etuLgGEojecsDOYTII8rYiGHjGyV5xTqsXi+ZQ715UU=
github.com/btcsuite/btcwallet/wallet/txauthor v1.3.2/go.mod h1:Zpk/LOb2sKqwP2lmHjaZT9AdaKsHPSbNLm2Uql5IQ/0=
github.com/btcsuite/btcwallet/wallet/txrules v1.2.0 h1:BtEN5Empw62/RVnZ0VcJaVtVlBijnLlJY+dwjAye2Bg=
Expand Down Expand Up @@ -307,8 +307,8 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY=
github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c=
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
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/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw=
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho=
Expand Down Expand Up @@ -455,8 +455,8 @@ github.com/lightninglabs/protobuf-go-hex-display v1.30.0-hex-display h1:pRdza2wl
github.com/lightninglabs/protobuf-go-hex-display v1.30.0-hex-display/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
github.com/lightningnetwork/lightning-onion v1.2.1-0.20230823005744-06182b1d7d2f h1:Pua7+5TcFEJXIIZ1I2YAUapmbcttmLj4TTi786bIi3s=
github.com/lightningnetwork/lightning-onion v1.2.1-0.20230823005744-06182b1d7d2f/go.mod h1:c0kvRShutpj3l6B9WtTsNTBUtjSmjZXbJd9ZBRQOSKI=
github.com/lightningnetwork/lnd v0.17.3-beta.rc1 h1:hdYy8mcdfVOtSNQ/NPOhl+YvMdYc6IPXrdT9Ey/cvMk=
github.com/lightningnetwork/lnd v0.17.3-beta.rc1/go.mod h1:zKLs8Rb+jhXML7R9juPPNm6rjnINJ7Ry3haoM6jQeWo=
github.com/lightningnetwork/lnd v0.17.4-beta.rc1 h1:z2rb3MlSvwLMgjRl/IEMCmWCBZeFeM6cJtMxBlrgX1E=
github.com/lightningnetwork/lnd v0.17.4-beta.rc1/go.mod h1:S5hugoB/FWyF9Up9sjEnOsA/ohmhXzIqRHHMLlrtyFk=
github.com/lightningnetwork/lnd/clock v1.0.1/go.mod h1:KnQudQ6w0IAMZi1SgvecLZQZ43ra2vpDNj7H/aasemg=
github.com/lightningnetwork/lnd/clock v1.1.1 h1:OfR3/zcJd2RhH0RU+zX/77c0ZiOnIMsDIBjgjWdZgA0=
github.com/lightningnetwork/lnd/clock v1.1.1/go.mod h1:mGnAhPyjYZQJmebS7aevElXKTFDuO+uNFFfMXK1W8xQ=
Expand Down
12 changes: 10 additions & 2 deletions internal/lnd/util.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
package lnd

import "fmt"
import (
"fmt"
"strings"
)

func satsToShortString(sats float64) string {
millionSats := (sats / 1000000.0)
return fmt.Sprintf("%.1fm", millionSats)
}
}

func SantizeBoltInvoice(invoice string) string {
cleanedInvoice := strings.Replace(invoice, "lightning:", "", -1)
return cleanedInvoice
}
16 changes: 16 additions & 0 deletions internal/lnd/util_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package lnd

import (
"strings"
"testing"

"github.com/stretchr/testify/assert"
)

func TestSantizeBoltInvoice(t *testing.T) {
invoiceStr := "lightning:lnbc10u1pju83nypp5ffwgtf2hheeyxt69u5pxku8ww83nsvy5n8jenl239cx8xq2fq3nqdp8fe5kxetgv9eksgzyv4cx7umfwssyjmnkda5kxegcqzysxqr8pqsp5z6dfwhvzkjwh8tzggnh82zhjk2mx3eweysaj93eaeuxs2mevz55q9qyyssqtpv4pq5enzaqv5d7yhftzpzwtxlmtq7wacv5jz4she9lphe99fazqehzff73k7hh64stmnsk4dvhcldazxpjaz9l6fwu5al0w9nq5wspvncy4m"

cleanedInvoiceStr := SantizeBoltInvoice(invoiceStr)

assert.True(t, strings.HasPrefix(cleanedInvoiceStr, "lnbc10"))
}
9 changes: 6 additions & 3 deletions internal/tui/dashboard.go
Original file line number Diff line number Diff line change
Expand Up @@ -257,17 +257,20 @@ func (m *DashboardModel) handleFormClick(component dashboardComponent) (tea.Mode
switch component {
case paymentTools:
if m.forms[0].GetString("payments") == OPTION_PAYMENT_RECEIVE {
m.forms[0] = m.generatePaymentToolsForm()
i = newInvoiceModel(m.ctx, &m.base, m.lndService, StateNone)
} else {
i = newPayInvoiceModel(m.lndService, &m.base)
}
m.forms[0] = m.generatePaymentToolsForm()
case messageTools:
if m.forms[2].GetString("messages") == OPTION_MESSAGE_SIGN {
m.forms[2] = m.generateMessageToolsForm()

i = newSignMessageModel(m.lndService, &m.base)
} else {
m.forms[2] = m.generateMessageToolsForm()

i = newVerifyMessageModel(m.lndService, &m.base)
}
m.forms[2] = m.generateMessageToolsForm()
}

return i.Update(windowSizeMsg)
Expand Down
214 changes: 214 additions & 0 deletions internal/tui/pay_invoice.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
package tui

import (
"context"
"fmt"
"strings"

"github.com/ardevd/flash/internal/lnd"
"github.com/btcsuite/btcd/btcutil"
"github.com/charmbracelet/bubbles/key"
"github.com/charmbracelet/bubbles/spinner"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/huh"
"github.com/charmbracelet/lipgloss"
"github.com/lightninglabs/lndclient"
"github.com/lightningnetwork/lnd/routing/route"
)

// Model
type PayInvoiceModel struct {
styles *Styles
lndService *lndclient.GrpcLndServices
ctx context.Context
base *BaseModel
keys keyMap
form *huh.Form
invoiceState PaymentState
spinner spinner.Model
}

// PaymentState indicates the state of a Bolt 11 invoice payment
type PaymentState int

const (
// PaymentStateNone is when the invoice is yet to be generated
PaymentStateNone PaymentState = iota

// PaymentStateDecoded is when the invoice has been and parsed.
PaymentStateDecoded

// PaymentStateSending is when the invoice payment is sending
PaymentStateSending

// PaymentStateSettled is when the invoice has settled
PaymentStateSettled
)

// Value container
var invoiceString string

// Instantiate model
func newPayInvoiceModel(service *lndclient.GrpcLndServices, base *BaseModel) *PayInvoiceModel {
m := PayInvoiceModel{lndService: service, base: base, ctx: context.Background(), keys: Keymap}
m.styles = GetDefaultStyles()
m.base.pushView(&m)
m.form = getInvoicePaymentForm()
m.invoiceState = PaymentStateNone
s := spinner.New()
s.Spinner = spinner.Dot
s.Style = lipgloss.NewStyle().Foreground(lipgloss.Color("205"))
m.spinner = s

return &m
}

// Model update logic
func (m *PayInvoiceModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
// Handle base model events
model, cmd := m.base.Update(msg)
if model != nil {
return model, cmd
}

var cmds []tea.Cmd
switch msg := msg.(type) {
case tea.WindowSizeMsg:
windowSizeMsg = msg

case tea.KeyMsg:
switch {
// Enter will pay the invoice is model is in appropriate state
case key.Matches(msg, Keymap.Enter):
if m.form.State == huh.StateCompleted && m.invoiceState == PaymentStateNone {
m.invoiceState = PaymentStateSending
return m, paymentCreatedMsg
}
}
// Payment has been decoded and issued.
case paymentCreated:
cmds = append(cmds, m.payInvoice)
// Payment failed
case paymentError:
m.invoiceState = PaymentStateNone
// Payment has been settled
case paymentSettled:
m.invoiceState = PaymentStateSettled
}

// Tick the spinner
m.spinner, cmd = m.spinner.Update(msg)
cmds = append(cmds, cmd)

// Process the invoice form
if m.form != nil {
form, cmd := m.form.Update(msg)
if f, ok := form.(*huh.Form); ok {
m.form = f
cmds = append(cmds, cmd)
}
}

return m, tea.Batch(cmds...)
}

// Get the invoice payment form
func getInvoicePaymentForm() *huh.Form {
form := huh.NewForm(
huh.NewGroup(huh.NewNote().
Title("Pay Invoice").
Description("Pay the provided invoice"),
huh.NewInput().
Title("BOLT11 Invoice").
Prompt(">").
Value(&invoiceString)))

form.NextField()
return form
}

// Init
func (m PayInvoiceModel) Init() tea.Cmd {
return m.spinner.Tick
}

// Model view logic
func (m PayInvoiceModel) View() string {
s := m.styles
v := strings.TrimSuffix(m.form.View(), "\n")
form := lipgloss.DefaultRenderer().NewStyle().Margin(1, 0).Render(v)
if m.invoiceState == PaymentStateSending {
return lipgloss.JoinVertical(lipgloss.Left, s.BorderedStyle.Render(m.getPaymentPendingView()))
} else if m.invoiceState == PaymentStateSettled {
return lipgloss.JoinVertical(lipgloss.Left, s.BorderedStyle.Render(m.getPaymentSettledView()))
} else if m.form.State == huh.StateCompleted {
return lipgloss.JoinVertical(lipgloss.Left, s.BorderedStyle.Render(fmt.Sprintf("\n%s\n", s.HeaderText.Render("Pay Invoice?"))+
"\n"+m.decodeInvoice()))
}
return lipgloss.JoinVertical(lipgloss.Left, form)
}

// Get the Payment pending view
func (m PayInvoiceModel) getPaymentPendingView() string {

return m.styles.HeaderText.Render("Invoice in flight") + "\n\n" +
fmt.Sprintf("\n\n %s Sending payment\n\n", m.spinner.View())
}

// Get the Payment settled view
func (m PayInvoiceModel) getPaymentSettledView() string {
s := m.styles
return s.HeaderText.Render("Invoice settled") + "\n\n" +
s.PositiveString("The invoice was successfully settled") + "\n" +
"Press Esc to return"
}

// Get node name for a given public key
func (m PayInvoiceModel) getNodeName(pubkey route.Vertex) string {
nodeInfo, err := m.lndService.Client.GetNodeInfo(m.ctx, pubkey, false)
if err != nil {
return ""
}

return nodeInfo.Alias
}

// Decode an invoice string
func (m PayInvoiceModel) decodeInvoice() string {
// Decode the invoice string
invoiceString = lnd.SantizeBoltInvoice(invoiceString)
decodedInvoice, err := m.lndService.Client.DecodePaymentRequest(m.ctx, invoiceString)
if err != nil {
return "Error decoding invoice: " + err.Error()
}

amountInSats := decodedInvoice.Value.ToSatoshis()

s := m.styles
return s.Keyword("Amount: ") + amountInSats.String() + "\n" +
s.Keyword("To: ") + decodedInvoice.Destination.String() + "\n" +
s.Keyword("Node: ") + m.getNodeName(decodedInvoice.Destination) + "\n" +
s.Keyword("Description: ") + decodedInvoice.Description + "\n\n" +
s.SubKeyword("Press Enter to accept, Esc to cancel")
}

// Pay the invoice
func (m *PayInvoiceModel) payInvoice() tea.Msg {
result := m.lndService.Client.PayInvoice(m.ctx, invoiceString, btcutil.Amount(10), nil)
defer close(result)
completion := make(chan tea.Msg)

defer close(completion)
go func() {
for update := range result {
if update.Err != nil {
fmt.Println(update.Err.Error())
completion <- paymentError{}
} else {
completion <- paymentSettled{}
}
}
}()

return <-completion
}
1 change: 1 addition & 0 deletions internal/tui/tui.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ type DataLoaded lnd.NodeData
type paymentSettled struct{}
type paymentExpired struct{}
type paymentCreated struct{}
type paymentError struct{}

func GetData(service *lndclient.GrpcLndServices, ctx context.Context) lnd.NodeData {
var nodeData lnd.NodeData
Expand Down
Loading