staticaddr: cmd listdeposits and listswaps

This commit is contained in:
Slyghtning 2024-11-05 10:15:10 +01:00
parent a3f7fe44af
commit 439d178b96
No known key found for this signature in database
GPG key ID: F82D456EA023C9BF
11 changed files with 1717 additions and 183 deletions

View file

@ -139,8 +139,8 @@ func quoteIn(ctx *cli.Context) error {
func depositAmount(ctx context.Context, client looprpc.SwapClientClient,
depositOutpoints []string) (btcutil.Amount, error) {
addressSummary, err := client.GetStaticAddressSummary(
ctx, &looprpc.StaticAddressSummaryRequest{
addressSummary, err := client.ListStaticAddressDeposits(
ctx, &looprpc.ListStaticAddressDepositsRequest{
Outpoints: depositOutpoints,
},
)

View file

@ -11,6 +11,7 @@ import (
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/lightninglabs/loop/labels"
"github.com/lightninglabs/loop/looprpc"
"github.com/lightninglabs/loop/staticaddr/deposit"
"github.com/lightninglabs/loop/staticaddr/loopin"
"github.com/lightninglabs/loop/swapserverrpc"
"github.com/lightningnetwork/lnd/routing/route"
@ -24,6 +25,8 @@ var staticAddressCommands = cli.Command{
Subcommands: []cli.Command{
newStaticAddressCommand,
listUnspentCommand,
listDepositsCommand,
listStaticAddressSwapsCommand,
withdrawalCommand,
summaryCommand,
},
@ -217,6 +220,36 @@ func withdraw(ctx *cli.Context) error {
return nil
}
var listDepositsCommand = cli.Command{
Name: "listdeposits",
Usage: "Display a summary of static address related information.",
Description: `
`,
Flags: []cli.Flag{
cli.StringFlag{
Name: "filter",
Usage: "specify a filter to only display deposits in " +
"the specified state. Leaving out the filter " +
"returns all deposits.\nThe state can be one " +
"of the following: \n" +
"deposited\nwithdrawing\nwithdrawn\n" +
"looping_in\nlooped_in\n" +
"publish_expired_deposit\n" +
"sweep_htlc_timeout\nhtlc_timeout_swept\n" +
"wait_for_expiry_sweep\nexpired\nfailed\n.",
},
},
Action: listDeposits,
}
var listStaticAddressSwapsCommand = cli.Command{
Name: "listswaps",
Usage: "Display a summary of static address related information.",
Description: `
`,
Action: listStaticAddressSwaps,
}
var summaryCommand = cli.Command{
Name: "summary",
ShortName: "s",
@ -242,10 +275,10 @@ var summaryCommand = cli.Command{
Action: summary,
}
func summary(ctx *cli.Context) error {
func listDeposits(ctx *cli.Context) error {
ctxb := context.Background()
if ctx.NArg() > 0 {
return cli.ShowCommandHelp(ctx, "summary")
return cli.ShowCommandHelp(ctx, "listdeposits")
}
client, cleanup, err := getClient(ctx)
@ -293,8 +326,8 @@ func summary(ctx *cli.Context) error {
filterState = looprpc.DepositState_UNKNOWN_STATE
}
resp, err := client.GetStaticAddressSummary(
ctxb, &looprpc.StaticAddressSummaryRequest{
resp, err := client.ListStaticAddressDeposits(
ctxb, &looprpc.ListStaticAddressDepositsRequest{
StateFilter: filterState,
},
)
@ -307,6 +340,54 @@ func summary(ctx *cli.Context) error {
return nil
}
func listStaticAddressSwaps(ctx *cli.Context) error {
ctxb := context.Background()
if ctx.NArg() > 0 {
return cli.ShowCommandHelp(ctx, "listswaps")
}
client, cleanup, err := getClient(ctx)
if err != nil {
return err
}
defer cleanup()
resp, err := client.ListStaticAddressSwaps(
ctxb, &looprpc.ListStaticAddressSwapsRequest{},
)
if err != nil {
return err
}
printRespJSON(resp)
return nil
}
func summary(ctx *cli.Context) error {
ctxb := context.Background()
if ctx.NArg() > 0 {
return cli.ShowCommandHelp(ctx, "summary")
}
client, cleanup, err := getClient(ctx)
if err != nil {
return err
}
defer cleanup()
resp, err := client.GetStaticAddressSummary(
ctxb, &looprpc.StaticAddressSummaryRequest{},
)
if err != nil {
return err
}
printRespJSON(resp)
return nil
}
func utxosToOutpoints(utxos []string) ([]*looprpc.OutPoint, error) {
outpoints := make([]*looprpc.OutPoint, 0, len(utxos))
if len(utxos) == 0 {
@ -391,8 +472,8 @@ func staticAddressLoopIn(ctx *cli.Context) error {
}
// Get the amount we need to quote for.
summaryResp, err := client.GetStaticAddressSummary(
ctxb, &looprpc.StaticAddressSummaryRequest{
depositList, err := client.ListStaticAddressDeposits(
ctxb, &looprpc.ListStaticAddressDepositsRequest{
StateFilter: looprpc.DepositState_DEPOSITED,
},
)
@ -400,6 +481,14 @@ func staticAddressLoopIn(ctx *cli.Context) error {
return err
}
if len(depositList.FilteredDeposits) == 0 {
errString := fmt.Sprintf("no confirmed deposits available, "+
"deposits need at least %v confirmations",
deposit.DefaultConfTarget)
return errors.New(errString)
}
var depositOutpoints []string
switch {
case isAllSelected == isUtxoSelected:
@ -407,7 +496,7 @@ func staticAddressLoopIn(ctx *cli.Context) error {
case isAllSelected:
depositOutpoints = depositsToOutpoints(
summaryResp.FilteredDeposits,
depositList.FilteredDeposits,
)
case isUtxoSelected:
@ -437,7 +526,7 @@ func staticAddressLoopIn(ctx *cli.Context) error {
// populate the quote request with the sum of selected deposits and
// prompt the user for acceptance.
quoteReq.Amt, err = sumDeposits(
depositOutpoints, summaryResp.FilteredDeposits,
depositOutpoints, depositList.FilteredDeposits,
)
if err != nil {
return err

View file

@ -94,6 +94,20 @@ var RequiredPermissions = map[string][]bakery.Op{
Entity: "loop",
Action: "in",
}},
"/looprpc.SwapClient/ListStaticAddressDeposits": {{
Entity: "swap",
Action: "read",
}, {
Entity: "loop",
Action: "in",
}},
"/looprpc.SwapClient/ListStaticAddressSwaps": {{
Entity: "swap",
Action: "read",
}, {
Entity: "loop",
Action: "in",
}},
"/looprpc.SwapClient/GetStaticAddressSummary": {{
Entity: "swap",
Action: "read",

View file

@ -763,11 +763,11 @@ func (s *swapClientServer) GetLoopInQuote(ctx context.Context,
}
// Retrieve deposits to calculate their total value.
var summary *looprpc.StaticAddressSummaryResponse
var depositList *looprpc.ListStaticAddressDepositsResponse
amount := btcutil.Amount(req.Amt)
if len(req.DepositOutpoints) > 0 {
summary, err = s.GetStaticAddressSummary(
ctx, &looprpc.StaticAddressSummaryRequest{
depositList, err = s.ListStaticAddressDeposits(
ctx, &looprpc.ListStaticAddressDepositsRequest{
Outpoints: req.DepositOutpoints,
},
)
@ -775,14 +775,14 @@ func (s *swapClientServer) GetLoopInQuote(ctx context.Context,
return nil, err
}
if summary == nil {
if depositList == nil {
return nil, fmt.Errorf("no summary returned for " +
"deposit outpoints")
}
// The requested amount should be 0 here if the request
// contained deposit outpoints.
if amount != 0 && len(summary.FilteredDeposits) > 0 {
if amount != 0 && len(depositList.FilteredDeposits) > 0 {
return nil, fmt.Errorf("amount should be 0 for " +
"deposit quotes")
}
@ -790,8 +790,8 @@ func (s *swapClientServer) GetLoopInQuote(ctx context.Context,
// In case we quote for deposits we send the server both the
// total value and the number of deposits. This is so the server
// can probe the total amount and calculate the per input fee.
if amount == 0 && len(summary.FilteredDeposits) > 0 {
for _, deposit := range summary.FilteredDeposits {
if amount == 0 && len(depositList.FilteredDeposits) > 0 {
for _, deposit := range depositList.FilteredDeposits {
amount += btcutil.Amount(deposit.Value)
}
}
@ -1459,15 +1459,16 @@ func (s *swapClientServer) WithdrawDeposits(ctx context.Context,
}, err
}
// GetStaticAddressSummary returns a summary static address related information.
// Amongst deposits and withdrawals and their total values it also includes a
// list of detailed deposit information filtered by their state.
func (s *swapClientServer) GetStaticAddressSummary(ctx context.Context,
req *looprpc.StaticAddressSummaryRequest) (
*looprpc.StaticAddressSummaryResponse, error) {
// ListStaticAddressDeposits returns a list of all sufficiently confirmed
// deposits behind the static address and displays properties like value,
// state or blocks til expiry.
func (s *swapClientServer) ListStaticAddressDeposits(ctx context.Context,
req *looprpc.ListStaticAddressDepositsRequest) (
*looprpc.ListStaticAddressDepositsResponse, error) {
outpoints := req.Outpoints
if req.StateFilter != looprpc.DepositState_UNKNOWN_STATE &&
len(req.Outpoints) > 0 {
len(outpoints) > 0 {
return nil, fmt.Errorf("can either filter by state or " +
"outpoints")
@ -1478,9 +1479,181 @@ func (s *swapClientServer) GetStaticAddressSummary(ctx context.Context,
return nil, err
}
return s.depositSummary(
ctx, allDeposits, req.StateFilter, req.Outpoints,
// Deposits filtered by state or outpoints.
var filteredDeposits []*looprpc.Deposit
if len(outpoints) > 0 {
f := func(d *deposit.Deposit) bool {
for _, outpoint := range outpoints {
if outpoint == d.OutPoint.String() {
return true
}
}
return false
}
filteredDeposits = filter(allDeposits, f)
if len(outpoints) != len(filteredDeposits) {
return nil, fmt.Errorf("not all outpoints found in " +
"deposits")
}
} else {
f := func(d *deposit.Deposit) bool {
if req.StateFilter == looprpc.DepositState_UNKNOWN_STATE {
// Per default, we return deposits in all
// states.
return true
}
return d.IsInState(toServerState(req.StateFilter))
}
filteredDeposits = filter(allDeposits, f)
}
// Calculate the blocks until expiry for each deposit.
lndInfo, err := s.lnd.Client.GetInfo(ctx)
if err != nil {
return nil, err
}
bestBlockHeight := int64(lndInfo.BlockHeight)
params, err := s.staticAddressManager.GetStaticAddressParameters(ctx)
if err != nil {
return nil, err
}
for i := 0; i < len(filteredDeposits); i++ {
filteredDeposits[i].BlocksUntilExpiry =
filteredDeposits[i].ConfirmationHeight +
int64(params.Expiry) - bestBlockHeight
}
return &looprpc.ListStaticAddressDepositsResponse{
FilteredDeposits: filteredDeposits,
}, nil
}
// ListStaticAddressSwaps returns a list of all swaps that are currently pending
// or previously succeeded.
func (s *swapClientServer) ListStaticAddressSwaps(ctx context.Context,
_ *looprpc.ListStaticAddressSwapsRequest) (
*looprpc.ListStaticAddressSwapsResponse, error) {
swaps, err := s.staticLoopInManager.GetAllSwaps(ctx)
if err != nil {
return nil, err
}
if len(swaps) == 0 {
return &looprpc.ListStaticAddressSwapsResponse{}, nil
}
var clientSwaps []*looprpc.StaticAddressLoopInSwap
for _, swp := range swaps {
chainParams, err := s.network.ChainParams()
if err != nil {
return nil, fmt.Errorf("error getting chain params")
}
swapPayReq, err := zpay32.Decode(swp.SwapInvoice, chainParams)
if err != nil {
return nil, fmt.Errorf("error decoding swap invoice: "+
"%v", err)
}
swap := &looprpc.StaticAddressLoopInSwap{
SwapHash: swp.SwapHash[:],
DepositOutpoints: swp.DepositOutpoints,
State: toClientStaticAddressLoopInState(
swp.GetState(),
),
SwapAmountSatoshis: int64(swp.TotalDepositAmount()),
PaymentRequestAmountSatoshis: int64(
swapPayReq.MilliSat.ToSatoshis(),
),
}
clientSwaps = append(clientSwaps, swap)
}
return &looprpc.ListStaticAddressSwapsResponse{
Swaps: clientSwaps,
}, nil
}
// GetStaticAddressSummary returns a summary static address related information.
// Amongst deposits and withdrawals and their total values it also includes a
// list of detailed deposit information filtered by their state.
func (s *swapClientServer) GetStaticAddressSummary(ctx context.Context,
_ *looprpc.StaticAddressSummaryRequest) (
*looprpc.StaticAddressSummaryResponse, error) {
allDeposits, err := s.depositManager.GetAllDeposits(ctx)
if err != nil {
return nil, err
}
var (
totalNumDeposits = len(allDeposits)
valueUnconfirmed int64
valueDeposited int64
valueExpired int64
valueWithdrawn int64
valueLoopedIn int64
htlcTimeoutSwept int64
)
// Value unconfirmed.
utxos, err := s.staticAddressManager.ListUnspent(
ctx, 0, deposit.MinConfs-1,
)
if err != nil {
return nil, err
}
for _, u := range utxos {
valueUnconfirmed += int64(u.Value)
}
// Confirmed total values by category.
for _, d := range allDeposits {
value := int64(d.Value)
switch d.GetState() {
case deposit.Deposited:
valueDeposited += value
case deposit.Expired:
valueExpired += value
case deposit.Withdrawn:
valueWithdrawn += value
case deposit.LoopedIn:
valueLoopedIn += value
case deposit.HtlcTimeoutSwept:
htlcTimeoutSwept += value
}
}
params, err := s.staticAddressManager.GetStaticAddressParameters(ctx)
if err != nil {
return nil, err
}
address, err := s.staticAddressManager.GetTaprootAddress(
params.ClientPubkey, params.ServerPubkey, int64(params.Expiry),
)
if err != nil {
return nil, err
}
return &looprpc.StaticAddressSummaryResponse{
StaticAddress: address.String(),
RelativeExpiryBlocks: uint64(params.Expiry),
TotalNumDeposits: uint32(totalNumDeposits),
ValueUnconfirmedSatoshis: valueUnconfirmed,
ValueDepositedSatoshis: valueDeposited,
ValueExpiredSatoshis: valueExpired,
ValueWithdrawnSatoshis: valueWithdrawn,
ValueLoopedInSatoshis: valueLoopedIn,
ValueHtlcTimeoutSweepsSatoshis: htlcTimeoutSwept,
}, nil
}
// StaticAddressLoopIn initiates a loop-in request using static address
@ -1534,108 +1707,6 @@ func (s *swapClientServer) StaticAddressLoopIn(ctx context.Context,
}, nil
}
func (s *swapClientServer) depositSummary(ctx context.Context,
deposits []*deposit.Deposit, stateFilter looprpc.DepositState,
outpointsFilter []string) (*looprpc.StaticAddressSummaryResponse,
error) {
var (
totalNumDeposits = len(deposits)
valueUnconfirmed int64
valueDeposited int64
valueExpired int64
valueWithdrawn int64
valueLoopedIn int64
htlcTimeoutSwept int64
)
// Value unconfirmed.
utxos, err := s.staticAddressManager.ListUnspent(
ctx, 0, deposit.MinConfs-1,
)
if err != nil {
return nil, err
}
for _, u := range utxos {
valueUnconfirmed += int64(u.Value)
}
// Confirmed total values by category.
for _, d := range deposits {
value := int64(d.Value)
switch d.GetState() {
case deposit.Deposited:
valueDeposited += value
case deposit.Expired:
valueExpired += value
case deposit.Withdrawn:
valueWithdrawn += value
case deposit.LoopedIn:
valueLoopedIn += value
case deposit.HtlcTimeoutSwept:
htlcTimeoutSwept += value
}
}
// Deposits filtered by state or outpoints.
var clientDeposits []*looprpc.Deposit
if len(outpointsFilter) > 0 {
f := func(d *deposit.Deposit) bool {
for _, outpoint := range outpointsFilter {
if outpoint == d.OutPoint.String() {
return true
}
}
return false
}
clientDeposits = filter(deposits, f)
if len(outpointsFilter) != len(clientDeposits) {
return nil, fmt.Errorf("not all outpoints found in " +
"deposits")
}
} else {
f := func(d *deposit.Deposit) bool {
if stateFilter == looprpc.DepositState_UNKNOWN_STATE {
// Per default, we return deposits in all
// states.
return true
}
return d.IsInState(toServerState(stateFilter))
}
clientDeposits = filter(deposits, f)
}
params, err := s.staticAddressManager.GetStaticAddressParameters(ctx)
if err != nil {
return nil, err
}
address, err := s.staticAddressManager.GetTaprootAddress(
params.ClientPubkey, params.ServerPubkey, int64(params.Expiry),
)
if err != nil {
return nil, err
}
return &looprpc.StaticAddressSummaryResponse{
StaticAddress: address.String(),
TotalNumDeposits: uint32(totalNumDeposits),
ValueUnconfirmedSatoshis: valueUnconfirmed,
ValueDepositedSatoshis: valueDeposited,
ValueExpiredSatoshis: valueExpired,
ValueWithdrawnSatoshis: valueWithdrawn,
ValueLoopedInSatoshis: valueLoopedIn,
ValueHtlcTimeoutSweepsSatoshis: htlcTimeoutSwept,
FilteredDeposits: clientDeposits,
}, nil
}
type filterFunc func(deposits *deposit.Deposit) bool
func filter(deposits []*deposit.Deposit, f filterFunc) []*looprpc.Deposit {
@ -1648,8 +1719,10 @@ func filter(deposits []*deposit.Deposit, f filterFunc) []*looprpc.Deposit {
hash := d.Hash
outpoint := wire.NewOutPoint(&hash, d.Index).String()
deposit := &looprpc.Deposit{
Id: d.ID[:],
State: toClientState(d.GetState()),
Id: d.ID[:],
State: toClientDepositState(
d.GetState(),
),
Outpoint: outpoint,
Value: int64(d.Value),
ConfirmationHeight: d.ConfirmationHeight,
@ -1661,7 +1734,7 @@ func filter(deposits []*deposit.Deposit, f filterFunc) []*looprpc.Deposit {
return clientDeposits
}
func toClientState(state fsm.StateType) looprpc.DepositState {
func toClientDepositState(state fsm.StateType) looprpc.DepositState {
switch state {
case deposit.Deposited:
return looprpc.DepositState_DEPOSITED
@ -1698,6 +1771,51 @@ func toClientState(state fsm.StateType) looprpc.DepositState {
}
}
func toClientStaticAddressLoopInState(
state fsm.StateType) looprpc.StaticAddressLoopInSwapState {
switch state {
case loopin.InitHtlcTx:
return looprpc.StaticAddressLoopInSwapState_INIT_HTLC
case loopin.SignHtlcTx:
return looprpc.StaticAddressLoopInSwapState_SIGN_HTLC_TX
case loopin.MonitorInvoiceAndHtlcTx:
return looprpc.StaticAddressLoopInSwapState_MONITOR_INVOICE_HTLC_TX
case loopin.PaymentReceived:
return looprpc.StaticAddressLoopInSwapState_PAYMENT_RECEIVED
case loopin.SweepHtlcTimeout:
return looprpc.StaticAddressLoopInSwapState_SWEEP_STATIC_ADDRESS_HTLC_TIMEOUT
case loopin.MonitorHtlcTimeoutSweep:
return looprpc.StaticAddressLoopInSwapState_MONITOR_HTLC_TIMEOUT_SWEEP
case loopin.HtlcTimeoutSwept:
return looprpc.StaticAddressLoopInSwapState_HTLC_STATIC_ADDRESS_TIMEOUT_SWEPT
case loopin.FetchSignPushSweeplessSweepTx:
return looprpc.StaticAddressLoopInSwapState_FETCH_SIGN_PUSH_SWEEPLESS_SWEEP_TX
case loopin.Succeeded:
return looprpc.StaticAddressLoopInSwapState_SUCCEEDED
case loopin.SucceededSweeplessSigFailed:
return looprpc.StaticAddressLoopInSwapState_SUCCEEDED_SWEEPLESS_SIG_FAILED
case loopin.UnlockDeposits:
return looprpc.StaticAddressLoopInSwapState_UNLOCK_DEPOSITS
case loopin.Failed:
return looprpc.StaticAddressLoopInSwapState_FAILED_STATIC_ADDRESS_SWAP
default:
return looprpc.StaticAddressLoopInSwapState_UNKNOWN_STATIC_ADDRESS_SWAP_STATE
}
}
func toServerState(state looprpc.DepositState) fsm.StateType {
switch state {
case looprpc.DepositState_DEPOSITED:

File diff suppressed because it is too large Load diff

View file

@ -168,6 +168,20 @@ service SwapClient {
rpc WithdrawDeposits (WithdrawDepositsRequest)
returns (WithdrawDepositsResponse);
/* loop:`listdeposits`
ListStaticAddressDeposits returns a list of filtered static address
deposits.
*/
rpc ListStaticAddressDeposits (ListStaticAddressDepositsRequest)
returns (ListStaticAddressDepositsResponse);
/* loop:`listswaps`
ListStaticAddressSwaps returns a list of filtered static address
swaps.
*/
rpc ListStaticAddressSwaps (ListStaticAddressSwapsRequest)
returns (ListStaticAddressSwapsResponse);
/* loop:`static summary`
GetStaticAddressSummary returns a summary of static address related
statistics.
@ -1599,7 +1613,7 @@ message OutPoint {
uint32 output_index = 3;
}
message StaticAddressSummaryRequest {
message ListStaticAddressDepositsRequest {
/*
Filters the list of all stored deposits by deposit state.
*/
@ -1611,51 +1625,71 @@ message StaticAddressSummaryRequest {
repeated string outpoints = 2;
}
message ListStaticAddressDepositsResponse {
/*
A list of all deposits that match the filtered state.
*/
repeated Deposit filtered_deposits = 1;
}
message ListStaticAddressSwapsRequest {
}
message ListStaticAddressSwapsResponse {
/*
A list of all swaps known static address loop-in swaps.
*/
repeated StaticAddressLoopInSwap swaps = 1;
}
message StaticAddressSummaryRequest {
}
message StaticAddressSummaryResponse {
/*
The static address of the client.
*/
string static_address = 1;
/*
The CSV expiry of the static address.
*/
uint64 relative_expiry_blocks = 2;
/*
The total number of deposits.
*/
uint32 total_num_deposits = 2;
uint32 total_num_deposits = 3;
/*
The total value of unconfirmed deposits.
*/
int64 value_unconfirmed_satoshis = 3;
int64 value_unconfirmed_satoshis = 4;
/*
The total value of confirmed deposits.
*/
int64 value_deposited_satoshis = 4;
int64 value_deposited_satoshis = 5;
/*
The total value of all expired deposits.
*/
int64 value_expired_satoshis = 5;
int64 value_expired_satoshis = 6;
/*
The total value of all deposits that have been withdrawn.
*/
int64 value_withdrawn_satoshis = 6;
int64 value_withdrawn_satoshis = 7;
/*
The total value of all loop-ins that have been finalized.
*/
int64 value_looped_in_satoshis = 7;
int64 value_looped_in_satoshis = 8;
/*
The total value of all htlc timeout sweeps that the client swept.
*/
int64 value_htlc_timeout_sweeps_satoshis = 8;
/*
A list of all deposits that match the filtered state.
*/
repeated Deposit filtered_deposits = 9;
int64 value_htlc_timeout_sweeps_satoshis = 9;
}
enum DepositState {
@ -1751,6 +1785,93 @@ message Deposit {
The block height at which the deposit was confirmed.
*/
int64 confirmation_height = 5;
/*
The number of blocks that are left until the deposit cannot be used for a
loop-in swap anymore.
*/
int64 blocks_until_expiry = 6;
}
message StaticAddressLoopInSwap {
/*
The swap hash of the swap. It represents the unique identifier of the swap.
*/
bytes swap_hash = 1;
/*
*/
repeated string deposit_outpoints = 2;
/*
*/
StaticAddressLoopInSwapState state = 3;
/*
The swap amount of the swap. It is the sum of the values of the deposit
outpoints that were used for this swap.
*/
int64 swap_amount_satoshis = 4;
/*
The invoiced swap amount. It is the swap amount minus the quoted server
fees.
*/
int64 payment_request_amount_satoshis = 5;
}
enum StaticAddressLoopInSwapState {
/*
*/
UNKNOWN_STATIC_ADDRESS_SWAP_STATE = 0;
/*
*/
INIT_HTLC = 1;
/*
*/
SIGN_HTLC_TX = 2;
/*
*/
MONITOR_INVOICE_HTLC_TX = 3;
/*
*/
PAYMENT_RECEIVED = 4;
/*
*/
SWEEP_STATIC_ADDRESS_HTLC_TIMEOUT = 5;
/*
*/
MONITOR_HTLC_TIMEOUT_SWEEP = 6;
/*
*/
HTLC_STATIC_ADDRESS_TIMEOUT_SWEPT = 7;
/*
*/
FETCH_SIGN_PUSH_SWEEPLESS_SWEEP_TX = 8;
/*
*/
SUCCEEDED = 9;
/*
*/
SUCCEEDED_SWEEPLESS_SIG_FAILED = 10;
/*
*/
UNLOCK_DEPOSITS = 11;
/*
*/
FAILED_STATIC_ADDRESS_SWAP = 12;
}
message StaticAddressLoopInRequest {

View file

@ -688,6 +688,11 @@
"type": "string",
"format": "int64",
"description": "The block height at which the deposit was confirmed."
},
"blocks_until_expiry": {
"type": "string",
"format": "int64",
"description": "The number of blocks that are left until the deposit cannot be used for a\nloop-in swap anymore."
}
}
},
@ -1152,6 +1157,30 @@
}
}
},
"looprpcListStaticAddressDepositsResponse": {
"type": "object",
"properties": {
"filtered_deposits": {
"type": "array",
"items": {
"$ref": "#/definitions/looprpcDeposit"
},
"description": "A list of all deposits that match the filtered state."
}
}
},
"looprpcListStaticAddressSwapsResponse": {
"type": "object",
"properties": {
"swaps": {
"type": "array",
"items": {
"$ref": "#/definitions/looprpcStaticAddressLoopInSwap"
},
"description": "A list of all swaps known static address loop-in swaps."
}
}
},
"looprpcListSwapsFilter": {
"type": "object",
"properties": {
@ -1565,6 +1594,57 @@
}
}
},
<<<<<<< HEAD
=======
"looprpcStaticAddressLoopInSwap": {
"type": "object",
"properties": {
"swap_hash": {
"type": "string",
"format": "byte",
"description": "The swap hash of the swap. It represents the unique identifier of the swap."
},
"deposit_outpoints": {
"type": "array",
"items": {
"type": "string"
}
},
"state": {
"$ref": "#/definitions/looprpcStaticAddressLoopInSwapState"
},
"swap_amount_satoshis": {
"type": "string",
"format": "int64",
"description": "The swap amount of the swap. It is the sum of the values of the deposit\noutpoints that were used for this swap."
},
"payment_request_amount_satoshis": {
"type": "string",
"format": "int64",
"description": "The invoiced swap amount. It is the swap amount minus the quoted server\nfees."
}
}
},
"looprpcStaticAddressLoopInSwapState": {
"type": "string",
"enum": [
"UNKNOWN_STATIC_ADDRESS_SWAP_STATE",
"INIT_HTLC",
"SIGN_HTLC_TX",
"MONITOR_INVOICE_HTLC_TX",
"PAYMENT_RECEIVED",
"SWEEP_STATIC_ADDRESS_HTLC_TIMEOUT",
"MONITOR_HTLC_TIMEOUT_SWEEP",
"HTLC_STATIC_ADDRESS_TIMEOUT_SWEPT",
"FETCH_SIGN_PUSH_SWEEPLESS_SWEEP_TX",
"SUCCEEDED",
"SUCCEEDED_SWEEPLESS_SIG_FAILED",
"UNLOCK_DEPOSITS",
"FAILED_STATIC_ADDRESS_SWAP"
],
"default": "UNKNOWN_STATIC_ADDRESS_SWAP_STATE"
},
>>>>>>> 3995e99a (staticaddr: cmd listdeposits and listswaps)
"looprpcStaticAddressSummaryResponse": {
"type": "object",
"properties": {
@ -1572,6 +1652,11 @@
"type": "string",
"description": "The static address of the client."
},
"relative_expiry_blocks": {
"type": "string",
"format": "uint64",
"description": "The CSV expiry of the static address."
},
"total_num_deposits": {
"type": "integer",
"format": "int64",
@ -1606,6 +1691,7 @@
"type": "string",
"format": "int64",
"description": "The total value of all htlc timeout sweeps that the client swept."
<<<<<<< HEAD
},
"filtered_deposits": {
"type": "array",
@ -1613,6 +1699,8 @@
"$ref": "#/definitions/looprpcDeposit"
},
"description": "A list of all deposits that match the filtered state."
=======
>>>>>>> 3995e99a (staticaddr: cmd listdeposits and listswaps)
}
}
},

View file

@ -115,6 +115,14 @@ type SwapClientClient interface {
// loop:`static withdraw`
// WithdrawDeposits withdraws a selection or all deposits of a static address.
WithdrawDeposits(ctx context.Context, in *WithdrawDepositsRequest, opts ...grpc.CallOption) (*WithdrawDepositsResponse, error)
// loop:`listdeposits`
// ListStaticAddressDeposits returns a list of filtered static address
// deposits.
ListStaticAddressDeposits(ctx context.Context, in *ListStaticAddressDepositsRequest, opts ...grpc.CallOption) (*ListStaticAddressDepositsResponse, error)
// loop:`listswaps`
// ListStaticAddressSwaps returns a list of filtered static address
// swaps.
ListStaticAddressSwaps(ctx context.Context, in *ListStaticAddressSwapsRequest, opts ...grpc.CallOption) (*ListStaticAddressSwapsResponse, error)
// loop:`static summary`
// GetStaticAddressSummary returns a summary of static address related
// statistics.
@ -380,6 +388,24 @@ func (c *swapClientClient) WithdrawDeposits(ctx context.Context, in *WithdrawDep
return out, nil
}
func (c *swapClientClient) ListStaticAddressDeposits(ctx context.Context, in *ListStaticAddressDepositsRequest, opts ...grpc.CallOption) (*ListStaticAddressDepositsResponse, error) {
out := new(ListStaticAddressDepositsResponse)
err := c.cc.Invoke(ctx, "/looprpc.SwapClient/ListStaticAddressDeposits", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *swapClientClient) ListStaticAddressSwaps(ctx context.Context, in *ListStaticAddressSwapsRequest, opts ...grpc.CallOption) (*ListStaticAddressSwapsResponse, error) {
out := new(ListStaticAddressSwapsResponse)
err := c.cc.Invoke(ctx, "/looprpc.SwapClient/ListStaticAddressSwaps", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *swapClientClient) GetStaticAddressSummary(ctx context.Context, in *StaticAddressSummaryRequest, opts ...grpc.CallOption) (*StaticAddressSummaryResponse, error) {
out := new(StaticAddressSummaryResponse)
err := c.cc.Invoke(ctx, "/looprpc.SwapClient/GetStaticAddressSummary", in, out, opts...)
@ -499,6 +525,14 @@ type SwapClientServer interface {
// loop:`static withdraw`
// WithdrawDeposits withdraws a selection or all deposits of a static address.
WithdrawDeposits(context.Context, *WithdrawDepositsRequest) (*WithdrawDepositsResponse, error)
// loop:`listdeposits`
// ListStaticAddressDeposits returns a list of filtered static address
// deposits.
ListStaticAddressDeposits(context.Context, *ListStaticAddressDepositsRequest) (*ListStaticAddressDepositsResponse, error)
// loop:`listswaps`
// ListStaticAddressSwaps returns a list of filtered static address
// swaps.
ListStaticAddressSwaps(context.Context, *ListStaticAddressSwapsRequest) (*ListStaticAddressSwapsResponse, error)
// loop:`static summary`
// GetStaticAddressSummary returns a summary of static address related
// statistics.
@ -588,6 +622,12 @@ func (UnimplementedSwapClientServer) ListUnspentDeposits(context.Context, *ListU
func (UnimplementedSwapClientServer) WithdrawDeposits(context.Context, *WithdrawDepositsRequest) (*WithdrawDepositsResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method WithdrawDeposits not implemented")
}
func (UnimplementedSwapClientServer) ListStaticAddressDeposits(context.Context, *ListStaticAddressDepositsRequest) (*ListStaticAddressDepositsResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method ListStaticAddressDeposits not implemented")
}
func (UnimplementedSwapClientServer) ListStaticAddressSwaps(context.Context, *ListStaticAddressSwapsRequest) (*ListStaticAddressSwapsResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method ListStaticAddressSwaps not implemented")
}
func (UnimplementedSwapClientServer) GetStaticAddressSummary(context.Context, *StaticAddressSummaryRequest) (*StaticAddressSummaryResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetStaticAddressSummary not implemented")
}
@ -1060,6 +1100,42 @@ func _SwapClient_WithdrawDeposits_Handler(srv interface{}, ctx context.Context,
return interceptor(ctx, in, info, handler)
}
func _SwapClient_ListStaticAddressDeposits_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(ListStaticAddressDepositsRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SwapClientServer).ListStaticAddressDeposits(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/looprpc.SwapClient/ListStaticAddressDeposits",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SwapClientServer).ListStaticAddressDeposits(ctx, req.(*ListStaticAddressDepositsRequest))
}
return interceptor(ctx, in, info, handler)
}
func _SwapClient_ListStaticAddressSwaps_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(ListStaticAddressSwapsRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SwapClientServer).ListStaticAddressSwaps(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/looprpc.SwapClient/ListStaticAddressSwaps",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SwapClientServer).ListStaticAddressSwaps(ctx, req.(*ListStaticAddressSwapsRequest))
}
return interceptor(ctx, in, info, handler)
}
func _SwapClient_GetStaticAddressSummary_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(StaticAddressSummaryRequest)
if err := dec(in); err != nil {
@ -1199,6 +1275,14 @@ var SwapClient_ServiceDesc = grpc.ServiceDesc{
MethodName: "WithdrawDeposits",
Handler: _SwapClient_WithdrawDeposits_Handler,
},
{
MethodName: "ListStaticAddressDeposits",
Handler: _SwapClient_ListStaticAddressDeposits_Handler,
},
{
MethodName: "ListStaticAddressSwaps",
Handler: _SwapClient_ListStaticAddressSwaps_Handler,
},
{
MethodName: "GetStaticAddressSummary",
Handler: _SwapClient_GetStaticAddressSummary_Handler,

View file

@ -663,6 +663,56 @@ func RegisterSwapClientJSONCallbacks(registry map[string]func(ctx context.Contex
callback(string(respBytes), nil)
}
registry["looprpc.SwapClient.ListStaticAddressDeposits"] = func(ctx context.Context,
conn *grpc.ClientConn, reqJSON string, callback func(string, error)) {
req := &ListStaticAddressDepositsRequest{}
err := marshaler.Unmarshal([]byte(reqJSON), req)
if err != nil {
callback("", err)
return
}
client := NewSwapClientClient(conn)
resp, err := client.ListStaticAddressDeposits(ctx, req)
if err != nil {
callback("", err)
return
}
respBytes, err := marshaler.Marshal(resp)
if err != nil {
callback("", err)
return
}
callback(string(respBytes), nil)
}
registry["looprpc.SwapClient.ListStaticAddressSwaps"] = func(ctx context.Context,
conn *grpc.ClientConn, reqJSON string, callback func(string, error)) {
req := &ListStaticAddressSwapsRequest{}
err := marshaler.Unmarshal([]byte(reqJSON), req)
if err != nil {
callback("", err)
return
}
client := NewSwapClientClient(conn)
resp, err := client.ListStaticAddressSwaps(ctx, req)
if err != nil {
callback("", err)
return
}
respBytes, err := marshaler.Marshal(resp)
if err != nil {
callback("", err)
return
}
callback(string(respBytes), nil)
}
registry["looprpc.SwapClient.GetStaticAddressSummary"] = func(ctx context.Context,
conn *grpc.ClientConn, reqJSON string, callback func(string, error)) {

View file

@ -33,6 +33,9 @@ type AddressManager interface {
// DepositManager handles the interaction of loop-ins with deposits.
type DepositManager interface {
// GetAllDeposits returns all known deposits from the database store.
GetAllDeposits(ctx context.Context) ([]*deposit.Deposit, error)
// AllStringOutpointsActiveDeposits returns all deposits that have the
// given outpoints and are in the given state. If any of the outpoints
// does not correspond to an active deposit, the function returns false.

View file

@ -456,3 +456,38 @@ func (m *Manager) startLoopInFsm(ctx context.Context,
return loopIn, nil
}
// GetAllSwaps returns all static address loop-in swaps from the database store.
func (m *Manager) GetAllSwaps(ctx context.Context) ([]*StaticAddressLoopIn,
error) {
swaps, err := m.cfg.Store.GetStaticAddressLoopInSwapsByStates(
ctx, AllStates,
)
if err != nil {
return nil, err
}
allDeposits, err := m.cfg.DepositManager.GetAllDeposits(ctx)
if err != nil {
return nil, err
}
var depositLookup = make(map[string]*deposit.Deposit)
for i, d := range allDeposits {
depositLookup[d.OutPoint.String()] = allDeposits[i]
}
for i, s := range swaps {
var deposits []*deposit.Deposit
for _, outpoint := range s.DepositOutpoints {
if d, ok := depositLookup[outpoint]; ok {
deposits = append(deposits, d)
}
}
swaps[i].Deposits = deposits
}
return swaps, nil
}