Documentation
¶
Index ¶
- Constants
- func DisableLog()
- func EstimateAssetUnits(ctx context.Context, oracle PriceOracle, specifier asset.Specifier, ...) (uint64, error)
- func MarshalAcceptedBuyQuote(q rfqmsg.BuyAccept) *rfqrpc.PeerAcceptedBuyQuote
- func MarshalAcceptedSellQuote(accept rfqmsg.SellAccept) *rfqrpc.PeerAcceptedSellQuote
- func MarshalAcceptedSellQuoteEvent(event *PeerAcceptedSellQuoteEvent) *rfqrpc.PeerAcceptedSellQuote
- func MarshalIncomingRejectQuoteEvent(event *IncomingRejectQuoteEvent) *rfqrpc.RejectedQuoteResponse
- func MarshalInvalidQuoteRespEvent(event *InvalidQuoteRespEvent) *rfqrpc.InvalidQuoteResponse
- func NewAddAssetBuyOrderResponse(event fn.Event) (*rfqrpc.AddAssetBuyOrderResponse, error)
- func NewAddAssetSellOrderResponse(event fn.Event) (*rfqrpc.AddAssetSellOrderResponse, error)
- func NewMacaroonDialOption(path string) (grpc.DialOption, error)
- func UseLogger(logger btclog.Logger)
- func Zpay32HopHintToLnrpc(h *zpay32.HopHint) *lnrpc.HopHint
- type AcceptHtlcEvent
- type AssetForwardPolicy
- func (a *AssetForwardPolicy) CheckHtlcCompliance(ctx context.Context, htlc lndclient.InterceptedHtlc, ...) error
- func (a *AssetForwardPolicy) Expiry() uint64
- func (a *AssetForwardPolicy) GenerateInterceptorResponse(htlc lndclient.InterceptedHtlc) (*lndclient.InterceptedHtlcResponse, error)
- func (a *AssetForwardPolicy) HasExpired() bool
- func (a *AssetForwardPolicy) RfqID() rfqmsg.ID
- func (a *AssetForwardPolicy) Scid() uint64
- func (a *AssetForwardPolicy) TrackAcceptedHtlc(circuitKey models.CircuitKey, amt lnwire.MilliSatoshi)
- func (a *AssetForwardPolicy) UntrackHtlc(circuitKey models.CircuitKey)
- type AssetPurchasePolicy
- func (c *AssetPurchasePolicy) CheckHtlcCompliance(ctx context.Context, htlc lndclient.InterceptedHtlc, ...) error
- func (c *AssetPurchasePolicy) Expiry() uint64
- func (c *AssetPurchasePolicy) GenerateInterceptorResponse(htlc lndclient.InterceptedHtlc) (*lndclient.InterceptedHtlcResponse, error)
- func (c *AssetPurchasePolicy) HasExpired() bool
- func (c *AssetPurchasePolicy) RfqID() rfqmsg.ID
- func (c *AssetPurchasePolicy) Scid() uint64
- func (c *AssetPurchasePolicy) TrackAcceptedHtlc(circuitKey models.CircuitKey, amt lnwire.MilliSatoshi)
- func (c *AssetPurchasePolicy) UntrackHtlc(circuitKey models.CircuitKey)
- type AssetRateQuery
- type AssetSalePolicy
- func (c *AssetSalePolicy) CheckHtlcCompliance(_ context.Context, htlc lndclient.InterceptedHtlc, _ rfqmsg.SpecifierChecker) error
- func (c *AssetSalePolicy) Expiry() uint64
- func (c *AssetSalePolicy) GenerateInterceptorResponse(htlc lndclient.InterceptedHtlc) (*lndclient.InterceptedHtlcResponse, error)
- func (c *AssetSalePolicy) HasExpired() bool
- func (c *AssetSalePolicy) RfqID() rfqmsg.ID
- func (c *AssetSalePolicy) Scid() uint64
- func (c *AssetSalePolicy) TrackAcceptedHtlc(circuitKey models.CircuitKey, amt lnwire.MilliSatoshi)
- func (c *AssetSalePolicy) UntrackHtlc(circuitKey models.CircuitKey)
- type AssetTransferDirection
- type BuyAcceptMap
- type BuyOffer
- type BuyOrder
- type ChanIntention
- type ChannelLister
- type CliConfig
- type ForwardInput
- type ForwardStore
- type ForwardingEvent
- type GroupLookup
- type HtlcInterceptor
- type HtlcSubscriber
- type InboundPolicyFetcher
- type IncomingRejectQuoteEvent
- type InternalPortfolioPilot
- func (p *InternalPortfolioPilot) Close() error
- func (p *InternalPortfolioPilot) QueryAssetRates(ctx context.Context, query AssetRateQuery) (rfqmsg.AssetRate, error)
- func (p *InternalPortfolioPilot) ResolveRequest(ctx context.Context, request rfqmsg.Request) (ResolveResp, error)
- func (p *InternalPortfolioPilot) VerifyAcceptQuote(ctx context.Context, accept rfqmsg.Accept) (QuoteRespStatus, error)
- type InternalPortfolioPilotConfig
- type InvalidQuoteRespEvent
- type Manager
- func (m *Manager) AssetMatchesSpecifier(ctx context.Context, specifier asset.Specifier, id asset.ID) (bool, error)
- func (m *Manager) ChannelMatchesFully(ctx context.Context, jsonChannel rfqmsg.JsonAssetChannel, ...) (bool, error)
- func (m *Manager) ComputeChannelAssetBalance(ctx context.Context, activeChannels []lndclient.ChannelInfo, ...) (PeerChanMap, bool, error)
- func (m *Manager) FetchChannel(ctx context.Context, specifier asset.Specifier, peerPubKey *route.Vertex, ...) (PeerChanMap, error)
- func (m *Manager) GetPriceDeviationPpm() uint64
- func (m *Manager) LocalAcceptedBuyQuotes() BuyAcceptMap
- func (m *Manager) LocalAcceptedSellQuotes() SellAcceptMap
- func (m *Manager) LookUpScid(scid uint64) (route.Vertex, error)
- func (m *Manager) PeerAcceptedBuyQuotes() BuyAcceptMap
- func (m *Manager) PeerAcceptedSellQuotes() SellAcceptMap
- func (m *Manager) QueryForwardsWithCount(ctx context.Context, params QueryForwardsParams) ([]ForwardingEvent, int64, error)
- func (m *Manager) RegisterSubscriber(receiver *fn.EventReceiver[fn.Event], deliverExisting bool, deliverFrom uint64) error
- func (m *Manager) RemoveAssetSellOffer(assetID *asset.ID, assetGroupKey *btcec.PublicKey) error
- func (m *Manager) RemoveSubscriber(subscriber *fn.EventReceiver[fn.Event]) error
- func (m *Manager) RfqToHopHint(ctx context.Context, policyFetcher InboundPolicyFetcher, channelID uint64, ...) (*zpay32.HopHint, error)
- func (m *Manager) Start() error
- func (m *Manager) Stop() error
- func (m *Manager) UpsertAssetBuyOffer(offer BuyOffer) error
- func (m *Manager) UpsertAssetBuyOrder(ctx context.Context, order BuyOrder) (rfqmsg.ID, error)
- func (m *Manager) UpsertAssetSellOffer(offer SellOffer) error
- func (m *Manager) UpsertAssetSellOrder(ctx context.Context, order SellOrder) (rfqmsg.ID, error)
- type ManagerCfg
- type MockPriceOracle
- type Negotiator
- func (n *Negotiator) HandleIncomingBuyAccept(ctx context.Context, msg rfqmsg.BuyAccept, ...)
- func (n *Negotiator) HandleIncomingQuoteRequest(ctx context.Context, request rfqmsg.Request) error
- func (n *Negotiator) HandleIncomingSellAccept(ctx context.Context, msg rfqmsg.SellAccept, ...)
- func (n *Negotiator) HandleOutgoingBuyOrder(ctx context.Context, buyOrder BuyOrder) (rfqmsg.ID, error)
- func (n *Negotiator) HandleOutgoingSellOrder(ctx context.Context, order SellOrder) (rfqmsg.ID, error)
- func (n *Negotiator) RemoveAssetSellOffer(assetID *asset.ID, assetGroupKey *btcec.PublicKey) error
- func (n *Negotiator) Start() error
- func (n *Negotiator) Stop() error
- func (n *Negotiator) UpsertAssetBuyOffer(offer BuyOffer) error
- func (n *Negotiator) UpsertAssetSellOffer(offer SellOffer) error
- type NegotiatorCfg
- type OracleAddr
- type OracleError
- type OracleErrorCode
- type OracleResponse
- type Order
- type OrderHandler
- func (h *OrderHandler) RegisterAssetPurchasePolicy(ctx context.Context, sellAccept rfqmsg.SellAccept) error
- func (h *OrderHandler) RegisterAssetSalePolicy(ctx context.Context, buyAccept rfqmsg.BuyAccept) error
- func (h *OrderHandler) ReportMainChanError(err error)
- func (h *OrderHandler) Start(ctx context.Context) error
- func (h *OrderHandler) Stop() error
- type OrderHandlerCfg
- type PeerAcceptedBuyQuoteEvent
- type PeerAcceptedSellQuoteEvent
- type PeerChanMap
- type PeerMessenger
- type Policy
- type PolicyStore
- type PortfolioPilot
- type PortfolioPilotAddr
- type PriceOracle
- type PriceQueryIntent
- type QueryForwardsParams
- type QuoteRespStatus
- type ResolveResp
- type RfqPolicyType
- type RpcPortfolioPilot
- func (r *RpcPortfolioPilot) Close() error
- func (r *RpcPortfolioPilot) QueryAssetRates(ctx context.Context, query AssetRateQuery) (rfqmsg.AssetRate, error)
- func (r *RpcPortfolioPilot) ResolveRequest(ctx context.Context, request rfqmsg.Request) (ResolveResp, error)
- func (r *RpcPortfolioPilot) VerifyAcceptQuote(ctx context.Context, accept rfqmsg.Accept) (QuoteRespStatus, error)
- type RpcPriceOracle
- type ScidAliasManager
- type SellAcceptMap
- type SellOffer
- type SellOrder
- type SerialisedScid
- type StreamHandler
- type StreamHandlerCfg
- type TLSConfig
- type TapChannel
Constants ¶
const ( MockPriceOracleServiceAddress = "use_mock_price_oracle_service_" + "promise_to_not_use_on_mainnet" // MinAssetsPerBTC is the minimum number of asset units that one BTC // should cost. If the value is lower, then one asset unit would cost // too much to be able to represent small amounts of satoshis. With this // value, one asset unit would still cost 1k sats. MinAssetsPerBTC = 100_000 )
const ( // DefaultTimeout is the default timeout used for context operations. DefaultTimeout = 30 * time.Second // DefaultInvoiceExpiry is the default expiry time for asset invoices. // The current value corresponds to 5 minutes. DefaultInvoiceExpiry = time.Second * 300 // CacheCleanupInterval is the interval at which local runtime caches // are cleaned up. CacheCleanupInterval = 30 * time.Second )
const ( // AssetTransferUndefined is the zero value and indicates an unspecified // direction. AssetTransferUndefined = 0 // AssetTransferBuy indicates we want to buy the asset (receive asset // from edge node peer, peer gets paid sats from the Lightning network). AssetTransferBuy = 1 // AssetTransferSell indicates we want to sell the asset (send asset // to edge node peer, peer forwards Lightning payment for us). AssetTransferSell = 2 )
const ( // DefaultAcceptPriceDeviationPpm is the default price deviation in // parts per million that is accepted by the RFQ negotiator. // // NOTE: This value is set to 5% (50,000 ppm). DefaultAcceptPriceDeviationPpm = 50_000 )
const ( // PortfolioPilotRpcAddrScheme is the URL address scheme used by an RPC // portfolio pilot service. PortfolioPilotRpcAddrScheme string = "portfoliopilotrpc" )
const ( // RfqRpcOracleAddrScheme is the URL address scheme used by an RPC price // oracle service. RfqRpcOracleAddrScheme string = "rfqrpc" )
const Subsystem = "RFQS"
Subsystem defines the logging code for this subsystem.
Variables ¶
This section is empty.
Functions ¶
func DisableLog ¶
func DisableLog()
DisableLog disables all library log output. Logging output is disabled by default until UseLogger is called.
func EstimateAssetUnits ¶ added in v0.6.0
func EstimateAssetUnits(ctx context.Context, oracle PriceOracle, specifier asset.Specifier, amtMsat lnwire.MilliSatoshi, counterparty fn.Option[route.Vertex], metadata string, intent PriceQueryIntent) (uint64, error)
EstimateAssetUnits is a helper function that queries our price oracle to find out how many units of an asset are needed to evaluate to the provided amount in milli satoshi.
func MarshalAcceptedBuyQuote ¶ added in v0.7.0
func MarshalAcceptedBuyQuote(q rfqmsg.BuyAccept) *rfqrpc.PeerAcceptedBuyQuote
MarshalAcceptedBuyQuote marshals a peer accepted buy quote to its RPC representation.
func MarshalAcceptedSellQuote ¶ added in v0.6.0
func MarshalAcceptedSellQuote( accept rfqmsg.SellAccept) *rfqrpc.PeerAcceptedSellQuote
MarshalAcceptedSellQuote marshals a peer accepted sell quote to its RPC representation.
func MarshalAcceptedSellQuoteEvent ¶ added in v0.6.0
func MarshalAcceptedSellQuoteEvent( event *PeerAcceptedSellQuoteEvent) *rfqrpc.PeerAcceptedSellQuote
MarshalAcceptedSellQuoteEvent marshals a peer accepted sell quote event to its RPC representation.
func MarshalIncomingRejectQuoteEvent ¶ added in v0.6.0
func MarshalIncomingRejectQuoteEvent( event *IncomingRejectQuoteEvent) *rfqrpc.RejectedQuoteResponse
MarshalIncomingRejectQuoteEvent marshals an incoming reject quote event to its RPC representation.
func MarshalInvalidQuoteRespEvent ¶ added in v0.6.0
func MarshalInvalidQuoteRespEvent( event *InvalidQuoteRespEvent) *rfqrpc.InvalidQuoteResponse
MarshalInvalidQuoteRespEvent marshals an invalid quote response event to its rpc representation.
func NewAddAssetBuyOrderResponse ¶ added in v0.6.0
func NewAddAssetBuyOrderResponse( event fn.Event) (*rfqrpc.AddAssetBuyOrderResponse, error)
NewAddAssetBuyOrderResponse creates a new AddAssetBuyOrderResponse from the given RFQ event.
func NewAddAssetSellOrderResponse ¶ added in v0.6.0
func NewAddAssetSellOrderResponse( event fn.Event) (*rfqrpc.AddAssetSellOrderResponse, error)
NewAddAssetSellOrderResponse creates a new AddAssetSellOrderResponse from the given RFQ event.
func NewMacaroonDialOption ¶
func NewMacaroonDialOption(path string) (grpc.DialOption, error)
NewMacaroonDialOption reads a macaroon file from disk and returns a gRPC DialOption that attaches it as per-RPC credentials.
Types ¶
type AcceptHtlcEvent ¶
type AcceptHtlcEvent struct {
// Htlc is the intercepted HTLC.
Htlc lndclient.InterceptedHtlc
// Policy is the policy with which the HTLC is compliant.
Policy Policy
// contains filtered or unexported fields
}
AcceptHtlcEvent is an event that is sent to the accept HTLCs channel when an HTLC is accepted.
func NewAcceptHtlcEvent ¶
func NewAcceptHtlcEvent(htlc lndclient.InterceptedHtlc, policy Policy) *AcceptHtlcEvent
NewAcceptHtlcEvent creates a new AcceptedHtlcEvent.
func (*AcceptHtlcEvent) Timestamp ¶
func (q *AcceptHtlcEvent) Timestamp() time.Time
Timestamp returns the event creation UTC timestamp.
type AssetForwardPolicy ¶
type AssetForwardPolicy struct {
// contains filtered or unexported fields
}
AssetForwardPolicy is a struct that holds the terms which determine whether a channel HTLC for an asset-to-asset forward is accepted or rejected.
func NewAssetForwardPolicy ¶
func NewAssetForwardPolicy(incoming, outgoing Policy) (*AssetForwardPolicy, error)
NewAssetForwardPolicy creates a new asset forward policy.
func (*AssetForwardPolicy) CheckHtlcCompliance ¶
func (a *AssetForwardPolicy) CheckHtlcCompliance(ctx context.Context, htlc lndclient.InterceptedHtlc, sChk rfqmsg.SpecifierChecker) error
CheckHtlcCompliance returns an error if the given HTLC intercept descriptor does not satisfy the subject policy.
func (*AssetForwardPolicy) Expiry ¶
func (a *AssetForwardPolicy) Expiry() uint64
Expiry returns the policy's expiry time as a unix timestamp in seconds. The returned expiry time is the earliest expiry time of the incoming and outgoing policies.
func (*AssetForwardPolicy) GenerateInterceptorResponse ¶
func (a *AssetForwardPolicy) GenerateInterceptorResponse( htlc lndclient.InterceptedHtlc) (*lndclient.InterceptedHtlcResponse, error)
GenerateInterceptorResponse generates an interceptor response for the policy.
func (*AssetForwardPolicy) HasExpired ¶
func (a *AssetForwardPolicy) HasExpired() bool
HasExpired returns true if the policy has expired.
func (*AssetForwardPolicy) RfqID ¶
func (a *AssetForwardPolicy) RfqID() rfqmsg.ID
RfqID returns the RFQ session identifier for this policy. For forward policies, we use the incoming policy's RFQ ID.
func (*AssetForwardPolicy) Scid ¶
func (a *AssetForwardPolicy) Scid() uint64
Scid returns the serialised short channel ID (SCID) of the channel to which the policy applies. This is the SCID of the incoming policy.
func (*AssetForwardPolicy) TrackAcceptedHtlc ¶ added in v0.5.0
func (a *AssetForwardPolicy) TrackAcceptedHtlc(circuitKey models.CircuitKey, amt lnwire.MilliSatoshi)
TrackAcceptedHtlc accounts for the newly accepted HTLC. This may affect the acceptance of future HTLCs.
func (*AssetForwardPolicy) UntrackHtlc ¶ added in v0.5.0
func (a *AssetForwardPolicy) UntrackHtlc(circuitKey models.CircuitKey)
UntrackHtlc stops tracking the uniquely identified HTLC.
type AssetPurchasePolicy ¶
type AssetPurchasePolicy struct {
// AssetSpecifier is the identifier for the specific asset or asset
// group to which this policy applies.
AssetSpecifier asset.Specifier
// AcceptedQuoteId is the ID of the accepted quote.
AcceptedQuoteId rfqmsg.ID
// CurrentAssetAmountMsat is the total amount that is held currently in
// accepted HTLCs.
CurrentAmountMsat lnwire.MilliSatoshi
// BidAssetRate is the quote's asset to BTC conversion rate.
BidAssetRate rfqmath.BigIntFixedPoint
// PaymentMaxAmt is the maximum agreed BTC payment.
PaymentMaxAmt lnwire.MilliSatoshi
// ExecutionPolicy is the execution policy from the original
// request (annotation only; not enforced at the HTLC level).
ExecutionPolicy fn.Option[rfqmsg.ExecutionPolicy]
// contains filtered or unexported fields
}
AssetPurchasePolicy is a struct that holds the terms which determine whether an asset purchase channel HTLC is accepted or rejected.
func NewAssetPurchasePolicy ¶
func NewAssetPurchasePolicy(quote rfqmsg.SellAccept) *AssetPurchasePolicy
NewAssetPurchasePolicy creates a new asset purchase policy.
func (*AssetPurchasePolicy) CheckHtlcCompliance ¶
func (c *AssetPurchasePolicy) CheckHtlcCompliance(ctx context.Context, htlc lndclient.InterceptedHtlc, specifierChecker rfqmsg.SpecifierChecker) error
CheckHtlcCompliance returns an error if the given HTLC intercept descriptor does not satisfy the subject policy.
func (*AssetPurchasePolicy) Expiry ¶
func (c *AssetPurchasePolicy) Expiry() uint64
Expiry returns the policy's expiry time as a unix timestamp in seconds.
func (*AssetPurchasePolicy) GenerateInterceptorResponse ¶
func (c *AssetPurchasePolicy) GenerateInterceptorResponse( htlc lndclient.InterceptedHtlc) (*lndclient.InterceptedHtlcResponse, error)
GenerateInterceptorResponse generates an interceptor response for the policy.
func (*AssetPurchasePolicy) HasExpired ¶
func (c *AssetPurchasePolicy) HasExpired() bool
HasExpired returns true if the policy has expired.
func (*AssetPurchasePolicy) RfqID ¶
func (c *AssetPurchasePolicy) RfqID() rfqmsg.ID
RfqID returns the RFQ session identifier for this policy.
func (*AssetPurchasePolicy) Scid ¶
func (c *AssetPurchasePolicy) Scid() uint64
Scid returns the serialised short channel ID (SCID) of the channel to which the policy applies.
func (*AssetPurchasePolicy) TrackAcceptedHtlc ¶ added in v0.5.0
func (c *AssetPurchasePolicy) TrackAcceptedHtlc(circuitKey models.CircuitKey, amt lnwire.MilliSatoshi)
TrackAcceptedHtlc accounts for the newly accepted HTLC. This may affect the acceptance of future HTLCs.
func (*AssetPurchasePolicy) UntrackHtlc ¶ added in v0.5.0
func (c *AssetPurchasePolicy) UntrackHtlc(circuitKey models.CircuitKey)
UntrackHtlc stops tracking the uniquely identified HTLC.
type AssetRateQuery ¶
type AssetRateQuery struct {
// AssetSpecifier identifies the asset being queried.
AssetSpecifier asset.Specifier
// Direction specifies whether we want to buy or sell the asset.
Direction AssetTransferDirection
// Intent specifies the purpose of the query (e.g., paying an invoice,
// receiving payment, etc.). This determines the context for pricing.
Intent PriceQueryIntent
// AssetAmount is an optional constraint on the asset amount.
AssetAmount fn.Option[uint64]
// PaymentAmount is an optional constraint on the payment amount.
PaymentAmount fn.Option[lnwire.MilliSatoshi]
// PeerID is an optional peer identifier for peer-specific pricing.
PeerID fn.Option[route.Vertex]
// RateHint is an optional rate hint to guide pricing.
RateHint fn.Option[rfqmsg.AssetRate]
// OracleMetadata is optional metadata to pass to the price oracle.
OracleMetadata fn.Option[string]
// Expiry is an optional expiry time for the rate query.
Expiry fn.Option[time.Time]
}
AssetRateQuery bundles parameters for querying asset rates for pricing and rate discovery purposes.
type AssetSalePolicy ¶
type AssetSalePolicy struct {
// AssetSpecifier is the identifier for the specific asset or asset
// group to which this policy applies.
AssetSpecifier asset.Specifier
// AcceptedQuoteId is the unique identifier of the RFQ session quote
// accept message that the policy is associated with.
AcceptedQuoteId rfqmsg.ID
// MaxOutboundAssetAmount represents the maximum asset amount permitted
// by policy for outbound transactions. It sets an upper limit on the
// amount of assets this node is willing to divest within the remit of
// the policy.
MaxOutboundAssetAmount uint64
// CurrentAssetAmountMsat is the total amount that is held currently in
// accepted HTLCs.
CurrentAmountMsat lnwire.MilliSatoshi
// AskAssetRate is the quote's asking asset unit to BTC conversion rate.
AskAssetRate rfqmath.BigIntFixedPoint
// NoOpHTLCs is a boolean indicating whether the daemon configuration
// wants us to produce NoOp HTLCs.
NoOpHTLCs bool
// ExecutionPolicy is the execution policy from the original
// request (annotation only; not enforced at the HTLC level).
ExecutionPolicy fn.Option[rfqmsg.ExecutionPolicy]
// contains filtered or unexported fields
}
AssetSalePolicy is a struct that holds the terms which determine whether an asset sale channel HTLC is accepted or rejected.
func NewAssetSalePolicy ¶
func NewAssetSalePolicy(quote rfqmsg.BuyAccept, noop bool, chanNegotiator *tapfeatures.AuxChannelNegotiator) *AssetSalePolicy
NewAssetSalePolicy creates a new asset sale policy.
func (*AssetSalePolicy) CheckHtlcCompliance ¶
func (c *AssetSalePolicy) CheckHtlcCompliance(_ context.Context, htlc lndclient.InterceptedHtlc, _ rfqmsg.SpecifierChecker) error
CheckHtlcCompliance returns an error if the given HTLC intercept descriptor does not satisfy the subject policy.
The HTLC examined by this function was likely created by a peer unaware of the RFQ agreement (i.e., they are simply paying an invoice), with the SCID included as a hop hint within the invoice. The SCID is the only piece of information used to determine the policy applicable to the HTLC. As a result, HTLC custom records are not expected to be present.
func (*AssetSalePolicy) Expiry ¶
func (c *AssetSalePolicy) Expiry() uint64
Expiry returns the policy's expiry time as a unix timestamp.
func (*AssetSalePolicy) GenerateInterceptorResponse ¶
func (c *AssetSalePolicy) GenerateInterceptorResponse( htlc lndclient.InterceptedHtlc) (*lndclient.InterceptedHtlcResponse, error)
GenerateInterceptorResponse generates an interceptor response for the policy.
func (*AssetSalePolicy) HasExpired ¶
func (c *AssetSalePolicy) HasExpired() bool
HasExpired returns true if the policy has expired.
func (*AssetSalePolicy) RfqID ¶
func (c *AssetSalePolicy) RfqID() rfqmsg.ID
RfqID returns the RFQ session identifier for this policy.
func (*AssetSalePolicy) Scid ¶
func (c *AssetSalePolicy) Scid() uint64
Scid returns the serialised short channel ID (SCID) of the channel to which the policy applies.
func (*AssetSalePolicy) TrackAcceptedHtlc ¶ added in v0.5.0
func (c *AssetSalePolicy) TrackAcceptedHtlc(circuitKey models.CircuitKey, amt lnwire.MilliSatoshi)
TrackAcceptedHtlc accounts for the newly accepted HTLC. This may affect the acceptance of future HTLCs.
func (*AssetSalePolicy) UntrackHtlc ¶ added in v0.5.0
func (c *AssetSalePolicy) UntrackHtlc(circuitKey models.CircuitKey)
UntrackHtlc stops tracking the uniquely identified HTLC.
type AssetTransferDirection ¶
type AssetTransferDirection uint8
AssetTransferDirection represents the direction of an asset transfer from our perspective for pricing and rate queries.
func AssetTransferDirectionFromOrder ¶
func AssetTransferDirectionFromOrder(order Order) AssetTransferDirection
AssetTransferDirectionFromOrder determines the AssetTransferDirection from the order type.
func (AssetTransferDirection) String ¶
func (d AssetTransferDirection) String() string
String returns a human-readable representation of the AssetTransferDirection.
type BuyAcceptMap ¶ added in v0.5.0
type BuyAcceptMap map[SerialisedScid]rfqmsg.BuyAccept
BuyAcceptMap is a map of buy accepts, keyed by the serialised SCID.
type BuyOffer ¶
type BuyOffer struct {
// AssetID represents the identifier of the subject asset.
AssetID *asset.ID
// AssetGroupKey is the public group key of the subject asset.
AssetGroupKey *btcec.PublicKey
// MaxUnits is the maximum amount of the asset which this node is
// willing to purchase.
MaxUnits uint64
}
BuyOffer is a struct that represents an asset buy offer. This data structure describes the maximum amount of an asset that this node is willing to purchase.
A buy offer is passive (unlike a buy order), meaning that it does not actively lead to a buy request being sent to a peer. Instead, it is used by the node to selectively accept or reject incoming asset sell quote requests before price is considered.
type BuyOrder ¶
type BuyOrder struct {
// AssetSpecifier is the asset that the buyer is interested in.
AssetSpecifier asset.Specifier
// AssetMaxAmt is the maximum amount of the asset that the provider must
// be willing to offer.
AssetMaxAmt uint64
// AssetMinAmt is an optional minimum asset amount for the order.
AssetMinAmt fn.Option[uint64]
// AssetRateLimit is an optional minimum acceptable rate (asset
// units per BTC) for the order.
AssetRateLimit fn.Option[rfqmath.BigIntFixedPoint]
// ExecutionPolicy is an optional execution policy (IOC or
// FOK) for the order.
ExecutionPolicy fn.Option[rfqmsg.ExecutionPolicy]
// Expiry is the time at which the order expires.
Expiry time.Time
// Peer is the peer that the buy order is intended for. This field is
// optional.
//
// TODO(ffranr): Currently, this field must be specified. In the future,
// the negotiator should be able to determine the optimal peer.
Peer fn.Option[route.Vertex]
// PriceOracleMetadata is an optional text field that can be used to
// provide additional metadata about the buy order to the price
// oracle. This can include information about the wallet end user that
// initiated the transaction, or any authentication information that the
// price oracle can use to give out a more accurate (or discount) asset
// rate. The maximum length of this field is 32'768 bytes.
PriceOracleMetadata string
}
BuyOrder instructs the RFQ (Request For Quote) system to request a quote from one or more peers for the acquisition of an asset.
The normal use of a buy order is as follows:
- Alice, operating a wallet node, wants to receive a Tap asset as payment by issuing a Lightning invoice.
- Alice has an asset channel established with Bob's edge node.
- Before issuing the invoice, Alice needs to agree on an exchange rate with Bob, who will facilitate the asset transfer.
- To obtain the best exchange rate, Alice creates a buy order specifying the desired asset.
- Alice's RFQ subsystem processes the buy order and sends buy requests to relevant peers to find the best rate. In this example, Bob is the only available peer.
- Once Bob provides a satisfactory quote, Alice accepts it.
- Alice issues the Lightning invoice, which Charlie will pay.
- Instead of paying Alice directly, Charlie pays Bob.
- Bob then forwards the agreed amount of the Tap asset to Alice over their asset channel.
func (*BuyOrder) GetAssetSpecifier ¶
GetAssetSpecifier returns the asset specifier for this buy order.
func (*BuyOrder) GetPriceOracleMetadata ¶
GetPriceOracleMetadata returns the price oracle metadata for this buy order.
type ChanIntention ¶ added in v0.6.0
type ChanIntention uint8
ChanIntention defines the intention of calling rfqChannel. This helps with returning the channel that is most suitable for what we want to do.
const ( // NoIntention defines the absence of any intention, signalling that we // don't really care which channel is returned. NoIntention ChanIntention = iota // SendIntention defines the intention to send over an asset channel. SendIntention // ReceiveIntention defines the intention to receive over an asset // channel. ReceiveIntention )
type ChannelLister ¶
type ChannelLister interface {
// ListChannels returns a list of channels that are available for
// routing.
ListChannels(ctx context.Context, activeOnly, publicOnly bool,
_ ...lndclient.ListChannelsOption) ([]lndclient.ChannelInfo,
error)
}
ChannelLister is an interface that provides a list of channels that are available for routing.
type CliConfig ¶
type CliConfig struct {
PriceOracleAddress string `` /* 215-byte string literal not displayed */
// PortfolioPilotAddress is the portfolio pilot gRPC server address.
PortfolioPilotAddress string `long:"portfoliopilotaddress" description:"Portfolio pilot gRPC server address (portfoliopilotrpc://<hostname>:<port>)"`
PriceOracleTLSDisable bool `long:"priceoracletlsdisable" description:"Disable TLS for price oracle communication."`
PriceOracleTLSInsecure bool `long:"priceoracletlsinsecure" description:"Disable price oracle certificate verification."`
PriceOracleTLSNoSystemCAs bool `` /* 144-byte string literal not displayed */
PriceOracleTLSCertPath string `` /* 145-byte string literal not displayed */
PriceOracleMacaroonPath string `long:"priceoraclemacaroonpath" description:"Path to the macaroon to use when connecting to the price oracle gRPC server."`
SendPriceHint bool `` /* 214-byte string literal not displayed */
PriceOracleSendPeerId bool `` /* 227-byte string literal not displayed */
PriceOracleDisableNodeId bool `` /* 232-byte string literal not displayed */
AcceptPriceDeviationPpm uint64 `` /* 132-byte string literal not displayed */
SkipQuoteAcceptVerify bool `long:"skipquoteacceptverify" description:"Skip verification of quote accept messages returned by RFQ peer"`
MockOracleAssetsPerBTC uint64 `` /* 270-byte string literal not displayed */
// TODO(ffranr): Remove in favour of MockOracleAssetsPerBTC.
MockOracleSatsPerAsset uint64 `` /* 289-byte string literal not displayed */
}
CliConfig is a struct that holds tapd cli configuration options for the RFQ service.
nolint: lll
type ForwardInput ¶
type ForwardInput struct {
// OpenedAt is the time when the forward was initiated.
OpenedAt time.Time
// SettledAt is the time when the forward settled (if any).
SettledAt fn.Option[time.Time]
// FailedAt is the time when the forward failed (if any).
FailedAt fn.Option[time.Time]
// RfqID is the RFQ session identifier for this forward.
RfqID rfqmsg.ID
// ChanIDIn is the short channel ID of the incoming channel.
ChanIDIn uint64
// ChanIDOut is the short channel ID of the outgoing channel.
ChanIDOut uint64
// HtlcID is the HTLC ID on the incoming channel.
HtlcID uint64
// AssetAmt is the asset amount involved in this swap.
AssetAmt uint64
// AmtInMsat is the actual amount received on the incoming channel in
// millisatoshis.
AmtInMsat uint64
// AmtOutMsat is the actual amount sent on the outgoing channel in
// millisatoshis.
AmtOutMsat uint64
}
ForwardInput contains the data needed to upsert a forward event.
type ForwardStore ¶
type ForwardStore interface {
// UpsertForward inserts or updates a forwarding event record in the
// database.
UpsertForward(ctx context.Context, input ForwardInput) error
// PendingForwards retrieves forwards that haven't settled or failed.
PendingForwards(ctx context.Context) ([]ForwardInput, error)
// QueryForwardsWithCount retrieves forwarding event records matching
// the given filters along with the total count.
QueryForwardsWithCount(ctx context.Context,
params QueryForwardsParams) ([]ForwardingEvent, int64, error)
}
ForwardStore abstracts persistence of forwarding events.
type ForwardingEvent ¶
type ForwardingEvent struct {
// OpenedAt is the time when the forward was initiated.
OpenedAt time.Time
// SettledAt is the time when the forward settled (nil if not settled).
SettledAt *time.Time
// FailedAt is the time when the forward failed (nil if not failed).
FailedAt *time.Time
// RfqID is the RFQ session identifier.
RfqID rfqmsg.ID
// ChanIDIn is the short channel ID of the incoming channel.
ChanIDIn uint64
// ChanIDOut is the short channel ID of the outgoing channel.
ChanIDOut uint64
// HtlcID is the HTLC ID on the incoming channel.
HtlcID uint64
// AssetAmt is the asset amount involved in this swap.
AssetAmt uint64
// AmtInMsat is the actual amount received on the incoming channel in
// millisatoshis.
AmtInMsat uint64
// AmtOutMsat is the actual amount sent on the outgoing channel in
// millisatoshis.
AmtOutMsat uint64
// PolicyType indicates whether this was a sale or purchase from the
// edge node's perspective.
PolicyType RfqPolicyType
// Peer is the counterparty peer's public key.
Peer route.Vertex
// AssetSpecifier identifies the specific asset or asset group (if set).
AssetSpecifier asset.Specifier
// Rate is the exchange rate used for this forward.
Rate rfqmath.BigIntFixedPoint
}
ForwardingEvent is a complete forwarding event record including policy data.
type GroupLookup ¶ added in v0.6.0
type GroupLookup interface {
// QueryAssetGroupByID fetches the group information of an asset, if it
// belongs in a group.
QueryAssetGroupByID(context.Context, asset.ID) (*asset.AssetGroup,
error)
}
GroupLookup is an interface that helps us look up a group of an asset based on the asset ID.
type HtlcInterceptor ¶
type HtlcInterceptor interface {
// InterceptHtlcs intercepts HTLCs, using the handling function provided
// to respond to HTLCs.
InterceptHtlcs(context.Context, lndclient.HtlcInterceptHandler) error
}
HtlcInterceptor is an interface that abstracts the hash time locked contract (HTLC) intercept functionality.
type HtlcSubscriber ¶ added in v0.5.0
type HtlcSubscriber interface {
// SubscribeHtlcEvents subscribes to a stream of events related to
// HTLC updates.
SubscribeHtlcEvents(ctx context.Context) (<-chan *routerrpc.HtlcEvent,
<-chan error, error)
// LookupHtlcResolution retrieves the final resolution for an HTLC.
LookupHtlcResolution(ctx context.Context, chanID uint64,
htlcID uint64) (*lnrpc.LookupHtlcResolutionResponse, error)
}
HtlcSubscriber is an interface that contains the function necessary for retrieving live HTLC event updates.
type InboundPolicyFetcher ¶ added in v0.6.0
type InboundPolicyFetcher func(ctx context.Context, chanID uint64, remotePubStr string) (*lnrpc.RoutingPolicy, error)
InboundPolicyFetcher is a helper that fetches the inbound policy of a channel based on its chanID.
type IncomingRejectQuoteEvent ¶
type IncomingRejectQuoteEvent struct {
// Reject is the rejected quote.
rfqmsg.Reject
// contains filtered or unexported fields
}
IncomingRejectQuoteEvent is an event that is broadcast when the RFQ manager receives a reject quote message from a peer.
func NewIncomingRejectQuoteEvent ¶
func NewIncomingRejectQuoteEvent( reject *rfqmsg.Reject) *IncomingRejectQuoteEvent
NewIncomingRejectQuoteEvent creates a new IncomingRejectQuoteEvent.
func (*IncomingRejectQuoteEvent) Timestamp ¶
func (q *IncomingRejectQuoteEvent) Timestamp() time.Time
Timestamp returns the event creation UTC timestamp.
type InternalPortfolioPilot ¶
type InternalPortfolioPilot struct {
// contains filtered or unexported fields
}
InternalPortfolioPilot is the built-in RFQ decision logic that delegates pricing to an external price oracle.
func NewInternalPortfolioPilot ¶
func NewInternalPortfolioPilot( cfg InternalPortfolioPilotConfig) (InternalPortfolioPilot, error)
NewInternalPortfolioPilot constructs a new pilot using the provided config.
func (*InternalPortfolioPilot) Close ¶
func (p *InternalPortfolioPilot) Close() error
Close releases resources held by the internal portfolio pilot. The internal pilot is in-memory only, so this is a no-op.
func (*InternalPortfolioPilot) QueryAssetRates ¶
func (p *InternalPortfolioPilot) QueryAssetRates(ctx context.Context, query AssetRateQuery) (rfqmsg.AssetRate, error)
QueryAssetRates returns current asset rate information by querying the configured price oracle based on the transfer direction and query parameters.
func (*InternalPortfolioPilot) ResolveRequest ¶
func (p *InternalPortfolioPilot) ResolveRequest(ctx context.Context, request rfqmsg.Request) (ResolveResp, error)
ResolveRequest resolves a quote request by querying the configured price oracle. It accepts with a quote when a valid rate is returned, rejects when no oracle is configured, and errors on unexpected oracle failures or missing rates.
func (*InternalPortfolioPilot) VerifyAcceptQuote ¶
func (p *InternalPortfolioPilot) VerifyAcceptQuote(ctx context.Context, accept rfqmsg.Accept) (QuoteRespStatus, error)
VerifyAcceptQuote verifies that an accepted quote from a peer meets acceptable conditions. It validates the quote expiry and checks that the peer's proposed rate falls within acceptable tolerance of the oracle price.
type InternalPortfolioPilotConfig ¶
type InternalPortfolioPilotConfig struct {
// PriceOracle supplies pricing data. If nil, the pilot rejects requests
// as the oracle is considered unavailable.
PriceOracle PriceOracle
// ForwardPeerIDToOracle controls whether the requesting peer ID is sent
// to the oracle for peer-specific pricing. Disabling this avoids
// sharing caller identity with the oracle.
ForwardPeerIDToOracle bool
// AcceptPriceDeviationPpm specifies the maximum allowable price
// deviation in parts per million (PPM) when verifying accepted quotes.
// This defines the tolerance threshold for comparing peer quotes
// against oracle prices.
AcceptPriceDeviationPpm uint64
// MinAssetRatesExpiryLifetime specifies the minimum lifetime in
// seconds for an asset rate expiry to be considered valid.
MinAssetRatesExpiryLifetime uint64
}
InternalPortfolioPilotConfig holds settings for the built-in pilot that uses a price oracle for pricing decisions.
func (*InternalPortfolioPilotConfig) Validate ¶
func (c *InternalPortfolioPilotConfig) Validate() error
Validate checks the config for validity.
type InvalidQuoteRespEvent ¶
type InvalidQuoteRespEvent struct {
// QuoteResponse is the quote response received from the peer which was
// deemed invalid.
QuoteResponse rfqmsg.QuoteResponse
// Status is the status of the quote response.
Status QuoteRespStatus
// contains filtered or unexported fields
}
InvalidQuoteRespEvent is an event that is broadcast when the RFQ manager receives an unacceptable quote response message from a peer.
func NewInvalidQuoteRespEvent ¶
func NewInvalidQuoteRespEvent(quoteResponse rfqmsg.QuoteResponse, status QuoteRespStatus) *InvalidQuoteRespEvent
NewInvalidQuoteRespEvent creates a new InvalidBuyRespEvent.
func (*InvalidQuoteRespEvent) Timestamp ¶
func (q *InvalidQuoteRespEvent) Timestamp() time.Time
Timestamp returns the event creation UTC timestamp.
type Manager ¶
type Manager struct {
// ContextGuard provides a wait group and main quit channel that can be
// used to create guarded contexts.
*fn.ContextGuard
// contains filtered or unexported fields
}
Manager is a struct that manages the request for quote (RFQ) system.
func NewManager ¶
func NewManager(cfg ManagerCfg) (*Manager, error)
NewManager creates a new RFQ manager.
func (*Manager) AssetMatchesSpecifier ¶ added in v0.6.0
func (m *Manager) AssetMatchesSpecifier(ctx context.Context, specifier asset.Specifier, id asset.ID) (bool, error)
AssetMatchesSpecifier checks if the provided asset satisfies the provided specifier. If the specifier includes a group key, we will check if the asset belongs to that group.
func (*Manager) ChannelMatchesFully ¶ added in v0.6.0
func (m *Manager) ChannelMatchesFully(ctx context.Context, jsonChannel rfqmsg.JsonAssetChannel, specifier asset.Specifier) (bool, error)
ChannelMatchesFully checks a channel's assets against an asset specifier. If the specifier is an asset ID, then all asset UTXOs must be of that specific ID, if the specifier is a group key, then all assets in the channel must belong to that group.
func (*Manager) ComputeChannelAssetBalance ¶ added in v0.6.0
func (m *Manager) ComputeChannelAssetBalance(ctx context.Context, activeChannels []lndclient.ChannelInfo, specifier asset.Specifier) (PeerChanMap, bool, error)
ComputeChannelAssetBalance computes the total local and remote balance for each asset channel that matches the provided asset specifier.
func (*Manager) FetchChannel ¶ added in v0.6.0
func (m *Manager) FetchChannel(ctx context.Context, specifier asset.Specifier, peerPubKey *route.Vertex, intention ChanIntention) (PeerChanMap, error)
FetchChannel returns the channel to use for RFQ operations. It returns a map of peers and their eligible channels. If a peerPubKey is specified then the map will only contain one entry for that peer.
func (*Manager) GetPriceDeviationPpm ¶ added in v0.6.0
GetPriceDeviationPpm returns the configured price deviation in ppm that is used in rfq negotiations.
func (*Manager) LocalAcceptedBuyQuotes ¶
func (m *Manager) LocalAcceptedBuyQuotes() BuyAcceptMap
LocalAcceptedBuyQuotes returns buy quotes that were accepted by our node and have been requested by our peers. These quotes are exclusively available to our node for the acquisition of assets.
func (*Manager) LocalAcceptedSellQuotes ¶
func (m *Manager) LocalAcceptedSellQuotes() SellAcceptMap
LocalAcceptedSellQuotes returns sell quotes that were accepted by our node and have been requested by our peers. These quotes are exclusively available to our node for the sale of assets.
func (*Manager) LookUpScid ¶
LookUpScid resolves the peer associated with a given SCID for peer-accepted buy quotes (i.e. quotes where our node requested to buy assets and the peer accepted). It checks (in order): the active in-memory peerBuyQuotes map, the LRU cache, and finally the database (filtered to peer-accepted buy policies only). Results from the DB are cached in the LRU for future lookups.
This method is safe for concurrent use. Each tier is individually thread-safe, and the composition is correct because SCID-to-peer mappings are immutable once created — a given SCID always resolves to the same peer. Concurrent misses that fall through to the DB will produce identical results, making the subsequent cache Put idempotent.
func (*Manager) PeerAcceptedBuyQuotes ¶
func (m *Manager) PeerAcceptedBuyQuotes() BuyAcceptMap
PeerAcceptedBuyQuotes returns buy quotes that were requested by our node and have been accepted by our peers. These quotes are exclusively available to our node for the acquisition of assets.
func (*Manager) PeerAcceptedSellQuotes ¶
func (m *Manager) PeerAcceptedSellQuotes() SellAcceptMap
PeerAcceptedSellQuotes returns sell quotes that were requested by our node and have been accepted by our peers. These quotes are exclusively available to our node for the sale of assets.
func (*Manager) QueryForwardsWithCount ¶
func (m *Manager) QueryForwardsWithCount(ctx context.Context, params QueryForwardsParams) ([]ForwardingEvent, int64, error)
QueryForwardsWithCount retrieves historical forwarding event records matching the given filters, along with the total count.
func (*Manager) RegisterSubscriber ¶
func (m *Manager) RegisterSubscriber( receiver *fn.EventReceiver[fn.Event], deliverExisting bool, deliverFrom uint64) error
RegisterSubscriber adds a new subscriber to the set of subscribers that will be notified of any new events that are broadcast.
TODO(ffranr): Add support for delivering existing events to new subscribers.
func (*Manager) RemoveAssetSellOffer ¶
RemoveAssetSellOffer removes an asset sell offer from the RFQ manager.
func (*Manager) RemoveSubscriber ¶
RemoveSubscriber removes a subscriber from the set of subscribers that will be notified of any new events that are broadcast.
func (*Manager) RfqToHopHint ¶ added in v0.6.0
func (m *Manager) RfqToHopHint(ctx context.Context, policyFetcher InboundPolicyFetcher, channelID uint64, peerPubKey route.Vertex, quote *rfqrpc.PeerAcceptedBuyQuote, hold bool) (*zpay32.HopHint, error)
RfqToHopHint creates the hop hint representation which encapsulates certain quote information along with some other data required by the payment to succeed. Depending on whether the hold flag is set, we either return the lnrpc version of a hop hint or the zpay32 version. This is because we use the lndclient wrapper for hold invoices while we use the raw lnrpc endpoint for simple invoices.
func (*Manager) UpsertAssetBuyOffer ¶
UpsertAssetBuyOffer upserts an asset buy offer for management by the RFQ system. If the offer already exists for the given asset, it will be updated.
func (*Manager) UpsertAssetBuyOrder ¶
UpsertAssetBuyOrder upserts an asset buy order for management.
func (*Manager) UpsertAssetSellOffer ¶
UpsertAssetSellOffer upserts an asset sell offer for management by the RFQ system. If the offer already exists for the given asset, it will be updated.
type ManagerCfg ¶
type ManagerCfg struct {
// PeerMessenger is the peer messenger. This component provides the RFQ
// manager with the ability to send and receive raw peer messages.
PeerMessenger PeerMessenger
// HtlcInterceptor is the HTLC interceptor. This component is used to
// intercept and accept/reject HTLCs.
HtlcInterceptor HtlcInterceptor
// HtlcSubscriber is a subscriber that is used to retrieve live HTLC
// event updates.
HtlcSubscriber HtlcSubscriber
// PriceOracle is the price oracle that the RFQ manager will use to
// determine whether a quote is accepted or rejected.
PriceOracle PriceOracle
// PortfolioPilot is the portfolio pilot that will make financial
// decisions based on RFQ requests.
PortfolioPilot PortfolioPilot
// ChannelLister is the channel lister that the RFQ manager will use to
// determine the available channels for routing.
ChannelLister ChannelLister
// GroupLookup is an interface that helps us querry asset groups by
// asset IDs.
GroupLookup GroupLookup
// AliasManager is the SCID alias manager. This component is injected
// into the manager once lnd and tapd are hooked together.
AliasManager ScidAliasManager
// AuxChannelNegotiator is responsible for producing the extra tlv blob
// that is encapsulated in the init and reestablish peer messages. This
// helps us communicate custom feature bits with our peer.
AuxChanNegotiator *tapfeatures.AuxChannelNegotiator
// PolicyStore provides persistence for agreed RFQ policies.
PolicyStore PolicyStore
// ForwardStore provides persistence for forwarding events. This is
// used for edge node accounting. If nil, forwarding event logging is
// disabled.
ForwardStore ForwardStore
// AcceptPriceDeviationPpm is the price deviation in
// parts per million that is accepted by the RFQ negotiator.
//
// Example: 50,000 ppm => price deviation is set to 5% .
AcceptPriceDeviationPpm uint64
// SkipQuoteAcceptVerify is a flag that, when set, will cause the
// RFQ negotiator to skip verification on incoming quote accept
// messages (this means that the price oracle will not be queried).
SkipQuoteAcceptVerify bool
// NoOpHTLCs is a boolean indicating whether the daemon configuration
// wants us to produce NoOp HTLCs.
NoOpHTLCs bool
// SendPriceHint is a flag that, if set, will send a price hint to the
// peer when requesting a quote.
SendPriceHint bool
// SendPeerId is a flag that, if set, will send the peer ID (public
// key of the peer) to the price oracle when requesting a price rate.
SendPeerId bool
// ErrChan is the main error channel which will be used to report back
// critical errors to the main server.
ErrChan chan<- error
}
ManagerCfg is a struct that holds the configuration parameters for the RFQ manager.
type MockPriceOracle ¶
type MockPriceOracle struct {
// Mock is the underlying mock object used to track method invocations
// in tests.
mock.Mock
// contains filtered or unexported fields
}
MockPriceOracle is a mock implementation of the PriceOracle interface. It returns the suggested rate as the exchange rate.
func NewMockPriceOracle ¶
func NewMockPriceOracle(expiryDelay, assetRateCoefficient uint64) *MockPriceOracle
NewMockPriceOracle creates a new mock price oracle.
func NewMockPriceOracleSatPerAsset ¶
func NewMockPriceOracleSatPerAsset(expiryDelay uint64, satsPerAsset uint64) *MockPriceOracle
NewMockPriceOracleSatPerAsset creates a new mock price oracle with a specified satoshis per asset rate.
func (*MockPriceOracle) QueryBuyPrice ¶ added in v0.7.0
func (m *MockPriceOracle) QueryBuyPrice(ctx context.Context, assetSpecifier asset.Specifier, assetMaxAmt fn.Option[uint64], paymentMaxAmt fn.Option[lnwire.MilliSatoshi], assetRateHint fn.Option[rfqmsg.AssetRate], counterparty fn.Option[route.Vertex], metadata string, intent PriceQueryIntent) (*OracleResponse, error)
QueryBuyPrice returns a buy price for the given asset amount.
func (*MockPriceOracle) QuerySellPrice ¶ added in v0.7.0
func (m *MockPriceOracle) QuerySellPrice(ctx context.Context, assetSpecifier asset.Specifier, assetMaxAmt fn.Option[uint64], paymentMaxAmt fn.Option[lnwire.MilliSatoshi], assetRateHint fn.Option[rfqmsg.AssetRate], counterparty fn.Option[route.Vertex], metadata string, intent PriceQueryIntent) (*OracleResponse, error)
QuerySellPrice returns the sell price for the given asset amount.
type Negotiator ¶
type Negotiator struct {
// ContextGuard provides a wait group and main quit channel that can be
// used to create guarded contexts.
*fn.ContextGuard
// contains filtered or unexported fields
}
Negotiator is a struct that handles the negotiation of quotes. It is a RFQ subsystem. It determines whether a quote request is accepted or rejected.
func NewNegotiator ¶
func NewNegotiator(cfg NegotiatorCfg) (*Negotiator, error)
NewNegotiator creates a new quote negotiator.
func (*Negotiator) HandleIncomingBuyAccept ¶
func (n *Negotiator) HandleIncomingBuyAccept(ctx context.Context, msg rfqmsg.BuyAccept, finalise func(rfqmsg.BuyAccept, fn.Option[InvalidQuoteRespEvent]))
HandleIncomingBuyAccept handles an incoming buy accept message. This method is called when a peer accepts a quote request from this node. The method delegates validation to the portfolio pilot. Once validation is complete, the finalise callback function is called.
func (*Negotiator) HandleIncomingQuoteRequest ¶
HandleIncomingQuoteRequest handles an incoming asset buy or sell quote request. It runs as a goroutine to avoid blocking the caller. The function queries the portfolio pilot to determine whether to accept or reject the quote. Based on the pilot's decision, it sends either an accept message with an asset rate or a reject message to outgoing messages channel.
func (*Negotiator) HandleIncomingSellAccept ¶
func (n *Negotiator) HandleIncomingSellAccept(ctx context.Context, msg rfqmsg.SellAccept, finalise func(rfqmsg.SellAccept, fn.Option[InvalidQuoteRespEvent]))
HandleIncomingSellAccept handles an incoming sell accept message. This method is called when a peer accepts a quote request from this node. The method delegates validation to the portfolio pilot. Once validation is complete, the finalise callback function is called.
func (*Negotiator) HandleOutgoingBuyOrder ¶
func (n *Negotiator) HandleOutgoingBuyOrder(ctx context.Context, buyOrder BuyOrder) (rfqmsg.ID, error)
HandleOutgoingBuyOrder handles an outgoing buy order by constructing buy requests and passing them to the outgoing messages channel. These requests are sent to peers.
func (*Negotiator) HandleOutgoingSellOrder ¶
func (n *Negotiator) HandleOutgoingSellOrder(ctx context.Context, order SellOrder) (rfqmsg.ID, error)
HandleOutgoingSellOrder handles an outgoing sell order by constructing sell requests and passing them to the outgoing messages channel. These requests are sent to peers.
func (*Negotiator) RemoveAssetSellOffer ¶
RemoveAssetSellOffer removes an asset sell offer from the negotiator.
func (*Negotiator) UpsertAssetBuyOffer ¶
func (n *Negotiator) UpsertAssetBuyOffer(offer BuyOffer) error
UpsertAssetBuyOffer upserts an asset buy offer. If the offer already exists for the given asset, it will be updated.
func (*Negotiator) UpsertAssetSellOffer ¶
func (n *Negotiator) UpsertAssetSellOffer(offer SellOffer) error
UpsertAssetSellOffer upserts an asset sell offer. If the offer already exists for the given asset, it will be updated.
type NegotiatorCfg ¶
type NegotiatorCfg struct {
// PriceOracle is the price oracle that the negotiator will use to
// determine whether a quote is accepted or rejected.
PriceOracle PriceOracle
// PortfolioPilot makes financial decisions when evaluating quotes.
PortfolioPilot PortfolioPilot
// OutgoingMessages is a channel which is populated with outgoing peer
// messages. These are messages which are destined to be sent to peers.
OutgoingMessages chan<- rfqmsg.OutgoingMsg
// AcceptPriceDeviationPpm specifies the maximum allowable price
// deviation in parts per million (PPM). This parameter defines the
// threshold for the price returned by the price oracle service,
// indicating how much it can deviate from a peer's quote accept price
// for the node to consider using the accepted quote.
AcceptPriceDeviationPpm uint64
// SkipQuoteAcceptVerify is a flag that, if set, will skip the
// verification process when validating an incoming quote accept
// message. This is useful for testing purposes.
SkipQuoteAcceptVerify bool
// SendPriceHint is a flag that, if set, will send a price hint to the
// peer when requesting a quote.
SendPriceHint bool
// SendPeerId is a flag that, if set, will send the peer ID (public
// key of the peer) to the price oracle when requesting a price rate.
SendPeerId bool
// ErrChan is a channel that is populated with errors by this subsystem.
ErrChan chan<- error
}
NegotiatorCfg holds the configuration for the negotiator.
type OracleAddr ¶
OracleAddr is a type alias for a URL type that represents a price oracle service address.
func ParsePriceOracleAddress ¶
func ParsePriceOracleAddress(addrStr string) (*OracleAddr, error)
ParsePriceOracleAddress parses a price oracle service address string and returns a URL type instance.
type OracleError ¶
type OracleError struct {
// Code is a code which uniquely identifies the error type.
Code OracleErrorCode
// Msg is a human-readable error message.
Msg string
}
OracleError is a struct that holds an error returned by the price oracle service.
func (*OracleError) Error ¶
func (o *OracleError) Error() string
Error returns a human-readable string representation of the error.
type OracleErrorCode ¶
type OracleErrorCode uint8
OracleErrorCode uniquely identifies the kinds of error an oracle may return.
const ( // UnspecifiedOracleErrorCode represents the case where the oracle has // declined to give a more specific reason for the error. UnspecifiedOracleErrorCode OracleErrorCode = 0 // UnsupportedAssetOracleErrorCode represents the case in which an // oracle does not provide quotes for the requested asset. UnsupportedAssetOracleErrorCode OracleErrorCode = 1 )
type OracleResponse ¶ added in v0.5.0
type OracleResponse struct {
// AssetRate is the asset to BTC rate. Other asset in the transfer is
// assumed to be BTC and therefore not included in the response.
AssetRate rfqmsg.AssetRate
// Err is an optional error returned by the price oracle service.
Err *OracleError
}
OracleResponse is a struct that holds the price oracle's suggested buy or sell price for an asset swap.
type Order ¶
type Order interface {
// GetAssetSpecifier returns the asset specifier for this order.
GetAssetSpecifier() asset.Specifier
// GetPeer returns the optional peer for this order.
GetPeer() fn.Option[route.Vertex]
// GetPriceOracleMetadata returns the price oracle metadata for this
// order.
GetPriceOracleMetadata() string
// GetExpiry returns the expiry time for this order.
GetExpiry() time.Time
}
Order is an interface that abstracts common functionality between buy and sell orders.
type OrderHandler ¶
type OrderHandler struct {
// ContextGuard provides a wait group and main quit channel that can be
// used to create guarded contexts.
*fn.ContextGuard
// contains filtered or unexported fields
}
OrderHandler orchestrates management of accepted quote bundles. It monitors HTLCs (Hash Time Locked Contracts), and determines acceptance/rejection based on the terms of the associated accepted quote.
func NewOrderHandler ¶
func NewOrderHandler(cfg OrderHandlerCfg) (*OrderHandler, error)
NewOrderHandler creates a new struct instance.
func (*OrderHandler) RegisterAssetPurchasePolicy ¶
func (h *OrderHandler) RegisterAssetPurchasePolicy(ctx context.Context, sellAccept rfqmsg.SellAccept) error
RegisterAssetPurchasePolicy generates and registers an asset buy policy with the order handler. This function takes an incoming sell accept message as an argument.
func (*OrderHandler) RegisterAssetSalePolicy ¶
func (h *OrderHandler) RegisterAssetSalePolicy(ctx context.Context, buyAccept rfqmsg.BuyAccept) error
RegisterAssetSalePolicy generates and registers an asset sale policy with the order handler. This function takes an outgoing buy accept message as an argument.
func (*OrderHandler) ReportMainChanError ¶ added in v0.7.1
func (h *OrderHandler) ReportMainChanError(err error)
ReportMainChanError sends an error to the main error channel.
type OrderHandlerCfg ¶
type OrderHandlerCfg struct {
// CleanupInterval is the interval at which the order handler cleans up
// expired accepted quotes from its local cache.
CleanupInterval time.Duration
// HtlcInterceptor is the HTLC interceptor. This component is used to
// intercept and accept/reject HTLCs.
HtlcInterceptor HtlcInterceptor
// AliasManager is the SCID alias manager. This component is used to add
// and remove SCID aliases.
AliasManager ScidAliasManager
// AcceptHtlcEvents is a channel that receives accepted HTLCs.
AcceptHtlcEvents chan<- *AcceptHtlcEvent
// HtlcSubscriber is a subscriber that is used to retrieve live HTLC
// event updates.
HtlcSubscriber HtlcSubscriber
// SpecifierChecker is an interface that contains methods for
// checking certain properties related to asset specifiers.
SpecifierChecker rfqmsg.SpecifierChecker
// NoOpHTLCs is a boolean indicating whether the daemon configuration
// wants us to produce NoOp HTLCs.
NoOpHTLCs bool
// AuxChannelNegotiator is responsible for producing the extra tlv blob
// that is encapsulated in the init and reestablish peer messages. This
// helps us communicate custom feature bits with our peer.
AuxChanNegotiator *tapfeatures.AuxChannelNegotiator
// ErrChan is the main error channel that is used to propagate critical
// errors back to the parent manager/server.
ErrChan chan<- error
// PolicyStore persists agreed RFQ policies.
PolicyStore PolicyStore
// ForwardStore persists forwarding events for accounting.
// If nil, forwarding event logging is disabled.
ForwardStore ForwardStore
}
OrderHandlerCfg is a struct that holds the configuration parameters for the order handler service.
type PeerAcceptedBuyQuoteEvent ¶
type PeerAcceptedBuyQuoteEvent struct {
// BuyAccept is the accepted asset buy quote.
rfqmsg.BuyAccept
// contains filtered or unexported fields
}
PeerAcceptedBuyQuoteEvent is an event that is broadcast when the RFQ manager receives an accept quote message from a peer. This is a quote which was requested by our node and has been accepted by a peer.
func NewPeerAcceptedBuyQuoteEvent ¶
func NewPeerAcceptedBuyQuoteEvent( buyAccept *rfqmsg.BuyAccept) *PeerAcceptedBuyQuoteEvent
NewPeerAcceptedBuyQuoteEvent creates a new PeerAcceptedBuyQuoteEvent.
func (*PeerAcceptedBuyQuoteEvent) MatchesOrder ¶ added in v0.6.0
func (q *PeerAcceptedBuyQuoteEvent) MatchesOrder(order BuyOrder) bool
MatchesOrder checks if the sell quote matches the provided order.
func (*PeerAcceptedBuyQuoteEvent) Timestamp ¶
func (q *PeerAcceptedBuyQuoteEvent) Timestamp() time.Time
Timestamp returns the event creation UTC timestamp.
type PeerAcceptedSellQuoteEvent ¶
type PeerAcceptedSellQuoteEvent struct {
// SellAccept is the accepted asset sell quote.
rfqmsg.SellAccept
// contains filtered or unexported fields
}
PeerAcceptedSellQuoteEvent is an event that is broadcast when the RFQ manager receives an asset sell request accept quote message from a peer. This is a quote which was requested by our node and has been accepted by a peer.
func NewPeerAcceptedSellQuoteEvent ¶
func NewPeerAcceptedSellQuoteEvent( sellAccept *rfqmsg.SellAccept) *PeerAcceptedSellQuoteEvent
NewPeerAcceptedSellQuoteEvent creates a new PeerAcceptedSellQuoteEvent.
func (*PeerAcceptedSellQuoteEvent) MatchesOrder ¶ added in v0.6.0
func (q *PeerAcceptedSellQuoteEvent) MatchesOrder(order SellOrder) bool
MatchesOrder checks if the sell quote matches the provided order.
func (*PeerAcceptedSellQuoteEvent) Timestamp ¶
func (q *PeerAcceptedSellQuoteEvent) Timestamp() time.Time
Timestamp returns the event creation UTC timestamp.
type PeerChanMap ¶ added in v0.6.0
type PeerChanMap map[route.Vertex][]TapChannel
PeerChanMap is a structure that maps peers to channels. This is used for filtering asset channels against an asset specifier.
type PeerMessenger ¶
type PeerMessenger interface {
// SubscribeCustomMessages creates a subscription to raw messages
// received from our peers.
SubscribeCustomMessages(
ctx context.Context) (<-chan lndclient.CustomMessage,
<-chan error, error)
// SendCustomMessage sends a raw message to a peer.
SendCustomMessage(context.Context, lndclient.CustomMessage) error
}
PeerMessenger is an interface that abstracts the peer message transport layer.
type Policy ¶
type Policy interface {
// CheckHtlcCompliance returns an error if the given HTLC intercept
// descriptor does not satisfy the subject policy.
CheckHtlcCompliance(ctx context.Context, htlc lndclient.InterceptedHtlc,
specifierChecker rfqmsg.SpecifierChecker) error
// Expiry returns the policy's expiry time as a unix timestamp.
Expiry() uint64
// HasExpired returns true if the policy has expired.
HasExpired() bool
// Scid returns the serialised short channel ID (SCID) of the channel to
// which the policy applies.
Scid() uint64
// RfqID returns the RFQ session identifier for this policy.
RfqID() rfqmsg.ID
// TrackAcceptedHtlc makes the policy aware of this new accepted HTLC.
// This is important in cases where the set of existing HTLCs may affect
// whether the next compliance check passes.
TrackAcceptedHtlc(circuitKey models.CircuitKey, amt lnwire.MilliSatoshi)
// UntrackHtlc stops tracking the uniquely identified HTLC.
UntrackHtlc(circuitKey models.CircuitKey)
// GenerateInterceptorResponse generates an interceptor response for the
// HTLC interceptor from the policy.
GenerateInterceptorResponse(
lndclient.InterceptedHtlc) (*lndclient.InterceptedHtlcResponse,
error)
}
Policy is an interface that abstracts the terms which determine whether an asset sale/purchase channel HTLC is accepted or rejected.
type PolicyStore ¶
type PolicyStore interface {
// StoreSalePolicy stores an asset sale policy.
StoreSalePolicy(ctx context.Context, accept rfqmsg.BuyAccept) error
// StorePurchasePolicy stores an asset purchase policy.
StorePurchasePolicy(ctx context.Context, accept rfqmsg.SellAccept) error
// FetchAcceptedQuotes fetches all non-expired accepted quotes.
// Returns sale policies as buy accepts, purchase policies as
// sell accepts, peer-accepted buy quotes, and peer-accepted
// sell quotes separately.
FetchAcceptedQuotes(ctx context.Context) ([]rfqmsg.BuyAccept,
[]rfqmsg.SellAccept, []rfqmsg.BuyAccept,
[]rfqmsg.SellAccept, error)
// StorePeerAcceptedBuyQuote persists a peer-accepted buy quote
// for historical SCID-to-peer lookup.
StorePeerAcceptedBuyQuote(ctx context.Context,
accept rfqmsg.BuyAccept) error
// StorePeerAcceptedSellQuote persists a peer-accepted sell
// quote for restart continuity.
StorePeerAcceptedSellQuote(ctx context.Context,
accept rfqmsg.SellAccept) error
// LookUpScid looks up the peer associated with the given SCID from
// persisted peer-accepted buy quote policies.
LookUpScid(ctx context.Context, scid uint64) (route.Vertex, error)
}
PolicyStore abstracts persistence of RFQ policies.
type PortfolioPilot ¶
type PortfolioPilot interface {
// ResolveRequest resolves a quote request by returning either an
// acceptable asset rate or a quote rejection error. Errors are reserved
// for unexpected failures while evaluating the request.
ResolveRequest(context.Context, rfqmsg.Request) (ResolveResp,
error)
// VerifyAcceptQuote verifies that an accepted quote from a peer meets
// acceptable conditions.
VerifyAcceptQuote(context.Context, rfqmsg.Accept) (QuoteRespStatus,
error)
// QueryAssetRates returns current asset rate information for a given
// asset and direction. Can be used for rate discovery, outgoing RFQ
// request construction, or general pricing information.
QueryAssetRates(context.Context, AssetRateQuery) (rfqmsg.AssetRate,
error)
// Close releases any resources held by the portfolio pilot.
Close() error
}
PortfolioPilot evaluates RFQs and returns either an accepted asset rate quote or a rejection reason.
type PortfolioPilotAddr ¶
PortfolioPilotAddr is a type alias for a URL type that represents a portfolio pilot service address.
func ParsePortfolioPilotAddress ¶
func ParsePortfolioPilotAddress(addrStr string) (*PortfolioPilotAddr, error)
ParsePortfolioPilotAddress parses a portfolio pilot service address string and returns a URL type instance.
type PriceOracle ¶
type PriceOracle interface {
// QuerySellPrice returns the sell price for a given asset amount. The
// sell price is the amount the oracle suggests a peer should accept
// from another peer to provide the specified asset amount.
QuerySellPrice(ctx context.Context, assetSpecifier asset.Specifier,
assetMaxAmt fn.Option[uint64],
paymentMaxAmt fn.Option[lnwire.MilliSatoshi],
assetRateHint fn.Option[rfqmsg.AssetRate],
counterparty fn.Option[route.Vertex], metadata string,
intent PriceQueryIntent) (*OracleResponse, error)
// QueryBuyPrice returns the buy price for a given asset amount. The buy
// price is the amount the oracle suggests a peer should pay to another
// peer to receive the specified asset amount.
QueryBuyPrice(ctx context.Context, assetSpecifier asset.Specifier,
assetMaxAmt fn.Option[uint64],
paymentMaxAmt fn.Option[lnwire.MilliSatoshi],
assetRateHint fn.Option[rfqmsg.AssetRate],
counterparty fn.Option[route.Vertex], metadata string,
intent PriceQueryIntent) (*OracleResponse, error)
}
PriceOracle is an interface that provides exchange rate information for assets.
type PriceQueryIntent ¶ added in v0.7.0
type PriceQueryIntent uint8
PriceQueryIntent is an enum that represents the intent of a price rate query. It is used to indicate the purpose of the price rate request, such as whether the user is requesting a hint for paying an invoice, or if they are qualifying a rate for an invoice payment. This information is used by the price oracle service to provide the appropriate asset rate for the requested intent.
const ( // IntentUnspecified is used to indicate that the intent of the price // rate query is not specified. This is the fallback default value and // should not be used in production code. It is primarily used for // backward compatibility with older versions of the protocol that did // not include intent information. IntentUnspecified PriceQueryIntent = 0 // IntentPayInvoiceHint is used to indicate that the user is requesting // a price rate hint for paying an invoice. This is typically used by // the payer of an invoice to provide a suggestion of the expected asset // rate to the RFQ peer (edge node) that will determine the actual rate // for the payment. IntentPayInvoiceHint PriceQueryIntent = 1 // IntentPayInvoice is used to indicate that a peer wants to pay an // invoice with assets. This is typically used by the edge node that // facilitates the swap from assets to BTC for the payer of an invoice. // This intent is used to provide the actual asset rate for the payment, // which may differ from the hint provided by the payer. IntentPayInvoice PriceQueryIntent = 2 // IntentPayInvoiceQualify is used to indicate that the payer of an // invoice has received an asset rate from their RFQ peer (edge node) // and is qualifying the rate for the payment. This is typically used by // the payer of an invoice to ensure that the asset rate provided by // their peer (edge node) is acceptable before proceeding with the // payment. IntentPayInvoiceQualify PriceQueryIntent = 3 // IntentRecvPaymentHint is used to indicate that the user is requesting // a price rate hint for receiving a payment through an invoice. This is // typically used by the creator of an invoice to provide a suggestion // of the expected asset rate to the RFQ peer (edge node) that will // determine the actual rate used for creating an invoice. IntentRecvPaymentHint PriceQueryIntent = 4 // IntentRecvPayment is used to indicate that a peer wants to create an // invoice to receive a payment with assets. This is typically used by // the edge node that facilitates the swap from BTC to assets for the // receiver of a payment. This intent is used to provide the actual // asset rate for the invoice creation, which may differ from the hint // provided by the receiver. IntentRecvPayment PriceQueryIntent = 5 // IntentRecvPaymentQualify is used to indicate that the creator of an // invoice received an asset rate from their RFQ peer (edge node) and is // qualifying the rate for the creation of the invoice. This is // typically used by the creator of an invoice to ensure that the asset // rate provided by their peer (edge node) is acceptable before // proceeding with creating the invoice. IntentRecvPaymentQualify PriceQueryIntent = 6 )
type QueryForwardsParams ¶
type QueryForwardsParams struct {
// MinTimestamp filters forwarding events to those settled at or after
// this time.
// None means no lower bound.
MinTimestamp fn.Option[time.Time]
// MaxTimestamp filters forwarding events to those settled at or before
// this
// time. None means no upper bound.
MaxTimestamp fn.Option[time.Time]
// Peer filters forwarding events to those with this counterparty.
// Nil means no filter.
Peer *route.Vertex
// AssetSpecifier filters forwarding events to those involving this
// asset or
// asset group. Nil means no filter.
AssetSpecifier *asset.Specifier
// Limit is the maximum number of records to return.
Limit int32
// Offset is the number of records to skip (for pagination).
Offset int32
}
QueryForwardsParams contains the parameters for querying forwarding event records.
type QuoteRespStatus ¶
type QuoteRespStatus uint8
QuoteRespStatus is an enumeration of possible quote response statuses.
const ( // InvalidAssetRatesQuoteRespStatus indicates that the asset rates in // the quote response is invalid. InvalidAssetRatesQuoteRespStatus QuoteRespStatus = 0 // InvalidExpiryQuoteRespStatus indicates that the expiry in the quote // response is invalid. InvalidExpiryQuoteRespStatus QuoteRespStatus = 1 // PriceOracleQueryErrQuoteRespStatus indicates that an error occurred // when querying the price oracle whilst evaluating the quote response. PriceOracleQueryErrQuoteRespStatus QuoteRespStatus = 2 // PortfolioPilotErrQuoteRespStatus indicates that an unexpected error // occurred in the portfolio pilot while evaluating the quote response. PortfolioPilotErrQuoteRespStatus QuoteRespStatus = 3 // ValidAcceptQuoteRespStatus indicates that the accepted quote passed // all validation checks successfully. ValidAcceptQuoteRespStatus QuoteRespStatus = 4 // MinFillNotMetQuoteRespStatus indicates that the minimum fill // constraint was not satisfiable at the accepted rate. MinFillNotMetQuoteRespStatus QuoteRespStatus = 5 // RateBoundMissQuoteRespStatus indicates that the accepted rate // violated the requester's rate limit constraint. RateBoundMissQuoteRespStatus QuoteRespStatus = 6 // FOKNotViableQuoteRespStatus indicates that the FOK execution // policy could not be satisfied at the accepted rate. FOKNotViableQuoteRespStatus QuoteRespStatus = 7 // FillExceedsMaxQuoteRespStatus indicates that the negotiated // fill amount exceeds the requester's maximum. FillExceedsMaxQuoteRespStatus QuoteRespStatus = 8 )
type ResolveResp ¶
type ResolveResp struct {
// contains filtered or unexported fields
}
ResolveResp captures the portfolio pilot's resolution decision for an RFQ. It carries either an accepted asset rate quote or a structured rejection reason, plus an optional fill amount.
func NewAcceptResolveResp ¶
NewAcceptResolveResp builds an acceptance response with the provided asset rate quote and optional fill amount.
func NewRejectResolveResp ¶
func NewRejectResolveResp(rejectErr rfqmsg.RejectErr) ResolveResp
NewRejectResolveResp builds a rejection response that explains why a quote cannot be provided.
func (*ResolveResp) FillAmount ¶
func (r *ResolveResp) FillAmount() fn.Option[uint64]
FillAmount returns the optional fill quantity.
func (*ResolveResp) IsAccept ¶
func (r *ResolveResp) IsAccept() bool
IsAccept reports whether the response contains an accepted asset rate.
func (*ResolveResp) IsReject ¶
func (r *ResolveResp) IsReject() bool
IsReject reports whether the response contains a rejection error.
func (*ResolveResp) WhenAccept ¶
func (r *ResolveResp) WhenAccept(pred func(rate rfqmsg.AssetRate))
WhenAccept executes the callback with the asset rate when the response is an acceptance and does nothing otherwise.
func (*ResolveResp) WhenReject ¶
func (r *ResolveResp) WhenReject(pred func(err rfqmsg.RejectErr))
WhenReject executes the callback with the rejection error when the response is a rejection and does nothing otherwise.
type RfqPolicyType ¶
type RfqPolicyType string
RfqPolicyType denotes the type of a persisted RFQ policy.
const ( // RfqPolicyTypeAssetSale identifies an asset sale policy. RfqPolicyTypeAssetSale RfqPolicyType = "RFQ_POLICY_TYPE_SALE" // RfqPolicyTypeAssetPurchase identifies an asset purchase policy. RfqPolicyTypeAssetPurchase RfqPolicyType = "RFQ_POLICY_TYPE_PURCHASE" // RfqPolicyTypeAssetPeerAcceptedBuy identifies a peer-accepted buy // quote that was persisted for historical SCID lookup. //nolint:lll RfqPolicyTypeAssetPeerAcceptedBuy RfqPolicyType = "RFQ_POLICY_TYPE_PEER_ACCEPTED_BUY" // RfqPolicyTypeAssetPeerAcceptedSell identifies a peer-accepted // sell quote that was persisted for restart continuity. //nolint:lll RfqPolicyTypeAssetPeerAcceptedSell RfqPolicyType = "RFQ_POLICY_TYPE_PEER_ACCEPTED_SELL" )
func (RfqPolicyType) String ¶
func (t RfqPolicyType) String() string
String converts the policy type to its string representation.
type RpcPortfolioPilot ¶
type RpcPortfolioPilot struct {
// contains filtered or unexported fields
}
RpcPortfolioPilot is a portfolio pilot that uses an external RPC server to evaluate RFQ requests and asset rates.
func NewRpcPortfolioPilot ¶
func NewRpcPortfolioPilot(addrStr string, dialInsecure bool) ( *RpcPortfolioPilot, error)
NewRpcPortfolioPilot creates a new RPC portfolio pilot handle given the address of the portfolio pilot RPC server.
func (*RpcPortfolioPilot) Close ¶
func (r *RpcPortfolioPilot) Close() error
Close closes the underlying gRPC connection.
func (*RpcPortfolioPilot) QueryAssetRates ¶
func (r *RpcPortfolioPilot) QueryAssetRates(ctx context.Context, query AssetRateQuery) (rfqmsg.AssetRate, error)
QueryAssetRates returns current asset rate information by calling the portfolio pilot RPC server.
func (*RpcPortfolioPilot) ResolveRequest ¶
func (r *RpcPortfolioPilot) ResolveRequest(ctx context.Context, request rfqmsg.Request) (ResolveResp, error)
ResolveRequest resolves a quote request by calling the portfolio pilot RPC server.
func (*RpcPortfolioPilot) VerifyAcceptQuote ¶
func (r *RpcPortfolioPilot) VerifyAcceptQuote(ctx context.Context, accept rfqmsg.Accept) (QuoteRespStatus, error)
VerifyAcceptQuote verifies an accepted quote by calling the portfolio pilot RPC server.
type RpcPriceOracle ¶
type RpcPriceOracle struct {
// contains filtered or unexported fields
}
RpcPriceOracle is a price oracle that uses an external RPC server to get exchange rate information.
func NewRpcPriceOracle ¶
func NewRpcPriceOracle(addrStr string, tlsConfig *TLSConfig, macaroonOpt fn.Option[grpc.DialOption], nodeID fn.Option[route.Vertex]) (*RpcPriceOracle, error)
NewRpcPriceOracle creates a new RPC price oracle handle given the address of the price oracle RPC server. An optional macaroon dial option can be provided for authentication with the oracle server.
func (*RpcPriceOracle) QueryBuyPrice ¶ added in v0.7.0
func (r *RpcPriceOracle) QueryBuyPrice(ctx context.Context, assetSpecifier asset.Specifier, assetMaxAmt fn.Option[uint64], paymentMaxAmt fn.Option[lnwire.MilliSatoshi], assetRateHint fn.Option[rfqmsg.AssetRate], counterparty fn.Option[route.Vertex], metadata string, intent PriceQueryIntent) (*OracleResponse, error)
QueryBuyPrice returns a buy price for the given asset amount.
func (*RpcPriceOracle) QuerySellPrice ¶ added in v0.7.0
func (r *RpcPriceOracle) QuerySellPrice(ctx context.Context, assetSpecifier asset.Specifier, assetMaxAmt fn.Option[uint64], paymentMaxAmt fn.Option[lnwire.MilliSatoshi], assetRateHint fn.Option[rfqmsg.AssetRate], counterparty fn.Option[route.Vertex], metadata string, intent PriceQueryIntent) (*OracleResponse, error)
QuerySellPrice returns the sell price for the given asset amount.
type ScidAliasManager ¶
type ScidAliasManager interface {
// AddLocalAlias adds a database mapping from the passed alias to the
// passed base SCID.
AddLocalAlias(ctx context.Context, alias,
baseScid lnwire.ShortChannelID) error
// DeleteLocalAlias removes a mapping from the database and the
// Manager's maps.
DeleteLocalAlias(ctx context.Context, alias,
baseScid lnwire.ShortChannelID) error
// FetchBaseAlias finds the base channel ID for a given alias. This scid
// will correspond to the real channel scid that is used to identify the
// channel.
FetchBaseAlias(ctx context.Context,
alias lnwire.ShortChannelID) (lnwire.ShortChannelID, error)
}
ScidAliasManager is an interface that can add short channel ID (SCID) aliases to the local SCID alias store.
type SellAcceptMap ¶ added in v0.5.0
type SellAcceptMap map[SerialisedScid]rfqmsg.SellAccept
SellAcceptMap is a map of sell accepts, keyed by the serialised SCID.
type SellOffer ¶
type SellOffer struct {
// AssetID represents the identifier of the subject asset.
AssetID *asset.ID
// AssetGroupKey is the public group key of the subject asset.
AssetGroupKey *btcec.PublicKey
// MaxUnits is the maximum amount of the asset under offer.
MaxUnits uint64
}
SellOffer is a struct that represents an asset sell offer. This data structure describes the maximum amount of an asset that is available for sale.
A sell offer is passive (unlike a buy order), meaning that it does not actively lead to a buy request from a peer. Instead, it is used by the node to selectively accept or reject incoming quote requests early before price considerations.
type SellOrder ¶
type SellOrder struct {
// AssetSpecifier is the asset that the seller is interested in.
AssetSpecifier asset.Specifier
// PaymentMaxAmt is the maximum msat amount that the responding peer
// must agree to pay.
PaymentMaxAmt lnwire.MilliSatoshi
// PaymentMinAmt is an optional minimum msat amount for the order.
PaymentMinAmt fn.Option[lnwire.MilliSatoshi]
// AssetRateLimit is an optional maximum acceptable rate (asset
// units per BTC) for the order.
AssetRateLimit fn.Option[rfqmath.BigIntFixedPoint]
// ExecutionPolicy is an optional execution policy (IOC or
// FOK) for the order.
ExecutionPolicy fn.Option[rfqmsg.ExecutionPolicy]
// Expiry is the time at which the order expires.
Expiry time.Time
// Peer is the peer that the buy order is intended for. This field is
// optional.
Peer fn.Option[route.Vertex]
// PriceOracleMetadata is an optional text field that can be used to
// provide additional metadata about the sell order to the price
// oracle. This can include information about the wallet end user that
// initiated the transaction, or any authentication information that the
// price oracle can use to give out a more accurate (or discount) asset
// rate. The maximum length of this field is 32'768 bytes.
PriceOracleMetadata string
}
SellOrder instructs the RFQ (Request For Quote) system to request a quote from one or more peers for the disposition of an asset.
Normal usage of a sell order:
- Alice creates a Lightning invoice for Bob to pay.
- Bob wants to pay the invoice using a Tap asset. To do so, Bob pays an edge node with a Tap asset, and the edge node forwards the payment to the network to settle Alice's invoice. Bob submits a SellOrder to his local RFQ service.
- The RFQ service converts the SellOrder into one or more SellRequests. These requests are sent to Charlie (the edge node), who shares a relevant Tap asset channel with Bob and can forward payments to settle Alice's invoice.
- Charlie responds with a quote that satisfies Bob.
- Bob transfers the appropriate Tap asset amount to Charlie via their shared Tap asset channel, and Charlie forwards the corresponding amount to Alice to settle the Lightning invoice.
func (*SellOrder) GetAssetSpecifier ¶
GetAssetSpecifier returns the asset specifier for this sell order.
func (*SellOrder) GetPriceOracleMetadata ¶
GetPriceOracleMetadata returns the price oracle metadata for this sell order.
type SerialisedScid ¶
type SerialisedScid = rfqmsg.SerialisedScid
SerialisedScid is a serialised short channel id (SCID).
type StreamHandler ¶
type StreamHandler struct {
// ContextGuard provides a wait group and main quit channel that can be
// used to create guarded contexts.
*fn.ContextGuard
// contains filtered or unexported fields
}
StreamHandler is a struct that handles incoming and outgoing peer RFQ stream messages.
This component subscribes to incoming raw peer messages (custom messages). It processes those messages with the aim of extracting relevant request for quotes (RFQs).
func NewStreamHandler ¶
func NewStreamHandler(ctx context.Context, cfg StreamHandlerCfg) (*StreamHandler, error)
NewStreamHandler creates and starts a new RFQ stream handler.
TODO(ffranr): Pass in a signer so that we can create a signature over output message fields.
func (*StreamHandler) HandleOutgoingMessage ¶
func (h *StreamHandler) HandleOutgoingMessage(ctx context.Context, outgoingMsg rfqmsg.OutgoingMsg) error
HandleOutgoingMessage handles an outgoing RFQ message.
type StreamHandlerCfg ¶
type StreamHandlerCfg struct {
// PeerMessenger is the peer messenger. This component provides the RFQ
// manager with the ability to send and receive raw peer messages.
PeerMessenger PeerMessenger
// IncomingMessages is a channel which is populated with incoming
// (received) RFQ messages. These messages have been extracted from the
// raw peer wire messages by the stream handler service.
IncomingMessages chan<- rfqmsg.IncomingMsg
}
StreamHandlerCfg is a struct that holds the configuration parameters for the RFQ peer message stream handler.
type TLSConfig ¶
type TLSConfig struct {
// Disabled indicates that we should not use TLS.
Disabled bool
// InsecureSkipVerify disables certificate verification.
InsecureSkipVerify bool
// TrustSystemRootCAs indicates whether or not to use the operating
// system's root certificate authority list.
TrustSystemRootCAs bool
// CustomCertificates contains PEM data for additional root CA and
// self-signed certificates to trust.
CustomCertificates []byte
}
TLSConfig represents TLS configuration options for oracle connections.
type TapChannel ¶ added in v0.6.0
type TapChannel struct {
// Specifier is the asset Specifier that is satisfied by this channels'
// assets.
Specifier asset.Specifier
// ChannelInfo is the information about the channel the asset is
// committed to.
ChannelInfo lndclient.ChannelInfo
// AssetInfo contains the asset related info of the channel.
AssetInfo rfqmsg.JsonAssetChannel
}
TapChannel is a helper struct that combines the information of an asset specifier that is satisfied by a channel with the channels' general information.