Skip to content

Commit bd2d39b

Browse files
authored
Merge pull request #203 from bhandras/lndclient_extension
lndclient: extend LightningClient with ListChannels and RouterClient with keysend
2 parents 3316c4b + cf9c374 commit bd2d39b

File tree

4 files changed

+95
-1
lines changed

4 files changed

+95
-1
lines changed

lndclient/lightning_client.go

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717
"github.com/lightningnetwork/lnd/lnrpc/invoicesrpc"
1818
"github.com/lightningnetwork/lnd/lntypes"
1919
"github.com/lightningnetwork/lnd/lnwire"
20+
"github.com/lightningnetwork/lnd/routing/route"
2021
"github.com/lightningnetwork/lnd/zpay32"
2122
"google.golang.org/grpc"
2223
"google.golang.org/grpc/codes"
@@ -46,6 +47,9 @@ type LightningClient interface {
4647
// node.
4748
ListTransactions(ctx context.Context) ([]*wire.MsgTx, error)
4849

50+
// ListChannels retrieves all channels of the backing lnd node.
51+
ListChannels(ctx context.Context) ([]ChannelInfo, error)
52+
4953
// ChannelBackup retrieves the backup for a particular channel. The
5054
// backup is returned as an encrypted chanbackup.Single payload.
5155
ChannelBackup(context.Context, wire.OutPoint) ([]byte, error)
@@ -65,6 +69,29 @@ type Info struct {
6569
Uris []string
6670
}
6771

72+
// ChannelInfo stores unpacked per-channel info.
73+
type ChannelInfo struct {
74+
// Active indecates whether the channel is active.
75+
Active bool
76+
77+
// ChannelID holds the unique channel ID for the channel. The first 3 bytes
78+
// are the block height, the next 3 the index within the block, and the last
79+
// 2 bytes are the /output index for the channel.
80+
ChannelID uint64
81+
82+
// PubKeyBytes is the raw bytes of the public key of the remote node.
83+
PubKeyBytes route.Vertex
84+
85+
// Capacity is the total amount of funds held in this channel.
86+
Capacity btcutil.Amount
87+
88+
// LocalBalance is the current balance of this node in this channel.
89+
LocalBalance btcutil.Amount
90+
91+
// RemoteBalance is the counterparty's current balance in this channel.
92+
RemoteBalance btcutil.Amount
93+
}
94+
6895
var (
6996
// ErrMalformedServerResponse is returned when the swap and/or prepay
7097
// invoice is malformed.
@@ -495,6 +522,41 @@ func (s *lightningClient) ListTransactions(ctx context.Context) ([]*wire.MsgTx,
495522
return txs, nil
496523
}
497524

525+
// ListChannels retrieves all channels of the backing lnd node.
526+
func (s *lightningClient) ListChannels(ctx context.Context) (
527+
[]ChannelInfo, error) {
528+
529+
rpcCtx, cancel := context.WithTimeout(ctx, rpcTimeout)
530+
defer cancel()
531+
532+
response, err := s.client.ListChannels(
533+
s.adminMac.WithMacaroonAuth(rpcCtx),
534+
&lnrpc.ListChannelsRequest{},
535+
)
536+
if err != nil {
537+
return nil, err
538+
}
539+
540+
result := make([]ChannelInfo, len(response.Channels))
541+
for i, channel := range response.Channels {
542+
remoteVertex, err := route.NewVertexFromStr(channel.RemotePubkey)
543+
if err != nil {
544+
return nil, err
545+
}
546+
547+
result[i] = ChannelInfo{
548+
Active: channel.Active,
549+
ChannelID: channel.ChanId,
550+
PubKeyBytes: remoteVertex,
551+
Capacity: btcutil.Amount(channel.Capacity),
552+
LocalBalance: btcutil.Amount(channel.LocalBalance),
553+
RemoteBalance: btcutil.Amount(channel.RemoteBalance),
554+
}
555+
}
556+
557+
return result, nil
558+
}
559+
498560
// ChannelBackup retrieves the backup for a particular channel. The backup is
499561
// returned as an encrypted chanbackup.Single payload.
500562
func (s *lightningClient) ChannelBackup(ctx context.Context,

lndclient/router_client.go

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package lndclient
22

33
import (
44
"context"
5+
"crypto/rand"
56
"encoding/hex"
67
"fmt"
78
"time"
@@ -12,6 +13,7 @@ import (
1213
"github.com/lightningnetwork/lnd/lnrpc/routerrpc"
1314
"github.com/lightningnetwork/lnd/lntypes"
1415
"github.com/lightningnetwork/lnd/lnwire"
16+
"github.com/lightningnetwork/lnd/record"
1517
"github.com/lightningnetwork/lnd/routing/route"
1618
"github.com/lightningnetwork/lnd/zpay32"
1719
"google.golang.org/grpc"
@@ -88,7 +90,7 @@ type SendPaymentRequest struct {
8890

8991
// PaymentHash is the r-hash value to use within the HTLC extended to
9092
// the first hop.
91-
PaymentHash [32]byte
93+
PaymentHash *lntypes.Hash
9294

9395
// FinalCLTVDelta is the CTLV expiry delta to use for the _final_ hop
9496
// in the route. This means that the final hop will have a CLTV delta
@@ -112,6 +114,9 @@ type SendPaymentRequest struct {
112114
// MaxParts is the maximum number of partial payments that may be used
113115
// to complete the full amount.
114116
MaxParts uint32
117+
118+
// KeySend is set to true if the tlv payload will include the preimage.
119+
KeySend bool
115120
}
116121

117122
// routerClient is a wrapper around the generated routerrpc proxy.
@@ -149,6 +154,24 @@ func (r *routerClient) SendPayment(ctx context.Context,
149154
if request.LastHopPubkey != nil {
150155
rpcReq.LastHopPubkey = request.LastHopPubkey[:]
151156
}
157+
if request.KeySend {
158+
if request.PaymentHash != nil {
159+
return nil, nil, fmt.Errorf(
160+
"keysend payment must not include a preset payment hash")
161+
}
162+
163+
var preimage lntypes.Preimage
164+
if _, err := rand.Read(preimage[:]); err != nil {
165+
return nil, nil, err
166+
}
167+
168+
// Override the payment hash.
169+
rpcReq.DestCustomRecords = map[uint64][]byte{
170+
record.KeySendType: preimage[:],
171+
}
172+
hash := preimage.Hash()
173+
request.PaymentHash = &hash
174+
}
152175

153176
// Only if there is no payment request set, we will parse the individual
154177
// payment parameters.

test/lightning_client_mock.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,13 @@ func (h *mockLightningClient) ListTransactions(
168168
return txs, nil
169169
}
170170

171+
// ListChannels retrieves all channels of the backing lnd node.
172+
func (h *mockLightningClient) ListChannels(ctx context.Context) (
173+
[]lndclient.ChannelInfo, error) {
174+
175+
return h.lnd.Channels, nil
176+
}
177+
171178
// ChannelBackup retrieves the backup for a particular channel. The
172179
// backup is returned as an encrypted chanbackup.Single payload.
173180
func (h *mockLightningClient) ChannelBackup(context.Context, wire.OutPoint) ([]byte, error) {

test/lnd_services_mock.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,8 @@ type LndMockServices struct {
163163
// keyed by hash string.
164164
Invoices map[lntypes.Hash]*lndclient.Invoice
165165

166+
Channels []lndclient.ChannelInfo
167+
166168
WaitForFinished func()
167169

168170
lock sync.Mutex

0 commit comments

Comments
 (0)