2024-10-24 12:18:02 +02:00
|
|
|
package loopin
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
|
|
|
|
|
|
|
|
|
"github.com/btcsuite/btcd/btcutil"
|
2026-06-26 13:20:45 +02:00
|
|
|
"github.com/btcsuite/btcd/wire"
|
2024-10-24 12:18:02 +02:00
|
|
|
"github.com/lightninglabs/loop"
|
|
|
|
|
"github.com/lightninglabs/loop/fsm"
|
|
|
|
|
"github.com/lightninglabs/loop/staticaddr/deposit"
|
|
|
|
|
"github.com/lightninglabs/loop/staticaddr/script"
|
2024-11-14 15:33:10 +01:00
|
|
|
"github.com/lightninglabs/loop/swapserverrpc"
|
2024-10-24 12:18:02 +02:00
|
|
|
"github.com/lightningnetwork/lnd/lntypes"
|
|
|
|
|
"github.com/lightningnetwork/lnd/routing/route"
|
|
|
|
|
"github.com/lightningnetwork/lnd/zpay32"
|
|
|
|
|
)
|
|
|
|
|
|
2025-10-08 09:41:58 +02:00
|
|
|
const (
|
|
|
|
|
// DefaultLoopInOnChainCltvDelta is the time lock relative to current
|
|
|
|
|
// block height that swap server will accept on the swap initiation
|
|
|
|
|
// call.
|
|
|
|
|
DefaultLoopInOnChainCltvDelta = 1000
|
|
|
|
|
|
|
|
|
|
// DepositHtlcDelta is a safety buffer of blocks that needs to exist
|
|
|
|
|
// between the deposit expiry height and the htlc expiry height.
|
|
|
|
|
DepositHtlcDelta = 50
|
|
|
|
|
)
|
|
|
|
|
|
2024-10-24 12:18:02 +02:00
|
|
|
type (
|
|
|
|
|
// ValidateLoopInContract validates the contract parameters against our
|
|
|
|
|
// request.
|
|
|
|
|
ValidateLoopInContract func(height int32, htlcExpiry int32) error
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// AddressManager handles fetching of address parameters.
|
|
|
|
|
type AddressManager interface {
|
|
|
|
|
// GetStaticAddressParameters returns the static address parameters.
|
2026-05-01 15:54:37 +05:30
|
|
|
GetStaticAddressParameters(ctx context.Context) (*script.Parameters,
|
2024-10-24 12:18:02 +02:00
|
|
|
error)
|
|
|
|
|
|
|
|
|
|
// GetStaticAddress returns the deposit address for the given client and
|
|
|
|
|
// server public keys.
|
|
|
|
|
GetStaticAddress(ctx context.Context) (*script.StaticAddress, error)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// DepositManager handles the interaction of loop-ins with deposits.
|
|
|
|
|
type DepositManager interface {
|
2026-06-26 12:52:51 +02:00
|
|
|
// EnsureDepositsFresh reconciles active deposits with the wallet view.
|
|
|
|
|
EnsureDepositsFresh(ctx context.Context) error
|
|
|
|
|
|
2024-11-05 10:15:10 +01:00
|
|
|
// GetAllDeposits returns all known deposits from the database store.
|
|
|
|
|
GetAllDeposits(ctx context.Context) ([]*deposit.Deposit, error)
|
|
|
|
|
|
2024-10-24 12:18:02 +02:00
|
|
|
// 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.
|
|
|
|
|
AllStringOutpointsActiveDeposits(outpoints []string,
|
|
|
|
|
stateFilter fsm.StateType) ([]*deposit.Deposit, bool)
|
|
|
|
|
|
|
|
|
|
// TransitionDeposits transitions the given deposits to the next state
|
|
|
|
|
// based on the given event. It returns an error if the transition is
|
|
|
|
|
// invalid.
|
|
|
|
|
TransitionDeposits(ctx context.Context, deposits []*deposit.Deposit,
|
|
|
|
|
event fsm.EventType, expectedFinalState fsm.StateType) error
|
2025-04-02 14:29:48 +02:00
|
|
|
|
|
|
|
|
// DepositsForOutpoints returns all deposits that behind the given
|
2025-09-26 11:14:00 +02:00
|
|
|
// outpoints. If ignoreUnknown is false, the function returns an error
|
|
|
|
|
// if any of the outpoints is not known, no error otherwise.
|
|
|
|
|
DepositsForOutpoints(ctx context.Context, outpoints []string,
|
|
|
|
|
ignoreUnknown bool) ([]*deposit.Deposit, error)
|
2025-06-27 10:56:28 +02:00
|
|
|
|
|
|
|
|
// GetActiveDepositsInState returns all active deposits in the given
|
|
|
|
|
// state.
|
|
|
|
|
GetActiveDepositsInState(stateFilter fsm.StateType) ([]*deposit.Deposit,
|
|
|
|
|
error)
|
2024-10-24 12:18:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// StaticAddressLoopInStore provides access to the static address loop-in DB.
|
|
|
|
|
type StaticAddressLoopInStore interface {
|
|
|
|
|
// CreateLoopIn creates a loop-in record in the database.
|
|
|
|
|
CreateLoopIn(ctx context.Context, loopIn *StaticAddressLoopIn) error
|
|
|
|
|
|
|
|
|
|
// UpdateLoopIn updates a loop-in record in the database.
|
|
|
|
|
UpdateLoopIn(ctx context.Context, loopIn *StaticAddressLoopIn) error
|
|
|
|
|
|
|
|
|
|
// GetStaticAddressLoopInSwapsByStates returns all loop-ins with given
|
|
|
|
|
// states.
|
|
|
|
|
GetStaticAddressLoopInSwapsByStates(ctx context.Context,
|
|
|
|
|
states []fsm.StateType) ([]*StaticAddressLoopIn, error)
|
|
|
|
|
|
|
|
|
|
// IsStored checks if the loop-in is already stored in the database.
|
|
|
|
|
IsStored(ctx context.Context, swapHash lntypes.Hash) (bool, error)
|
2024-11-14 15:04:18 +01:00
|
|
|
|
2026-06-26 12:54:30 +02:00
|
|
|
// RecordStaticAddressRiskDecision persists the server's
|
|
|
|
|
// confirmation-risk decision for the loop-in identified by swapHash.
|
|
|
|
|
RecordStaticAddressRiskDecision(ctx context.Context,
|
|
|
|
|
swapHash lntypes.Hash, decision ConfirmationRiskDecision) error
|
|
|
|
|
|
2024-11-14 15:04:18 +01:00
|
|
|
// GetLoopInByHash returns the loop-in swap with the given hash.
|
|
|
|
|
GetLoopInByHash(ctx context.Context, swapHash lntypes.Hash) (
|
|
|
|
|
*StaticAddressLoopIn, error)
|
2025-09-22 10:06:42 +02:00
|
|
|
|
|
|
|
|
// SwapHashesForDepositIDs returns a map of swap hashes to deposit IDs
|
|
|
|
|
// for the given deposit IDs.
|
|
|
|
|
SwapHashesForDepositIDs(ctx context.Context,
|
|
|
|
|
depositIDs []deposit.ID) (map[lntypes.Hash][]deposit.ID, error)
|
2024-10-24 12:18:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type QuoteGetter interface {
|
|
|
|
|
// GetLoopInQuote returns a quote for a loop-in swap.
|
|
|
|
|
GetLoopInQuote(ctx context.Context, amt btcutil.Amount,
|
|
|
|
|
pubKey route.Vertex, lastHop *route.Vertex,
|
2025-10-01 08:49:32 +02:00
|
|
|
routeHints [][]zpay32.HopHint, initiator string,
|
|
|
|
|
numDeposits uint32, fast bool) (*loop.LoopInQuote, error)
|
2024-10-24 12:18:02 +02:00
|
|
|
}
|
2024-11-14 15:33:10 +01:00
|
|
|
|
2026-06-26 13:20:45 +02:00
|
|
|
// TxOutChecker checks whether an outpoint is still available in the chain
|
|
|
|
|
// backend's UTXO view.
|
|
|
|
|
type TxOutChecker interface {
|
|
|
|
|
// GetTxOut returns nil if the outpoint is unavailable or spent. The
|
|
|
|
|
// includeMempool flag must be passed through to the underlying chain
|
|
|
|
|
// backend.
|
|
|
|
|
GetTxOut(ctx context.Context, outpoint wire.OutPoint,
|
|
|
|
|
includeMempool bool) (*wire.TxOut, error)
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-14 15:33:10 +01:00
|
|
|
type NotificationManager interface {
|
|
|
|
|
// SubscribeStaticLoopInSweepRequests subscribes to the static loop in
|
|
|
|
|
// sweep requests. These are sent by the server to the client to request
|
|
|
|
|
// a sweep of a static loop in that has been finished.
|
|
|
|
|
SubscribeStaticLoopInSweepRequests(ctx context.Context,
|
|
|
|
|
) <-chan *swapserverrpc.ServerStaticLoopInSweepNotification
|
2026-06-26 12:53:17 +02:00
|
|
|
|
|
|
|
|
// SubscribeStaticLoopInRiskAccepted subscribes to static loop in risk
|
|
|
|
|
// accepted notifications. These are sent by the server after the selected
|
|
|
|
|
// deposits are accepted by confirmation risk tracking.
|
|
|
|
|
SubscribeStaticLoopInRiskAccepted(
|
|
|
|
|
ctx context.Context, swapHash lntypes.Hash,
|
|
|
|
|
) <-chan *swapserverrpc.ServerStaticLoopInRiskAcceptedNotification
|
|
|
|
|
|
|
|
|
|
// SubscribeStaticLoopInRiskRejected subscribes to static loop in risk
|
|
|
|
|
// rejected notifications. These are sent by the server if it aborts the
|
|
|
|
|
// confirmation risk wait before payment.
|
|
|
|
|
SubscribeStaticLoopInRiskRejected(
|
|
|
|
|
ctx context.Context, swapHash lntypes.Hash,
|
|
|
|
|
) <-chan *swapserverrpc.ServerStaticLoopInRiskRejectedNotification
|
2024-11-14 15:33:10 +01:00
|
|
|
}
|