Skip to content

Commit 3192b4d

Browse files
committed
Add watchtower client interface
Adds WtClientClient which exposes the full gRPC watchtower client interface.
1 parent b14415f commit 3192b4d

File tree

3 files changed

+210
-0
lines changed

3 files changed

+210
-0
lines changed

lnd_services.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ type LndServices struct {
180180
Router RouterClient
181181
Versioner VersionerClient
182182
State StateClient
183+
WtClient wtClientClient
183184

184185
ChainParams *chaincfg.Params
185186
NodeAlias string

macaroon_recipes.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ var (
2121
"signrpc": (*SignerClient)(nil),
2222
"verrpc": (*VersionerClient)(nil),
2323
"walletrpc": (*WalletKitClient)(nil),
24+
"wtclientrpc": (*WtClientClient)(nil),
2425
}
2526

2627
// renames is a map of renamed RPC method names. The key is the name as

wtclient_client.go

Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
package lndclient
2+
3+
import (
4+
"context"
5+
"time"
6+
7+
"github.com/lightningnetwork/lnd/lnrpc/wtclientrpc"
8+
"google.golang.org/grpc"
9+
)
10+
11+
type WtClientClient interface {
12+
ServiceClient[wtclientrpc.WatchtowerClientClient]
13+
14+
AddTower(ctx context.Context, pubkey []byte, address string) error
15+
16+
DeactivateTower(ctx context.Context, pubkey []byte) (string, error)
17+
18+
GetTowerInfo(ctx context.Context, pubkey []byte, includeSessions,
19+
excludeExhaustedSessions bool) (*wtclientrpc.Tower, error)
20+
21+
ListTowers(ctx context.Context, includeSessions,
22+
excludeExhaustedSessions bool) ([]*wtclientrpc.Tower, error)
23+
24+
Policy(ctx context.Context, policyType wtclientrpc.PolicyType) (*PolicyResponse, error)
25+
26+
RemoveTower(ctx context.Context, pubkey []byte, address string) error
27+
28+
Stats(ctx context.Context) (*StatsResponse, error)
29+
30+
TerminateSession(ctx context.Context, sessionId []byte) (string, error)
31+
}
32+
33+
type PolicyResponse struct {
34+
maxUpdates uint32
35+
sweepSatPerVbyte uint32
36+
}
37+
38+
type StatsResponse struct {
39+
numBackups uint32
40+
numPendingBackups uint32
41+
numFailedBackups uint32
42+
numSessionsAcquired uint32
43+
numSessionsExhausted uint32
44+
}
45+
46+
type wtClientClient struct {
47+
client wtclientrpc.WatchtowerClientClient
48+
wtClientMac serializedMacaroon
49+
timeout time.Duration
50+
}
51+
52+
// A compile time check to ensure that wtClientClient implements the
53+
// WtclientClient interface.
54+
var _ WtClientClient = (*wtClientClient)(nil)
55+
56+
func newWtClientClient(conn grpc.ClientConnInterface,
57+
wtClientMac serializedMacaroon, timeout time.Duration) *wtClientClient {
58+
59+
return &wtClientClient{
60+
client: wtclientrpc.NewWatchtowerClientClient(conn),
61+
wtClientMac: wtClientMac,
62+
timeout: timeout,
63+
}
64+
}
65+
66+
// RawClientWithMacAuth returns a context with the proper macaroon
67+
// authentication, the default RPC timeout, and the raw client.
68+
func (m *wtClientClient) RawClientWithMacAuth(
69+
parentCtx context.Context) (context.Context, time.Duration,
70+
wtclientrpc.WatchtowerClientClient) {
71+
72+
return m.wtClientMac.WithMacaroonAuth(parentCtx), m.timeout, m.client
73+
}
74+
75+
func (m *wtClientClient) AddTower(ctx context.Context, pubkey []byte, address string) error {
76+
rpcCtx, cancel := context.WithTimeout(ctx, m.timeout)
77+
defer cancel()
78+
79+
rpcReq := &wtclientrpc.AddTowerRequest{
80+
Pubkey: pubkey,
81+
Address: address,
82+
}
83+
84+
rpcCtx = m.wtClientMac.WithMacaroonAuth(rpcCtx)
85+
_, err := m.client.AddTower(rpcCtx, rpcReq)
86+
if err != nil {
87+
return err
88+
}
89+
90+
return nil
91+
}
92+
93+
func (m *wtClientClient) DeactivateTower(ctx context.Context, pubkey []byte) (string, error) {
94+
rpcCtx, cancel := context.WithTimeout(ctx, m.timeout)
95+
defer cancel()
96+
97+
rpcCtx = m.wtClientMac.WithMacaroonAuth(rpcCtx)
98+
resp, err := m.client.DeactivateTower(rpcCtx, &wtclientrpc.DeactivateTowerRequest{
99+
Pubkey: pubkey,
100+
})
101+
if err != nil {
102+
return "", err
103+
}
104+
105+
return resp.Status, nil
106+
}
107+
108+
func (m *wtClientClient) GetTowerInfo(ctx context.Context, pubkey []byte, includeSessions,
109+
excludeExhaustedSessions bool) (*wtclientrpc.Tower, error) {
110+
rpcCtx, cancel := context.WithTimeout(ctx, m.timeout)
111+
defer cancel()
112+
113+
rpcCtx = m.wtClientMac.WithMacaroonAuth(rpcCtx)
114+
resp, err := m.client.GetTowerInfo(rpcCtx, &wtclientrpc.GetTowerInfoRequest{
115+
Pubkey: pubkey,
116+
IncludeSessions: includeSessions,
117+
ExcludeExhaustedSessions: excludeExhaustedSessions,
118+
})
119+
if err != nil {
120+
return nil, err
121+
}
122+
123+
return resp, nil
124+
}
125+
126+
func (m *wtClientClient) ListTowers(ctx context.Context, includeSessions,
127+
excludeExhaustedSessions bool) ([]*wtclientrpc.Tower, error) {
128+
rpcCtx, cancel := context.WithTimeout(ctx, m.timeout)
129+
defer cancel()
130+
131+
rpcCtx = m.wtClientMac.WithMacaroonAuth(rpcCtx)
132+
resp, err := m.client.ListTowers(rpcCtx, &wtclientrpc.ListTowersRequest{
133+
IncludeSessions: includeSessions,
134+
ExcludeExhaustedSessions: excludeExhaustedSessions,
135+
})
136+
if err != nil {
137+
return nil, err
138+
}
139+
140+
return resp.Towers, nil
141+
}
142+
143+
func (m *wtClientClient) Policy(ctx context.Context, policyType wtclientrpc.PolicyType) (*PolicyResponse, error) {
144+
rpcCtx, cancel := context.WithTimeout(ctx, m.timeout)
145+
defer cancel()
146+
147+
rpcCtx = m.wtClientMac.WithMacaroonAuth(rpcCtx)
148+
resp, err := m.client.Policy(rpcCtx, &wtclientrpc.PolicyRequest{
149+
PolicyType: policyType,
150+
})
151+
if err != nil {
152+
return nil, err
153+
}
154+
155+
return &PolicyResponse{
156+
maxUpdates: resp.MaxUpdates,
157+
sweepSatPerVbyte: resp.SweepSatPerVbyte,
158+
}, nil
159+
}
160+
func (m *wtClientClient) RemoveTower(ctx context.Context, pubkey []byte, address string) error {
161+
rpcCtx, cancel := context.WithTimeout(ctx, m.timeout)
162+
defer cancel()
163+
164+
rpcCtx = m.wtClientMac.WithMacaroonAuth(rpcCtx)
165+
_, err := m.client.RemoveTower(rpcCtx, &wtclientrpc.RemoveTowerRequest{
166+
Pubkey: pubkey,
167+
Address: address,
168+
})
169+
if err != nil {
170+
return err
171+
}
172+
173+
return nil
174+
}
175+
176+
func (m *wtClientClient) Stats(ctx context.Context) (*StatsResponse, error) {
177+
rpcCtx, cancel := context.WithTimeout(ctx, m.timeout)
178+
defer cancel()
179+
180+
rpcCtx = m.wtClientMac.WithMacaroonAuth(rpcCtx)
181+
resp, err := m.client.Stats(rpcCtx, &wtclientrpc.StatsRequest{})
182+
if err != nil {
183+
return nil, err
184+
}
185+
186+
return &StatsResponse{
187+
numBackups: resp.NumBackups,
188+
numPendingBackups: resp.NumPendingBackups,
189+
numFailedBackups: resp.NumFailedBackups,
190+
numSessionsAcquired: resp.NumSessionsAcquired,
191+
numSessionsExhausted: resp.NumSessionsExhausted,
192+
}, nil
193+
}
194+
195+
func (m *wtClientClient) TerminateSession(ctx context.Context, sessionId []byte) (string, error) {
196+
rpcCtx, cancel := context.WithTimeout(ctx, m.timeout)
197+
defer cancel()
198+
199+
rpcCtx = m.wtClientMac.WithMacaroonAuth(rpcCtx)
200+
resp, err := m.client.TerminateSession(rpcCtx, &wtclientrpc.TerminateSessionRequest{
201+
SessionId: sessionId,
202+
})
203+
if err != nil {
204+
return "", err
205+
}
206+
207+
return resp.Status, nil
208+
}

0 commit comments

Comments
 (0)