Skip to content

Commit 6ea560e

Browse files
committed
loopd: static address withdrawals support
1 parent 9e9daa2 commit 6ea560e

File tree

3 files changed

+112
-0
lines changed

3 files changed

+112
-0
lines changed

loopd/daemon.go

+41
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
loop_looprpc "github.com/lightninglabs/loop/looprpc"
2424
"github.com/lightninglabs/loop/staticaddr/address"
2525
"github.com/lightninglabs/loop/staticaddr/deposit"
26+
"github.com/lightninglabs/loop/staticaddr/withdraw"
2627
loop_swaprpc "github.com/lightninglabs/loop/swapserverrpc"
2728
"github.com/lightninglabs/loop/sweepbatcher"
2829
"github.com/lightningnetwork/lnd/clock"
@@ -511,6 +512,7 @@ func (d *Daemon) initialize(withMacaroonService bool) error {
511512

512513
staticAddressManager *address.Manager
513514
depositManager *deposit.Manager
515+
withdrawalManager *withdraw.Manager
514516
)
515517
// Create the reservation and instantout managers.
516518
if d.cfg.EnableExperimental {
@@ -575,6 +577,18 @@ func (d *Daemon) initialize(withMacaroonService bool) error {
575577
Signer: d.lnd.Signer,
576578
}
577579
depositManager = deposit.NewManager(depoCfg)
580+
581+
// Static address deposit withdrawal manager setup.
582+
withdrawalCfg := &withdraw.ManagerConfig{
583+
StaticAddressServerClient: staticAddressClient,
584+
AddressManager: staticAddressManager,
585+
DepositManager: depositManager,
586+
WalletKit: d.lnd.WalletKit,
587+
ChainParams: d.lnd.ChainParams,
588+
ChainNotifier: d.lnd.ChainNotifier,
589+
Signer: d.lnd.Signer,
590+
}
591+
withdrawalManager = withdraw.NewManager(withdrawalCfg)
578592
}
579593

580594
// Now finally fully initialize the swap client RPC server instance.
@@ -592,6 +606,7 @@ func (d *Daemon) initialize(withMacaroonService bool) error {
592606
instantOutManager: instantOutManager,
593607
staticAddressManager: staticAddressManager,
594608
depositManager: depositManager,
609+
withdrawalManager: withdrawalManager,
595610
}
596611

597612
// Retrieve all currently existing swaps from the database.
@@ -723,6 +738,32 @@ func (d *Daemon) initialize(withMacaroonService bool) error {
723738
depositManager.WaitInitComplete()
724739
}
725740

741+
// Start the static address deposit withdrawal manager.
742+
if withdrawalManager != nil {
743+
d.wg.Add(1)
744+
go func() {
745+
defer d.wg.Done()
746+
747+
// Lnd's GetInfo call supplies us with the current block
748+
// height.
749+
info, err := d.lnd.Client.GetInfo(d.mainCtx)
750+
if err != nil {
751+
d.internalErrChan <- err
752+
return
753+
}
754+
755+
log.Info("Starting static address deposit withdrawal " +
756+
"manager...")
757+
err = withdrawalManager.Run(d.mainCtx, info.BlockHeight)
758+
if err != nil && !errors.Is(context.Canceled, err) {
759+
d.internalErrChan <- err
760+
}
761+
log.Info("Static address deposit withdrawal manager " +
762+
"stopped")
763+
}()
764+
withdrawalManager.WaitInitComplete()
765+
}
766+
726767
// Last, start our internal error handler. This will return exactly one
727768
// error or nil on the main error channel to inform the caller that
728769
// something went wrong or that shutdown is complete. We don't add to

loopd/perms/perms.go

+7
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,13 @@ var RequiredPermissions = map[string][]bakery.Op{
8787
Entity: "loop",
8888
Action: "in",
8989
}},
90+
"/looprpc.SwapClient/WithdrawDeposits": {{
91+
Entity: "swap",
92+
Action: "execute",
93+
}, {
94+
Entity: "loop",
95+
Action: "in",
96+
}},
9097
"/looprpc.SwapClient/GetLsatTokens": {{
9198
Entity: "auth",
9299
Action: "read",

loopd/swapclient_server.go

+64
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"github.com/btcsuite/btcd/btcec/v2"
1616
"github.com/btcsuite/btcd/btcutil"
1717
"github.com/btcsuite/btcd/chaincfg"
18+
"github.com/btcsuite/btcd/wire"
1819
"github.com/lightninglabs/aperture/l402"
1920
"github.com/lightninglabs/lndclient"
2021
"github.com/lightninglabs/loop"
@@ -26,6 +27,7 @@ import (
2627
clientrpc "github.com/lightninglabs/loop/looprpc"
2728
"github.com/lightninglabs/loop/staticaddr/address"
2829
"github.com/lightninglabs/loop/staticaddr/deposit"
30+
"github.com/lightninglabs/loop/staticaddr/withdraw"
2931
"github.com/lightninglabs/loop/swap"
3032
looprpc "github.com/lightninglabs/loop/swapserverrpc"
3133
"github.com/lightningnetwork/lnd/lnrpc/walletrpc"
@@ -87,6 +89,7 @@ type swapClientServer struct {
8789
instantOutManager *instantout.Manager
8890
staticAddressManager *address.Manager
8991
depositManager *deposit.Manager
92+
withdrawalManager *withdraw.Manager
9093
swaps map[lntypes.Hash]loop.SwapInfo
9194
subscribers map[int]chan<- interface{}
9295
statusChan chan loop.SwapInfo
@@ -1348,6 +1351,67 @@ func (s *swapClientServer) ListUnspentDeposits(ctx context.Context,
13481351
return &clientrpc.ListUnspentDepositsResponse{Utxos: respUtxos}, nil
13491352
}
13501353

1354+
// WithdrawDeposits tries to obtain a partial signature from the server to spend
1355+
// the selected deposits to the client's wallet.
1356+
func (s *swapClientServer) WithdrawDeposits(ctx context.Context,
1357+
req *clientrpc.WithdrawDepositsRequest) (
1358+
*clientrpc.WithdrawDepositsResponse, error) {
1359+
1360+
var (
1361+
isAllSelected = req.All
1362+
isUtxoSelected = len(req.Outpoints) > 0
1363+
outpoints []wire.OutPoint
1364+
err error
1365+
)
1366+
1367+
switch {
1368+
case isAllSelected == isUtxoSelected:
1369+
return nil, fmt.Errorf("must select either all or some utxos")
1370+
1371+
case isAllSelected:
1372+
deposits, err := s.depositManager.GetActiveDepositsInState(
1373+
deposit.Deposited,
1374+
)
1375+
if err != nil {
1376+
return nil, err
1377+
}
1378+
1379+
for _, d := range deposits {
1380+
outpoints = append(outpoints, d.OutPoint)
1381+
}
1382+
1383+
case isUtxoSelected:
1384+
outpoints, err = toServerOutpoints(req.Outpoints)
1385+
if err != nil {
1386+
return nil, err
1387+
}
1388+
}
1389+
1390+
err = s.withdrawalManager.WithdrawDeposits(ctx, outpoints)
1391+
if err != nil {
1392+
return nil, err
1393+
}
1394+
1395+
return &clientrpc.WithdrawDepositsResponse{}, err
1396+
}
1397+
1398+
func toServerOutpoints(outpoints []*clientrpc.OutPoint) ([]wire.OutPoint,
1399+
error) {
1400+
1401+
var serverOutpoints []wire.OutPoint
1402+
for _, o := range outpoints {
1403+
outpointStr := fmt.Sprintf("%s:%d", o.TxidStr, o.OutputIndex)
1404+
newOutpoint, err := wire.NewOutPointFromString(outpointStr)
1405+
if err != nil {
1406+
return nil, err
1407+
}
1408+
1409+
serverOutpoints = append(serverOutpoints, *newOutpoint)
1410+
}
1411+
1412+
return serverOutpoints, nil
1413+
}
1414+
13511415
func rpcAutoloopReason(reason liquidity.Reason) (clientrpc.AutoReason, error) {
13521416
switch reason {
13531417
case liquidity.ReasonNone:

0 commit comments

Comments
 (0)