diff --git a/assets/actions.go b/assets/actions.go new file mode 100644 index 000000000..e7d188192 --- /dev/null +++ b/assets/actions.go @@ -0,0 +1,421 @@ +package assets + +import ( + "context" + "crypto/rand" + "time" + + "github.com/btcsuite/btcd/btcec/v2" + "github.com/btcsuite/btcd/btcutil" + "github.com/lightninglabs/lndclient" + "github.com/lightninglabs/loop/fsm" + "github.com/lightninglabs/loop/swapserverrpc" + "github.com/lightninglabs/taproot-assets/taprpc/tapdevrpc" + "github.com/lightningnetwork/lnd/chainntnfs" + "github.com/lightningnetwork/lnd/lnrpc" + "github.com/lightningnetwork/lnd/lntypes" +) + +// InitSwapOutContext is the initial context for the InitSwapOut state. +type InitSwapOutContext struct { + // Amount is the amount of the swap. + Amount btcutil.Amount + // AssetId is the id of the asset we are swapping. + AssetId []byte +} + +// InitSwapOut is the first state of the swap out FSM. It is responsible for +// creating a new swap out and prepay invoice. +func (o *OutFSM) InitSwapOut(ctx context.Context, + initCtx fsm.EventContext) fsm.EventType { + + // We expect the event context to be of type *InstantOutContext. + req, ok := initCtx.(*InitSwapOutContext) + if !ok { + o.Errorf("expected InstantOutContext, got %T", initCtx) + return o.HandleError(fsm.ErrInvalidContextType) + } + + // Create a new key for the swap. + clientKeyDesc, err := o.cfg.Wallet.DeriveNextKey( + o.runCtx, AssetKeyFamily, + ) + if err != nil { + return o.HandleError(err) + } + + // Request the asset out. + assetOutRes, err := o.cfg.AssetClient.RequestAssetLoopOut( + o.runCtx, &swapserverrpc.RequestAssetLoopOutRequest{ + Amount: uint64(req.Amount), + RequestedAsset: req.AssetId, + ReceiverKey: clientKeyDesc.PubKey.SerializeCompressed(), + }, + ) + if err != nil { + return o.HandleError(err) + } + + // Create the swap hash from the response. + swapHash, err := lntypes.MakeHash(assetOutRes.SwapHash) + if err != nil { + return o.HandleError(err) + } + + // Parse the server pubkey. + senderPubkey, err := btcec.ParsePubKey(assetOutRes.SenderPubkey) + if err != nil { + return o.HandleError(err) + } + + // With our params, we'll now create the swap out. + swapOut := NewSwapOut( + swapHash, btcutil.Amount(req.Amount), + req.AssetId, clientKeyDesc, senderPubkey, + int32(assetOutRes.Expiry), + o.cfg.BlockHeightSubscriber.GetBlockHeight(), + ) + o.SwapOut = swapOut + o.PrepayInvoice = assetOutRes.PrepayInvoice + + err = o.cfg.Store.CreateAssetSwapOut(o.runCtx, o.SwapOut) + if err != nil { + return o.HandleError(err) + } + + return onAssetOutInit +} + +// PayPrepay is the state where we try to pay the prepay invoice. +func (o *OutFSM) PayPrepay(ctx context.Context, + _ fsm.EventContext) fsm.EventType { + + trackChan, errChan, err := o.cfg.Router.SendPayment( + o.runCtx, lndclient.SendPaymentRequest{ + Invoice: o.PrepayInvoice, + Timeout: time.Minute, + MaxFee: btcutil.Amount(1000), + }, + ) + if err != nil { + return o.HandleError(err) + } + + go func() { + for { + select { + case result := <-trackChan: + if result.State == lnrpc.Payment_IN_FLIGHT { + o.Debugf("payment in flight") + } + if result.State == lnrpc.Payment_FAILED { + o.Errorf("payment failed: %v", result.FailureReason) + err = o.SendEvent(ctx, fsm.OnError, nil) + if err != nil { + o.Errorf("unable to send event: %v", err) + } + return + } + if result.State == lnrpc.Payment_SUCCEEDED { + o.Debugf("payment succeeded") + err := o.SendEvent(ctx, onPrepaySettled, nil) + if err != nil { + o.Errorf("unable to send event: %v", err) + } + return + } + + case err := <-errChan: + o.Errorf("payment error: %v", err) + err = o.SendEvent(ctx, fsm.OnError, nil) + if err != nil { + o.Errorf("unable to send event: %v", err) + } + return + + case <-o.runCtx.Done(): + return + } + } + }() + + return fsm.NoOp +} + +// FetchProof is the state where we fetch the proof. +func (o *OutFSM) FetchProof(ctx context.Context, + _ fsm.EventContext) fsm.EventType { + + // Fetch the proof from the server. + proofRes, err := o.cfg.AssetClient.PollAssetLoopOutProof( + o.runCtx, &swapserverrpc.PollAssetLoopOutProofRequest{ + SwapHash: o.SwapOut.SwapHash[:], + }, + ) + // If we have an error, we'll wait for the next block and try again. + if err != nil { + return onWaitForBlock + } + // We'll now import the proof into the asset client. + _, err = o.cfg.TapdClient.ImportProof( + o.runCtx, &tapdevrpc.ImportProofRequest{ + ProofFile: proofRes.RawProofFile, + }, + ) + if err != nil { + return o.HandleError(err) + } + + o.SwapOut.RawHtlcProof = proofRes.RawProofFile + + // We'll now save the proof in the database. + err = o.cfg.Store.UpdateAssetSwapOutProof( + o.runCtx, o.SwapOut.SwapHash, proofRes.RawProofFile, + ) + if err != nil { + return o.HandleError(err) + } + + return onProofReceived +} + +func (o *OutFSM) waitForBlock(ctx context.Context, + _ fsm.EventContext) fsm.EventType { + + blockHeight := o.cfg.BlockHeightSubscriber.GetBlockHeight() + + cb := func() { + o.SendEvent(ctx, onBlockReceived, nil) + } + + subscriberId, err := getRandomHash() + if err != nil { + return o.HandleError(err) + } + + alreadyPassed := o.cfg.BlockHeightSubscriber.SubscribeExpiry( + subscriberId, blockHeight+1, cb, + ) + if alreadyPassed { + return onBlockReceived + } + + return fsm.NoOp +} + +// subscribeToHtlcTxConfirmed is the state where we subscribe to the htlc +// transaction to wait for it to be confirmed. +// +// Todo(sputn1ck): handle rebroadcasting if it doesn't confirm. +func (o *OutFSM) subscribeToHtlcTxConfirmed(ctx context.Context, + _ fsm.EventContext) fsm.EventType { + + // First we'll get the htlc pkscript. + htlcPkScript, err := o.getHtlcPkscript() + if err != nil { + return o.HandleError(err) + } + + o.Debugf("pkscript: %x", htlcPkScript) + + txConfCtx, cancel := context.WithCancel(o.runCtx) + + confCallback := func(conf *chainntnfs.TxConfirmation, err error) { + if err != nil { + o.LastActionError = err + o.SendEvent(ctx, fsm.OnError, nil) + } + cancel() + o.SendEvent(ctx, onHtlcTxConfirmed, conf) + } + + err = o.cfg.TxConfSubscriber.SubscribeTxConfirmation( + txConfCtx, o.SwapOut.SwapHash, nil, + htlcPkScript, defaultHtlcConfRequirement, + o.SwapOut.InitiationHeight, confCallback, + ) + if err != nil { + return o.HandleError(err) + } + + return fsm.NoOp +} + +// sendSwapPayment is the state where we pay the swap invoice. +func (o *OutFSM) sendSwapPayment(ctx context.Context, + event fsm.EventContext) fsm.EventType { + + // If we have an EventContext with a confirmation, we'll save the + // confirmation height. + if event != nil { + if conf, ok := event.(*chainntnfs.TxConfirmation); ok { + outpoint, err := o.findPkScript(conf.Tx) + if err != nil { + return o.HandleError(err) + } + o.SwapOut.HtlcConfirmationHeight = conf.BlockHeight + o.SwapOut.HtlcOutPoint = outpoint + + err = o.cfg.Store.UpdateAssetSwapHtlcOutpoint( + o.runCtx, o.SwapOut.SwapHash, + outpoint, int32(conf.BlockHeight), + ) + if err != nil { + o.Errorf( + "unable to update swap outpoint: %v", + err, + ) + } + } + } + + // Fetch the proof from the server. + buyRes, err := o.cfg.AssetClient.RequestAssetBuy( + o.runCtx, &swapserverrpc.RequestAssetBuyRequest{ + SwapHash: o.SwapOut.SwapHash[:], + }, + ) + if err != nil { + return o.HandleError(err) + } + + // We'll also set the swap invoice. + o.SwapInvoice = buyRes.SwapInvoice + + // If the htlc has been confirmed, we can now pay the swap invoice. + trackChan, errChan, err := o.cfg.Router.SendPayment( + o.runCtx, lndclient.SendPaymentRequest{ + Invoice: o.SwapInvoice, + Timeout: time.Minute, + MaxFee: btcutil.Amount(100000), + }, + ) + if err != nil { + return o.HandleError(err) + } + + go func() { + for { + select { + case result := <-trackChan: + if result.State == lnrpc.Payment_FAILED { + o.Errorf("payment failed: %v", result.FailureReason) + err = o.SendEvent(ctx, fsm.OnError, nil) + if err != nil { + o.Errorf("unable to send event: %v", err) + } + return + } + if result.State == lnrpc.Payment_SUCCEEDED { + o.SwapOut.SwapPreimage = result.Preimage + err = o.cfg.Store.UpdateAssetSwapOutPreimage( + o.runCtx, o.SwapOut.SwapHash, + result.Preimage, + ) + if err != nil { + o.Errorf( + "unable to update swap preimage: %v", + err, + ) + } + err := o.SendEvent(ctx, onSwapPreimageReceived, nil) + if err != nil { + o.Errorf("unable to send event: %v", err) + } + return + } + + case err := <-errChan: + o.Errorf("payment error: %v", err) + err = o.SendEvent(ctx, fsm.OnError, nil) + if err != nil { + o.Errorf("unable to send event: %v", err) + } + return + + case <-o.runCtx.Done(): + return + } + } + }() + + return fsm.NoOp +} + +// publishSweepTx is the state where we publish the timeout transaction. +func (o *OutFSM) publishSweepTx(ctx context.Context, + _ fsm.EventContext) fsm.EventType { + + // Publish and log the sweep transaction. + outpoint, pkScript, err := o.publishPreimageSweep() + if err != nil { + return o.HandleError(err) + } + + o.SwapOut.SweepOutpoint = outpoint + o.SwapOut.SweepPkscript = pkScript + + // We can now save the swap outpoint. + err = o.cfg.Store.UpdateAssetSwapOutSweepTx( + o.runCtx, o.SwapOut.SwapHash, outpoint.Hash, + 0, pkScript, + ) + if err != nil { + return o.HandleError(err) + } + + return onHtlcSuccessSweep +} + +// subscribeSweepConf is the state where we subscribe to the sweep transaction +// confirmation. +func (o *OutFSM) subscribeSweepConf(ctx context.Context, + _ fsm.EventContext) fsm.EventType { + + // We'll now subscribe to the confirmation of the sweep transaction. + txConfCtx, cancel := context.WithCancel(o.runCtx) + + confCallback := func(conf *chainntnfs.TxConfirmation, err error) { + if err != nil { + o.LastActionError = err + o.SendEvent(ctx, fsm.OnError, nil) + } + cancel() + o.SendEvent(ctx, onSweepTxConfirmed, conf) + } + + err := o.cfg.TxConfSubscriber.SubscribeTxConfirmation( + txConfCtx, o.SwapOut.SwapHash, + &o.SwapOut.SweepOutpoint.Hash, o.SwapOut.SweepPkscript, + defaultHtlcConfRequirement, o.SwapOut.InitiationHeight, + confCallback, + ) + if err != nil { + return o.HandleError(err) + } + + return fsm.NoOp +} + +// HandleError is a helper function that can be used by actions to handle +// errors. +func (o *OutFSM) HandleError(err error) fsm.EventType { + if o == nil { + log.Errorf("StateMachine error: %s", err) + return fsm.OnError + } + o.Errorf("StateMachine error: %s", err) + o.LastActionError = err + return fsm.OnError +} + +// getRandomHash returns a random hash. +func getRandomHash() (lntypes.Hash, error) { + var preimage lntypes.Preimage + _, err := rand.Read(preimage[:]) + if err != nil { + return lntypes.Hash{}, err + } + + return preimage.Hash(), nil +} diff --git a/assets/interfaces.go b/assets/interfaces.go new file mode 100644 index 000000000..066be58ed --- /dev/null +++ b/assets/interfaces.go @@ -0,0 +1,134 @@ +package assets + +import ( + "context" + + "github.com/btcsuite/btcd/btcutil" + "github.com/btcsuite/btcd/btcutil/psbt" + "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/btcsuite/btcd/wire" + "github.com/lightninglabs/lndclient" + "github.com/lightninglabs/loop/fsm" + "github.com/lightninglabs/taproot-assets/asset" + "github.com/lightninglabs/taproot-assets/tappsbt" + "github.com/lightninglabs/taproot-assets/taprpc" + wrpc "github.com/lightninglabs/taproot-assets/taprpc/assetwalletrpc" + "github.com/lightninglabs/taproot-assets/taprpc/mintrpc" + "github.com/lightninglabs/taproot-assets/taprpc/tapdevrpc" + "github.com/lightninglabs/taproot-assets/taprpc/universerpc" + "github.com/lightningnetwork/lnd/chainntnfs" + "github.com/lightningnetwork/lnd/keychain" + "github.com/lightningnetwork/lnd/lntypes" + "github.com/lightningnetwork/lnd/lnwallet/chainfee" +) + +const ( + // DefaultSwapCSVExpiry is the default expiry for a swap in blocks. + DefaultSwapCSVExpiry = int32(24) + + defaultHtlcFeeConfTarget = 3 + defaultHtlcConfRequirement = 2 + + AssetKeyFamily = 696969 +) + +// TapdClient is an interface that groups the methods required to interact with +// the taproot-assets server and the wallet. +type AssetClient interface { + taprpc.TaprootAssetsClient + wrpc.AssetWalletClient + mintrpc.MintClient + universerpc.UniverseClient + tapdevrpc.TapDevClient + + // FundAndSignVpacket funds ands signs a vpacket. + FundAndSignVpacket(ctx context.Context, + vpkt *tappsbt.VPacket) (*tappsbt.VPacket, error) + + // PrepareAndCommitVirtualPsbts prepares and commits virtual psbts. + PrepareAndCommitVirtualPsbts(ctx context.Context, + vpkt *tappsbt.VPacket, feeRateSatPerKVByte chainfee.SatPerVByte) ( + *psbt.Packet, []*tappsbt.VPacket, []*tappsbt.VPacket, + *wrpc.CommitVirtualPsbtsResponse, error) + + // LogAndPublish logs and publishes the virtual psbts. + LogAndPublish(ctx context.Context, btcPkt *psbt.Packet, + activeAssets []*tappsbt.VPacket, passiveAssets []*tappsbt.VPacket, + commitResp *wrpc.CommitVirtualPsbtsResponse) (*taprpc.SendAssetResponse, + error) + + // CheckBalanceById checks the balance of an asset by its id. + CheckBalanceById(ctx context.Context, assetId []byte, + requestedBalance btcutil.Amount) error + + // DeriveNewKeys derives a new internal and script key. + DeriveNewKeys(ctx context.Context) (asset.ScriptKey, + keychain.KeyDescriptor, error) +} + +// SwapStore is an interface that groups the methods required to store swap +// information. +type SwapStore interface { + // CreateAssetSwapOut creates a new swap out in the store. + CreateAssetSwapOut(ctx context.Context, swap *SwapOut) error + + // UpdateAssetSwapHtlcOutpoint updates the htlc outpoint of a swap out. + UpdateAssetSwapHtlcOutpoint(ctx context.Context, swapHash lntypes.Hash, + outpoint *wire.OutPoint, confirmationHeight int32) error + + // UpdateAssetSwapOutProof updates the proof of a swap out. + UpdateAssetSwapOutProof(ctx context.Context, swapHash lntypes.Hash, + rawProof []byte) error + + // UpdateAssetSwapOutSweepTx updates the sweep tx of a swap out. + UpdateAssetSwapOutSweepTx(ctx context.Context, + swapHash lntypes.Hash, sweepTxid chainhash.Hash, + confHeight int32, sweepPkscript []byte) error + + // InsertAssetSwapUpdate inserts a new swap update in the store. + InsertAssetSwapUpdate(ctx context.Context, + swapHash lntypes.Hash, state fsm.StateType) error + + UpdateAssetSwapOutPreimage(ctx context.Context, + swapHash lntypes.Hash, preimage lntypes.Preimage) error +} + +// BlockHeightSubscriber is responsible for subscribing to the expiry height +// of a swap, as well as getting the current block height. +type BlockHeightSubscriber interface { + // SubscribeExpiry subscribes to the expiry of a swap. It returns true + // if the expiry is already past. Otherwise, it returns false and calls + // the expiryFunc when the expiry height is reached. + SubscribeExpiry(swapHash [32]byte, + expiryHeight int32, expiryFunc func()) bool + // GetBlockHeight returns the current block height. + GetBlockHeight() int32 +} + +// InvoiceSubscriber is responsible for subscribing to an invoice. +type InvoiceSubscriber interface { + // SubscribeInvoice subscribes to an invoice. The update callback is + // called when the invoice is updated and the error callback is called + // when an error occurs. + SubscribeInvoice(ctx context.Context, invoiceHash lntypes.Hash, + updateCallback func(lndclient.InvoiceUpdate, error)) error +} + +// TxConfirmationSubscriber is responsible for subscribing to the confirmation +// of a transaction. +type TxConfirmationSubscriber interface { + + // SubscribeTxConfirmation subscribes to the confirmation of a + // pkscript on the chain. The callback is called when the pkscript is + // confirmed or when an error occurs. + SubscribeTxConfirmation(ctx context.Context, swapHash lntypes.Hash, + txid *chainhash.Hash, pkscript []byte, numConfs int32, + eightHint int32, cb func(*chainntnfs.TxConfirmation, error)) error +} + +// ExchangeRateProvider is responsible for providing the exchange rate between +// assets. +type ExchangeRateProvider interface { + // GetSatsPerAssetUnit returns the amount of satoshis per asset unit. + GetSatsPerAssetUnit(assetId []byte) (btcutil.Amount, error) +} diff --git a/assets/log.go b/assets/log.go new file mode 100644 index 000000000..321f8d855 --- /dev/null +++ b/assets/log.go @@ -0,0 +1,26 @@ +package assets + +import ( + "github.com/btcsuite/btclog" + "github.com/lightningnetwork/lnd/build" +) + +// Subsystem defines the sub system name of this package. +const Subsystem = "ASSETS" + +// log is a logger that is initialized with no output filters. This means the +// package will not perform any logging by default until the caller requests +// it. +var log btclog.Logger + +// The default amount of logging is none. +func init() { + UseLogger(build.NewSubLogger(Subsystem, nil)) +} + +// UseLogger uses a specified Logger to output package logging info. This +// should be used in preference to SetLogWriter if the caller is also using +// btclog. +func UseLogger(logger btclog.Logger) { + log = logger +} diff --git a/assets/manager.go b/assets/manager.go new file mode 100644 index 000000000..79e98af53 --- /dev/null +++ b/assets/manager.go @@ -0,0 +1,203 @@ +package assets + +import ( + "context" + "sync" + "time" + + "github.com/btcsuite/btcd/btcutil" + "github.com/lightninglabs/lndclient" + "github.com/lightninglabs/loop/fsm" + loop_rpc "github.com/lightninglabs/loop/swapserverrpc" + "github.com/lightninglabs/loop/utils" + "github.com/lightninglabs/taproot-assets/taprpc" + "github.com/lightningnetwork/lnd/lntypes" +) + +const ( + ClientKeyFamily = 696969 +) + +type Config struct { + AssetClient *TapdClient + Wallet lndclient.WalletKitClient + // ExchangeRateProvider is the exchange rate provider. + ExchangeRateProvider *FixedExchangeRateProvider + Signer lndclient.SignerClient + ChainNotifier lndclient.ChainNotifierClient + Router lndclient.RouterClient + LndClient lndclient.LightningClient + Store *PostgresStore + ServerClient loop_rpc.AssetsSwapServerClient +} + +type AssetsSwapManager struct { + cfg *Config + + expiryManager *utils.ExpiryManager + txConfManager *utils.TxSubscribeConfirmationManager + + blockHeight int32 + runCtx context.Context + activeSwapOuts map[lntypes.Hash]*OutFSM + + sync.Mutex +} + +func NewAssetSwapServer(config *Config) *AssetsSwapManager { + return &AssetsSwapManager{ + cfg: config, + + activeSwapOuts: make(map[lntypes.Hash]*OutFSM), + } +} + +func (m *AssetsSwapManager) Run(ctx context.Context, blockHeight int32) error { + m.runCtx = ctx + m.blockHeight = blockHeight + + // Get our tapd client info. + tapdInfo, err := m.cfg.AssetClient.GetInfo( + ctx, &taprpc.GetInfoRequest{}, + ) + if err != nil { + return err + } + log.Infof("Tapd info: %v", tapdInfo) + + // Create our subscriptionManagers. + m.expiryManager = utils.NewExpiryManager(m.cfg.ChainNotifier) + m.txConfManager = utils.NewTxSubscribeConfirmationManager( + m.cfg.ChainNotifier, + ) + + // Start the expiry manager. + errChan := make(chan error, 1) + wg := &sync.WaitGroup{} + wg.Add(1) + go func() { + defer wg.Done() + err := m.expiryManager.Start(ctx, blockHeight) + if err != nil { + log.Errorf("Expiry manager failed: %v", err) + errChan <- err + log.Errorf("Gude1") + } + }() + + // Recover all the active asset swap outs from the database. + err = m.recoverSwapOuts(ctx) + if err != nil { + return err + } + + for { + select { + case err := <-errChan: + log.Errorf("Gude2") + return err + + case <-ctx.Done(): + log.Errorf("Gude3") + // wg.Wait() + log.Errorf("Gude4") + return nil + } + } +} + +func (m *AssetsSwapManager) NewSwapOut(ctx context.Context, + amt btcutil.Amount, asset []byte) (*OutFSM, error) { + + // Create a new out fsm. + outFSM := NewOutFSM(m.runCtx, m.getFSMOutConfig()) + + // Send the initial event to the fsm. + err := outFSM.SendEvent( + ctx, OnRequestAssetOut, &InitSwapOutContext{ + Amount: amt, + AssetId: asset, + }, + ) + if err != nil { + return nil, err + } + // Check if the fsm has an error. + if outFSM.LastActionError != nil { + return nil, outFSM.LastActionError + } + + // Wait for the fsm to be in the state we expect. + err = outFSM.DefaultObserver.WaitForState( + ctx, time.Second*15, PayPrepay, + fsm.WithAbortEarlyOnErrorOption(), + ) + if err != nil { + return nil, err + } + + // Add the swap to the active swap outs. + m.Lock() + m.activeSwapOuts[outFSM.SwapOut.SwapHash] = outFSM + m.Unlock() + + return outFSM, nil +} + +// recoverSwapOuts recovers all the active asset swap outs from the database. +func (m *AssetsSwapManager) recoverSwapOuts(ctx context.Context) error { + // Fetch all the active asset swap outs from the database. + activeSwapOuts, err := m.cfg.Store.GetActiveAssetOuts(ctx) + if err != nil { + return err + } + + for _, swapOut := range activeSwapOuts { + log.Debugf("Recovering asset out %v with state %v", + swapOut.SwapHash, swapOut.State) + + swapOutFSM := NewOutFSMFromSwap( + ctx, m.getFSMOutConfig(), swapOut, + ) + + m.Lock() + m.activeSwapOuts[swapOut.SwapHash] = swapOutFSM + m.Unlock() + + // As SendEvent can block, we'll start a goroutine to process + // the event. + go func() { + err := swapOutFSM.SendEvent(ctx, OnRecover, nil) + if err != nil { + log.Errorf("FSM %v Error sending recover "+ + "event %v, state: %v", + swapOutFSM.SwapOut.SwapHash, + err, swapOutFSM.SwapOut.State) + } + }() + } + + return nil +} + +// getFSMOutConfig returns a fsmconfig from the manager. +func (m *AssetsSwapManager) getFSMOutConfig() *FSMConfig { + return &FSMConfig{ + TapdClient: m.cfg.AssetClient, + AssetClient: m.cfg.ServerClient, + BlockHeightSubscriber: m.expiryManager, + TxConfSubscriber: m.txConfManager, + ExchangeRateProvider: m.cfg.ExchangeRateProvider, + Wallet: m.cfg.Wallet, + Router: m.cfg.Router, + + Store: m.cfg.Store, + Signer: m.cfg.Signer, + } +} + +func (m *AssetsSwapManager) ListSwapOutoutputs(ctx context.Context) ([]*SwapOut, + error) { + + return m.cfg.Store.GetAllAssetOuts(ctx) +} diff --git a/assets/out_fsm.go b/assets/out_fsm.go new file mode 100644 index 000000000..82f1c36f2 --- /dev/null +++ b/assets/out_fsm.go @@ -0,0 +1,612 @@ +package assets + +import ( + "bytes" + "context" + "errors" + + "github.com/btcsuite/btcd/btcutil/psbt" + "github.com/btcsuite/btcd/txscript" + "github.com/btcsuite/btcd/wire" + "github.com/lightninglabs/lndclient" + "github.com/lightninglabs/loop/fsm" + "github.com/lightninglabs/loop/swapserverrpc" + "github.com/lightninglabs/taproot-assets/commitment" + "github.com/lightninglabs/taproot-assets/proof" + "github.com/lightninglabs/taproot-assets/tapscript" + "github.com/lightningnetwork/lnd/input" + "github.com/lightningnetwork/lnd/keychain" +) + +const ( + // Limit the observers transition observation stack to 15 entries. + defaultObserverSize = 15 +) + +// States +const ( + // Init is the initial state of the swap. + Init fsm.StateType = "Init" + + // PayPrepay is the state where we are waiting for the + // prepay invoice to be accepted. + PayPrepay fsm.StateType = "PayPrepay" + + // FetchProof is the state where the prepay invoice has been + // accepted. + FetchProof fsm.StateType = "FetchProof" + + // WaitForBlock is the state where we are waiting for the next block + // to be mined. + WaitForBlock fsm.StateType = "WaitForBlock" + + // WaitForHtlcConfirmed is the state where the htlc transaction + // has been broadcast. + WaitForHtlcConfirmed fsm.StateType = "WaitForHtlcConfirmed" + + // HtlcTxConfirmed is the state where the htlc transaction + // has been confirmed. + HtlcTxConfirmed fsm.StateType = "HtlcTxConfirmed" + + // SweepHtlc is the state where we are creating the swap + // invoice. + SweepHtlc fsm.StateType = "SweepHtlc" + + // WaitForSweepConfirmed is the state where we are waiting for the swap + // payment to be made. This is after we have given the receiver the + // taproot assets proof. + WaitForSweepConfirmed fsm.StateType = "WaitForSweepConfirmed" + + // Finished is the state where the swap has finished. + Finished fsm.StateType = "Finished" + + // FinishedTimeout is the state where the swap has finished due to + // a timeout. + FinishedTimeout fsm.StateType = "FinishedTimeout" + + // Failed is the state where the swap has failed. + Failed fsm.StateType = "Failed" +) + +var ( + finishedStates = []fsm.StateType{ + Finished, FinishedTimeout, Failed, + } +) + +// Events +var ( + // OnRequestAssetOut is the event where the server receives a swap + // request from the client. + OnRequestAssetOut = fsm.EventType("OnRequestAssetOut") + + // onAssetOutInit is the event where the server has initialized the + // swap. + onAssetOutInit = fsm.EventType("OnAssetOutInit") + + // onPrepaySettled is the event where the prepay invoice has been + // accepted. + onPrepaySettled = fsm.EventType("onPrepaySettled") + + onWaitForBlock = fsm.EventType("onWaitForBlock") + + onBlockReceived = fsm.EventType("onBlockReceived") + + onProofReceived = fsm.EventType("OnProofReceived") + + onHtlcTxConfirmed = fsm.EventType("onHtlcTxConfirmed") + + onSwapPreimageReceived = fsm.EventType("OnSwapPreimageReceived") + + // onHtlcSuccessSweep is the event where the htlc has timed out and we + // are trying to sweep the htlc output. + onHtlcSuccessSweep = fsm.EventType("onHtlcSuccessSweep") + + // onSweepTxConfirmed is the event where the sweep transaction has been + // confirmed. + onSweepTxConfirmed = fsm.EventType("OnSweepTxConfirmed") + + // OnRecover is the event where the swap is being recovered. + OnRecover = fsm.EventType("OnRecover") +) + +// FSMConfig contains the configuration for the FSM. +type FSMConfig struct { + // TapdClient is the client to interact with the taproot asset daemon. + TapdClient AssetClient + + // AssetClient is the client to interact with the asset swap server. + AssetClient swapserverrpc.AssetsSwapServerClient + + // BlockHeightSubscriber is the subscriber to the block height. + BlockHeightSubscriber BlockHeightSubscriber + + // TxConfSubscriber is the subscriber to the transaction confirmation. + TxConfSubscriber TxConfirmationSubscriber + + // ExchangeRateProvider is the provider for the exchange rate. + ExchangeRateProvider ExchangeRateProvider + + // Wallet is the wallet client. + Wallet lndclient.WalletKitClient + + // Router is the lnd router client. + Router lndclient.RouterClient + + // Signer is the signer client. + Signer lndclient.SignerClient + + // Store is the swap store. + Store SwapStore +} + +type OutFSM struct { + *fsm.StateMachine + + runCtx context.Context + + cfg *FSMConfig + + // SwapOut contains all the information about the swap. + SwapOut *SwapOut + + // PrepayInvoice is the prepay invoice that we are paying to initiate + // the swap. + PrepayInvoice string + + // SwapInvoice is the swap invoice that we are sending to the receiver. + SwapInvoice string + + // HtlcProof is the htlc proof that we use to sweep the htlc output. + HtlcProof *proof.Proof +} + +// NewOutFSM creates a new OutFSM. +func NewOutFSM(ctx context.Context, cfg *FSMConfig) *OutFSM { + out := &SwapOut{ + State: fsm.EmptyState, + } + + return NewOutFSMFromSwap(ctx, cfg, out) +} + +// NewOutFSMFromSwap creates a new OutFSM from a existing swap. +func NewOutFSMFromSwap(ctx context.Context, cfg *FSMConfig, swap *SwapOut, +) *OutFSM { + + outFSM := &OutFSM{ + runCtx: ctx, + cfg: cfg, + SwapOut: swap, + } + + outFSM.StateMachine = fsm.NewStateMachineWithState( + outFSM.GetStates(), outFSM.SwapOut.State, defaultObserverSize, + ) + outFSM.ActionEntryFunc = outFSM.updateSwap + + return outFSM +} + +// GetStates returns the swap out state machine. +func (o *OutFSM) GetStates() fsm.States { + return fsm.States{ + fsm.EmptyState: fsm.State{ + Transitions: fsm.Transitions{ + OnRequestAssetOut: Init, + }, + Action: nil, + }, + Init: fsm.State{ + Transitions: fsm.Transitions{ + onAssetOutInit: PayPrepay, + // Before the htlc has been signed we can always + // fail the swap. + OnRecover: Failed, + fsm.OnError: Failed, + }, + Action: o.InitSwapOut, + }, + PayPrepay: fsm.State{ + Transitions: fsm.Transitions{ + onPrepaySettled: FetchProof, + fsm.OnError: Failed, + OnRecover: Failed, + }, + Action: o.PayPrepay, + }, + FetchProof: fsm.State{ + Transitions: fsm.Transitions{ + onWaitForBlock: WaitForBlock, + onProofReceived: WaitForHtlcConfirmed, + fsm.OnError: Failed, + OnRecover: FetchProof, + }, + Action: o.FetchProof, + }, + WaitForBlock: fsm.State{ + Transitions: fsm.Transitions{ + onBlockReceived: FetchProof, + OnRecover: FetchProof, + }, + Action: o.waitForBlock, + }, + WaitForHtlcConfirmed: fsm.State{ + Transitions: fsm.Transitions{ + onHtlcTxConfirmed: HtlcTxConfirmed, + fsm.OnError: Failed, + OnRecover: WaitForHtlcConfirmed, + }, + Action: o.subscribeToHtlcTxConfirmed, + }, + HtlcTxConfirmed: fsm.State{ + Transitions: fsm.Transitions{ + onSwapPreimageReceived: SweepHtlc, + // Todo(sputn1ck) change to wait for expiry state. + fsm.OnError: Failed, + OnRecover: HtlcTxConfirmed, + }, + Action: o.sendSwapPayment, + }, + SweepHtlc: fsm.State{ + Transitions: fsm.Transitions{ + onHtlcSuccessSweep: WaitForSweepConfirmed, + fsm.OnError: SweepHtlc, + OnRecover: SweepHtlc, + }, + Action: o.publishSweepTx, + }, + WaitForSweepConfirmed: fsm.State{ + Transitions: fsm.Transitions{ + onSweepTxConfirmed: Finished, + fsm.OnError: WaitForSweepConfirmed, + OnRecover: WaitForSweepConfirmed, + }, + Action: o.subscribeSweepConf, + }, + Finished: fsm.State{ + Action: fsm.NoOpAction, + }, + Failed: fsm.State{ + Action: fsm.NoOpAction, + }, + } +} + +// // getSwapCopy returns a copy of the swap that is safe to be used from the +// // caller. +// func (o *OutFSM) getSwapCopy() *SwapOut { + +// updateSwap is called after every action and updates the swap in the db. +func (o *OutFSM) updateSwap(ctx context.Context, + notification fsm.Notification) { + + o.Infof("Current: %v", notification.NextState) + + // Skip the update if the swap is not yet initialized. + if o.SwapOut == nil { + return + } + + o.SwapOut.State = notification.NextState + + // If we're in the early stages we don't have created the swap in the + // store yet and won't need to update it. + if o.SwapOut.State == Init || (notification.PreviousState == Init && + notification.NextState == Failed) { + + return + } + + err := o.cfg.Store.InsertAssetSwapUpdate( + ctx, o.SwapOut.SwapHash, o.SwapOut.State, + ) + if err != nil { + log.Errorf("Error updating swap : %v", err) + return + } +} + +// getHtlcPkscript returns the pkscript of the htlc output. +func (o *OutFSM) getHtlcPkscript() ([]byte, error) { + // First fetch the proof. + proof, err := o.getHtlcProof() + if err != nil { + return nil, err + } + + // // Verify that the asset script matches the one predicted. + // assetScriptkey, _, _, _, err := createOpTrueLeaf() + // if err != nil { + // return nil, err + // } + + // o.Debugf("Asset script key: %x", assetScriptkey.PubKey.SerializeCompressed()) + // o.Debugf("Proof script key: %x", proof.Asset.ScriptKey.PubKey.SerializeCompressed()) + // if !bytes.Equal( + // proof.Asset.ScriptKey.PubKey.SerializeCompressed(), + // assetScriptkey.PubKey.SerializeCompressed(), + // ) { + // return nil, fmt.Errorf("asset script key mismatch") + // } + + assetCpy := proof.Asset.Copy() + assetCpy.PrevWitnesses[0].SplitCommitment = nil + sendCommitment, err := commitment.NewAssetCommitment( + assetCpy, + ) + if err != nil { + return nil, err + } + + version := commitment.TapCommitmentV2 + assetCommitment, err := commitment.NewTapCommitment( + &version, sendCommitment, + ) + if err != nil { + return nil, err + } + + siblingPreimage, err := o.SwapOut.getSiblingPreimage() + if err != nil { + return nil, err + } + + siblingHash, err := siblingPreimage.TapHash() + if err != nil { + return nil, err + } + + btcInternalKey, err := o.SwapOut.getAggregateKey() + if err != nil { + return nil, err + } + + anchorPkScript, err := tapscript.PayToAddrScript( + *btcInternalKey, siblingHash, *assetCommitment, + ) + if err != nil { + return nil, err + } + + return anchorPkScript, nil +} + +// publishPreimageSweep publishes and logs the preimage sweep transaction. +func (o *OutFSM) publishPreimageSweep() (*wire.OutPoint, []byte, error) { + ctx := o.runCtx + scriptKey, internalKey, err := o.cfg.TapdClient.DeriveNewKeys(ctx) + if err != nil { + return nil, nil, err + } + + // Check if we have the proof in memory. + htlcProof, err := o.getHtlcProof() + if err != nil { + return nil, nil, err + } + + sweepVpkt, err := o.SwapOut.createSweepVpkt( + ctx, htlcProof, scriptKey, internalKey, + ) + if err != nil { + return nil, nil, err + } + + feeRate, err := o.cfg.Wallet.EstimateFeeRate( + ctx, defaultHtlcFeeConfTarget, + ) + if err != nil { + return nil, nil, err + } + + // We'll now commit the vpkt in the btcpacket. + sweepBtcPacket, activeAssets, passiveAssets, commitResp, err := + o.cfg.TapdClient.PrepareAndCommitVirtualPsbts( + ctx, sweepVpkt, feeRate.FeePerVByte(), + ) + if err != nil { + return nil, nil, err + } + + witness, err := o.createPreimageWitness( + ctx, sweepBtcPacket, htlcProof, + ) + if err != nil { + return nil, nil, err + } + + var buf bytes.Buffer + err = psbt.WriteTxWitness(&buf, witness) + if err != nil { + return nil, nil, err + } + sweepBtcPacket.Inputs[0].SighashType = txscript.SigHashDefault + sweepBtcPacket.Inputs[0].FinalScriptWitness = buf.Bytes() + + signedBtcPacket, err := o.cfg.Wallet.SignPsbt(ctx, sweepBtcPacket) + if err != nil { + return nil, nil, err + } + + finalizedBtcPacket, _, err := o.cfg.Wallet.FinalizePsbt( + ctx, signedBtcPacket, "", + ) + if err != nil { + return nil, nil, err + } + + pkScript := finalizedBtcPacket.UnsignedTx.TxOut[0].PkScript + + // Now we'll publish and log the transfer. + sendResp, err := o.cfg.TapdClient.LogAndPublish( + ctx, finalizedBtcPacket, activeAssets, passiveAssets, + commitResp, + ) + if err != nil { + return nil, nil, err + } + + sweepAnchor := sendResp.Transfer.Outputs[0].Anchor + + outPoint, err := wire.NewOutPointFromString(sweepAnchor.Outpoint) + if err != nil { + return nil, nil, err + } + + return outPoint, pkScript, nil +} + +// getHtlcProof returns the htlc proof for the swap. If the proof is not +// in memory, we will recreate it from the stored proof file. +func (o *OutFSM) getHtlcProof() (*proof.Proof, error) { + // Check if we have the proof in memory. + if o.HtlcProof != nil { + return o.HtlcProof, nil + } + + // Parse the proof. + htlcProofFile, err := proof.DecodeFile(o.SwapOut.RawHtlcProof) + if err != nil { + return nil, err + } + + // Get the proofs. + htlcProof, err := htlcProofFile.LastProof() + if err != nil { + return nil, err + } + + return htlcProof, nil +} + +// createPreimageWitness creates a preimage witness for the swap. +func (o *OutFSM) createPreimageWitness(ctx context.Context, + sweepBtcPacket *psbt.Packet, htlcProof *proof.Proof) (wire.TxWitness, + error) { + + assetTxOut := &wire.TxOut{ + PkScript: sweepBtcPacket.Inputs[0].WitnessUtxo.PkScript, + Value: sweepBtcPacket.Inputs[0].WitnessUtxo.Value, + } + feeTxOut := &wire.TxOut{ + PkScript: sweepBtcPacket.Inputs[1].WitnessUtxo.PkScript, + Value: sweepBtcPacket.Inputs[1].WitnessUtxo.Value, + } + + sweepBtcPacket.UnsignedTx.TxIn[0].Sequence = 1 + + successScript, err := o.SwapOut.GetSuccesScript() + if err != nil { + return nil, err + } + + signDesc := &lndclient.SignDescriptor{ + KeyDesc: keychain.KeyDescriptor{ + KeyLocator: o.SwapOut.ClientKeyLocator, + }, + SignMethod: input.TaprootScriptSpendSignMethod, + WitnessScript: successScript, + Output: assetTxOut, + InputIndex: 0, + } + sig, err := o.cfg.Signer.SignOutputRaw( + ctx, sweepBtcPacket.UnsignedTx, []*lndclient.SignDescriptor{signDesc}, + []*wire.TxOut{assetTxOut, feeTxOut}, + ) + if err != nil { + return nil, err + } + taprootAssetRoot, err := o.SwapOut.genTaprootAssetRootFromProof( + htlcProof, + ) + if err != nil { + return nil, err + } + successControlBlock, err := o.SwapOut.genSuccessBtcControlBlock( + taprootAssetRoot, + ) + if err != nil { + return nil, err + } + controlBlockBytes, err := successControlBlock.ToBytes() + if err != nil { + return nil, err + } + + return wire.TxWitness{ + o.SwapOut.SwapPreimage[:], + sig[0], + successScript, + controlBlockBytes, + }, nil +} + +// Infof logs an info message with the swap hash as prefix. +func (o *OutFSM) Infof(format string, args ...interface{}) { + log.Infof( + "Swap %v: "+format, + append( + []interface{}{o.SwapOut.SwapHash}, + args..., + )..., + ) +} + +// Debugf logs a debug message with the swap hash as prefix. +func (o *OutFSM) Debugf(format string, args ...interface{}) { + log.Debugf( + "Swap %v: "+format, + append( + []interface{}{o.SwapOut.SwapHash}, + args..., + )..., + ) +} + +// Errorf logs an error message with the swap hash as prefix. +func (o *OutFSM) Errorf(format string, args ...interface{}) { + log.Errorf( + "Swap %v: "+format, + append( + []interface{}{o.SwapOut.SwapHash}, + args..., + )..., + ) +} +func (o *OutFSM) findPkScript(tx *wire.MsgTx) (*wire.OutPoint, + error) { + pkScript, err := o.getHtlcPkscript() + if err != nil { + return nil, err + } + + for i, out := range tx.TxOut { + if bytes.Equal(out.PkScript, pkScript) { + txHash := tx.TxHash() + return wire.NewOutPoint(&txHash, uint32(i)), nil + } + } + return nil, errors.New("pkscript not found") +} + +// IsFinishedState returns true if the passed state is a finished state. +func IsFinishedState(state fsm.StateType) bool { + for _, s := range finishedStates { + if s == state { + return true + } + } + + return false +} + +// FinishedStates returns a string slice of all finished states. +func FinishedStates() []string { + states := make([]string, 0, len(finishedStates)) + for _, s := range finishedStates { + states = append(states, string(s)) + } + + return states +} diff --git a/assets/rateprovider.go b/assets/rateprovider.go new file mode 100644 index 000000000..6faf66b3f --- /dev/null +++ b/assets/rateprovider.go @@ -0,0 +1,24 @@ +package assets + +import "github.com/btcsuite/btcd/btcutil" + +const ( + fixedPrice = 100 +) + +// FixedExchangeRateProvider is a fixed exchange rate provider. +type FixedExchangeRateProvider struct { + price btcutil.Amount +} + +// NewFixedExchangeRateProvider creates a new fixed exchange rate provider. +func NewFixedExchangeRateProvider() *FixedExchangeRateProvider { + return &FixedExchangeRateProvider{} +} + +// GetSatsPerAssetUnit returns the fixed price in sats per asset unit. +func (e *FixedExchangeRateProvider) GetSatsPerAssetUnit(assetId []byte) ( + btcutil.Amount, error) { + + return btcutil.Amount(fixedPrice), nil +} diff --git a/assets/script.go b/assets/script.go new file mode 100644 index 000000000..85b232d1b --- /dev/null +++ b/assets/script.go @@ -0,0 +1,88 @@ +package assets + +import ( + "github.com/btcsuite/btcd/btcec/v2" + "github.com/btcsuite/btcd/btcec/v2/schnorr" + "github.com/btcsuite/btcd/txscript" + "github.com/decred/dcrd/dcrec/secp256k1/v4" + "github.com/lightninglabs/taproot-assets/asset" + "github.com/lightningnetwork/lnd/input" + "github.com/lightningnetwork/lnd/keychain" + "github.com/lightningnetwork/lnd/lntypes" +) + +// GenSuccessPathScript constructs an HtlcScript for the success payment path. +func GenSuccessPathScript(receiverHtlcKey *btcec.PublicKey, + swapHash lntypes.Hash) ([]byte, error) { + + builder := txscript.NewScriptBuilder() + + builder.AddData(schnorr.SerializePubKey(receiverHtlcKey)) + builder.AddOp(txscript.OP_CHECKSIGVERIFY) + builder.AddOp(txscript.OP_SIZE) + builder.AddInt64(32) + builder.AddOp(txscript.OP_EQUALVERIFY) + builder.AddOp(txscript.OP_HASH160) + builder.AddData(input.Ripemd160H(swapHash[:])) + builder.AddOp(txscript.OP_EQUALVERIFY) + builder.AddInt64(1) + builder.AddOp(txscript.OP_CHECKSEQUENCEVERIFY) + + return builder.Script() +} + +// GenTimeoutPathScript constructs an HtlcScript for the timeout payment path. +func GenTimeoutPathScript(senderHtlcKey *btcec.PublicKey, cltvExpiry int64) ( + []byte, error) { + + builder := txscript.NewScriptBuilder() + builder.AddData(schnorr.SerializePubKey(senderHtlcKey)) + builder.AddOp(txscript.OP_CHECKSIGVERIFY) + builder.AddInt64(cltvExpiry) + builder.AddOp(txscript.OP_CHECKSEQUENCEVERIFY) + return builder.Script() +} + +// GetOpTrueScript returns a script that always evaluates to true. +func GetOpTrueScript() ([]byte, error) { + return txscript.NewScriptBuilder().AddOp(txscript.OP_TRUE).Script() +} + +// createOpTrueLeaf creates a taproot leaf that always evaluates to true. +func createOpTrueLeaf() (asset.ScriptKey, txscript.TapLeaf, + *txscript.IndexedTapScriptTree, *txscript.ControlBlock, error) { + + // Create the taproot OP_TRUE script. + tapScript, err := GetOpTrueScript() + if err != nil { + return asset.ScriptKey{}, txscript.TapLeaf{}, nil, nil, err + } + + tapLeaf := txscript.NewBaseTapLeaf(tapScript) + tree := txscript.AssembleTaprootScriptTree(tapLeaf) + rootHash := tree.RootNode.TapHash() + tapKey := txscript.ComputeTaprootOutputKey(asset.NUMSPubKey, rootHash[:]) + + merkleRootHash := tree.RootNode.TapHash() + + controlBlock := &txscript.ControlBlock{ + LeafVersion: txscript.BaseLeafVersion, + InternalKey: asset.NUMSPubKey, + } + tapScriptKey := asset.ScriptKey{ + PubKey: tapKey, + TweakedScriptKey: &asset.TweakedScriptKey{ + RawKey: keychain.KeyDescriptor{ + PubKey: asset.NUMSPubKey, + }, + Tweak: merkleRootHash[:], + }, + } + if tapKey.SerializeCompressed()[0] == + secp256k1.PubKeyFormatCompressedOdd { + + controlBlock.OutputKeyYIsOdd = true + } + + return tapScriptKey, tapLeaf, tree, controlBlock, nil +} diff --git a/assets/server.go b/assets/server.go new file mode 100644 index 000000000..4e9753c65 --- /dev/null +++ b/assets/server.go @@ -0,0 +1,128 @@ +package assets + +import ( + "context" + + "github.com/btcsuite/btcd/btcutil" + clientrpc "github.com/lightninglabs/loop/looprpc" + "github.com/lightninglabs/loop/swapserverrpc" + "github.com/lightninglabs/taproot-assets/taprpc/universerpc" +) + +type AssetsClientServer struct { + manager *AssetsSwapManager + + clientrpc.UnimplementedAssetsClientServer +} + +func NewAssetsServer(manager *AssetsSwapManager) *AssetsClientServer { + return &AssetsClientServer{ + manager: manager, + } +} + +func (a *AssetsClientServer) SwapOut(ctx context.Context, + req *clientrpc.SwapOutRequest) (*clientrpc.SwapOutResponse, error) { + + swap, err := a.manager.NewSwapOut( + ctx, btcutil.Amount(req.Amt), req.Asset, + ) + if err != nil { + return nil, err + } + return &clientrpc.SwapOutResponse{ + SwapStatus: &clientrpc.AssetSwapStatus{ + SwapHash: swap.SwapOut.SwapHash[:], + SwapStatus: string(swap.SwapOut.State), + }, + }, nil +} + +func (a *AssetsClientServer) ListAssetSwaps(ctx context.Context, + _ *clientrpc.ListAssetSwapsRequest) (*clientrpc.ListAssetSwapsResponse, + error) { + + swaps, err := a.manager.ListSwapOutoutputs(ctx) + if err != nil { + return nil, err + } + + rpcSwaps := make([]*clientrpc.AssetSwapStatus, 0, len(swaps)) + for _, swap := range swaps { + rpcSwaps = append(rpcSwaps, &clientrpc.AssetSwapStatus{ + SwapHash: swap.SwapHash[:], + SwapStatus: string(swap.State), + }) + } + + return &clientrpc.ListAssetSwapsResponse{ + SwapStatus: rpcSwaps, + }, nil +} + +func (a *AssetsClientServer) ClientListAvailableAssets(ctx context.Context, + req *clientrpc.ClientListAvailableAssetsRequest, +) (*clientrpc.ClientListAvailableAssetsResponse, error) { + + assets, err := a.manager.cfg.ServerClient.ListAvailableAssets( + ctx, &swapserverrpc.ListAvailableAssetsRequest{}, + ) + if err != nil { + return nil, err + } + + availableAssets := make([]*clientrpc.Asset, 0, len(assets.Assets)) + + for _, asset := range assets.Assets { + asset := asset + clientAsset := &clientrpc.Asset{ + AssetId: asset.AssetId, + SatsPerUnit: asset.CurrentSatsPerAssetUnit, + Name: "Asset unknown in known universes", + } + universeRes, err := a.manager.cfg.AssetClient.QueryAssetRoots( + ctx, &universerpc.AssetRootQuery{ + Id: &universerpc.ID{ + Id: &universerpc.ID_AssetId{ + AssetId: asset.AssetId, + }, + ProofType: universerpc.ProofType_PROOF_TYPE_ISSUANCE, + }, + }, + ) + if err != nil { + return nil, err + } + + if universeRes.IssuanceRoot != nil { + clientAsset.Name = universeRes.IssuanceRoot.AssetName + } + + availableAssets = append(availableAssets, clientAsset) + } + + return &clientrpc.ClientListAvailableAssetsResponse{ + AvailableAssets: availableAssets, + }, nil +} +func (a *AssetsClientServer) ClientGetAssetSwapOutQuote(ctx context.Context, + req *clientrpc.ClientGetAssetSwapOutQuoteRequest, +) (*clientrpc.ClientGetAssetSwapOutQuoteResponse, error) { + + // Get the quote from the server. + quoteRes, err := a.manager.cfg.ServerClient.QuoteAssetLoopOut( + ctx, &swapserverrpc.QuoteAssetLoopOutRequest{ + Amount: req.Amt, + Asset: req.Asset, + }, + ) + if err != nil { + return nil, err + } + + return &clientrpc.ClientGetAssetSwapOutQuoteResponse{ + SwapFee: quoteRes.SwapFeeRate, + PrepayAmt: quoteRes.FixedPrepayAmt, + SatsPerUnit: quoteRes.CurrentSatsPerAssetUnit, + }, nil +} diff --git a/assets/store.go b/assets/store.go new file mode 100644 index 000000000..b2dbb3d60 --- /dev/null +++ b/assets/store.go @@ -0,0 +1,292 @@ +package assets + +import ( + "context" + + "github.com/btcsuite/btcd/btcec/v2" + "github.com/btcsuite/btcd/btcutil" + "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/btcsuite/btcd/wire" + "github.com/lightninglabs/loop/fsm" + "github.com/lightninglabs/loop/loopdb" + "github.com/lightninglabs/loop/loopdb/sqlc" + "github.com/lightningnetwork/lnd/clock" + "github.com/lightningnetwork/lnd/keychain" + "github.com/lightningnetwork/lnd/lntypes" +) + +const ( + emptyUserAgent = "" +) + +// BaseDB is the interface that contains all the queries generated +// by sqlc for the instantout table. +type BaseDB interface { + // ExecTx allows for executing a function in the context of a database + // transaction. + ExecTx(ctx context.Context, txOptions loopdb.TxOptions, + txBody func(*sqlc.Queries) error) error + + CreateAssetSwap(ctx context.Context, arg sqlc.CreateAssetSwapParams) error + CreateAssetOutSwap(ctx context.Context, swapHash []byte) error + GetAllAssetOutSwaps(ctx context.Context) ([]sqlc.GetAllAssetOutSwapsRow, error) + GetAssetOutSwap(ctx context.Context, swapHash []byte) (sqlc.GetAssetOutSwapRow, error) + InsertAssetSwapUpdate(ctx context.Context, arg sqlc.InsertAssetSwapUpdateParams) error + UpdateAssetSwapHtlcTx(ctx context.Context, arg sqlc.UpdateAssetSwapHtlcTxParams) error + UpdateAssetSwapOutPreimage(ctx context.Context, arg sqlc.UpdateAssetSwapOutPreimageParams) error + UpdateAssetSwapOutProof(ctx context.Context, arg sqlc.UpdateAssetSwapOutProofParams) error + UpdateAssetSwapSweepTx(ctx context.Context, arg sqlc.UpdateAssetSwapSweepTxParams) error +} + +// PostgresStore is the backing store for the instant out manager. +type PostgresStore struct { + queries BaseDB + clock clock.Clock +} + +// NewPostgresStore creates a new PostgresStore. +func NewPostgresStore(queries BaseDB) *PostgresStore { + + return &PostgresStore{ + queries: queries, + clock: clock.NewDefaultClock(), + } +} + +// CreateAssetSwapOut creates a new asset swap out in the database. +func (p *PostgresStore) CreateAssetSwapOut(ctx context.Context, + swap *SwapOut) error { + + params := sqlc.CreateAssetSwapParams{ + SwapHash: swap.SwapHash[:], + AssetID: swap.AssetId, + Amt: int64(swap.Amount), + SenderPubkey: swap.SenderPubkey.SerializeCompressed(), + ReceiverPubkey: swap.ReceiverPubkey.SerializeCompressed(), + CsvExpiry: swap.CsvExpiry, + InitiationHeight: swap.InitiationHeight, + CreatedTime: p.clock.Now(), + ServerKeyFamily: int64(swap.ClientKeyLocator.Family), + ServerKeyIndex: int64(swap.ClientKeyLocator.Index), + } + + return p.queries.ExecTx( + ctx, &loopdb.SqliteTxOptions{}, func(q *sqlc.Queries) error { + err := q.CreateAssetSwap(ctx, params) + if err != nil { + return err + } + + return q.CreateAssetOutSwap(ctx, swap.SwapHash[:]) + }, + ) +} + +// UpdateAssetSwapHtlcOutpoint updates the htlc outpoint of the swap out in the +// database. +func (p *PostgresStore) UpdateAssetSwapHtlcOutpoint(ctx context.Context, + swapHash lntypes.Hash, outpoint *wire.OutPoint, confirmationHeight int32) error { + + return p.queries.ExecTx( + ctx, &loopdb.SqliteTxOptions{}, func(q *sqlc.Queries) error { + return q.UpdateAssetSwapHtlcTx( + ctx, sqlc.UpdateAssetSwapHtlcTxParams{ + SwapHash: swapHash[:], + HtlcTxid: outpoint.Hash[:], + HtlcVout: int32(outpoint.Index), + HtlcConfirmationHeight: confirmationHeight, + }) + }, + ) +} + +// UpdateAssetSwapOutProof updates the raw proof of the swap out in the +// database. +func (p *PostgresStore) UpdateAssetSwapOutProof(ctx context.Context, + swapHash lntypes.Hash, rawProof []byte) error { + + return p.queries.ExecTx( + ctx, &loopdb.SqliteTxOptions{}, func(q *sqlc.Queries) error { + return q.UpdateAssetSwapOutProof( + ctx, sqlc.UpdateAssetSwapOutProofParams{ + SwapHash: swapHash[:], + RawProofFile: rawProof, + }) + }, + ) +} + +// UpdateAssetSwapOutPreimage updates the preimage of the swap out in the +// database. +func (p *PostgresStore) UpdateAssetSwapOutPreimage(ctx context.Context, + swapHash lntypes.Hash, preimage lntypes.Preimage) error { + + return p.queries.ExecTx( + ctx, &loopdb.SqliteTxOptions{}, func(q *sqlc.Queries) error { + return q.UpdateAssetSwapOutPreimage( + ctx, sqlc.UpdateAssetSwapOutPreimageParams{ + SwapHash: swapHash[:], + SwapPreimage: preimage[:], + }) + }, + ) +} + +// UpdateAssetSwapOutSweepTx updates the sweep tx of the swap out in the +// database. +func (p *PostgresStore) UpdateAssetSwapOutSweepTx(ctx context.Context, + swapHash lntypes.Hash, sweepTxid chainhash.Hash, confHeight int32, + sweepPkscript []byte) error { + + return p.queries.ExecTx( + ctx, &loopdb.SqliteTxOptions{}, func(q *sqlc.Queries) error { + return q.UpdateAssetSwapSweepTx( + ctx, sqlc.UpdateAssetSwapSweepTxParams{ + SwapHash: swapHash[:], + SweepTxid: sweepTxid[:], + SweepConfirmationHeight: confHeight, + SweepPkscript: sweepPkscript, + }) + }, + ) +} + +// InsertAssetSwapUpdate inserts a new swap update in the database. +func (p *PostgresStore) InsertAssetSwapUpdate(ctx context.Context, + swapHash lntypes.Hash, state fsm.StateType) error { + + return p.queries.ExecTx( + ctx, &loopdb.SqliteTxOptions{}, func(q *sqlc.Queries) error { + return q.InsertAssetSwapUpdate( + ctx, sqlc.InsertAssetSwapUpdateParams{ + SwapHash: swapHash[:], + UpdateState: string(state), + UpdateTimestamp: p.clock.Now(), + }) + }, + ) +} + +// GetAllAssetOuts returns all the asset outs from the database. +func (p *PostgresStore) GetAllAssetOuts(ctx context.Context) ([]*SwapOut, error) { + dbAssetOuts, err := p.queries.GetAllAssetOutSwaps(ctx) + if err != nil { + return nil, err + } + + assetOuts := make([]*SwapOut, 0, len(dbAssetOuts)) + for _, dbAssetOut := range dbAssetOuts { + assetOut, err := newSwapOutFromDB( + dbAssetOut.AssetSwap, dbAssetOut.AssetOutSwap, + dbAssetOut.UpdateState, + ) + if err != nil { + return nil, err + } + assetOuts = append(assetOuts, assetOut) + } + return assetOuts, nil +} + +// GetActiveAssetOuts returns all the active asset outs from the database. +func (p *PostgresStore) GetActiveAssetOuts(ctx context.Context) ([]*SwapOut, + error) { + + dbAssetOuts, err := p.queries.GetAllAssetOutSwaps(ctx) + if err != nil { + return nil, err + } + + assetOuts := make([]*SwapOut, 0) + for _, dbAssetOut := range dbAssetOuts { + if IsFinishedState(fsm.StateType(dbAssetOut.UpdateState)) { + continue + } + + assetOut, err := newSwapOutFromDB( + dbAssetOut.AssetSwap, dbAssetOut.AssetOutSwap, + dbAssetOut.UpdateState, + ) + if err != nil { + return nil, err + } + assetOuts = append(assetOuts, assetOut) + } + + return assetOuts, nil +} + +// newSwapOutFromDB creates a new SwapOut from the databse rows. +func newSwapOutFromDB(assetSwap sqlc.AssetSwap, + assetOutSwap sqlc.AssetOutSwap, state string) ( + *SwapOut, error) { + + swapHash, err := lntypes.MakeHash(assetSwap.SwapHash) + if err != nil { + return nil, err + } + + var swapPreimage lntypes.Preimage + if assetSwap.SwapPreimage != nil { + swapPreimage, err = lntypes.MakePreimage(assetSwap.SwapPreimage) + if err != nil { + return nil, err + } + } + + senderPubkey, err := btcec.ParsePubKey(assetSwap.SenderPubkey) + if err != nil { + return nil, err + } + + receiverPubkey, err := btcec.ParsePubKey(assetSwap.ReceiverPubkey) + if err != nil { + return nil, err + } + + var htlcOutpoint *wire.OutPoint + if assetSwap.HtlcTxid != nil { + htlcHash, err := chainhash.NewHash(assetSwap.HtlcTxid) + if err != nil { + return nil, err + } + htlcOutpoint = wire.NewOutPoint( + htlcHash, uint32(assetSwap.HtlcVout), + ) + } + + var sweepOutpoint *wire.OutPoint + if assetSwap.SweepTxid != nil { + sweepHash, err := chainhash.NewHash(assetSwap.SweepTxid) + if err != nil { + return nil, err + } + sweepOutpoint = wire.NewOutPoint( + sweepHash, 0, + ) + } + + return &SwapOut{ + SwapHash: swapHash, + SwapPreimage: swapPreimage, + State: fsm.StateType(state), + Amount: btcutil.Amount(assetSwap.Amt), + SenderPubkey: senderPubkey, + ReceiverPubkey: receiverPubkey, + CsvExpiry: int32(assetSwap.CsvExpiry), + AssetId: assetSwap.AssetID, + InitiationHeight: int32(assetSwap.InitiationHeight), + ClientKeyLocator: keychain.KeyLocator{ + Family: keychain.KeyFamily( + assetSwap.ServerKeyFamily, + ), + Index: uint32(assetSwap.ServerKeyIndex), + }, + HtlcOutPoint: htlcOutpoint, + HtlcConfirmationHeight: uint32(assetSwap.HtlcConfirmationHeight), + SweepOutpoint: sweepOutpoint, + SweepConfirmationHeight: uint32(assetSwap.SweepConfirmationHeight), + SweepPkscript: assetSwap.SweepPkscript, + RawHtlcProof: assetOutSwap.RawProofFile, + }, nil +} diff --git a/assets/store_test.go b/assets/store_test.go new file mode 100644 index 000000000..878663b09 --- /dev/null +++ b/assets/store_test.go @@ -0,0 +1,109 @@ +package assets + +import ( + "context" + "crypto/rand" + "encoding/hex" + "testing" + + "github.com/btcsuite/btcd/btcec/v2" + "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/btcsuite/btcd/wire" + "github.com/lightninglabs/loop/fsm" + "github.com/lightninglabs/loop/loopdb" + "github.com/lightningnetwork/lnd/keychain" + "github.com/lightningnetwork/lnd/lntypes" + "github.com/stretchr/testify/require" +) + +var ( + defaultClientPubkeyBytes, _ = hex.DecodeString("021c97a90a411ff2b10dc2a8e32de2f29d2fa49d41bfbb52bd416e460db0747d0d") + defaultClientPubkey, _ = btcec.ParsePubKey(defaultClientPubkeyBytes) + defaultServerPubkeyBytes, _ = hex.DecodeString("021d97a90a411ff2b10dc2a8e32de2f29d2fa49d41bfbb52bd416e460db0747d0d") + defaultServerPubkey, _ = btcec.ParsePubKey(defaultServerPubkeyBytes) + + defaultOutpoint = &wire.OutPoint{ + Hash: chainhash.Hash{0x01}, + Index: 1, + } +) + +// TestSqlStore tests the asset swap store. +func TestSqlStore(t *testing.T) { + + ctxb := context.Background() + testDb := loopdb.NewTestDB(t) + defer testDb.Close() + + store := NewPostgresStore(testDb) + + swapPreimage := getRandomPreimage() + SwapHash := swapPreimage.Hash() + + // Create a new SwapOut. + swapOut := &SwapOut{ + SwapHash: SwapHash, + SwapPreimage: swapPreimage, + State: fsm.StateType("init"), + Amount: 100, + SenderPubkey: defaultClientPubkey, + ReceiverPubkey: defaultClientPubkey, + CsvExpiry: 100, + AssetId: []byte("assetid"), + InitiationHeight: 1, + ClientKeyLocator: keychain.KeyLocator{ + Family: 1, + Index: 1, + }, + } + + // Save the swap out in the db. + err := store.CreateAssetSwapOut(ctxb, swapOut) + require.NoError(t, err) + + // Insert a new swap out update. + err = store.InsertAssetSwapUpdate( + ctxb, SwapHash, fsm.StateType("state2"), + ) + require.NoError(t, err) + + // Try to fetch all swap outs. + swapOuts, err := store.GetAllAssetOuts(ctxb) + require.NoError(t, err) + require.Len(t, swapOuts, 1) + + // Update the htlc outpoint. + err = store.UpdateAssetSwapHtlcOutpoint( + ctxb, SwapHash, defaultOutpoint, 100, + ) + require.NoError(t, err) + + // Update the offchain payment amount. + err = store.UpdateAssetSwapOutProof( + ctxb, SwapHash, []byte("proof"), + ) + require.NoError(t, err) + + // Try to fetch all active swap outs. + activeSwapOuts, err := store.GetActiveAssetOuts(ctxb) + require.NoError(t, err) + require.Len(t, activeSwapOuts, 1) + + // Update the swap out state to a finished state. + err = store.InsertAssetSwapUpdate( + ctxb, SwapHash, fsm.StateType(FinishedStates()[0]), + ) + require.NoError(t, err) + + // Try to fetch all active swap outs. + activeSwapOuts, err = store.GetActiveAssetOuts(ctxb) + require.NoError(t, err) + require.Len(t, activeSwapOuts, 0) +} + +// getRandomPreimage generates a random reservation ID. +func getRandomPreimage() lntypes.Preimage { + var id lntypes.Preimage + rand.Read(id[:]) + return id +} diff --git a/assets/swap_out.go b/assets/swap_out.go new file mode 100644 index 000000000..203761a50 --- /dev/null +++ b/assets/swap_out.go @@ -0,0 +1,295 @@ +package assets + +import ( + "context" + + "github.com/btcsuite/btcd/btcec/v2" + "github.com/btcsuite/btcd/btcutil" + "github.com/btcsuite/btcd/txscript" + "github.com/btcsuite/btcd/wire" + "github.com/decred/dcrd/dcrec/secp256k1/v4" + "github.com/lightninglabs/loop/fsm" + "github.com/lightninglabs/taproot-assets/address" + "github.com/lightninglabs/taproot-assets/asset" + "github.com/lightninglabs/taproot-assets/commitment" + "github.com/lightninglabs/taproot-assets/proof" + "github.com/lightninglabs/taproot-assets/tapsend" + + "github.com/lightninglabs/taproot-assets/tappsbt" + "github.com/lightningnetwork/lnd/input" + "github.com/lightningnetwork/lnd/keychain" + "github.com/lightningnetwork/lnd/lntypes" +) + +// SwapOut is a struct that represents a swap out. It contains all the +// information needed to perform a swap out. +type SwapOut struct { + // SwapHash is the hash of the swap. + SwapHash lntypes.Hash + + // SwapPreimage is the preimage of the swap, that enables spending + // the success path, it's hash is the main identifier of the swap. + SwapPreimage lntypes.Preimage + + // State is the current state of the swap. + State fsm.StateType + + // Amount is the amount of the asset to swap. + Amount btcutil.Amount + + // SenderPubkey is the pubkey of the sender of onchain asset funds. + SenderPubkey *btcec.PublicKey + + // ReceiverPubkey is the pubkey of the receiver of the onchain asset + // funds. + ReceiverPubkey *btcec.PublicKey + + // CsvExpiry is the relative timelock in blocks for the swap. + CsvExpiry int32 + + // AssetId is the identifier of the asset to swap. + AssetId []byte + + // InitiationHeight is the height at which the swap was initiated. + InitiationHeight int32 + + // ClientKeyLocator is the key locator of the clients key. + ClientKeyLocator keychain.KeyLocator + + // HtlcOutPoint is the outpoint of the htlc that was created to + // perform the swap. + HtlcOutPoint *wire.OutPoint + + // HtlcConfirmationHeight is the height at which the htlc was + // confirmed. + HtlcConfirmationHeight uint32 + + // SweepOutpoint is the outpoint of the htlc that was swept. + SweepOutpoint *wire.OutPoint + + // SweepConfirmationHeight is the height at which the sweep was + // confirmed. + SweepConfirmationHeight uint32 + + // SweepPkscript is the pkscript of the sweep transaction. + SweepPkscript []byte + + // RawHtlcProof is the raw htlc proof that we need to send to the + // receiver. We only keep this in the OutFSM struct as we don't want + // to save it in the store. + RawHtlcProof []byte +} + +// NewSwapOut creates a new swap out. +func NewSwapOut(swapHash lntypes.Hash, amt btcutil.Amount, + assetId []byte, clientKeyDesc *keychain.KeyDescriptor, + senderPubkey *btcec.PublicKey, csvExpiry, initiationHeight int32, +) *SwapOut { + + return &SwapOut{ + SwapHash: swapHash, + State: Init, + Amount: amt, + SenderPubkey: senderPubkey, + ReceiverPubkey: clientKeyDesc.PubKey, + CsvExpiry: csvExpiry, + InitiationHeight: initiationHeight, + ClientKeyLocator: clientKeyDesc.KeyLocator, + AssetId: assetId, + } +} + +// GetSuccesScript returns the success path script of the swap. +func (s *SwapOut) GetSuccesScript() ([]byte, error) { + return GenSuccessPathScript(s.ReceiverPubkey, s.SwapHash) +} + +// GetTimeoutScript returns the timeout path script of the swap. +func (s *SwapOut) GetTimeoutScript() ([]byte, error) { + return GenTimeoutPathScript(s.SenderPubkey, int64(s.CsvExpiry)) +} + +// getAggregateKey returns the aggregate musig2 key of the swap. +func (s *SwapOut) getAggregateKey() (*btcec.PublicKey, error) { + aggregateKey, err := input.MuSig2CombineKeys( + input.MuSig2Version100RC2, + []*btcec.PublicKey{ + s.SenderPubkey, s.ReceiverPubkey, + }, + true, + &input.MuSig2Tweaks{}, + ) + if err != nil { + return nil, err + } + + return aggregateKey.PreTweakedKey, nil +} + +// GetTimeOutLeaf returns the timeout leaf of the swap. +func (s *SwapOut) GetTimeOutLeaf() (txscript.TapLeaf, error) { + timeoutScript, err := s.GetTimeoutScript() + if err != nil { + return txscript.TapLeaf{}, err + } + + timeoutLeaf := txscript.NewBaseTapLeaf(timeoutScript) + + return timeoutLeaf, nil +} + +// GetSuccessLeaf returns the success leaf of the swap. +func (s *SwapOut) GetSuccessLeaf() (txscript.TapLeaf, error) { + successScript, err := s.GetSuccesScript() + if err != nil { + return txscript.TapLeaf{}, err + } + + successLeaf := txscript.NewBaseTapLeaf(successScript) + + return successLeaf, nil +} + +// getSiblingPreimage returns the sibling preimage of the htlc bitcoin toplevel +// output. +func (s *SwapOut) getSiblingPreimage() (commitment.TapscriptPreimage, error) { + timeOutLeaf, err := s.GetTimeOutLeaf() + if err != nil { + return commitment.TapscriptPreimage{}, err + } + + successLeaf, err := s.GetSuccessLeaf() + if err != nil { + return commitment.TapscriptPreimage{}, err + } + + branch := txscript.NewTapBranch(timeOutLeaf, successLeaf) + + siblingPreimage := commitment.NewPreimageFromBranch(branch) + + return siblingPreimage, nil +} + +// createSweepVpkt creates the vpacket for the sweep. +func (s *SwapOut) createSweepVpkt(ctx context.Context, htlcProof *proof.Proof, + scriptKey asset.ScriptKey, internalKey keychain.KeyDescriptor, +) (*tappsbt.VPacket, error) { + + sweepVpkt, err := tappsbt.FromProofs( + []*proof.Proof{htlcProof}, &address.RegressionNetTap, + ) + if err != nil { + return nil, err + } + sweepVpkt.Outputs = append(sweepVpkt.Outputs, &tappsbt.VOutput{ + AssetVersion: asset.Version(1), + Amount: uint64(s.Amount), + Interactive: true, + AnchorOutputIndex: 0, + ScriptKey: scriptKey, + AnchorOutputInternalKey: internalKey.PubKey, + }) + sweepVpkt.Outputs[0].SetAnchorInternalKey( + internalKey, address.RegressionNetTap.HDCoinType, + ) + + err = tapsend.PrepareOutputAssets(ctx, sweepVpkt) + if err != nil { + return nil, err + } + + _, _, _, controlBlock, err := createOpTrueLeaf() + if err != nil { + return nil, err + } + + controlBlockBytes, err := controlBlock.ToBytes() + if err != nil { + return nil, err + } + + opTrueScript, err := GetOpTrueScript() + if err != nil { + return nil, err + } + + witness := wire.TxWitness{ + opTrueScript, + controlBlockBytes, + } + firstPrevWitness := &sweepVpkt.Outputs[0].Asset.PrevWitnesses[0] + if sweepVpkt.Outputs[0].Asset.HasSplitCommitmentWitness() { + rootAsset := firstPrevWitness.SplitCommitment.RootAsset + firstPrevWitness = &rootAsset.PrevWitnesses[0] + } + firstPrevWitness.TxWitness = witness + + return sweepVpkt, nil +} + +// genSuccessBtcControlBlock generates the control block for the timeout path of +// the swap. +func (s *SwapOut) genSuccessBtcControlBlock(taprootAssetRoot []byte) ( + *txscript.ControlBlock, error) { + + internalKey, err := s.getAggregateKey() + if err != nil { + return nil, err + } + + timeOutLeaf, err := s.GetTimeOutLeaf() + if err != nil { + return nil, err + } + + timeOutLeafHash := timeOutLeaf.TapHash() + + btcControlBlock := &txscript.ControlBlock{ + LeafVersion: txscript.BaseLeafVersion, + InternalKey: internalKey, + InclusionProof: append(timeOutLeafHash[:], taprootAssetRoot[:]...), + } + + successPathScript, err := s.GetSuccesScript() + if err != nil { + return nil, err + } + + rootHash := btcControlBlock.RootHash(successPathScript) + tapKey := txscript.ComputeTaprootOutputKey(internalKey, rootHash) + if tapKey.SerializeCompressed()[0] == + secp256k1.PubKeyFormatCompressedOdd { + + btcControlBlock.OutputKeyYIsOdd = true + } + + return btcControlBlock, nil +} + +// genTaprootAssetRootFromProof generates the taproot asset root from the proof +// of the swap. +func (s *SwapOut) genTaprootAssetRootFromProof(proof *proof.Proof) ([]byte, + error) { + + assetCpy := proof.Asset.Copy() + assetCpy.PrevWitnesses[0].SplitCommitment = nil + sendCommitment, err := commitment.NewAssetCommitment( + assetCpy, + ) + if err != nil { + return nil, err + } + + version := commitment.TapCommitmentV2 + assetCommitment, err := commitment.NewTapCommitment( + &version, sendCommitment, + ) + if err != nil { + return nil, err + } + taprootAssetRoot := txscript.AssembleTaprootScriptTree( + assetCommitment.TapLeaf(), + ).RootNode.TapHash() + + return taprootAssetRoot[:], nil +} diff --git a/assets/tapdclient.go b/assets/tapdclient.go new file mode 100644 index 000000000..cc8bd938f --- /dev/null +++ b/assets/tapdclient.go @@ -0,0 +1,351 @@ +package assets + +import ( + "bytes" + "context" + "encoding/hex" + "os" + + "github.com/btcsuite/btcd/btcutil" + "github.com/btcsuite/btcd/btcutil/psbt" + "github.com/lightninglabs/taproot-assets/asset" + "github.com/lightninglabs/taproot-assets/tappsbt" + "github.com/lightninglabs/taproot-assets/taprpc" + wrpc "github.com/lightninglabs/taproot-assets/taprpc/assetwalletrpc" + "github.com/lightninglabs/taproot-assets/taprpc/mintrpc" + "github.com/lightninglabs/taproot-assets/taprpc/tapdevrpc" + "github.com/lightninglabs/taproot-assets/taprpc/universerpc" + "github.com/lightninglabs/taproot-assets/tapsend" + "github.com/lightningnetwork/lnd/keychain" + "github.com/lightningnetwork/lnd/lnwallet/chainfee" + "github.com/lightningnetwork/lnd/macaroons" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/credentials" + "google.golang.org/grpc/status" + "gopkg.in/macaroon.v2" +) + +var ( + maxMsgRecvSize = grpc.MaxCallRecvMsgSize(400 * 1024 * 1024) +) + +// TapdConfig is a struct that holds the configuration options to connect to a +// taproot assets daemon. +type TapdConfig struct { + Host string `long:"host" description:"The host of the Tap daemon"` + MacaroonPath string `long:"macaroonpath" description:"Path to the admin macaroon"` + TLSPath string `long:"tlspath" description:"Path to the TLS certificate"` +} + +// DefaultTapdConfig returns a default configuration to connect to a taproot +// assets daemon. +func DefaultTapdConfig() *TapdConfig { + return &TapdConfig{ + Host: "localhost:10030", + MacaroonPath: "/home/kon-dev/docker/mounts/regtest/tapd-alice/admin.macaroon", + TLSPath: "/home/kon-dev/docker/mounts/regtest/tapd-alice/tls.cert", + } + +} + +// NewTapdClient retusn a new taproot assets client. +func NewTapdClient(config *TapdConfig) (*TapdClient, error) { + // Create the client connection to the server. + conn, err := getClientConn(config) + if err != nil { + return nil, err + } + + // Create the TapdClient. + client := &TapdClient{ + cc: conn, + TaprootAssetsClient: taprpc.NewTaprootAssetsClient(conn), + AssetWalletClient: wrpc.NewAssetWalletClient(conn), + MintClient: mintrpc.NewMintClient(conn), + UniverseClient: universerpc.NewUniverseClient(conn), + TapDevClient: tapdevrpc.NewTapDevClient(conn), + } + + return client, nil +} + +// Close closes the client connection to the server. +func (c *TapdClient) Close() { + c.cc.Close() +} + +// TapdClient is a client for the Tap daemon. +type TapdClient struct { + cc *grpc.ClientConn + taprpc.TaprootAssetsClient + wrpc.AssetWalletClient + mintrpc.MintClient + universerpc.UniverseClient + tapdevrpc.TapDevClient +} + +// FundAndSignVpacket funds ands signs a vpacket. +func (t *TapdClient) FundAndSignVpacket(ctx context.Context, + vpkt *tappsbt.VPacket) (*tappsbt.VPacket, error) { + + // Fund the packet. + var buf bytes.Buffer + err := vpkt.Serialize(&buf) + if err != nil { + return nil, err + } + + fundResp, err := t.FundVirtualPsbt( + ctx, &wrpc.FundVirtualPsbtRequest{ + Template: &wrpc.FundVirtualPsbtRequest_Psbt{ + Psbt: buf.Bytes(), + }, + }, + ) + if err != nil { + return nil, err + } + + // Sign the packet. + signResp, err := t.SignVirtualPsbt( + ctx, &wrpc.SignVirtualPsbtRequest{ + FundedPsbt: fundResp.FundedPsbt, + }, + ) + if err != nil { + return nil, err + } + + return tappsbt.NewFromRawBytes( + bytes.NewReader(signResp.SignedPsbt), false, + ) +} + +// PrepareAndCommitVirtualPsbts prepares and commits virtual psbts. +func (t *TapdClient) PrepareAndCommitVirtualPsbts(ctx context.Context, + vpkt *tappsbt.VPacket, feeRateSatPerKVByte chainfee.SatPerVByte) ( + *psbt.Packet, []*tappsbt.VPacket, []*tappsbt.VPacket, + *wrpc.CommitVirtualPsbtsResponse, error) { + + htlcVPackets, err := tappsbt.Encode(vpkt) + if err != nil { + return nil, nil, nil, nil, err + } + + htlcBtcPkt, err := tapsend.PrepareAnchoringTemplate( + []*tappsbt.VPacket{vpkt}, + ) + if err != nil { + return nil, nil, nil, nil, err + } + + var buf bytes.Buffer + err = htlcBtcPkt.Serialize(&buf) + if err != nil { + return nil, nil, nil, nil, err + } + + commitResponse, err := t.AssetWalletClient.CommitVirtualPsbts( + ctx, &wrpc.CommitVirtualPsbtsRequest{ + AnchorPsbt: buf.Bytes(), + Fees: &wrpc.CommitVirtualPsbtsRequest_SatPerVbyte{ + SatPerVbyte: uint64(feeRateSatPerKVByte), + }, + AnchorChangeOutput: &wrpc.CommitVirtualPsbtsRequest_Add{ + Add: true, + }, + VirtualPsbts: [][]byte{ + htlcVPackets, + }, + }, + ) + if err != nil { + return nil, nil, nil, nil, err + } + + fundedPacket, err := psbt.NewFromRawBytes( + bytes.NewReader(commitResponse.AnchorPsbt), false, + ) + if err != nil { + return nil, nil, nil, nil, err + } + + activePackets := make( + []*tappsbt.VPacket, len(commitResponse.VirtualPsbts), + ) + for idx := range commitResponse.VirtualPsbts { + activePackets[idx], err = tappsbt.Decode( + commitResponse.VirtualPsbts[idx], + ) + if err != nil { + return nil, nil, nil, nil, err + } + } + + passivePackets := make( + []*tappsbt.VPacket, len(commitResponse.PassiveAssetPsbts), + ) + for idx := range commitResponse.PassiveAssetPsbts { + passivePackets[idx], err = tappsbt.Decode( + commitResponse.PassiveAssetPsbts[idx], + ) + if err != nil { + return nil, nil, nil, nil, err + } + } + + return fundedPacket, activePackets, passivePackets, commitResponse, nil +} + +// LogAndPublish logs and publishes the virtual psbts. +func (t *TapdClient) LogAndPublish(ctx context.Context, btcPkt *psbt.Packet, + activeAssets []*tappsbt.VPacket, passiveAssets []*tappsbt.VPacket, + commitResp *wrpc.CommitVirtualPsbtsResponse) (*taprpc.SendAssetResponse, + error) { + + var buf bytes.Buffer + err := btcPkt.Serialize(&buf) + if err != nil { + return nil, err + } + + request := &wrpc.PublishAndLogRequest{ + AnchorPsbt: buf.Bytes(), + VirtualPsbts: make([][]byte, len(activeAssets)), + PassiveAssetPsbts: make([][]byte, len(passiveAssets)), + ChangeOutputIndex: commitResp.ChangeOutputIndex, + LndLockedUtxos: commitResp.LndLockedUtxos, + } + + for idx := range activeAssets { + request.VirtualPsbts[idx], err = tappsbt.Encode( + activeAssets[idx], + ) + if err != nil { + return nil, err + } + } + for idx := range passiveAssets { + request.PassiveAssetPsbts[idx], err = tappsbt.Encode( + passiveAssets[idx], + ) + if err != nil { + return nil, err + } + } + + resp, err := t.PublishAndLogTransfer(ctx, request) + if err != nil { + return nil, err + } + + return resp, nil +} + +// CheckBalanceById checks the balance of an asset by its id. +func (t *TapdClient) CheckBalanceById(ctx context.Context, assetId []byte, + requestedBalance btcutil.Amount) error { + + // Check if we have enough funds to do the swap. + balanceResp, err := t.ListBalances( + ctx, &taprpc.ListBalancesRequest{ + GroupBy: &taprpc.ListBalancesRequest_AssetId{ + AssetId: true, + }, + AssetFilter: assetId, + }, + ) + if err != nil { + return err + } + + // Check if we have enough funds to do the swap. + balance, ok := balanceResp.AssetBalances[hex.EncodeToString( + assetId, + )] + if !ok { + return status.Error( + codes.Internal, "internal error", + ) + } + if balance.Balance < uint64(requestedBalance) { + return status.Error( + codes.Internal, "internal error", + ) + } + + return nil +} + +// DeriveNewKeys derives a new internal and script key. +func (t *TapdClient) DeriveNewKeys(ctx context.Context) (asset.ScriptKey, + keychain.KeyDescriptor, error) { + scriptKeyDesc, err := t.NextScriptKey( + ctx, &wrpc.NextScriptKeyRequest{ + KeyFamily: uint32(asset.TaprootAssetsKeyFamily), + }, + ) + if err != nil { + return asset.ScriptKey{}, keychain.KeyDescriptor{}, err + } + + scriptKey, err := taprpc.UnmarshalScriptKey(scriptKeyDesc.ScriptKey) + if err != nil { + return asset.ScriptKey{}, keychain.KeyDescriptor{}, err + } + + internalKeyDesc, err := t.NextInternalKey( + ctx, &wrpc.NextInternalKeyRequest{ + KeyFamily: uint32(asset.TaprootAssetsKeyFamily), + }, + ) + if err != nil { + return asset.ScriptKey{}, keychain.KeyDescriptor{}, err + } + internalKeyLnd, err := taprpc.UnmarshalKeyDescriptor( + internalKeyDesc.InternalKey, + ) + if err != nil { + return asset.ScriptKey{}, keychain.KeyDescriptor{}, err + } + + return *scriptKey, internalKeyLnd, nil +} + +func getClientConn(config *TapdConfig) (*grpc.ClientConn, error) { + // Load the specified TLS certificate and build transport credentials. + creds, err := credentials.NewClientTLSFromFile(config.TLSPath, "") + if err != nil { + return nil, err + } + + // Load the specified macaroon file. + macBytes, err := os.ReadFile(config.MacaroonPath) + if err != nil { + return nil, err + } + mac := &macaroon.Macaroon{} + if err := mac.UnmarshalBinary(macBytes); err != nil { + return nil, err + } + + macaroon, err := macaroons.NewMacaroonCredential(mac) + if err != nil { + return nil, err + } + // Create the DialOptions with the macaroon credentials. + opts := []grpc.DialOption{ + grpc.WithTransportCredentials(creds), + grpc.WithPerRPCCredentials(macaroon), + grpc.WithDefaultCallOptions(maxMsgRecvSize), + } + + // Dial the gRPC server. + conn, err := grpc.Dial(config.Host, opts...) + if err != nil { + return nil, err + } + + return conn, nil +} diff --git a/cmd/loop/assets.go b/cmd/loop/assets.go new file mode 100644 index 000000000..4ef62ab97 --- /dev/null +++ b/cmd/loop/assets.go @@ -0,0 +1,229 @@ +package main + +import ( + "bytes" + "context" + "encoding/hex" + "errors" + "fmt" + + "github.com/btcsuite/btcd/btcutil" + "github.com/lightninglabs/loop/looprpc" + "github.com/urfave/cli" +) + +var assetsCommands = cli.Command{ + + Name: "assets", + ShortName: "a", + Usage: "manage asset swaps", + Description: ` + `, + Subcommands: []cli.Command{ + assetsOutCommand, + listOutCommand, + listAvailableAssetsComand, + }, +} +var ( + assetsOutCommand = cli.Command{ + Name: "out", + ShortName: "o", + Usage: "swap asset out", + ArgsUsage: "", + Description: ` + List all reservations. + `, + Flags: []cli.Flag{ + cli.Uint64Flag{ + Name: "amt", + Usage: "the amount in satoshis to loop out.", + }, + cli.StringFlag{ + Name: "asset_id", + Usage: "asset_id", + }, + }, + Action: assetSwapOut, + } + listAvailableAssetsComand = cli.Command{ + Name: "available", + ShortName: "a", + Usage: "list available assets", + ArgsUsage: "", + Description: ` + List available assets from the loop server + `, + + Action: listAvailable, + } + listOutCommand = cli.Command{ + Name: "list", + ShortName: "l", + Usage: "list asset swaps", + ArgsUsage: "", + Description: ` + List all reservations. + `, + Action: listOut, + } +) + +func assetSwapOut(ctx *cli.Context) error { + // First set up the swap client itself. + client, cleanup, err := getAssetsClient(ctx) + if err != nil { + return err + } + defer cleanup() + + args := ctx.Args() + + var amtStr string + switch { + case ctx.IsSet("amt"): + amtStr = ctx.String("amt") + case ctx.NArg() > 0: + amtStr = args[0] + args = args.Tail() + default: + // Show command help if no arguments and flags were provided. + return cli.ShowCommandHelp(ctx, "out") + } + + amt, err := parseAmt(amtStr) + if err != nil { + return err + } + if amt <= 0 { + return fmt.Errorf("amount must be greater than zero") + } + + assetId, err := hex.DecodeString(ctx.String("asset_id")) + if err != nil { + return err + } + + if len(assetId) != 32 { + return fmt.Errorf("invalid asset id") + } + + // First we'll list the available assets. + assets, err := client.ClientListAvailableAssets( + context.Background(), + &looprpc.ClientListAvailableAssetsRequest{}, + ) + if err != nil { + return err + } + + // We now extract the asset name from the list of available assets. + var assetName string + for _, asset := range assets.AvailableAssets { + if bytes.Equal(asset.AssetId, assetId) { + assetName = asset.Name + break + } + } + if assetName == "" { + return fmt.Errorf("asset not found") + } + + // First we'll quote the swap out to get the current fee and rate. + quote, err := client.ClientGetAssetSwapOutQuote( + context.Background(), + &looprpc.ClientGetAssetSwapOutQuoteRequest{ + Amt: uint64(amt), + Asset: assetId, + }, + ) + if err != nil { + return err + } + + totalSats := btcutil.Amount(amt * btcutil.Amount(quote.SatsPerUnit)).MulF64(float64(1) + quote.SwapFee) + + fmt.Printf(satAmtFmt, "Fixed prepay cost:", quote.PrepayAmt) + fmt.Printf(bpsFmt, "Swap fee:", int64(quote.SwapFee*10000)) + fmt.Printf(satAmtFmt, "Sats per unit:", quote.SatsPerUnit) + fmt.Printf(satAmtFmt, "Swap Offchain payment:", totalSats) + fmt.Printf(satAmtFmt, "Total Send off-chain:", totalSats+btcutil.Amount(quote.PrepayAmt)) + fmt.Printf(assetFmt, "Receive assets on-chain:", int64(amt), assetName) + + fmt.Println("CONTINUE SWAP? (y/n): ") + + var answer string + fmt.Scanln(&answer) + if answer != "y" { + return errors.New("swap canceled") + } + + res, err := client.SwapOut( + context.Background(), + &looprpc.SwapOutRequest{ + Amt: uint64(amt), + Asset: assetId, + }, + ) + if err != nil { + return err + } + + printRespJSON(res) + return nil +} + +func listAvailable(ctx *cli.Context) error { + // First set up the swap client itself. + client, cleanup, err := getAssetsClient(ctx) + if err != nil { + return err + } + defer cleanup() + + res, err := client.ClientListAvailableAssets( + context.Background(), + &looprpc.ClientListAvailableAssetsRequest{}, + ) + if err != nil { + return err + } + + printRespJSON(res) + return nil +} +func listOut(ctx *cli.Context) error { + // First set up the swap client itself. + client, cleanup, err := getAssetsClient(ctx) + if err != nil { + return err + } + defer cleanup() + + res, err := client.ListAssetSwaps( + context.Background(), + &looprpc.ListAssetSwapsRequest{}, + ) + if err != nil { + return err + } + + printRespJSON(res) + return nil +} + +func getAssetsClient(ctx *cli.Context) (looprpc.AssetsClientClient, func(), error) { + rpcServer := ctx.GlobalString("rpcserver") + tlsCertPath, macaroonPath, err := extractPathArgs(ctx) + if err != nil { + return nil, nil, err + } + conn, err := getClientConn(rpcServer, tlsCertPath, macaroonPath) + if err != nil { + return nil, nil, err + } + cleanup := func() { conn.Close() } + + loopClient := looprpc.NewAssetsClientClient(conn) + return loopClient, cleanup, nil +} diff --git a/cmd/loop/main.go b/cmd/loop/main.go index cfed2c220..61bf9ecb8 100644 --- a/cmd/loop/main.go +++ b/cmd/loop/main.go @@ -87,6 +87,20 @@ const ( // Estimated on-chain fee: 7262 sat satAmtFmt = "%-36s %12d sat\n" + // bpsFmt formats a basis point value into a one line string, intended to + // prettify the terminal output. For Instance, + // fmt.Printf(f, "Service fee:", fee) + // prints out as, + // Service fee: 20 bps + bpsFmt = "%-36s %12d bps\n" + + // assetFmt formats an asset into a one line string, intended to + // prettify the terminal output. For Instance, + // fmt.Printf(f, "Receive asset onchain:", assetName, assetAmt) + // prints out as, + // Receive asset onchain: 0.0001 USD + assetFmt = "%-36s %12d %s\n" + // blkFmt formats the number of blocks into a one line string, intended // to prettify the terminal output. For Instance, // fmt.Printf(f, "Conf target", target) @@ -148,7 +162,7 @@ func main() { listSwapsCommand, swapInfoCommand, getLiquidityParamsCommand, setLiquidityRuleCommand, suggestSwapCommand, setParamsCommand, getInfoCommand, abandonSwapCommand, reservationsCommands, - instantOutCommand, listInstantOutsCommand, + instantOutCommand, listInstantOutsCommand, assetsCommands, } err := app.Run(os.Args) diff --git a/fsm/fsm.go b/fsm/fsm.go index a16a33567..c6a5d46f9 100644 --- a/fsm/fsm.go +++ b/fsm/fsm.go @@ -297,6 +297,16 @@ func (s *StateMachine) RemoveObserver(observer Observer) bool { return false } +// Lock locks the state machine. +func (s *StateMachine) Lock() { + s.mutex.Lock() +} + +// Unlock unlocks the state machine. +func (s *StateMachine) Unlock() { + s.mutex.Unlock() +} + // HandleError is a helper function that can be used by actions to handle // errors. func (s *StateMachine) HandleError(err error) EventType { diff --git a/go.mod b/go.mod index 25329312f..900bc3c05 100644 --- a/go.mod +++ b/go.mod @@ -6,24 +6,24 @@ require ( github.com/btcsuite/btcd/btcutil v1.1.5 github.com/btcsuite/btcd/btcutil/psbt v1.1.8 github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 - github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f - github.com/btcsuite/btcwallet v0.16.10-0.20240809133323-7d3434c65ae2 - github.com/btcsuite/btcwallet/wtxmgr v1.5.3 + github.com/btcsuite/btclog v0.0.0-20241003133417-09c4e92e319c + github.com/btcsuite/btcwallet v0.16.10-0.20240912233857-ffb143c77cc5 + github.com/btcsuite/btcwallet/wtxmgr v1.5.4 github.com/coreos/bbolt v1.3.3 github.com/davecgh/go-spew v1.1.1 github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 github.com/fortytw2/leaktest v1.3.0 github.com/golang-migrate/migrate/v4 v4.17.0 - github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3 + github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 github.com/jackc/pgconn v1.14.3 github.com/jackc/pgerrcode v0.0.0-20240316143900-6e2875d9b438 github.com/jessevdk/go-flags v1.4.0 github.com/lib/pq v1.10.9 - github.com/lightninglabs/aperture v0.3.2-beta - github.com/lightninglabs/lndclient v0.18.4-0 + github.com/lightninglabs/aperture v0.3.2-beta.0.20241015115230-d59b5514c19a + github.com/lightninglabs/lndclient v0.18.4-1 github.com/lightninglabs/loop/looprpc v1.0.0 github.com/lightninglabs/loop/swapserverrpc v1.0.8 - github.com/lightningnetwork/lnd v0.18.3-beta.rc3.0.20241011124628-ca3bde901eb8 + github.com/lightningnetwork/lnd v0.18.3-beta.rc3.0.20241025090009-615f3d633e61 github.com/lightningnetwork/lnd/cert v1.2.2 github.com/lightningnetwork/lnd/clock v1.1.1 github.com/lightningnetwork/lnd/queue v1.1.1 @@ -37,7 +37,12 @@ require ( google.golang.org/protobuf v1.34.2 gopkg.in/macaroon-bakery.v2 v2.1.0 gopkg.in/macaroon.v2 v2.1.0 - modernc.org/sqlite v1.29.10 + modernc.org/sqlite v1.30.0 +) + +require ( + github.com/lightninglabs/lightning-node-connect/hashmailrpc v1.0.2 // indirect + github.com/lightningnetwork/lnd/kvdb v1.4.10 // indirect ) require ( @@ -51,18 +56,18 @@ require ( github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da // indirect github.com/aead/siphash v1.0.1 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/btcsuite/btcwallet/wallet/txauthor v1.3.4 // indirect - github.com/btcsuite/btcwallet/wallet/txrules v1.2.1 // indirect - github.com/btcsuite/btcwallet/wallet/txsizes v1.2.4 // indirect - github.com/btcsuite/btcwallet/walletdb v1.4.2 // indirect + github.com/btcsuite/btcwallet/wallet/txauthor v1.3.5 // indirect + github.com/btcsuite/btcwallet/wallet/txrules v1.2.2 // indirect + github.com/btcsuite/btcwallet/wallet/txsizes v1.2.5 // indirect + github.com/btcsuite/btcwallet/walletdb v1.4.4 // indirect github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd // indirect github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792 // indirect github.com/btcsuite/winsvc v1.0.0 // indirect - github.com/cenkalti/backoff/v4 v4.1.3 // indirect + github.com/cenkalti/backoff/v4 v4.2.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/containerd/continuity v0.3.0 // indirect github.com/coreos/go-semver v0.3.0 // indirect - github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f // indirect + github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf // indirect github.com/coreos/go-systemd/v22 v22.3.2 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect github.com/decred/dcrd/crypto/blake256 v1.0.1 // indirect @@ -86,7 +91,7 @@ require ( github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/google/uuid v1.6.0 // indirect github.com/gorilla/websocket v1.5.0 // indirect - github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect + github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect @@ -111,16 +116,16 @@ require ( github.com/lightninglabs/gozmq v0.0.0-20191113021534-d20a764486bf // indirect github.com/lightninglabs/neutrino v0.16.1-0.20240425105051-602843d34ffd // indirect github.com/lightninglabs/neutrino/cache v1.1.2 // indirect + github.com/lightninglabs/taproot-assets v0.4.2-0.20241031160301-588e58bfae6c github.com/lightningnetwork/lightning-onion v1.2.1-0.20240712235311-98bd56499dfb // indirect - github.com/lightningnetwork/lnd/fn v1.2.1 // indirect + github.com/lightningnetwork/lnd/fn v1.2.3 // indirect github.com/lightningnetwork/lnd/healthcheck v1.2.5 // indirect - github.com/lightningnetwork/lnd/kvdb v1.4.10 // indirect github.com/lightningnetwork/lnd/sqldb v1.0.4 // indirect github.com/lightningnetwork/lnd/tlv v1.2.6 // indirect github.com/ltcsuite/ltcd v0.0.0-20190101042124-f37f8bf35796 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect - github.com/miekg/dns v1.1.43 // indirect + github.com/miekg/dns v1.1.50 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect github.com/moby/term v0.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect @@ -131,10 +136,10 @@ require ( github.com/opencontainers/runc v1.1.14 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/prometheus/client_golang v1.11.1 // indirect + github.com/prometheus/client_golang v1.14.0 // indirect github.com/prometheus/client_model v0.3.0 // indirect - github.com/prometheus/common v0.30.0 // indirect - github.com/prometheus/procfs v0.7.3 // indirect + github.com/prometheus/common v0.37.0 // indirect + github.com/prometheus/procfs v0.8.0 // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/rogpeppe/fastuuid v1.2.0 // indirect github.com/russross/blackfriday/v2 v2.0.1 // indirect @@ -152,27 +157,26 @@ require ( github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect gitlab.com/yawning/bsaes.git v0.0.0-20190805113838-0a714cd429ec // indirect - go.etcd.io/bbolt v1.3.7 // indirect - go.etcd.io/etcd/api/v3 v3.5.7 // indirect - go.etcd.io/etcd/client/pkg/v3 v3.5.7 // indirect - go.etcd.io/etcd/client/v2 v2.305.7 // indirect - go.etcd.io/etcd/client/v3 v3.5.7 // indirect - go.etcd.io/etcd/pkg/v3 v3.5.7 // indirect - go.etcd.io/etcd/raft/v3 v3.5.7 // indirect - go.etcd.io/etcd/server/v3 v3.5.7 // indirect + go.etcd.io/bbolt v1.3.11 // indirect + go.etcd.io/etcd/api/v3 v3.5.12 // indirect + go.etcd.io/etcd/client/pkg/v3 v3.5.12 // indirect + go.etcd.io/etcd/client/v2 v2.305.12 // indirect + go.etcd.io/etcd/client/v3 v3.5.12 // indirect + go.etcd.io/etcd/pkg/v3 v3.5.12 // indirect + go.etcd.io/etcd/raft/v3 v3.5.12 // indirect + go.etcd.io/etcd/server/v3 v3.5.12 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect go.opentelemetry.io/otel v1.28.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.3.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.3.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.3.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.20.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.20.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/sdk v1.21.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect - go.opentelemetry.io/proto/otlp v0.19.0 // indirect - go.uber.org/atomic v1.7.0 // indirect + go.opentelemetry.io/proto/otlp v1.0.0 // indirect + go.uber.org/atomic v1.10.0 // indirect go.uber.org/multierr v1.6.0 // indirect - go.uber.org/zap v1.17.0 // indirect + go.uber.org/zap v1.23.0 // indirect golang.org/x/crypto v0.25.0 // indirect golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 // indirect golang.org/x/mod v0.17.0 // indirect @@ -190,7 +194,7 @@ require ( gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 // indirect - modernc.org/libc v1.49.3 // indirect + modernc.org/libc v1.50.9 // indirect modernc.org/mathutil v1.6.0 // indirect modernc.org/memory v1.8.0 // indirect modernc.org/strutil v1.2.0 // indirect @@ -206,6 +210,8 @@ replace github.com/lightninglabs/loop/swapserverrpc => ./swapserverrpc replace github.com/lightninglabs/loop/looprpc => ./looprpc +// replace github.com/lightninglabs/taproot-assets => ../taproot-assets + go 1.22.6 toolchain go1.22.7 diff --git a/go.sum b/go.sum index bd246209c..fe7bf7362 100644 --- a/go.sum +++ b/go.sum @@ -639,6 +639,8 @@ github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kd github.com/apache/arrow/go/v10 v10.0.1/go.mod h1:YvhnlEePVnBS4+0z3fhPfUy7W1Ikj0Ih0vcRo/gZ1M0= github.com/apache/arrow/go/v11 v11.0.0/go.mod h1:Eg5OsL5H+e299f7u5ssuXsuHQVEGC4xei5aX110hRiI= github.com/apache/thrift v0.16.0/go.mod h1:PHK3hniurgQaNMZYaCLEqXKsYK8upmhPbmdP2FXSqgU= +github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -664,21 +666,22 @@ github.com/btcsuite/btcd/chaincfg/chainhash v1.0.0/go.mod h1:7SFka0XMvUgj3hfZtyd github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 h1:59Kx4K6lzOW5w6nFlA0v5+lk/6sjybR934QNHSJZPTQ= github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= -github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f h1:bAs4lUbRJpnnkd9VhRV3jjAVU7DJVjMaK+IsvSeZvFo= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btclog v0.0.0-20241003133417-09c4e92e319c h1:4HxD1lBUGUddhzgaNgrCPsFWd7cGYNpeFUgd9ZIgyM0= +github.com/btcsuite/btclog v0.0.0-20241003133417-09c4e92e319c/go.mod h1:w7xnGOhwT3lmrS4H3b/D1XAXxvh+tbhUm8xeHN2y3TQ= github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= -github.com/btcsuite/btcwallet v0.16.10-0.20240809133323-7d3434c65ae2 h1:qa4Avm7p97JroZZyMJADbEb9u853pjleJYSeitENvLc= -github.com/btcsuite/btcwallet v0.16.10-0.20240809133323-7d3434c65ae2/go.mod h1:X2xDre+j1QphTRo54y2TikUzeSvreL1t1aMXrD8Kc5A= -github.com/btcsuite/btcwallet/wallet/txauthor v1.3.4 h1:poyHFf7+5+RdxNp5r2T6IBRD7RyraUsYARYbp/7t4D8= -github.com/btcsuite/btcwallet/wallet/txauthor v1.3.4/go.mod h1:GETGDQuyq+VFfH1S/+/7slLM/9aNa4l7P4ejX6dJfb0= -github.com/btcsuite/btcwallet/wallet/txrules v1.2.1 h1:UZo7YRzdHbwhK7Rhv3PO9bXgTxiOH45edK5qdsdiatk= -github.com/btcsuite/btcwallet/wallet/txrules v1.2.1/go.mod h1:MVSqRkju/IGxImXYPfBkG65FgEZYA4fXchheILMVl8g= -github.com/btcsuite/btcwallet/wallet/txsizes v1.2.4 h1:nmcKAVTv/cmYrs0A4hbiC6Qw+WTLYy/14SmTt3mLnCo= -github.com/btcsuite/btcwallet/wallet/txsizes v1.2.4/go.mod h1:YqJR8WAAHiKIPesZTr9Cx9Az4fRhRLcJ6GcxzRUZCAc= -github.com/btcsuite/btcwallet/walletdb v1.4.2 h1:zwZZ+zaHo4mK+FAN6KeK85S3oOm+92x2avsHvFAhVBE= -github.com/btcsuite/btcwallet/walletdb v1.4.2/go.mod h1:7ZQ+BvOEre90YT7eSq8bLoxTsgXidUzA/mqbRS114CQ= -github.com/btcsuite/btcwallet/wtxmgr v1.5.3 h1:QrWCio9Leh3DwkWfp+A1SURj8pYn3JuTLv3waP5uEro= -github.com/btcsuite/btcwallet/wtxmgr v1.5.3/go.mod h1:M4nQpxGTXiDlSOODKXboXX7NFthmiBNjzAKKNS7Fhjg= +github.com/btcsuite/btcwallet v0.16.10-0.20240912233857-ffb143c77cc5 h1:zYy233eUBvkF3lq2MUkybEhxhDsrRDSgiToIKN57mtk= +github.com/btcsuite/btcwallet v0.16.10-0.20240912233857-ffb143c77cc5/go.mod h1:1HJXYbjJzgumlnxOC2+ViR1U+gnHWoOn7WeK5OfY1eU= +github.com/btcsuite/btcwallet/wallet/txauthor v1.3.5 h1:Rr0njWI3r341nhSPesKQ2JF+ugDSzdPoeckS75SeDZk= +github.com/btcsuite/btcwallet/wallet/txauthor v1.3.5/go.mod h1:+tXJ3Ym0nlQc/iHSwW1qzjmPs3ev+UVWMbGgfV1OZqU= +github.com/btcsuite/btcwallet/wallet/txrules v1.2.2 h1:YEO+Lx1ZJJAtdRrjuhXjWrYsmAk26wLTlNzxt2q0lhk= +github.com/btcsuite/btcwallet/wallet/txrules v1.2.2/go.mod h1:4v+grppsDpVn91SJv+mZT7B8hEV4nSmpREM4I8Uohws= +github.com/btcsuite/btcwallet/wallet/txsizes v1.2.5 h1:93o5Xz9dYepBP4RMFUc9RGIFXwqP2volSWRkYJFrNtI= +github.com/btcsuite/btcwallet/wallet/txsizes v1.2.5/go.mod h1:lQ+e9HxZ85QP7r3kdxItkiMSloSLg1PEGis5o5CXUQw= +github.com/btcsuite/btcwallet/walletdb v1.4.4 h1:BDel6iT/ltYSIYKs0YbjwnEDi7xR3yzABIsQxN2F1L8= +github.com/btcsuite/btcwallet/walletdb v1.4.4/go.mod h1:jk/hvpLFINF0C1kfTn0bfx2GbnFT+Nvnj6eblZALfjs= +github.com/btcsuite/btcwallet/wtxmgr v1.5.4 h1:hJjHy1h/dJwSfD9uDsCwcH21D1iOrus6OrI5gR9E/O0= +github.com/btcsuite/btcwallet/wtxmgr v1.5.4/go.mod h1:lAv0b1Vj9Ig5U8QFm0yiJ9WqPl8yGO/6l7JxdHY1PKE= github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd h1:R/opQEbFEy9JGkIguV40SvRY1uliPX8ifOvi6ICsFCw= github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= github.com/btcsuite/golangcrypto v0.0.0-20150304025918-53f62d9b43e8/go.mod h1:tYvUd8KLhm/oXvUeSEs2VlLghFjQt9+ZaF9ghH0JNjc= @@ -690,16 +693,14 @@ github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792 h1:R8vQdOQdZ9Y3 github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0 h1:J9B4L7e3oqhXOcm+2IuNApwzQec85lE+QaikUcCs+dk= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= -github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= -github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4= -github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= +github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= +github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= -github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054 h1:uH66TXeswKn5PW5zdZ39xEwfS9an067BirqA+P4QaLI= -github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= @@ -723,12 +724,8 @@ github.com/cncf/xds/go v0.0.0-20240318125728-8a4994d93e50 h1:DBmgJDC9dTfkVyGgipa github.com/cncf/xds/go v0.0.0-20240318125728-8a4994d93e50/go.mod h1:5e1+Vvlzido69INQaVO6d87Qn543Xr6nooe9Kz7oBFM= github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= -github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5 h1:xD/lrqdvwsc+O2bjSSi3YqY73Ke3LAiSCx49aCesA0E= -github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo= -github.com/cockroachdb/errors v1.2.4 h1:Lap807SXTH5tri2TivECb/4abUkMZC9zRoLarvcKDqs= -github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA= -github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f h1:o/kfcElHqOiXqcou5a3rIlMc7oJbMQkeLk0VQJ7zgqY= -github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= +github.com/cockroachdb/datadriven v1.0.2 h1:H9MtNqVoVhvd9nCBwOyDjUEdZCREqbIdCJD93PBm/jA= +github.com/cockroachdb/datadriven v1.0.2/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM= github.com/coreos/bbolt v1.3.3 h1:n6AiVyVRKQFNb6mJlwESEvvLoDyiTzXX7ORAUlkeBdY= @@ -736,8 +733,9 @@ github.com/coreos/bbolt v1.3.3/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkE github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f h1:JOrtw2xFKzlg+cbHpyrpLDmnN1HqhBfnX7WDiW7eG2c= github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf h1:iW4rZ826su+pqaw19uhpSCzhj44qo35pNgKFGqzDKkU= +github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.3.2 h1:D9/bQk5vlXQFZ6Kwuu6zaiXJ9oTPe68++AzAJc1DzSI= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= @@ -809,8 +807,6 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= -github.com/getsentry/raven-go v0.2.0 h1:no+xWJRb5ZI7eE8TWgIq1jLulQiIoLG0IfYxv5JYMGs= -github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= @@ -825,17 +821,16 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2 github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= +github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= github.com/go-latex/latex v0.0.0-20210118124228-b3d85cf34e07/go.mod h1:CO1AlKB2CSIqUrmQPqA0gdRIlnLEY0gK5JGjh37zN5U= github.com/go-latex/latex v0.0.0-20210823091927-c0d11ff05a81/go.mod h1:SX0U8uGpxhq9o2S/CELCSUxEWWAuoCUcVCQWv7G2OCk= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.1/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-logr/stdr v1.2.0/go.mod h1:YkVgnZu1ZjjL7xTxrfm/LLZBfkhTqSR1ydtm6jTKKwI= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-pdf/fpdf v0.5.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= @@ -859,6 +854,7 @@ github.com/golang-migrate/migrate/v4 v4.17.0 h1:rd40H3QXU0AA4IoLllFcEAEo9dYKRHYN github.com/golang-migrate/migrate/v4 v4.17.0/go.mod h1:+Cp2mtLP4/aXDTKb9wmXYitdrNx2HGs45rbWAo6OsKM= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/glog v0.0.0-20210429001901-424d2337a529/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= github.com/golang/glog v1.2.0 h1:uCdmnmatrKCgMBlM4rMuJZWOkPDqdbZPnrMXDY4gI68= @@ -967,15 +963,21 @@ github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+ github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= -github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= +github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI= +github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8= +github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.0-rc.0 h1:mdLirNAJBxnGgyB6pjZLcs6ue/6eZGBui6gXspfq4ks= +github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.0-rc.0/go.mod h1:kdXbOySqcQeTxiqglW7aahTmWZy3Pgi6SYL36yvKeyA= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.3 h1:o95KDiV/b1xdkumY5YbLR0/n2+wBxUpgf3HgfKgTyLI= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.3/go.mod h1:hTxjzRcX49ogbTGVJ1sM5mz5s+SSgiGIyL3jjPxl32E= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.5.0/go.mod h1:r1hZAcvfFXuYmcKyCJI9wlyOPIZUJl6FCB8Cpca/NLE= github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3 h1:lLT7ZLSzGLI08vc9cpd+tYmNWjdKDqyr/2L+f6U12Fk= github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -1115,28 +1117,32 @@ github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/lightninglabs/aperture v0.3.2-beta h1:J2GQwBmSHxpr5VOatXbgrTogF/qN2l6UWLPHfIowq10= -github.com/lightninglabs/aperture v0.3.2-beta/go.mod h1:M/5dPzHjHvuYXQuxzicqaGiCclHUvKW6N0ay1t/HGiM= +github.com/lightninglabs/aperture v0.3.2-beta.0.20241015115230-d59b5514c19a h1:SFC1FrJdNjjt/XTdF9c4wswemeDEItg3J+yhKK6C4sw= +github.com/lightninglabs/aperture v0.3.2-beta.0.20241015115230-d59b5514c19a/go.mod h1:O4xvD6LfGPEF+fK2z2a3s9nwfcGlmDHsGnlq3jSiWnE= github.com/lightninglabs/gozmq v0.0.0-20191113021534-d20a764486bf h1:HZKvJUHlcXI/f/O0Avg7t8sqkPo78HFzjmeYFl6DPnc= github.com/lightninglabs/gozmq v0.0.0-20191113021534-d20a764486bf/go.mod h1:vxmQPeIQxPf6Jf9rM8R+B4rKBqLA2AjttNxkFBL2Plk= -github.com/lightninglabs/lndclient v0.18.4-0 h1:TdorvV9UIw3fjZrNpVKn3fpsOdw2KWF2Eqdx7+++lcY= -github.com/lightninglabs/lndclient v0.18.4-0/go.mod h1:LbINSPfKEdZuTGqqJ+ZmUxXWNvUCaDqrZeJ7/Al0Z3Y= +github.com/lightninglabs/lightning-node-connect/hashmailrpc v1.0.2 h1:Er1miPZD2XZwcfE4xoS5AILqP1mj7kqnhbBSxW9BDxY= +github.com/lightninglabs/lightning-node-connect/hashmailrpc v1.0.2/go.mod h1:antQGRDRJiuyQF6l+k6NECCSImgCpwaZapATth2Chv4= +github.com/lightninglabs/lndclient v0.18.4-1 h1:k2UnxHGNH243NRe5/dL2sKgrxc8WMHbFQRdnCtfilwc= +github.com/lightninglabs/lndclient v0.18.4-1/go.mod h1:/HLqmZGL9MtP8F1g+laq+L9VrsugBN5tsTct3C5wWCg= github.com/lightninglabs/neutrino v0.16.1-0.20240425105051-602843d34ffd h1:D8aRocHpoCv43hL8egXEMYyPmyOiefFHZ66338KQB2s= github.com/lightninglabs/neutrino v0.16.1-0.20240425105051-602843d34ffd/go.mod h1:x3OmY2wsA18+Kc3TSV2QpSUewOCiscw2mKpXgZv2kZk= github.com/lightninglabs/neutrino/cache v1.1.2 h1:C9DY/DAPaPxbFC+xNNEI/z1SJY9GS3shmlu5hIQ798g= github.com/lightninglabs/neutrino/cache v1.1.2/go.mod h1:XJNcgdOw1LQnanGjw8Vj44CvguYA25IMKjWFZczwZuo= github.com/lightninglabs/protobuf-go-hex-display v1.33.0-hex-display h1:Y2WiPkBS/00EiEg0qp0FhehxnQfk3vv8U6Xt3nN+rTY= github.com/lightninglabs/protobuf-go-hex-display v1.33.0-hex-display/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +github.com/lightninglabs/taproot-assets v0.4.2-0.20241031160301-588e58bfae6c h1:HfU82bWD4Yk+Mf2Ax25uhcIwq0SxToTq8J8YJLReW/U= +github.com/lightninglabs/taproot-assets v0.4.2-0.20241031160301-588e58bfae6c/go.mod h1:AYq9p1FOMdwAGjEjVaT79+cDyAwcc4fj8W0YJvCU0JE= github.com/lightningnetwork/lightning-onion v1.2.1-0.20240712235311-98bd56499dfb h1:yfM05S8DXKhuCBp5qSMZdtSwvJ+GFzl94KbXMNB1JDY= github.com/lightningnetwork/lightning-onion v1.2.1-0.20240712235311-98bd56499dfb/go.mod h1:c0kvRShutpj3l6B9WtTsNTBUtjSmjZXbJd9ZBRQOSKI= -github.com/lightningnetwork/lnd v0.18.3-beta.rc3.0.20241011124628-ca3bde901eb8 h1:+z0s8M0QItH51qMPgFGlRvi6uBltbURQj6u1srTyRb4= -github.com/lightningnetwork/lnd v0.18.3-beta.rc3.0.20241011124628-ca3bde901eb8/go.mod h1:gzVQkOCZxTLzlUPqnI6t68FVGLbiO6Jj+TcLb4b78n0= +github.com/lightningnetwork/lnd v0.18.3-beta.rc3.0.20241025090009-615f3d633e61 h1:EcBM2tz+iyspYRFaDVjUe5a2bkuBWFxOWD2mzdCraUc= +github.com/lightningnetwork/lnd v0.18.3-beta.rc3.0.20241025090009-615f3d633e61/go.mod h1:q2DlXwj6ev8TMbo+CvfJ3BIrqw42HFM/fSBoyCFrjdc= github.com/lightningnetwork/lnd/cert v1.2.2 h1:71YK6hogeJtxSxw2teq3eGeuy4rHGKcFf0d0Uy4qBjI= github.com/lightningnetwork/lnd/cert v1.2.2/go.mod h1:jQmFn/Ez4zhDgq2hnYSw8r35bqGVxViXhX6Cd7HXM6U= github.com/lightningnetwork/lnd/clock v1.1.1 h1:OfR3/zcJd2RhH0RU+zX/77c0ZiOnIMsDIBjgjWdZgA0= github.com/lightningnetwork/lnd/clock v1.1.1/go.mod h1:mGnAhPyjYZQJmebS7aevElXKTFDuO+uNFFfMXK1W8xQ= -github.com/lightningnetwork/lnd/fn v1.2.1 h1:pPsVGrwi9QBwdLJzaEGK33wmiVKOxs/zc8H7+MamFf0= -github.com/lightningnetwork/lnd/fn v1.2.1/go.mod h1:SyFohpVrARPKH3XVAJZlXdVe+IwMYc4OMAvrDY32kw0= +github.com/lightningnetwork/lnd/fn v1.2.3 h1:Q1OrgNSgQynVheBNa16CsKVov1JI5N2AR6G07x9Mles= +github.com/lightningnetwork/lnd/fn v1.2.3/go.mod h1:SyFohpVrARPKH3XVAJZlXdVe+IwMYc4OMAvrDY32kw0= github.com/lightningnetwork/lnd/healthcheck v1.2.5 h1:aTJy5xeBpcWgRtW/PGBDe+LMQEmNm/HQewlQx2jt7OA= github.com/lightningnetwork/lnd/healthcheck v1.2.5/go.mod h1:G7Tst2tVvWo7cx6mSBEToQC5L1XOGxzZTPB29g9Rv2I= github.com/lightningnetwork/lnd/kvdb v1.4.10 h1:vK89IVv1oVH9ubQWU+EmoCQFeVRaC8kfmOrqHbY5zoY= @@ -1172,8 +1178,8 @@ github.com/mattn/go-sqlite3 v1.14.14/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4 github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= -github.com/miekg/dns v1.1.43 h1:JKfpVSCB84vrAmHzyrsxB5NAr5kLoMXZArPSw7Qlgyg= -github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= +github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA= +github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8/go.mod h1:mC1jAcsrzbxHt8iiaC+zU4b1ylILSosueou12R++wfY= github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3/go.mod h1:RagcQ7I8IeTMnF8JTXieKnO4Z6JCsikNEzj0DwauVzE= github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= @@ -1234,8 +1240,9 @@ github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXP github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.11.1 h1:+4eQaD7vAZ6DsfsxB15hbE0odUjGI5ARs9yskGu1v4s= -github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= +github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= +github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -1245,14 +1252,16 @@ github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3d github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.30.0 h1:JEkYlQnpzrzQFxi6gnukFPdQ+ac82oRhzMcIduJu/Ug= -github.com/prometheus/common v0.30.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= +github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= +github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= @@ -1342,22 +1351,22 @@ github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaD github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= gitlab.com/yawning/bsaes.git v0.0.0-20190805113838-0a714cd429ec h1:FpfFs4EhNehiVfzQttTuxanPIT43FtkkCFypIod8LHo= gitlab.com/yawning/bsaes.git v0.0.0-20190805113838-0a714cd429ec/go.mod h1:BZ1RAoRPbCxum9Grlv5aeksu2H8BiKehBYooU2LFiOQ= -go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ= -go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= -go.etcd.io/etcd/api/v3 v3.5.7 h1:sbcmosSVesNrWOJ58ZQFitHMdncusIifYcrBfwrlJSY= -go.etcd.io/etcd/api/v3 v3.5.7/go.mod h1:9qew1gCdDDLu+VwmeG+iFpL+QlpHTo7iubavdVDgCAA= -go.etcd.io/etcd/client/pkg/v3 v3.5.7 h1:y3kf5Gbp4e4q7egZdn5T7W9TSHUvkClN6u+Rq9mEOmg= -go.etcd.io/etcd/client/pkg/v3 v3.5.7/go.mod h1:o0Abi1MK86iad3YrWhgUsbGx1pmTS+hrORWc2CamuhY= -go.etcd.io/etcd/client/v2 v2.305.7 h1:AELPkjNR3/igjbO7CjyF1fPuVPjrblliiKj+Y6xSGOU= -go.etcd.io/etcd/client/v2 v2.305.7/go.mod h1:GQGT5Z3TBuAQGvgPfhR7VPySu/SudxmEkRq9BgzFU6s= -go.etcd.io/etcd/client/v3 v3.5.7 h1:u/OhpiuCgYY8awOHlhIhmGIGpxfBU/GZBUP3m/3/Iz4= -go.etcd.io/etcd/client/v3 v3.5.7/go.mod h1:sOWmj9DZUMyAngS7QQwCyAXXAL6WhgTOPLNS/NabQgw= -go.etcd.io/etcd/pkg/v3 v3.5.7 h1:obOzeVwerFwZ9trMWapU/VjDcYUJb5OfgC1zqEGWO/0= -go.etcd.io/etcd/pkg/v3 v3.5.7/go.mod h1:kcOfWt3Ov9zgYdOiJ/o1Y9zFfLhQjylTgL4Lru8opRo= -go.etcd.io/etcd/raft/v3 v3.5.7 h1:aN79qxLmV3SvIq84aNTliYGmjwsW6NqJSnqmI1HLJKc= -go.etcd.io/etcd/raft/v3 v3.5.7/go.mod h1:TflkAb/8Uy6JFBxcRaH2Fr6Slm9mCPVdI2efzxY96yU= -go.etcd.io/etcd/server/v3 v3.5.7 h1:BTBD8IJUV7YFgsczZMHhMTS67XuA4KpRquL0MFOJGRk= -go.etcd.io/etcd/server/v3 v3.5.7/go.mod h1:gxBgT84issUVBRpZ3XkW1T55NjOb4vZZRI4wVvNhf4A= +go.etcd.io/bbolt v1.3.11 h1:yGEzV1wPz2yVCLsD8ZAiGHhHVlczyC9d1rP43/VCRJ0= +go.etcd.io/bbolt v1.3.11/go.mod h1:dksAq7YMXoljX0xu6VF5DMZGbhYYoLUalEiSySYAS4I= +go.etcd.io/etcd/api/v3 v3.5.12 h1:W4sw5ZoU2Juc9gBWuLk5U6fHfNVyY1WC5g9uiXZio/c= +go.etcd.io/etcd/api/v3 v3.5.12/go.mod h1:Ot+o0SWSyT6uHhA56al1oCED0JImsRiU9Dc26+C2a+4= +go.etcd.io/etcd/client/pkg/v3 v3.5.12 h1:EYDL6pWwyOsylrQyLp2w+HkQ46ATiOvoEdMarindU2A= +go.etcd.io/etcd/client/pkg/v3 v3.5.12/go.mod h1:seTzl2d9APP8R5Y2hFL3NVlD6qC/dOT+3kvrqPyTas4= +go.etcd.io/etcd/client/v2 v2.305.12 h1:0m4ovXYo1CHaA/Mp3X/Fak5sRNIWf01wk/X1/G3sGKI= +go.etcd.io/etcd/client/v2 v2.305.12/go.mod h1:aQ/yhsxMu+Oht1FOupSr60oBvcS9cKXHrzBpDsPTf9E= +go.etcd.io/etcd/client/v3 v3.5.12 h1:v5lCPXn1pf1Uu3M4laUE2hp/geOTc5uPcYYsNe1lDxg= +go.etcd.io/etcd/client/v3 v3.5.12/go.mod h1:tSbBCakoWmmddL+BKVAJHa9km+O/E+bumDe9mSbPiqw= +go.etcd.io/etcd/pkg/v3 v3.5.12 h1:OK2fZKI5hX/+BTK76gXSTyZMrbnARyX9S643GenNGb8= +go.etcd.io/etcd/pkg/v3 v3.5.12/go.mod h1:UVwg/QIMoJncyeb/YxvJBJCE/NEwtHWashqc8A1nj/M= +go.etcd.io/etcd/raft/v3 v3.5.12 h1:7r22RufdDsq2z3STjoR7Msz6fYH8tmbkdheGfwJNRmU= +go.etcd.io/etcd/raft/v3 v3.5.12/go.mod h1:ERQuZVe79PI6vcC3DlKBukDCLja/L7YMu29B74Iwj4U= +go.etcd.io/etcd/server/v3 v3.5.12 h1:EtMjsbfyfkwZuA2JlKOiBfuGkFCekv5H178qjXypbG8= +go.etcd.io/etcd/server/v3 v3.5.12/go.mod h1:axB0oCjMy+cemo5290/CutIjoxlfA6KVYKD1w0uue10= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -1370,36 +1379,33 @@ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.4 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1/go.mod h1:4UoMYEZOC0yN/sPGH76KPkkU7zgiEWYWL9vwmbnTJPE= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIXefpVJtvA/8srF4V4y0akAoPHkIslgAkjixJA= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg= -go.opentelemetry.io/otel v1.3.0/go.mod h1:PWIKzi6JCp7sM0k9yZ43VX+T345uNbAkDKwHVjb2PTs= go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= -go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.3.0 h1:R/OBkMoGgfy2fLhs2QhkCI1w4HLEQX92GCcJB6SSdNk= -go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.3.0/go.mod h1:VpP4/RMn8bv8gNo9uK7/IMY4mtWLELsS+JIP0inH0h4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.3.0 h1:giGm8w67Ja7amYNfYMdme7xSp2pIxThWopw8+QP51Yk= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.3.0/go.mod h1:hO1KLR7jcKaDDKDkvI9dP/FIhpmna5lkqPUQdEjFAM8= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.3.0 h1:VQbUHoJqytHHSJ1OZodPH9tvZZSVzUHjPHpkO85sT6k= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.3.0/go.mod h1:keUU7UfnwWTWpJ+FWnyqmogPa82nuU5VUANFq49hlMY= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.20.0 h1:DeFD0VgTZ+Cj6hxravYYZE2W4GlneVH81iAOPjZkzk8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.20.0/go.mod h1:GijYcYmNpX1KazD5JmWGsi4P7dDTTTnfv1UbGn84MnU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.20.0 h1:gvmNvqrPYovvyRmCSygkUDyL8lC5Tl845MLEwqpxhEU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.20.0/go.mod h1:vNUq47TGFioo+ffTSnKNdob241vePmtNZnAODKapKd0= go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= -go.opentelemetry.io/otel/sdk v1.3.0/go.mod h1:rIo4suHNhQwBIPg9axF8V9CA72Wz2mKF1teNrup8yzs= go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8= go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= -go.opentelemetry.io/otel/trace v1.3.0/go.mod h1:c/VDhno8888bvQYmbYLqe41/Ldmr/KKunbvWM4/fEjk= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -go.opentelemetry.io/proto/otlp v0.11.0/go.mod h1:QpEjXPrNQzrFDZgoTo49dgHR9RYRSrg3NAKnUGl9YpQ= go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= -go.opentelemetry.io/proto/otlp v0.19.0 h1:IVN6GR+mhC4s5yfcTbmzHYODqvWAp3ZedA2SJPI1Nnw= go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= +go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= +go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= -go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= -go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= +go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= +go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= @@ -1409,8 +1415,9 @@ go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9E go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -go.uber.org/zap v1.17.0 h1:MTjgFu6ZLKvY6Pvaqk97GlxNBuMpV4Hy/3P6tRGlI2U= -go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= +go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= +go.uber.org/zap v1.23.0 h1:OjGQ5KQDEUawVHxNwQgPpiypGHOxo2mNZsOqTak4fFY= +go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180723164146-c126467f60eb/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -1535,6 +1542,7 @@ golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLd golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= @@ -1570,6 +1578,7 @@ golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210615190721-d04028783cf1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= @@ -1659,7 +1668,6 @@ golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210304124612-50617c2ba197/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1680,9 +1688,11 @@ golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1765,6 +1775,7 @@ golang.org/x/tools v0.0.0-20190927191325-030b2cf1153e/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -1806,6 +1817,7 @@ golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= @@ -1945,6 +1957,7 @@ google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQ google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210617175327-b9e0b3197ced/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= @@ -2128,16 +2141,16 @@ lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl modernc.org/cc/v3 v3.36.0/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= modernc.org/cc/v3 v3.36.2/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= modernc.org/cc/v3 v3.36.3/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= -modernc.org/cc/v4 v4.20.0 h1:45Or8mQfbUqJOG9WaxvlFYOAQO0lQ5RvqBcFCXngjxk= -modernc.org/cc/v4 v4.20.0/go.mod h1:HM7VJTZbUCR3rV8EYBi9wxnJ0ZBRiGE5OeGXNA0IsLQ= +modernc.org/cc/v4 v4.21.2 h1:dycHFB/jDc3IyacKipCNSDrjIC0Lm1hyoWOZTRR20Lk= +modernc.org/cc/v4 v4.21.2/go.mod h1:HM7VJTZbUCR3rV8EYBi9wxnJ0ZBRiGE5OeGXNA0IsLQ= modernc.org/ccgo/v3 v3.0.0-20220428102840-41399a37e894/go.mod h1:eI31LL8EwEBKPpNpA4bU1/i+sKOwOrQy8D87zWUcRZc= modernc.org/ccgo/v3 v3.0.0-20220430103911-bc99d88307be/go.mod h1:bwdAnOoaIt8Ax9YdWGjxWsdkPcZyRPHqrOvJxaKAKGw= modernc.org/ccgo/v3 v3.16.4/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ= modernc.org/ccgo/v3 v3.16.6/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ= modernc.org/ccgo/v3 v3.16.8/go.mod h1:zNjwkizS+fIFDrDjIAgBSCLkWbJuHF+ar3QRn+Z9aws= modernc.org/ccgo/v3 v3.16.9/go.mod h1:zNMzC9A9xeNUepy6KuZBbugn3c0Mc9TeiJO4lgvkJDo= -modernc.org/ccgo/v4 v4.16.0 h1:ofwORa6vx2FMm0916/CkZjpFPSR70VwTjUCe2Eg5BnA= -modernc.org/ccgo/v4 v4.16.0/go.mod h1:dkNyWIjFrVIZ68DTo36vHK+6/ShBn4ysU61So6PIqCI= +modernc.org/ccgo/v4 v4.17.8 h1:yyWBf2ipA0Y9GGz/MmCmi3EFpKgeS7ICrAFes+suEbs= +modernc.org/ccgo/v4 v4.17.8/go.mod h1:buJnJ6Fn0tyAdP/dqePbrrvLyr6qslFfTbFrCuaYvtA= modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ= modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE= modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ= @@ -2153,8 +2166,8 @@ modernc.org/libc v1.16.17/go.mod h1:hYIV5VZczAmGZAnG15Vdngn5HSF5cSkbvfz2B7GRuVU= modernc.org/libc v1.16.19/go.mod h1:p7Mg4+koNjc8jkqwcoFBJx7tXkpj00G77X7A72jXPXA= modernc.org/libc v1.17.0/go.mod h1:XsgLldpP4aWlPlsjqKRdHPqCxCjISdHfM/yeWC5GyW0= modernc.org/libc v1.17.1/go.mod h1:FZ23b+8LjxZs7XtFMbSzL/EhPxNbfZbErxEHc7cbD9s= -modernc.org/libc v1.49.3 h1:j2MRCRdwJI2ls/sGbeSk0t2bypOG/uvPZUsGQFDulqg= -modernc.org/libc v1.49.3/go.mod h1:yMZuGkn7pXbKfoT/M35gFJOAEdSKdxL0q64sF7KqCDo= +modernc.org/libc v1.50.9 h1:hIWf1uz55lorXQhfoEoezdUHjxzuO6ceshET/yWjSjk= +modernc.org/libc v1.50.9/go.mod h1:15P6ublJ9FJR8YQCGy8DeQ2Uwur7iW9Hserr/T3OFZE= modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= modernc.org/mathutil v1.4.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= @@ -2171,8 +2184,8 @@ modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= modernc.org/sortutil v1.2.0 h1:jQiD3PfS2REGJNzNCMMaLSp/wdMNieTbKX920Cqdgqc= modernc.org/sortutil v1.2.0/go.mod h1:TKU2s7kJMf1AE84OoiGppNHJwvB753OYfNl2WRb++Ss= modernc.org/sqlite v1.18.1/go.mod h1:6ho+Gow7oX5V+OiOQ6Tr4xeqbx13UZ6t+Fw9IRUG4d4= -modernc.org/sqlite v1.29.10 h1:3u93dz83myFnMilBGCOLbr+HjklS6+5rJLx4q86RDAg= -modernc.org/sqlite v1.29.10/go.mod h1:ItX2a1OVGgNsFh6Dv60JQvGfJfTPHPVpV6DF59akYOA= +modernc.org/sqlite v1.30.0 h1:8YhPUs/HTnlEgErn/jSYQTwHN/ex8CjHHjg+K9iG7LM= +modernc.org/sqlite v1.30.0/go.mod h1:cgkTARJ9ugeXSNaLBPK3CqbOe7Ec7ZhWPoMFGldEYEw= modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw= modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= @@ -2182,6 +2195,8 @@ modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= modernc.org/z v1.5.1/go.mod h1:eWFB510QWW5Th9YGZT81s+LwvaAs3Q2yr4sP0rmLkv8= +pgregory.net/rapid v1.1.0 h1:CMa0sjHSru3puNx+J0MIAuiiEV4N0qj8/cMWGBBCsjw= +pgregory.net/rapid v1.1.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= diff --git a/loopd/config.go b/loopd/config.go index 3adc81d34..6239f5abd 100644 --- a/loopd/config.go +++ b/loopd/config.go @@ -11,6 +11,7 @@ import ( "github.com/btcsuite/btcd/btcutil" "github.com/lightninglabs/aperture/l402" + "github.com/lightninglabs/loop/assets" "github.com/lightninglabs/loop/loopdb" "github.com/lightningnetwork/lnd/cert" "github.com/lightningnetwork/lnd/lncfg" @@ -192,6 +193,8 @@ type Config struct { Server *loopServerConfig `group:"server" namespace:"server"` View viewParameters `command:"view" alias:"v" description:"View all swaps in the database. This command can only be executed when loopd is not running."` + + TapdConfig *assets.TapdConfig `group:"tapd" namespace:"tapd"` } const ( @@ -236,6 +239,7 @@ func DefaultConfig() Config { MacaroonPath: DefaultLndMacaroonPath, RPCTimeout: DefaultLndRPCTimeout, }, + TapdConfig: assets.DefaultTapdConfig(), } } diff --git a/loopd/daemon.go b/loopd/daemon.go index e96e04286..d9dbff926 100644 --- a/loopd/daemon.go +++ b/loopd/daemon.go @@ -16,6 +16,7 @@ import ( proxy "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" "github.com/lightninglabs/lndclient" "github.com/lightninglabs/loop" + "github.com/lightninglabs/loop/assets" "github.com/lightninglabs/loop/instantout" "github.com/lightninglabs/loop/instantout/reservation" "github.com/lightninglabs/loop/loopd/perms" @@ -234,6 +235,8 @@ func (d *Daemon) startWebServers() error { ) loop_looprpc.RegisterSwapClientServer(d.grpcServer, d) + loop_looprpc.RegisterAssetsClientServer(d.grpcServer, d.assetsServer) + // Register our debug server if it is compiled in. d.registerDebugServer() @@ -317,7 +320,7 @@ func (d *Daemon) startWebServers() error { d.wg.Add(1) go func() { defer d.wg.Done() - + defer log.Info("REST proxy stopped") log.Infof("REST proxy listening on %s", d.restListener.Addr()) err := d.restServer.Serve(d.restListener) @@ -339,7 +342,7 @@ func (d *Daemon) startWebServers() error { d.wg.Add(1) go func() { defer d.wg.Done() - + defer log.Info("RPC server stopped") log.Infof("RPC server listening on %s", d.grpcListener.Addr()) err = d.grpcServer.Serve(d.grpcListener) if err != nil && !errors.Is(err, grpc.ErrServerStopped) { @@ -450,6 +453,11 @@ func (d *Daemon) initialize(withMacaroonService bool) error { swapClient.Conn, ) + // Create a assets server client. + assetsClient := loop_swaprpc.NewAssetsSwapServerClient( + swapClient.Conn, + ) + // Both the client RPC server and the swap server client should stop // on main context cancel. So we create it early and pass it down. d.mainCtx, d.mainCtxCancel = context.WithCancel(context.Background()) @@ -529,6 +537,8 @@ func (d *Daemon) initialize(withMacaroonService bool) error { var ( reservationManager *reservation.Manager instantOutManager *instantout.Manager + assetManager *assets.AssetsSwapManager + assetClientServer *assets.AssetsClientServer ) // Create the reservation and instantout managers. @@ -569,6 +579,27 @@ func (d *Daemon) initialize(withMacaroonService bool) error { instantOutManager = instantout.NewInstantOutManager( instantOutConfig, ) + + tapdClient, err := assets.NewTapdClient( + d.cfg.TapdConfig, + ) + if err != nil { + return err + } + assetsStore := assets.NewPostgresStore(baseDb) + assetsConfig := &assets.Config{ + ServerClient: assetsClient, + Store: assetsStore, + AssetClient: tapdClient, + LndClient: d.lnd.Client, + Router: d.lnd.Router, + ChainNotifier: d.lnd.ChainNotifier, + Signer: d.lnd.Signer, + Wallet: d.lnd.WalletKit, + ExchangeRateProvider: assets.NewFixedExchangeRateProvider(), + } + assetManager = assets.NewAssetSwapServer(assetsConfig) + assetClientServer = assets.NewAssetsServer(assetManager) } // Now finally fully initialize the swap client RPC server instance. @@ -584,6 +615,8 @@ func (d *Daemon) initialize(withMacaroonService bool) error { mainCtx: d.mainCtx, reservationManager: reservationManager, instantOutManager: instantOutManager, + assetManager: assetManager, + assetsServer: assetClientServer, } // Retrieve all currently existing swaps from the database. @@ -689,6 +722,10 @@ func (d *Daemon) initialize(withMacaroonService bool) error { cancel() } } + getInfo, err := d.lnd.Client.GetInfo(d.mainCtx) + if err != nil { + return err + } // Start the instant out manager. if d.instantOutManager != nil { @@ -697,12 +734,6 @@ func (d *Daemon) initialize(withMacaroonService bool) error { go func() { defer d.wg.Done() - getInfo, err := d.lnd.Client.GetInfo(d.mainCtx) - if err != nil { - d.internalErrChan <- err - return - } - log.Info("Starting instantout manager") defer log.Info("Instantout manager stopped") @@ -728,6 +759,20 @@ func (d *Daemon) initialize(withMacaroonService bool) error { } } + // Start the asset manager. + if d.assetManager != nil { + d.wg.Add(1) + go func() { + defer d.wg.Done() + log.Infof("Starting asset manager") + defer log.Infof("Asset manager stopped") + err := d.assetManager.Run(d.mainCtx, int32(getInfo.BlockHeight)) + if err != nil && !errors.Is(err, context.Canceled) { + d.internalErrChan <- err + } + }() + } + // Last, start our internal error handler. This will return exactly one // error or nil on the main error channel to inform the caller that // something went wrong or that shutdown is complete. We don't add to @@ -773,6 +818,9 @@ func (d *Daemon) Stop() { // stop does the actual shutdown and blocks until all goroutines have exit. func (d *Daemon) stop() { + // Sleep a second in order to fix a blocking issue when having a + // startup error. + <-time.After(time.Second) // First of all, we can cancel the main context that all event handlers // are using. This should stop all swap activity and all event handlers // should exit. @@ -790,6 +838,7 @@ func (d *Daemon) stop() { if d.restServer != nil { // Don't return the error here, we first want to give everything // else a chance to shut down cleanly. + err := d.restServer.Close() if err != nil { log.Errorf("Error stopping REST server: %v", err) diff --git a/loopd/log.go b/loopd/log.go index ef8c64779..838608a1a 100644 --- a/loopd/log.go +++ b/loopd/log.go @@ -5,6 +5,7 @@ import ( "github.com/lightninglabs/aperture/l402" "github.com/lightninglabs/lndclient" "github.com/lightninglabs/loop" + "github.com/lightninglabs/loop/assets" "github.com/lightninglabs/loop/fsm" "github.com/lightninglabs/loop/instantout" "github.com/lightninglabs/loop/instantout/reservation" @@ -13,6 +14,7 @@ import ( "github.com/lightninglabs/loop/notifications" "github.com/lightninglabs/loop/sweep" "github.com/lightninglabs/loop/sweepbatcher" + "github.com/lightninglabs/loop/utils" "github.com/lightningnetwork/lnd" "github.com/lightningnetwork/lnd/build" "github.com/lightningnetwork/lnd/signal" @@ -54,6 +56,13 @@ func SetupLoggers(root *build.RotatingLogWriter, intercept signal.Interceptor) { lnd.AddSubLogger( root, sweep.Subsystem, intercept, sweep.UseLogger, ) + + lnd.AddSubLogger( + root, assets.Subsystem, intercept, assets.UseLogger, + ) + lnd.AddSubLogger( + root, utils.Subsystem, intercept, utils.UseLogger, + ) } // genSubLogger creates a logger for a subsystem. We provide an instance of diff --git a/loopd/perms/perms.go b/loopd/perms/perms.go index 12022fb8e..b786f76b7 100644 --- a/loopd/perms/perms.go +++ b/loopd/perms/perms.go @@ -120,4 +120,20 @@ var RequiredPermissions = map[string][]bakery.Op{ Entity: "swap", Action: "read", }}, + "/looprpc.AssetsClient/SwapOut": {{ + Entity: "swap", + Action: "execute", + }}, + "/looprpc.AssetsClient/ListAssetSwaps": {{ + Entity: "swap", + Action: "read", + }}, + "/looprpc.AssetsClient/ClientListAvailableAssets": {{ + Entity: "swap", + Action: "read", + }}, + "/looprpc.AssetsClient/ClientGetAssetSwapOutQuote": {{ + Entity: "swap", + Action: "read", + }}, } diff --git a/loopd/swapclient_server.go b/loopd/swapclient_server.go index b27bf4230..77d8dbba3 100644 --- a/loopd/swapclient_server.go +++ b/loopd/swapclient_server.go @@ -18,6 +18,7 @@ import ( "github.com/lightninglabs/aperture/l402" "github.com/lightninglabs/lndclient" "github.com/lightninglabs/loop" + "github.com/lightninglabs/loop/assets" "github.com/lightninglabs/loop/instantout" "github.com/lightninglabs/loop/instantout/reservation" "github.com/lightninglabs/loop/labels" @@ -83,6 +84,8 @@ type swapClientServer struct { lnd *lndclient.LndServices reservationManager *reservation.Manager instantOutManager *instantout.Manager + assetManager *assets.AssetsSwapManager + assetsServer *assets.AssetsClientServer swaps map[lntypes.Hash]loop.SwapInfo subscribers map[int]chan<- interface{} statusChan chan loop.SwapInfo diff --git a/loopdb/sqlc/asset_swaps.sql.go b/loopdb/sqlc/asset_swaps.sql.go new file mode 100644 index 000000000..29ce0b4c9 --- /dev/null +++ b/loopdb/sqlc/asset_swaps.sql.go @@ -0,0 +1,314 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.25.0 +// source: asset_swaps.sql + +package sqlc + +import ( + "context" + "time" +) + +const createAssetOutSwap = `-- name: CreateAssetOutSwap :exec +INSERT INTO asset_out_swaps ( + swap_hash +) VALUES ( + $1 +) +` + +func (q *Queries) CreateAssetOutSwap(ctx context.Context, swapHash []byte) error { + _, err := q.db.ExecContext(ctx, createAssetOutSwap, swapHash) + return err +} + +const createAssetSwap = `-- name: CreateAssetSwap :exec + INSERT INTO asset_swaps( + swap_hash, + swap_preimage, + asset_id, + amt, + sender_pubkey, + receiver_pubkey, + csv_expiry, + initiation_height, + created_time, + server_key_family, + server_key_index + ) + VALUES + ( + $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11 + ) +` + +type CreateAssetSwapParams struct { + SwapHash []byte + SwapPreimage []byte + AssetID []byte + Amt int64 + SenderPubkey []byte + ReceiverPubkey []byte + CsvExpiry int32 + InitiationHeight int32 + CreatedTime time.Time + ServerKeyFamily int64 + ServerKeyIndex int64 +} + +func (q *Queries) CreateAssetSwap(ctx context.Context, arg CreateAssetSwapParams) error { + _, err := q.db.ExecContext(ctx, createAssetSwap, + arg.SwapHash, + arg.SwapPreimage, + arg.AssetID, + arg.Amt, + arg.SenderPubkey, + arg.ReceiverPubkey, + arg.CsvExpiry, + arg.InitiationHeight, + arg.CreatedTime, + arg.ServerKeyFamily, + arg.ServerKeyIndex, + ) + return err +} + +const getAllAssetOutSwaps = `-- name: GetAllAssetOutSwaps :many +SELECT DISTINCT + asw.id, asw.swap_hash, asw.swap_preimage, asw.asset_id, asw.amt, asw.sender_pubkey, asw.receiver_pubkey, asw.csv_expiry, asw.server_key_family, asw.server_key_index, asw.initiation_height, asw.created_time, asw.htlc_confirmation_height, asw.htlc_txid, asw.htlc_vout, asw.sweep_txid, asw.sweep_confirmation_height, asw.sweep_pkscript, + aos.swap_hash, aos.raw_proof_file, + asu.update_state +FROM + asset_swaps asw +INNER JOIN ( + SELECT + swap_hash, + update_state, + ROW_NUMBER() OVER(PARTITION BY swap_hash ORDER BY id DESC) as rn + FROM + asset_swaps_updates +) asu ON asw.swap_hash = asu.swap_hash AND asu.rn = 1 +INNER JOIN asset_out_swaps aos ON asw.swap_hash = aos.swap_hash +ORDER BY + asw.id +` + +type GetAllAssetOutSwapsRow struct { + AssetSwap AssetSwap + AssetOutSwap AssetOutSwap + UpdateState string +} + +func (q *Queries) GetAllAssetOutSwaps(ctx context.Context) ([]GetAllAssetOutSwapsRow, error) { + rows, err := q.db.QueryContext(ctx, getAllAssetOutSwaps) + if err != nil { + return nil, err + } + defer rows.Close() + var items []GetAllAssetOutSwapsRow + for rows.Next() { + var i GetAllAssetOutSwapsRow + if err := rows.Scan( + &i.AssetSwap.ID, + &i.AssetSwap.SwapHash, + &i.AssetSwap.SwapPreimage, + &i.AssetSwap.AssetID, + &i.AssetSwap.Amt, + &i.AssetSwap.SenderPubkey, + &i.AssetSwap.ReceiverPubkey, + &i.AssetSwap.CsvExpiry, + &i.AssetSwap.ServerKeyFamily, + &i.AssetSwap.ServerKeyIndex, + &i.AssetSwap.InitiationHeight, + &i.AssetSwap.CreatedTime, + &i.AssetSwap.HtlcConfirmationHeight, + &i.AssetSwap.HtlcTxid, + &i.AssetSwap.HtlcVout, + &i.AssetSwap.SweepTxid, + &i.AssetSwap.SweepConfirmationHeight, + &i.AssetSwap.SweepPkscript, + &i.AssetOutSwap.SwapHash, + &i.AssetOutSwap.RawProofFile, + &i.UpdateState, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const getAssetOutSwap = `-- name: GetAssetOutSwap :one +SELECT DISTINCT + asw.id, asw.swap_hash, asw.swap_preimage, asw.asset_id, asw.amt, asw.sender_pubkey, asw.receiver_pubkey, asw.csv_expiry, asw.server_key_family, asw.server_key_index, asw.initiation_height, asw.created_time, asw.htlc_confirmation_height, asw.htlc_txid, asw.htlc_vout, asw.sweep_txid, asw.sweep_confirmation_height, asw.sweep_pkscript, + aos.swap_hash, aos.raw_proof_file, + asu.update_state +FROM + asset_swaps asw +INNER JOIN ( + SELECT + swap_hash, + update_state, + ROW_NUMBER() OVER(PARTITION BY swap_hash ORDER BY id DESC) as rn + FROM + asset_swaps_updates +) asu ON asw.swap_hash = asu.swap_hash AND asu.rn = 1 +INNER JOIN asset_out_swaps aos ON asw.swap_hash = aos.swap_hash +WHERE + asw.swap_hash = $1 +` + +type GetAssetOutSwapRow struct { + AssetSwap AssetSwap + AssetOutSwap AssetOutSwap + UpdateState string +} + +func (q *Queries) GetAssetOutSwap(ctx context.Context, swapHash []byte) (GetAssetOutSwapRow, error) { + row := q.db.QueryRowContext(ctx, getAssetOutSwap, swapHash) + var i GetAssetOutSwapRow + err := row.Scan( + &i.AssetSwap.ID, + &i.AssetSwap.SwapHash, + &i.AssetSwap.SwapPreimage, + &i.AssetSwap.AssetID, + &i.AssetSwap.Amt, + &i.AssetSwap.SenderPubkey, + &i.AssetSwap.ReceiverPubkey, + &i.AssetSwap.CsvExpiry, + &i.AssetSwap.ServerKeyFamily, + &i.AssetSwap.ServerKeyIndex, + &i.AssetSwap.InitiationHeight, + &i.AssetSwap.CreatedTime, + &i.AssetSwap.HtlcConfirmationHeight, + &i.AssetSwap.HtlcTxid, + &i.AssetSwap.HtlcVout, + &i.AssetSwap.SweepTxid, + &i.AssetSwap.SweepConfirmationHeight, + &i.AssetSwap.SweepPkscript, + &i.AssetOutSwap.SwapHash, + &i.AssetOutSwap.RawProofFile, + &i.UpdateState, + ) + return i, err +} + +const insertAssetSwapUpdate = `-- name: InsertAssetSwapUpdate :exec +INSERT INTO asset_swaps_updates ( + swap_hash, + update_state, + update_timestamp +) VALUES ( + $1, + $2, + $3 +) +` + +type InsertAssetSwapUpdateParams struct { + SwapHash []byte + UpdateState string + UpdateTimestamp time.Time +} + +func (q *Queries) InsertAssetSwapUpdate(ctx context.Context, arg InsertAssetSwapUpdateParams) error { + _, err := q.db.ExecContext(ctx, insertAssetSwapUpdate, arg.SwapHash, arg.UpdateState, arg.UpdateTimestamp) + return err +} + +const updateAssetSwapHtlcTx = `-- name: UpdateAssetSwapHtlcTx :exec +UPDATE asset_swaps +SET + htlc_confirmation_height = $2, + htlc_txid = $3, + htlc_vout = $4 +WHERE + asset_swaps.swap_hash = $1 +` + +type UpdateAssetSwapHtlcTxParams struct { + SwapHash []byte + HtlcConfirmationHeight int32 + HtlcTxid []byte + HtlcVout int32 +} + +func (q *Queries) UpdateAssetSwapHtlcTx(ctx context.Context, arg UpdateAssetSwapHtlcTxParams) error { + _, err := q.db.ExecContext(ctx, updateAssetSwapHtlcTx, + arg.SwapHash, + arg.HtlcConfirmationHeight, + arg.HtlcTxid, + arg.HtlcVout, + ) + return err +} + +const updateAssetSwapOutPreimage = `-- name: UpdateAssetSwapOutPreimage :exec +UPDATE asset_swaps +SET + swap_preimage = $2 +WHERE + asset_swaps.swap_hash = $1 +` + +type UpdateAssetSwapOutPreimageParams struct { + SwapHash []byte + SwapPreimage []byte +} + +func (q *Queries) UpdateAssetSwapOutPreimage(ctx context.Context, arg UpdateAssetSwapOutPreimageParams) error { + _, err := q.db.ExecContext(ctx, updateAssetSwapOutPreimage, arg.SwapHash, arg.SwapPreimage) + return err +} + +const updateAssetSwapOutProof = `-- name: UpdateAssetSwapOutProof :exec +UPDATE asset_out_swaps +SET + raw_proof_file = $2 +WHERE + asset_out_swaps.swap_hash = $1 +` + +type UpdateAssetSwapOutProofParams struct { + SwapHash []byte + RawProofFile []byte +} + +func (q *Queries) UpdateAssetSwapOutProof(ctx context.Context, arg UpdateAssetSwapOutProofParams) error { + _, err := q.db.ExecContext(ctx, updateAssetSwapOutProof, arg.SwapHash, arg.RawProofFile) + return err +} + +const updateAssetSwapSweepTx = `-- name: UpdateAssetSwapSweepTx :exec +UPDATE asset_swaps +SET + sweep_confirmation_height = $2, + sweep_txid = $3, + sweep_pkscript = $4 +WHERE + asset_swaps.swap_hash = $1 +` + +type UpdateAssetSwapSweepTxParams struct { + SwapHash []byte + SweepConfirmationHeight int32 + SweepTxid []byte + SweepPkscript []byte +} + +func (q *Queries) UpdateAssetSwapSweepTx(ctx context.Context, arg UpdateAssetSwapSweepTxParams) error { + _, err := q.db.ExecContext(ctx, updateAssetSwapSweepTx, + arg.SwapHash, + arg.SweepConfirmationHeight, + arg.SweepTxid, + arg.SweepPkscript, + ) + return err +} diff --git a/loopdb/sqlc/migrations/000009_asset_swaps.down.sql b/loopdb/sqlc/migrations/000009_asset_swaps.down.sql new file mode 100644 index 000000000..93b3502c2 --- /dev/null +++ b/loopdb/sqlc/migrations/000009_asset_swaps.down.sql @@ -0,0 +1,5 @@ +DROP INDEX IF EXISTS asset_out_swaps_swap_hash_idx; +DROP TABLE IF EXISTS asset_out_swaps; +DROP INDEX IF EXISTS asset_swaps_updates_swap_hash_idx; +DROP TABLE IF EXISTS asset_swaps; +DROP TABLE IF EXISTS asset_swaps; \ No newline at end of file diff --git a/loopdb/sqlc/migrations/000009_asset_swaps.up.sql b/loopdb/sqlc/migrations/000009_asset_swaps.up.sql new file mode 100644 index 000000000..3f48e9d16 --- /dev/null +++ b/loopdb/sqlc/migrations/000009_asset_swaps.up.sql @@ -0,0 +1,85 @@ +CREATE TABLE IF NOT EXISTS asset_swaps ( + --- id is the autoincrementing primary key. + id INTEGER PRIMARY KEY, + + -- swap_hash is the randomly generated hash of the swap, which is used + -- as the swap identifier for the clients. + swap_hash BLOB NOT NULL UNIQUE, + + -- swap_preimage is the preimage of the swap. + swap_preimage BLOB, + + -- asset_id is the identifier of the asset being swapped. + asset_id BLOB NOT NULL, + + -- amt is the requested amount to be swapped. + amt BIGINT NOT NULL, + + -- sender_pubkey is the pubkey of the sender. + sender_pubkey BLOB NOT NULL, + + -- receiver_pubkey is the pubkey of the receiver. + receiver_pubkey BLOB NOT NULL, + + -- csv_expiry is the expiry of the swap. + csv_expiry INTEGER NOT NULL, + + -- server_key_family is the family of key being identified. + server_key_family BIGINT NOT NULL, + + -- server_key_index is the precise index of the key being identified. + server_key_index BIGINT NOT NULL, + + -- initiation_height is the height at which the swap was initiated. + initiation_height INTEGER NOT NULL, + + -- created_time is the time at which the swap was created. + created_time TIMESTAMP NOT NULL, + + -- htlc_confirmation_height is the height at which the swap was confirmed. + htlc_confirmation_height INTEGER NOT NULL DEFAULT(0), + + -- htlc_txid is the txid of the confirmation transaction. + htlc_txid BLOB, + + -- htlc_vout is the vout of the confirmation transaction. + htlc_vout INTEGER NOT NULL DEFAULT (0), + + -- sweep_txid is the txid of the sweep transaction. + sweep_txid BLOB, + + -- sweep_confirmation_height is the height at which the swap was swept. + sweep_confirmation_height INTEGER NOT NULL DEFAULT(0), + + sweep_pkscript BLOB +); + + +CREATE TABLE IF NOT EXISTS asset_swaps_updates ( + -- id is auto incremented for each update. + id INTEGER PRIMARY KEY, + + -- swap_hash is the hash of the swap that this update is for. + swap_hash BLOB NOT NULL REFERENCES asset_swaps(swap_hash), + + -- update_state is the state of the swap at the time of the update. + update_state TEXT NOT NULL, + + -- update_timestamp is the time at which the update was created. + update_timestamp TIMESTAMP NOT NULL +); + + +CREATE INDEX IF NOT EXISTS asset_swaps_updates_swap_hash_idx ON asset_swaps_updates(swap_hash); + + +CREATE TABLE IF NOT EXISTS asset_out_swaps ( + -- swap_hash is the identifier of the swap. + swap_hash BLOB PRIMARY KEY REFERENCES asset_swaps(swap_hash), + + -- raw_proof_file is the file containing the raw proof. + raw_proof_file BLOB +); + +CREATE INDEX IF NOT EXISTS asset_out_swaps_swap_hash_idx ON asset_out_swaps(swap_hash); + diff --git a/loopdb/sqlc/models.go b/loopdb/sqlc/models.go index 03c5c6762..afb084788 100644 --- a/loopdb/sqlc/models.go +++ b/loopdb/sqlc/models.go @@ -9,6 +9,39 @@ import ( "time" ) +type AssetOutSwap struct { + SwapHash []byte + RawProofFile []byte +} + +type AssetSwap struct { + ID int32 + SwapHash []byte + SwapPreimage []byte + AssetID []byte + Amt int64 + SenderPubkey []byte + ReceiverPubkey []byte + CsvExpiry int32 + ServerKeyFamily int64 + ServerKeyIndex int64 + InitiationHeight int32 + CreatedTime time.Time + HtlcConfirmationHeight int32 + HtlcTxid []byte + HtlcVout int32 + SweepTxid []byte + SweepConfirmationHeight int32 + SweepPkscript []byte +} + +type AssetSwapsUpdate struct { + ID int32 + SwapHash []byte + UpdateState string + UpdateTimestamp time.Time +} + type HtlcKey struct { SwapHash []byte SenderScriptPubkey []byte diff --git a/loopdb/sqlc/querier.go b/loopdb/sqlc/querier.go index 8fbc6b7e5..02034f290 100644 --- a/loopdb/sqlc/querier.go +++ b/loopdb/sqlc/querier.go @@ -10,9 +10,13 @@ import ( type Querier interface { ConfirmBatch(ctx context.Context, id int32) error + CreateAssetOutSwap(ctx context.Context, swapHash []byte) error + CreateAssetSwap(ctx context.Context, arg CreateAssetSwapParams) error CreateReservation(ctx context.Context, arg CreateReservationParams) error DropBatch(ctx context.Context, id int32) error FetchLiquidityParams(ctx context.Context) ([]byte, error) + GetAllAssetOutSwaps(ctx context.Context) ([]GetAllAssetOutSwapsRow, error) + GetAssetOutSwap(ctx context.Context, swapHash []byte) (GetAssetOutSwapRow, error) GetBatchSweeps(ctx context.Context, batchID int32) ([]Sweep, error) GetBatchSweptAmount(ctx context.Context, batchID int32) (int64, error) GetInstantOutSwap(ctx context.Context, swapHash []byte) (GetInstantOutSwapRow, error) @@ -31,6 +35,7 @@ type Querier interface { GetSwapUpdates(ctx context.Context, swapHash []byte) ([]SwapUpdate, error) GetSweepStatus(ctx context.Context, swapHash []byte) (bool, error) GetUnconfirmedBatches(ctx context.Context) ([]SweepBatch, error) + InsertAssetSwapUpdate(ctx context.Context, arg InsertAssetSwapUpdateParams) error InsertBatch(ctx context.Context, arg InsertBatchParams) (int32, error) InsertHtlcKeys(ctx context.Context, arg InsertHtlcKeysParams) error InsertInstantOut(ctx context.Context, arg InsertInstantOutParams) error @@ -42,6 +47,10 @@ type Querier interface { InsertSwap(ctx context.Context, arg InsertSwapParams) error InsertSwapUpdate(ctx context.Context, arg InsertSwapUpdateParams) error OverrideSwapCosts(ctx context.Context, arg OverrideSwapCostsParams) error + UpdateAssetSwapHtlcTx(ctx context.Context, arg UpdateAssetSwapHtlcTxParams) error + UpdateAssetSwapOutPreimage(ctx context.Context, arg UpdateAssetSwapOutPreimageParams) error + UpdateAssetSwapOutProof(ctx context.Context, arg UpdateAssetSwapOutProofParams) error + UpdateAssetSwapSweepTx(ctx context.Context, arg UpdateAssetSwapSweepTxParams) error UpdateBatch(ctx context.Context, arg UpdateBatchParams) error UpdateInstantOut(ctx context.Context, arg UpdateInstantOutParams) error UpdateReservation(ctx context.Context, arg UpdateReservationParams) error diff --git a/loopdb/sqlc/queries/asset_swaps.sql b/loopdb/sqlc/queries/asset_swaps.sql new file mode 100644 index 000000000..98201c4b4 --- /dev/null +++ b/loopdb/sqlc/queries/asset_swaps.sql @@ -0,0 +1,108 @@ +-- name: CreateAssetSwap :exec + INSERT INTO asset_swaps( + swap_hash, + swap_preimage, + asset_id, + amt, + sender_pubkey, + receiver_pubkey, + csv_expiry, + initiation_height, + created_time, + server_key_family, + server_key_index + ) + VALUES + ( + $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11 + ); + +-- name: CreateAssetOutSwap :exec +INSERT INTO asset_out_swaps ( + swap_hash +) VALUES ( + $1 +); + +-- name: UpdateAssetSwapHtlcTx :exec +UPDATE asset_swaps +SET + htlc_confirmation_height = $2, + htlc_txid = $3, + htlc_vout = $4 +WHERE + asset_swaps.swap_hash = $1; + +-- name: UpdateAssetSwapOutProof :exec +UPDATE asset_out_swaps +SET + raw_proof_file = $2 +WHERE + asset_out_swaps.swap_hash = $1; + +-- name: UpdateAssetSwapOutPreimage :exec +UPDATE asset_swaps +SET + swap_preimage = $2 +WHERE + asset_swaps.swap_hash = $1; + +-- name: UpdateAssetSwapSweepTx :exec +UPDATE asset_swaps +SET + sweep_confirmation_height = $2, + sweep_txid = $3, + sweep_pkscript = $4 +WHERE + asset_swaps.swap_hash = $1; + +-- name: InsertAssetSwapUpdate :exec +INSERT INTO asset_swaps_updates ( + swap_hash, + update_state, + update_timestamp +) VALUES ( + $1, + $2, + $3 +); + + +-- name: GetAssetOutSwap :one +SELECT DISTINCT + sqlc.embed(asw), + sqlc.embed(aos), + asu.update_state +FROM + asset_swaps asw +INNER JOIN ( + SELECT + swap_hash, + update_state, + ROW_NUMBER() OVER(PARTITION BY swap_hash ORDER BY id DESC) as rn + FROM + asset_swaps_updates +) asu ON asw.swap_hash = asu.swap_hash AND asu.rn = 1 +INNER JOIN asset_out_swaps aos ON asw.swap_hash = aos.swap_hash +WHERE + asw.swap_hash = $1; + +-- name: GetAllAssetOutSwaps :many +SELECT DISTINCT + sqlc.embed(asw), + sqlc.embed(aos), + asu.update_state +FROM + asset_swaps asw +INNER JOIN ( + SELECT + swap_hash, + update_state, + ROW_NUMBER() OVER(PARTITION BY swap_hash ORDER BY id DESC) as rn + FROM + asset_swaps_updates +) asu ON asw.swap_hash = asu.swap_hash AND asu.rn = 1 +INNER JOIN asset_out_swaps aos ON asw.swap_hash = aos.swap_hash +ORDER BY + asw.id; + diff --git a/looprpc/clientassets.pb.go b/looprpc/clientassets.pb.go new file mode 100644 index 000000000..90f91bfda --- /dev/null +++ b/looprpc/clientassets.pb.go @@ -0,0 +1,805 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.31.0 +// protoc v3.6.1 +// source: clientassets.proto + +package looprpc + +import ( + _ "github.com/lightninglabs/loop/swapserverrpc" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type SwapOutRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Amt uint64 `protobuf:"varint,1,opt,name=amt,proto3" json:"amt,omitempty"` + Asset []byte `protobuf:"bytes,2,opt,name=asset,proto3" json:"asset,omitempty"` +} + +func (x *SwapOutRequest) Reset() { + *x = SwapOutRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_clientassets_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SwapOutRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SwapOutRequest) ProtoMessage() {} + +func (x *SwapOutRequest) ProtoReflect() protoreflect.Message { + mi := &file_clientassets_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SwapOutRequest.ProtoReflect.Descriptor instead. +func (*SwapOutRequest) Descriptor() ([]byte, []int) { + return file_clientassets_proto_rawDescGZIP(), []int{0} +} + +func (x *SwapOutRequest) GetAmt() uint64 { + if x != nil { + return x.Amt + } + return 0 +} + +func (x *SwapOutRequest) GetAsset() []byte { + if x != nil { + return x.Asset + } + return nil +} + +type SwapOutResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + SwapStatus *AssetSwapStatus `protobuf:"bytes,1,opt,name=swap_status,json=swapStatus,proto3" json:"swap_status,omitempty"` +} + +func (x *SwapOutResponse) Reset() { + *x = SwapOutResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_clientassets_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SwapOutResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SwapOutResponse) ProtoMessage() {} + +func (x *SwapOutResponse) ProtoReflect() protoreflect.Message { + mi := &file_clientassets_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SwapOutResponse.ProtoReflect.Descriptor instead. +func (*SwapOutResponse) Descriptor() ([]byte, []int) { + return file_clientassets_proto_rawDescGZIP(), []int{1} +} + +func (x *SwapOutResponse) GetSwapStatus() *AssetSwapStatus { + if x != nil { + return x.SwapStatus + } + return nil +} + +type ListAssetSwapsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ListAssetSwapsRequest) Reset() { + *x = ListAssetSwapsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_clientassets_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListAssetSwapsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListAssetSwapsRequest) ProtoMessage() {} + +func (x *ListAssetSwapsRequest) ProtoReflect() protoreflect.Message { + mi := &file_clientassets_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListAssetSwapsRequest.ProtoReflect.Descriptor instead. +func (*ListAssetSwapsRequest) Descriptor() ([]byte, []int) { + return file_clientassets_proto_rawDescGZIP(), []int{2} +} + +type ListAssetSwapsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + SwapStatus []*AssetSwapStatus `protobuf:"bytes,1,rep,name=swap_status,json=swapStatus,proto3" json:"swap_status,omitempty"` +} + +func (x *ListAssetSwapsResponse) Reset() { + *x = ListAssetSwapsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_clientassets_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListAssetSwapsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListAssetSwapsResponse) ProtoMessage() {} + +func (x *ListAssetSwapsResponse) ProtoReflect() protoreflect.Message { + mi := &file_clientassets_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListAssetSwapsResponse.ProtoReflect.Descriptor instead. +func (*ListAssetSwapsResponse) Descriptor() ([]byte, []int) { + return file_clientassets_proto_rawDescGZIP(), []int{3} +} + +func (x *ListAssetSwapsResponse) GetSwapStatus() []*AssetSwapStatus { + if x != nil { + return x.SwapStatus + } + return nil +} + +type AssetSwapStatus struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + SwapHash []byte `protobuf:"bytes,1,opt,name=swap_hash,json=swapHash,proto3" json:"swap_hash,omitempty"` + SwapStatus string `protobuf:"bytes,2,opt,name=swap_status,json=swapStatus,proto3" json:"swap_status,omitempty"` +} + +func (x *AssetSwapStatus) Reset() { + *x = AssetSwapStatus{} + if protoimpl.UnsafeEnabled { + mi := &file_clientassets_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AssetSwapStatus) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AssetSwapStatus) ProtoMessage() {} + +func (x *AssetSwapStatus) ProtoReflect() protoreflect.Message { + mi := &file_clientassets_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AssetSwapStatus.ProtoReflect.Descriptor instead. +func (*AssetSwapStatus) Descriptor() ([]byte, []int) { + return file_clientassets_proto_rawDescGZIP(), []int{4} +} + +func (x *AssetSwapStatus) GetSwapHash() []byte { + if x != nil { + return x.SwapHash + } + return nil +} + +func (x *AssetSwapStatus) GetSwapStatus() string { + if x != nil { + return x.SwapStatus + } + return "" +} + +type ClientListAvailableAssetsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ClientListAvailableAssetsRequest) Reset() { + *x = ClientListAvailableAssetsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_clientassets_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ClientListAvailableAssetsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ClientListAvailableAssetsRequest) ProtoMessage() {} + +func (x *ClientListAvailableAssetsRequest) ProtoReflect() protoreflect.Message { + mi := &file_clientassets_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ClientListAvailableAssetsRequest.ProtoReflect.Descriptor instead. +func (*ClientListAvailableAssetsRequest) Descriptor() ([]byte, []int) { + return file_clientassets_proto_rawDescGZIP(), []int{5} +} + +type ClientListAvailableAssetsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AvailableAssets []*Asset `protobuf:"bytes,1,rep,name=available_assets,json=availableAssets,proto3" json:"available_assets,omitempty"` +} + +func (x *ClientListAvailableAssetsResponse) Reset() { + *x = ClientListAvailableAssetsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_clientassets_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ClientListAvailableAssetsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ClientListAvailableAssetsResponse) ProtoMessage() {} + +func (x *ClientListAvailableAssetsResponse) ProtoReflect() protoreflect.Message { + mi := &file_clientassets_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ClientListAvailableAssetsResponse.ProtoReflect.Descriptor instead. +func (*ClientListAvailableAssetsResponse) Descriptor() ([]byte, []int) { + return file_clientassets_proto_rawDescGZIP(), []int{6} +} + +func (x *ClientListAvailableAssetsResponse) GetAvailableAssets() []*Asset { + if x != nil { + return x.AvailableAssets + } + return nil +} + +type Asset struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AssetId []byte `protobuf:"bytes,1,opt,name=asset_id,json=assetId,proto3" json:"asset_id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + SatsPerUnit uint64 `protobuf:"varint,3,opt,name=sats_per_unit,json=satsPerUnit,proto3" json:"sats_per_unit,omitempty"` +} + +func (x *Asset) Reset() { + *x = Asset{} + if protoimpl.UnsafeEnabled { + mi := &file_clientassets_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Asset) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Asset) ProtoMessage() {} + +func (x *Asset) ProtoReflect() protoreflect.Message { + mi := &file_clientassets_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Asset.ProtoReflect.Descriptor instead. +func (*Asset) Descriptor() ([]byte, []int) { + return file_clientassets_proto_rawDescGZIP(), []int{7} +} + +func (x *Asset) GetAssetId() []byte { + if x != nil { + return x.AssetId + } + return nil +} + +func (x *Asset) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Asset) GetSatsPerUnit() uint64 { + if x != nil { + return x.SatsPerUnit + } + return 0 +} + +type ClientGetAssetSwapOutQuoteRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Amt uint64 `protobuf:"varint,1,opt,name=amt,proto3" json:"amt,omitempty"` + Asset []byte `protobuf:"bytes,2,opt,name=asset,proto3" json:"asset,omitempty"` +} + +func (x *ClientGetAssetSwapOutQuoteRequest) Reset() { + *x = ClientGetAssetSwapOutQuoteRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_clientassets_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ClientGetAssetSwapOutQuoteRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ClientGetAssetSwapOutQuoteRequest) ProtoMessage() {} + +func (x *ClientGetAssetSwapOutQuoteRequest) ProtoReflect() protoreflect.Message { + mi := &file_clientassets_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ClientGetAssetSwapOutQuoteRequest.ProtoReflect.Descriptor instead. +func (*ClientGetAssetSwapOutQuoteRequest) Descriptor() ([]byte, []int) { + return file_clientassets_proto_rawDescGZIP(), []int{8} +} + +func (x *ClientGetAssetSwapOutQuoteRequest) GetAmt() uint64 { + if x != nil { + return x.Amt + } + return 0 +} + +func (x *ClientGetAssetSwapOutQuoteRequest) GetAsset() []byte { + if x != nil { + return x.Asset + } + return nil +} + +type ClientGetAssetSwapOutQuoteResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + SwapFee float64 `protobuf:"fixed64,1,opt,name=swap_fee,json=swapFee,proto3" json:"swap_fee,omitempty"` + PrepayAmt uint64 `protobuf:"varint,2,opt,name=prepay_amt,json=prepayAmt,proto3" json:"prepay_amt,omitempty"` + SatsPerUnit uint64 `protobuf:"varint,3,opt,name=sats_per_unit,json=satsPerUnit,proto3" json:"sats_per_unit,omitempty"` +} + +func (x *ClientGetAssetSwapOutQuoteResponse) Reset() { + *x = ClientGetAssetSwapOutQuoteResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_clientassets_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ClientGetAssetSwapOutQuoteResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ClientGetAssetSwapOutQuoteResponse) ProtoMessage() {} + +func (x *ClientGetAssetSwapOutQuoteResponse) ProtoReflect() protoreflect.Message { + mi := &file_clientassets_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ClientGetAssetSwapOutQuoteResponse.ProtoReflect.Descriptor instead. +func (*ClientGetAssetSwapOutQuoteResponse) Descriptor() ([]byte, []int) { + return file_clientassets_proto_rawDescGZIP(), []int{9} +} + +func (x *ClientGetAssetSwapOutQuoteResponse) GetSwapFee() float64 { + if x != nil { + return x.SwapFee + } + return 0 +} + +func (x *ClientGetAssetSwapOutQuoteResponse) GetPrepayAmt() uint64 { + if x != nil { + return x.PrepayAmt + } + return 0 +} + +func (x *ClientGetAssetSwapOutQuoteResponse) GetSatsPerUnit() uint64 { + if x != nil { + return x.SatsPerUnit + } + return 0 +} + +var File_clientassets_proto protoreflect.FileDescriptor + +var file_clientassets_proto_rawDesc = []byte{ + 0x0a, 0x12, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x73, 0x73, 0x65, 0x74, 0x73, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x1a, 0x1a, 0x73, + 0x77, 0x61, 0x70, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x72, 0x70, 0x63, 0x2f, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x38, 0x0a, 0x0e, 0x53, 0x77, 0x61, + 0x70, 0x4f, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x61, + 0x6d, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x61, 0x6d, 0x74, 0x12, 0x14, 0x0a, + 0x05, 0x61, 0x73, 0x73, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x61, 0x73, + 0x73, 0x65, 0x74, 0x22, 0x4c, 0x0a, 0x0f, 0x53, 0x77, 0x61, 0x70, 0x4f, 0x75, 0x74, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x0b, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x73, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6c, 0x6f, + 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, 0x77, 0x61, 0x70, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x0a, 0x73, 0x77, 0x61, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x22, 0x17, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, 0x77, + 0x61, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x53, 0x0a, 0x16, 0x4c, 0x69, + 0x73, 0x74, 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, 0x77, 0x61, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x0b, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x73, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, + 0x72, 0x70, 0x63, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, 0x77, 0x61, 0x70, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x52, 0x0a, 0x73, 0x77, 0x61, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, + 0x4f, 0x0a, 0x0f, 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, 0x77, 0x61, 0x70, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x73, 0x77, 0x61, 0x70, 0x48, 0x61, 0x73, 0x68, 0x12, + 0x1f, 0x0a, 0x0b, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x77, 0x61, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x22, 0x22, 0x0a, 0x20, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x76, + 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x41, 0x73, 0x73, 0x65, 0x74, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x22, 0x5e, 0x0a, 0x21, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4c, 0x69, + 0x73, 0x74, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x41, 0x73, 0x73, 0x65, 0x74, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x10, 0x61, 0x76, 0x61, + 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x61, 0x73, 0x73, 0x65, 0x74, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x73, + 0x73, 0x65, 0x74, 0x52, 0x0f, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x41, 0x73, + 0x73, 0x65, 0x74, 0x73, 0x22, 0x5a, 0x0a, 0x05, 0x41, 0x73, 0x73, 0x65, 0x74, 0x12, 0x19, 0x0a, + 0x08, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x07, 0x61, 0x73, 0x73, 0x65, 0x74, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x22, 0x0a, 0x0d, + 0x73, 0x61, 0x74, 0x73, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x75, 0x6e, 0x69, 0x74, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x0b, 0x73, 0x61, 0x74, 0x73, 0x50, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x74, + 0x22, 0x4b, 0x0a, 0x21, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x47, 0x65, 0x74, 0x41, 0x73, 0x73, + 0x65, 0x74, 0x53, 0x77, 0x61, 0x70, 0x4f, 0x75, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x6d, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x03, 0x61, 0x6d, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x73, 0x73, 0x65, 0x74, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x61, 0x73, 0x73, 0x65, 0x74, 0x22, 0x82, 0x01, + 0x0a, 0x22, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x47, 0x65, 0x74, 0x41, 0x73, 0x73, 0x65, 0x74, + 0x53, 0x77, 0x61, 0x70, 0x4f, 0x75, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x66, 0x65, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x52, 0x07, 0x73, 0x77, 0x61, 0x70, 0x46, 0x65, 0x65, 0x12, + 0x1d, 0x0a, 0x0a, 0x70, 0x72, 0x65, 0x70, 0x61, 0x79, 0x5f, 0x61, 0x6d, 0x74, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x09, 0x70, 0x72, 0x65, 0x70, 0x61, 0x79, 0x41, 0x6d, 0x74, 0x12, 0x22, + 0x0a, 0x0d, 0x73, 0x61, 0x74, 0x73, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x75, 0x6e, 0x69, 0x74, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x73, 0x61, 0x74, 0x73, 0x50, 0x65, 0x72, 0x55, 0x6e, + 0x69, 0x74, 0x32, 0x8a, 0x03, 0x0a, 0x0c, 0x41, 0x73, 0x73, 0x65, 0x74, 0x73, 0x43, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x12, 0x3c, 0x0a, 0x07, 0x53, 0x77, 0x61, 0x70, 0x4f, 0x75, 0x74, 0x12, 0x17, + 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x77, 0x61, 0x70, 0x4f, 0x75, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, + 0x63, 0x2e, 0x53, 0x77, 0x61, 0x70, 0x4f, 0x75, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x51, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, 0x77, + 0x61, 0x70, 0x73, 0x12, 0x1e, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, 0x77, 0x61, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, 0x77, 0x61, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x72, 0x0a, 0x19, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4c, 0x69, + 0x73, 0x74, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x41, 0x73, 0x73, 0x65, 0x74, + 0x73, 0x12, 0x29, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x41, + 0x73, 0x73, 0x65, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x6c, + 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x73, + 0x74, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x41, 0x73, 0x73, 0x65, 0x74, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x75, 0x0a, 0x1a, 0x43, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x47, 0x65, 0x74, 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, 0x77, 0x61, 0x70, 0x4f, 0x75, + 0x74, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x12, 0x2a, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, + 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x47, 0x65, 0x74, 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, + 0x77, 0x61, 0x70, 0x4f, 0x75, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x47, 0x65, 0x74, 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, 0x77, 0x61, 0x70, 0x4f, + 0x75, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, + 0x27, 0x5a, 0x25, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69, + 0x67, 0x68, 0x74, 0x6e, 0x69, 0x6e, 0x67, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x6c, 0x6f, 0x6f, 0x70, + 0x2f, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_clientassets_proto_rawDescOnce sync.Once + file_clientassets_proto_rawDescData = file_clientassets_proto_rawDesc +) + +func file_clientassets_proto_rawDescGZIP() []byte { + file_clientassets_proto_rawDescOnce.Do(func() { + file_clientassets_proto_rawDescData = protoimpl.X.CompressGZIP(file_clientassets_proto_rawDescData) + }) + return file_clientassets_proto_rawDescData +} + +var file_clientassets_proto_msgTypes = make([]protoimpl.MessageInfo, 10) +var file_clientassets_proto_goTypes = []interface{}{ + (*SwapOutRequest)(nil), // 0: looprpc.SwapOutRequest + (*SwapOutResponse)(nil), // 1: looprpc.SwapOutResponse + (*ListAssetSwapsRequest)(nil), // 2: looprpc.ListAssetSwapsRequest + (*ListAssetSwapsResponse)(nil), // 3: looprpc.ListAssetSwapsResponse + (*AssetSwapStatus)(nil), // 4: looprpc.AssetSwapStatus + (*ClientListAvailableAssetsRequest)(nil), // 5: looprpc.ClientListAvailableAssetsRequest + (*ClientListAvailableAssetsResponse)(nil), // 6: looprpc.ClientListAvailableAssetsResponse + (*Asset)(nil), // 7: looprpc.Asset + (*ClientGetAssetSwapOutQuoteRequest)(nil), // 8: looprpc.ClientGetAssetSwapOutQuoteRequest + (*ClientGetAssetSwapOutQuoteResponse)(nil), // 9: looprpc.ClientGetAssetSwapOutQuoteResponse +} +var file_clientassets_proto_depIdxs = []int32{ + 4, // 0: looprpc.SwapOutResponse.swap_status:type_name -> looprpc.AssetSwapStatus + 4, // 1: looprpc.ListAssetSwapsResponse.swap_status:type_name -> looprpc.AssetSwapStatus + 7, // 2: looprpc.ClientListAvailableAssetsResponse.available_assets:type_name -> looprpc.Asset + 0, // 3: looprpc.AssetsClient.SwapOut:input_type -> looprpc.SwapOutRequest + 2, // 4: looprpc.AssetsClient.ListAssetSwaps:input_type -> looprpc.ListAssetSwapsRequest + 5, // 5: looprpc.AssetsClient.ClientListAvailableAssets:input_type -> looprpc.ClientListAvailableAssetsRequest + 8, // 6: looprpc.AssetsClient.ClientGetAssetSwapOutQuote:input_type -> looprpc.ClientGetAssetSwapOutQuoteRequest + 1, // 7: looprpc.AssetsClient.SwapOut:output_type -> looprpc.SwapOutResponse + 3, // 8: looprpc.AssetsClient.ListAssetSwaps:output_type -> looprpc.ListAssetSwapsResponse + 6, // 9: looprpc.AssetsClient.ClientListAvailableAssets:output_type -> looprpc.ClientListAvailableAssetsResponse + 9, // 10: looprpc.AssetsClient.ClientGetAssetSwapOutQuote:output_type -> looprpc.ClientGetAssetSwapOutQuoteResponse + 7, // [7:11] is the sub-list for method output_type + 3, // [3:7] is the sub-list for method input_type + 3, // [3:3] is the sub-list for extension type_name + 3, // [3:3] is the sub-list for extension extendee + 0, // [0:3] is the sub-list for field type_name +} + +func init() { file_clientassets_proto_init() } +func file_clientassets_proto_init() { + if File_clientassets_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_clientassets_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SwapOutRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_clientassets_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SwapOutResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_clientassets_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListAssetSwapsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_clientassets_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListAssetSwapsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_clientassets_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AssetSwapStatus); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_clientassets_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ClientListAvailableAssetsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_clientassets_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ClientListAvailableAssetsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_clientassets_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Asset); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_clientassets_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ClientGetAssetSwapOutQuoteRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_clientassets_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ClientGetAssetSwapOutQuoteResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_clientassets_proto_rawDesc, + NumEnums: 0, + NumMessages: 10, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_clientassets_proto_goTypes, + DependencyIndexes: file_clientassets_proto_depIdxs, + MessageInfos: file_clientassets_proto_msgTypes, + }.Build() + File_clientassets_proto = out.File + file_clientassets_proto_rawDesc = nil + file_clientassets_proto_goTypes = nil + file_clientassets_proto_depIdxs = nil +} diff --git a/looprpc/clientassets.proto b/looprpc/clientassets.proto new file mode 100644 index 000000000..25ca74717 --- /dev/null +++ b/looprpc/clientassets.proto @@ -0,0 +1,61 @@ +syntax = "proto3"; + +import "swapserverrpc/common.proto"; + +package looprpc; + +option go_package = "github.com/lightninglabs/loop/looprpc"; + +service AssetsClient { + rpc SwapOut (SwapOutRequest) returns (SwapOutResponse); + rpc ListAssetSwaps (ListAssetSwapsRequest) returns (ListAssetSwapsResponse); + rpc ClientListAvailableAssets (ClientListAvailableAssetsRequest) + returns (ClientListAvailableAssetsResponse); + rpc ClientGetAssetSwapOutQuote (ClientGetAssetSwapOutQuoteRequest) + returns (ClientGetAssetSwapOutQuoteResponse); +} + +message SwapOutRequest { + uint64 amt = 1; + bytes asset = 2; +} + +message SwapOutResponse { + AssetSwapStatus swap_status = 1; +} + +message ListAssetSwapsRequest { +} + +message ListAssetSwapsResponse { + repeated AssetSwapStatus swap_status = 1; +} + +message AssetSwapStatus { + bytes swap_hash = 1; + string swap_status = 2; +} + +message ClientListAvailableAssetsRequest { +} + +message ClientListAvailableAssetsResponse { + repeated Asset available_assets = 1; +} + +message Asset { + bytes asset_id = 1; + string name = 2; + uint64 sats_per_unit = 3; +} + +message ClientGetAssetSwapOutQuoteRequest { + uint64 amt = 1; + bytes asset = 2; +} + +message ClientGetAssetSwapOutQuoteResponse { + double swap_fee = 1; + uint64 prepay_amt = 2; + uint64 sats_per_unit = 3; +} \ No newline at end of file diff --git a/looprpc/clientassets_grpc.pb.go b/looprpc/clientassets_grpc.pb.go new file mode 100644 index 000000000..129381600 --- /dev/null +++ b/looprpc/clientassets_grpc.pb.go @@ -0,0 +1,209 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. + +package looprpc + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// AssetsClientClient is the client API for AssetsClient service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type AssetsClientClient interface { + SwapOut(ctx context.Context, in *SwapOutRequest, opts ...grpc.CallOption) (*SwapOutResponse, error) + ListAssetSwaps(ctx context.Context, in *ListAssetSwapsRequest, opts ...grpc.CallOption) (*ListAssetSwapsResponse, error) + ClientListAvailableAssets(ctx context.Context, in *ClientListAvailableAssetsRequest, opts ...grpc.CallOption) (*ClientListAvailableAssetsResponse, error) + ClientGetAssetSwapOutQuote(ctx context.Context, in *ClientGetAssetSwapOutQuoteRequest, opts ...grpc.CallOption) (*ClientGetAssetSwapOutQuoteResponse, error) +} + +type assetsClientClient struct { + cc grpc.ClientConnInterface +} + +func NewAssetsClientClient(cc grpc.ClientConnInterface) AssetsClientClient { + return &assetsClientClient{cc} +} + +func (c *assetsClientClient) SwapOut(ctx context.Context, in *SwapOutRequest, opts ...grpc.CallOption) (*SwapOutResponse, error) { + out := new(SwapOutResponse) + err := c.cc.Invoke(ctx, "/looprpc.AssetsClient/SwapOut", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *assetsClientClient) ListAssetSwaps(ctx context.Context, in *ListAssetSwapsRequest, opts ...grpc.CallOption) (*ListAssetSwapsResponse, error) { + out := new(ListAssetSwapsResponse) + err := c.cc.Invoke(ctx, "/looprpc.AssetsClient/ListAssetSwaps", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *assetsClientClient) ClientListAvailableAssets(ctx context.Context, in *ClientListAvailableAssetsRequest, opts ...grpc.CallOption) (*ClientListAvailableAssetsResponse, error) { + out := new(ClientListAvailableAssetsResponse) + err := c.cc.Invoke(ctx, "/looprpc.AssetsClient/ClientListAvailableAssets", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *assetsClientClient) ClientGetAssetSwapOutQuote(ctx context.Context, in *ClientGetAssetSwapOutQuoteRequest, opts ...grpc.CallOption) (*ClientGetAssetSwapOutQuoteResponse, error) { + out := new(ClientGetAssetSwapOutQuoteResponse) + err := c.cc.Invoke(ctx, "/looprpc.AssetsClient/ClientGetAssetSwapOutQuote", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// AssetsClientServer is the server API for AssetsClient service. +// All implementations must embed UnimplementedAssetsClientServer +// for forward compatibility +type AssetsClientServer interface { + SwapOut(context.Context, *SwapOutRequest) (*SwapOutResponse, error) + ListAssetSwaps(context.Context, *ListAssetSwapsRequest) (*ListAssetSwapsResponse, error) + ClientListAvailableAssets(context.Context, *ClientListAvailableAssetsRequest) (*ClientListAvailableAssetsResponse, error) + ClientGetAssetSwapOutQuote(context.Context, *ClientGetAssetSwapOutQuoteRequest) (*ClientGetAssetSwapOutQuoteResponse, error) + mustEmbedUnimplementedAssetsClientServer() +} + +// UnimplementedAssetsClientServer must be embedded to have forward compatible implementations. +type UnimplementedAssetsClientServer struct { +} + +func (UnimplementedAssetsClientServer) SwapOut(context.Context, *SwapOutRequest) (*SwapOutResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SwapOut not implemented") +} +func (UnimplementedAssetsClientServer) ListAssetSwaps(context.Context, *ListAssetSwapsRequest) (*ListAssetSwapsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListAssetSwaps not implemented") +} +func (UnimplementedAssetsClientServer) ClientListAvailableAssets(context.Context, *ClientListAvailableAssetsRequest) (*ClientListAvailableAssetsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ClientListAvailableAssets not implemented") +} +func (UnimplementedAssetsClientServer) ClientGetAssetSwapOutQuote(context.Context, *ClientGetAssetSwapOutQuoteRequest) (*ClientGetAssetSwapOutQuoteResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ClientGetAssetSwapOutQuote not implemented") +} +func (UnimplementedAssetsClientServer) mustEmbedUnimplementedAssetsClientServer() {} + +// UnsafeAssetsClientServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to AssetsClientServer will +// result in compilation errors. +type UnsafeAssetsClientServer interface { + mustEmbedUnimplementedAssetsClientServer() +} + +func RegisterAssetsClientServer(s grpc.ServiceRegistrar, srv AssetsClientServer) { + s.RegisterService(&AssetsClient_ServiceDesc, srv) +} + +func _AssetsClient_SwapOut_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SwapOutRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AssetsClientServer).SwapOut(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/looprpc.AssetsClient/SwapOut", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AssetsClientServer).SwapOut(ctx, req.(*SwapOutRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AssetsClient_ListAssetSwaps_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListAssetSwapsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AssetsClientServer).ListAssetSwaps(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/looprpc.AssetsClient/ListAssetSwaps", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AssetsClientServer).ListAssetSwaps(ctx, req.(*ListAssetSwapsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AssetsClient_ClientListAvailableAssets_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ClientListAvailableAssetsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AssetsClientServer).ClientListAvailableAssets(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/looprpc.AssetsClient/ClientListAvailableAssets", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AssetsClientServer).ClientListAvailableAssets(ctx, req.(*ClientListAvailableAssetsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AssetsClient_ClientGetAssetSwapOutQuote_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ClientGetAssetSwapOutQuoteRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AssetsClientServer).ClientGetAssetSwapOutQuote(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/looprpc.AssetsClient/ClientGetAssetSwapOutQuote", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AssetsClientServer).ClientGetAssetSwapOutQuote(ctx, req.(*ClientGetAssetSwapOutQuoteRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// AssetsClient_ServiceDesc is the grpc.ServiceDesc for AssetsClient service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var AssetsClient_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "looprpc.AssetsClient", + HandlerType: (*AssetsClientServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "SwapOut", + Handler: _AssetsClient_SwapOut_Handler, + }, + { + MethodName: "ListAssetSwaps", + Handler: _AssetsClient_ListAssetSwaps_Handler, + }, + { + MethodName: "ClientListAvailableAssets", + Handler: _AssetsClient_ClientListAvailableAssets_Handler, + }, + { + MethodName: "ClientGetAssetSwapOutQuote", + Handler: _AssetsClient_ClientGetAssetSwapOutQuote_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "clientassets.proto", +} diff --git a/swapserverrpc/assets.pb.go b/swapserverrpc/assets.pb.go new file mode 100644 index 000000000..fece61211 --- /dev/null +++ b/swapserverrpc/assets.pb.go @@ -0,0 +1,1103 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.30.0 +// protoc v3.6.1 +// source: assets.proto + +// We can't change this to swapserverrpc, it would be a breaking change because +// the package name is also contained in the HTTP URIs and old clients would +// call the wrong endpoints. Luckily with the go_package option we can have +// different golang and RPC package names to fix protobuf namespace conflicts. + +package swapserverrpc + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type QuoteAssetLoopOutRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // amount is the amount of the asset to loop out. + Amount uint64 `protobuf:"varint,1,opt,name=amount,proto3" json:"amount,omitempty"` + // asset is the asset to loop out. + Asset []byte `protobuf:"bytes,2,opt,name=asset,proto3" json:"asset,omitempty"` +} + +func (x *QuoteAssetLoopOutRequest) Reset() { + *x = QuoteAssetLoopOutRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_assets_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *QuoteAssetLoopOutRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QuoteAssetLoopOutRequest) ProtoMessage() {} + +func (x *QuoteAssetLoopOutRequest) ProtoReflect() protoreflect.Message { + mi := &file_assets_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use QuoteAssetLoopOutRequest.ProtoReflect.Descriptor instead. +func (*QuoteAssetLoopOutRequest) Descriptor() ([]byte, []int) { + return file_assets_proto_rawDescGZIP(), []int{0} +} + +func (x *QuoteAssetLoopOutRequest) GetAmount() uint64 { + if x != nil { + return x.Amount + } + return 0 +} + +func (x *QuoteAssetLoopOutRequest) GetAsset() []byte { + if x != nil { + return x.Asset + } + return nil +} + +type QuoteAssetLoopOutResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // fixed_prepay_amt is the fixed prepay amount of the swap. + FixedPrepayAmt uint64 `protobuf:"varint,1,opt,name=fixed_prepay_amt,json=fixedPrepayAmt,proto3" json:"fixed_prepay_amt,omitempty"` + // swap_fee_rate is the fee rate that is added to the swap invoice. + SwapFeeRate float64 `protobuf:"fixed64,2,opt,name=swap_fee_rate,json=swapFeeRate,proto3" json:"swap_fee_rate,omitempty"` + // current_sats_per_asset_unit is the sats per asset unit of the swap. + CurrentSatsPerAssetUnit uint64 `protobuf:"varint,3,opt,name=current_sats_per_asset_unit,json=currentSatsPerAssetUnit,proto3" json:"current_sats_per_asset_unit,omitempty"` +} + +func (x *QuoteAssetLoopOutResponse) Reset() { + *x = QuoteAssetLoopOutResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_assets_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *QuoteAssetLoopOutResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QuoteAssetLoopOutResponse) ProtoMessage() {} + +func (x *QuoteAssetLoopOutResponse) ProtoReflect() protoreflect.Message { + mi := &file_assets_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use QuoteAssetLoopOutResponse.ProtoReflect.Descriptor instead. +func (*QuoteAssetLoopOutResponse) Descriptor() ([]byte, []int) { + return file_assets_proto_rawDescGZIP(), []int{1} +} + +func (x *QuoteAssetLoopOutResponse) GetFixedPrepayAmt() uint64 { + if x != nil { + return x.FixedPrepayAmt + } + return 0 +} + +func (x *QuoteAssetLoopOutResponse) GetSwapFeeRate() float64 { + if x != nil { + return x.SwapFeeRate + } + return 0 +} + +func (x *QuoteAssetLoopOutResponse) GetCurrentSatsPerAssetUnit() uint64 { + if x != nil { + return x.CurrentSatsPerAssetUnit + } + return 0 +} + +type ListAvailableAssetsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ListAvailableAssetsRequest) Reset() { + *x = ListAvailableAssetsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_assets_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListAvailableAssetsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListAvailableAssetsRequest) ProtoMessage() {} + +func (x *ListAvailableAssetsRequest) ProtoReflect() protoreflect.Message { + mi := &file_assets_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListAvailableAssetsRequest.ProtoReflect.Descriptor instead. +func (*ListAvailableAssetsRequest) Descriptor() ([]byte, []int) { + return file_assets_proto_rawDescGZIP(), []int{2} +} + +type ListAvailableAssetsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // assets is the list of assets that the server supports. + Assets []*AssetInfo `protobuf:"bytes,1,rep,name=assets,proto3" json:"assets,omitempty"` +} + +func (x *ListAvailableAssetsResponse) Reset() { + *x = ListAvailableAssetsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_assets_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListAvailableAssetsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListAvailableAssetsResponse) ProtoMessage() {} + +func (x *ListAvailableAssetsResponse) ProtoReflect() protoreflect.Message { + mi := &file_assets_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListAvailableAssetsResponse.ProtoReflect.Descriptor instead. +func (*ListAvailableAssetsResponse) Descriptor() ([]byte, []int) { + return file_assets_proto_rawDescGZIP(), []int{3} +} + +func (x *ListAvailableAssetsResponse) GetAssets() []*AssetInfo { + if x != nil { + return x.Assets + } + return nil +} + +type AssetInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AssetId []byte `protobuf:"bytes,1,opt,name=asset_id,json=assetId,proto3" json:"asset_id,omitempty"` + CurrentSatsPerAssetUnit uint64 `protobuf:"varint,2,opt,name=current_sats_per_asset_unit,json=currentSatsPerAssetUnit,proto3" json:"current_sats_per_asset_unit,omitempty"` +} + +func (x *AssetInfo) Reset() { + *x = AssetInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_assets_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AssetInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AssetInfo) ProtoMessage() {} + +func (x *AssetInfo) ProtoReflect() protoreflect.Message { + mi := &file_assets_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AssetInfo.ProtoReflect.Descriptor instead. +func (*AssetInfo) Descriptor() ([]byte, []int) { + return file_assets_proto_rawDescGZIP(), []int{4} +} + +func (x *AssetInfo) GetAssetId() []byte { + if x != nil { + return x.AssetId + } + return nil +} + +func (x *AssetInfo) GetCurrentSatsPerAssetUnit() uint64 { + if x != nil { + return x.CurrentSatsPerAssetUnit + } + return 0 +} + +type RequestAssetLoopOutRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // amount is the amount of the asset to loop out. + Amount uint64 `protobuf:"varint,1,opt,name=amount,proto3" json:"amount,omitempty"` + // receiver_key is the public key of the receiver. + ReceiverKey []byte `protobuf:"bytes,2,opt,name=receiver_key,json=receiverKey,proto3" json:"receiver_key,omitempty"` + // requested_asset is the asset to loop out. + RequestedAsset []byte `protobuf:"bytes,3,opt,name=requested_asset,json=requestedAsset,proto3" json:"requested_asset,omitempty"` +} + +func (x *RequestAssetLoopOutRequest) Reset() { + *x = RequestAssetLoopOutRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_assets_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RequestAssetLoopOutRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RequestAssetLoopOutRequest) ProtoMessage() {} + +func (x *RequestAssetLoopOutRequest) ProtoReflect() protoreflect.Message { + mi := &file_assets_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RequestAssetLoopOutRequest.ProtoReflect.Descriptor instead. +func (*RequestAssetLoopOutRequest) Descriptor() ([]byte, []int) { + return file_assets_proto_rawDescGZIP(), []int{5} +} + +func (x *RequestAssetLoopOutRequest) GetAmount() uint64 { + if x != nil { + return x.Amount + } + return 0 +} + +func (x *RequestAssetLoopOutRequest) GetReceiverKey() []byte { + if x != nil { + return x.ReceiverKey + } + return nil +} + +func (x *RequestAssetLoopOutRequest) GetRequestedAsset() []byte { + if x != nil { + return x.RequestedAsset + } + return nil +} + +type RequestAssetLoopOutResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // swap_hash is the main identifier of the swap. + SwapHash []byte `protobuf:"bytes,1,opt,name=swap_hash,json=swapHash,proto3" json:"swap_hash,omitempty"` + // prepay_invoice is the invoice to pay to start the swap. On accepted + // the server will publish the htlc output. + PrepayInvoice string `protobuf:"bytes,2,opt,name=prepay_invoice,json=prepayInvoice,proto3" json:"prepay_invoice,omitempty"` + // expiry is the expiry of the htlc output. + Expiry int64 `protobuf:"varint,3,opt,name=expiry,proto3" json:"expiry,omitempty"` + // sender_pubkey is the public key of the sender. + SenderPubkey []byte `protobuf:"bytes,4,opt,name=sender_pubkey,json=senderPubkey,proto3" json:"sender_pubkey,omitempty"` +} + +func (x *RequestAssetLoopOutResponse) Reset() { + *x = RequestAssetLoopOutResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_assets_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RequestAssetLoopOutResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RequestAssetLoopOutResponse) ProtoMessage() {} + +func (x *RequestAssetLoopOutResponse) ProtoReflect() protoreflect.Message { + mi := &file_assets_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RequestAssetLoopOutResponse.ProtoReflect.Descriptor instead. +func (*RequestAssetLoopOutResponse) Descriptor() ([]byte, []int) { + return file_assets_proto_rawDescGZIP(), []int{6} +} + +func (x *RequestAssetLoopOutResponse) GetSwapHash() []byte { + if x != nil { + return x.SwapHash + } + return nil +} + +func (x *RequestAssetLoopOutResponse) GetPrepayInvoice() string { + if x != nil { + return x.PrepayInvoice + } + return "" +} + +func (x *RequestAssetLoopOutResponse) GetExpiry() int64 { + if x != nil { + return x.Expiry + } + return 0 +} + +func (x *RequestAssetLoopOutResponse) GetSenderPubkey() []byte { + if x != nil { + return x.SenderPubkey + } + return nil +} + +type PollAssetLoopOutProofRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // swap_hash is the main identifier of the swap. + SwapHash []byte `protobuf:"bytes,1,opt,name=swap_hash,json=swapHash,proto3" json:"swap_hash,omitempty"` +} + +func (x *PollAssetLoopOutProofRequest) Reset() { + *x = PollAssetLoopOutProofRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_assets_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PollAssetLoopOutProofRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PollAssetLoopOutProofRequest) ProtoMessage() {} + +func (x *PollAssetLoopOutProofRequest) ProtoReflect() protoreflect.Message { + mi := &file_assets_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PollAssetLoopOutProofRequest.ProtoReflect.Descriptor instead. +func (*PollAssetLoopOutProofRequest) Descriptor() ([]byte, []int) { + return file_assets_proto_rawDescGZIP(), []int{7} +} + +func (x *PollAssetLoopOutProofRequest) GetSwapHash() []byte { + if x != nil { + return x.SwapHash + } + return nil +} + +type PollAssetLoopOutProofResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // raw_proof_file is the raw proof file of the swap. + RawProofFile []byte `protobuf:"bytes,1,opt,name=raw_proof_file,json=rawProofFile,proto3" json:"raw_proof_file,omitempty"` +} + +func (x *PollAssetLoopOutProofResponse) Reset() { + *x = PollAssetLoopOutProofResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_assets_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PollAssetLoopOutProofResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PollAssetLoopOutProofResponse) ProtoMessage() {} + +func (x *PollAssetLoopOutProofResponse) ProtoReflect() protoreflect.Message { + mi := &file_assets_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PollAssetLoopOutProofResponse.ProtoReflect.Descriptor instead. +func (*PollAssetLoopOutProofResponse) Descriptor() ([]byte, []int) { + return file_assets_proto_rawDescGZIP(), []int{8} +} + +func (x *PollAssetLoopOutProofResponse) GetRawProofFile() []byte { + if x != nil { + return x.RawProofFile + } + return nil +} + +type RequestAssetBuyRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // swap_hash is the main identifier of the swap. + SwapHash []byte `protobuf:"bytes,1,opt,name=swap_hash,json=swapHash,proto3" json:"swap_hash,omitempty"` +} + +func (x *RequestAssetBuyRequest) Reset() { + *x = RequestAssetBuyRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_assets_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RequestAssetBuyRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RequestAssetBuyRequest) ProtoMessage() {} + +func (x *RequestAssetBuyRequest) ProtoReflect() protoreflect.Message { + mi := &file_assets_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RequestAssetBuyRequest.ProtoReflect.Descriptor instead. +func (*RequestAssetBuyRequest) Descriptor() ([]byte, []int) { + return file_assets_proto_rawDescGZIP(), []int{9} +} + +func (x *RequestAssetBuyRequest) GetSwapHash() []byte { + if x != nil { + return x.SwapHash + } + return nil +} + +type RequestAssetBuyResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // swap_invoice is the invoice to pay to receive the preimage to claim the + // asset. + SwapInvoice string `protobuf:"bytes,1,opt,name=swap_invoice,json=swapInvoice,proto3" json:"swap_invoice,omitempty"` +} + +func (x *RequestAssetBuyResponse) Reset() { + *x = RequestAssetBuyResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_assets_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RequestAssetBuyResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RequestAssetBuyResponse) ProtoMessage() {} + +func (x *RequestAssetBuyResponse) ProtoReflect() protoreflect.Message { + mi := &file_assets_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RequestAssetBuyResponse.ProtoReflect.Descriptor instead. +func (*RequestAssetBuyResponse) Descriptor() ([]byte, []int) { + return file_assets_proto_rawDescGZIP(), []int{10} +} + +func (x *RequestAssetBuyResponse) GetSwapInvoice() string { + if x != nil { + return x.SwapInvoice + } + return "" +} + +type RequestMusig2SweepRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // swap_hash is the main identifier of the swap. + SwapHash []byte `protobuf:"bytes,1,opt,name=swap_hash,json=swapHash,proto3" json:"swap_hash,omitempty"` + // digest is that the client wants the server to sign. + Digest []byte `protobuf:"bytes,2,opt,name=digest,proto3" json:"digest,omitempty"` + // receiver_nonce is the nonce of the receiver. + ReceiverNonce []byte `protobuf:"bytes,3,opt,name=receiver_nonce,json=receiverNonce,proto3" json:"receiver_nonce,omitempty"` +} + +func (x *RequestMusig2SweepRequest) Reset() { + *x = RequestMusig2SweepRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_assets_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RequestMusig2SweepRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RequestMusig2SweepRequest) ProtoMessage() {} + +func (x *RequestMusig2SweepRequest) ProtoReflect() protoreflect.Message { + mi := &file_assets_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RequestMusig2SweepRequest.ProtoReflect.Descriptor instead. +func (*RequestMusig2SweepRequest) Descriptor() ([]byte, []int) { + return file_assets_proto_rawDescGZIP(), []int{11} +} + +func (x *RequestMusig2SweepRequest) GetSwapHash() []byte { + if x != nil { + return x.SwapHash + } + return nil +} + +func (x *RequestMusig2SweepRequest) GetDigest() []byte { + if x != nil { + return x.Digest + } + return nil +} + +func (x *RequestMusig2SweepRequest) GetReceiverNonce() []byte { + if x != nil { + return x.ReceiverNonce + } + return nil +} + +type RequestMusig2SweepResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // sender_nonce is the nonce of the sender. + SenderNonce []byte `protobuf:"bytes,1,opt,name=sender_nonce,json=senderNonce,proto3" json:"sender_nonce,omitempty"` + // sender_sig is the signature of the sender. + SenderSig []byte `protobuf:"bytes,2,opt,name=sender_sig,json=senderSig,proto3" json:"sender_sig,omitempty"` +} + +func (x *RequestMusig2SweepResponse) Reset() { + *x = RequestMusig2SweepResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_assets_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RequestMusig2SweepResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RequestMusig2SweepResponse) ProtoMessage() {} + +func (x *RequestMusig2SweepResponse) ProtoReflect() protoreflect.Message { + mi := &file_assets_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RequestMusig2SweepResponse.ProtoReflect.Descriptor instead. +func (*RequestMusig2SweepResponse) Descriptor() ([]byte, []int) { + return file_assets_proto_rawDescGZIP(), []int{12} +} + +func (x *RequestMusig2SweepResponse) GetSenderNonce() []byte { + if x != nil { + return x.SenderNonce + } + return nil +} + +func (x *RequestMusig2SweepResponse) GetSenderSig() []byte { + if x != nil { + return x.SenderSig + } + return nil +} + +var File_assets_proto protoreflect.FileDescriptor + +var file_assets_proto_rawDesc = []byte{ + 0x0a, 0x0c, 0x61, 0x73, 0x73, 0x65, 0x74, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x07, + 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x22, 0x48, 0x0a, 0x18, 0x51, 0x75, 0x6f, 0x74, 0x65, + 0x41, 0x73, 0x73, 0x65, 0x74, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x61, + 0x73, 0x73, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x61, 0x73, 0x73, 0x65, + 0x74, 0x22, 0xa7, 0x01, 0x0a, 0x19, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x41, 0x73, 0x73, 0x65, 0x74, + 0x4c, 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x28, 0x0a, 0x10, 0x66, 0x69, 0x78, 0x65, 0x64, 0x5f, 0x70, 0x72, 0x65, 0x70, 0x61, 0x79, 0x5f, + 0x61, 0x6d, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x66, 0x69, 0x78, 0x65, 0x64, + 0x50, 0x72, 0x65, 0x70, 0x61, 0x79, 0x41, 0x6d, 0x74, 0x12, 0x22, 0x0a, 0x0d, 0x73, 0x77, 0x61, + 0x70, 0x5f, 0x66, 0x65, 0x65, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, + 0x52, 0x0b, 0x73, 0x77, 0x61, 0x70, 0x46, 0x65, 0x65, 0x52, 0x61, 0x74, 0x65, 0x12, 0x3c, 0x0a, + 0x1b, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x61, 0x74, 0x73, 0x5f, 0x70, 0x65, + 0x72, 0x5f, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x75, 0x6e, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x17, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x53, 0x61, 0x74, 0x73, 0x50, + 0x65, 0x72, 0x41, 0x73, 0x73, 0x65, 0x74, 0x55, 0x6e, 0x69, 0x74, 0x22, 0x1c, 0x0a, 0x1a, 0x4c, + 0x69, 0x73, 0x74, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x41, 0x73, 0x73, 0x65, + 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x49, 0x0a, 0x1b, 0x4c, 0x69, 0x73, + 0x74, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x41, 0x73, 0x73, 0x65, 0x74, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x61, 0x73, 0x73, 0x65, + 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, + 0x70, 0x63, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x06, 0x61, 0x73, + 0x73, 0x65, 0x74, 0x73, 0x22, 0x64, 0x0a, 0x09, 0x41, 0x73, 0x73, 0x65, 0x74, 0x49, 0x6e, 0x66, + 0x6f, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x07, 0x61, 0x73, 0x73, 0x65, 0x74, 0x49, 0x64, 0x12, 0x3c, 0x0a, 0x1b, + 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x61, 0x74, 0x73, 0x5f, 0x70, 0x65, 0x72, + 0x5f, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x75, 0x6e, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x17, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x53, 0x61, 0x74, 0x73, 0x50, 0x65, + 0x72, 0x41, 0x73, 0x73, 0x65, 0x74, 0x55, 0x6e, 0x69, 0x74, 0x22, 0x80, 0x01, 0x0a, 0x1a, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, + 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, + 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, + 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x5f, 0x6b, 0x65, + 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, + 0x72, 0x4b, 0x65, 0x79, 0x12, 0x27, 0x0a, 0x0f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, + 0x64, 0x5f, 0x61, 0x73, 0x73, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x72, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x41, 0x73, 0x73, 0x65, 0x74, 0x22, 0x9e, 0x01, + 0x0a, 0x1b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4c, 0x6f, + 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1b, 0x0a, + 0x09, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x08, 0x73, 0x77, 0x61, 0x70, 0x48, 0x61, 0x73, 0x68, 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x72, + 0x65, 0x70, 0x61, 0x79, 0x5f, 0x69, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0d, 0x70, 0x72, 0x65, 0x70, 0x61, 0x79, 0x49, 0x6e, 0x76, 0x6f, 0x69, 0x63, + 0x65, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x06, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x73, 0x65, 0x6e, + 0x64, 0x65, 0x72, 0x5f, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x0c, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x50, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x22, 0x3b, + 0x0a, 0x1c, 0x50, 0x6f, 0x6c, 0x6c, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, + 0x75, 0x74, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, + 0x0a, 0x09, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x08, 0x73, 0x77, 0x61, 0x70, 0x48, 0x61, 0x73, 0x68, 0x22, 0x45, 0x0a, 0x1d, 0x50, + 0x6f, 0x6c, 0x6c, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x50, + 0x72, 0x6f, 0x6f, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, 0x0a, 0x0e, + 0x72, 0x61, 0x77, 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x72, 0x61, 0x77, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x46, 0x69, + 0x6c, 0x65, 0x22, 0x35, 0x0a, 0x16, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x41, 0x73, 0x73, + 0x65, 0x74, 0x42, 0x75, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, + 0x73, 0x77, 0x61, 0x70, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x08, 0x73, 0x77, 0x61, 0x70, 0x48, 0x61, 0x73, 0x68, 0x22, 0x3c, 0x0a, 0x17, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x41, 0x73, 0x73, 0x65, 0x74, 0x42, 0x75, 0x79, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x69, 0x6e, 0x76, + 0x6f, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x77, 0x61, 0x70, + 0x49, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x22, 0x77, 0x0a, 0x19, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x4d, 0x75, 0x73, 0x69, 0x67, 0x32, 0x53, 0x77, 0x65, 0x65, 0x70, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x68, 0x61, 0x73, + 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x73, 0x77, 0x61, 0x70, 0x48, 0x61, 0x73, + 0x68, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x65, 0x63, + 0x65, 0x69, 0x76, 0x65, 0x72, 0x5f, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x0d, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x4e, 0x6f, 0x6e, 0x63, 0x65, + 0x22, 0x5e, 0x0a, 0x1a, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x75, 0x73, 0x69, 0x67, + 0x32, 0x53, 0x77, 0x65, 0x65, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21, + 0x0a, 0x0c, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x5f, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x4e, 0x6f, 0x6e, 0x63, + 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x5f, 0x73, 0x69, 0x67, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x53, 0x69, 0x67, + 0x32, 0xcf, 0x04, 0x0a, 0x10, 0x41, 0x73, 0x73, 0x65, 0x74, 0x73, 0x53, 0x77, 0x61, 0x70, 0x53, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x5a, 0x0a, 0x11, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x41, 0x73, + 0x73, 0x65, 0x74, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x12, 0x21, 0x2e, 0x6c, 0x6f, 0x6f, + 0x70, 0x72, 0x70, 0x63, 0x2e, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4c, + 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, + 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x41, 0x73, 0x73, + 0x65, 0x74, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x60, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, + 0x6c, 0x65, 0x41, 0x73, 0x73, 0x65, 0x74, 0x73, 0x12, 0x23, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, + 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, + 0x41, 0x73, 0x73, 0x65, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, + 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x76, 0x61, 0x69, + 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x41, 0x73, 0x73, 0x65, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x60, 0x0a, 0x13, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x41, 0x73, + 0x73, 0x65, 0x74, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x12, 0x23, 0x2e, 0x6c, 0x6f, 0x6f, + 0x70, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x41, 0x73, 0x73, 0x65, + 0x74, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x24, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x66, 0x0a, 0x15, 0x50, 0x6f, 0x6c, 0x6c, 0x41, 0x73, 0x73, + 0x65, 0x74, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x25, + 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x6f, 0x6c, 0x6c, 0x41, 0x73, 0x73, + 0x65, 0x74, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, + 0x50, 0x6f, 0x6c, 0x6c, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, + 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x54, 0x0a, + 0x0f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x41, 0x73, 0x73, 0x65, 0x74, 0x42, 0x75, 0x79, + 0x12, 0x1f, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x41, 0x73, 0x73, 0x65, 0x74, 0x42, 0x75, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x20, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x41, 0x73, 0x73, 0x65, 0x74, 0x42, 0x75, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x5d, 0x0a, 0x12, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x75, + 0x73, 0x69, 0x67, 0x32, 0x53, 0x77, 0x65, 0x65, 0x70, 0x12, 0x22, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, + 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x75, 0x73, 0x69, 0x67, + 0x32, 0x53, 0x77, 0x65, 0x65, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, + 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, + 0x75, 0x73, 0x69, 0x67, 0x32, 0x53, 0x77, 0x65, 0x65, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x42, 0x2d, 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x6e, 0x69, 0x6e, 0x67, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x6c, + 0x6f, 0x6f, 0x70, 0x2f, 0x73, 0x77, 0x61, 0x70, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x72, 0x70, + 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_assets_proto_rawDescOnce sync.Once + file_assets_proto_rawDescData = file_assets_proto_rawDesc +) + +func file_assets_proto_rawDescGZIP() []byte { + file_assets_proto_rawDescOnce.Do(func() { + file_assets_proto_rawDescData = protoimpl.X.CompressGZIP(file_assets_proto_rawDescData) + }) + return file_assets_proto_rawDescData +} + +var file_assets_proto_msgTypes = make([]protoimpl.MessageInfo, 13) +var file_assets_proto_goTypes = []interface{}{ + (*QuoteAssetLoopOutRequest)(nil), // 0: looprpc.QuoteAssetLoopOutRequest + (*QuoteAssetLoopOutResponse)(nil), // 1: looprpc.QuoteAssetLoopOutResponse + (*ListAvailableAssetsRequest)(nil), // 2: looprpc.ListAvailableAssetsRequest + (*ListAvailableAssetsResponse)(nil), // 3: looprpc.ListAvailableAssetsResponse + (*AssetInfo)(nil), // 4: looprpc.AssetInfo + (*RequestAssetLoopOutRequest)(nil), // 5: looprpc.RequestAssetLoopOutRequest + (*RequestAssetLoopOutResponse)(nil), // 6: looprpc.RequestAssetLoopOutResponse + (*PollAssetLoopOutProofRequest)(nil), // 7: looprpc.PollAssetLoopOutProofRequest + (*PollAssetLoopOutProofResponse)(nil), // 8: looprpc.PollAssetLoopOutProofResponse + (*RequestAssetBuyRequest)(nil), // 9: looprpc.RequestAssetBuyRequest + (*RequestAssetBuyResponse)(nil), // 10: looprpc.RequestAssetBuyResponse + (*RequestMusig2SweepRequest)(nil), // 11: looprpc.RequestMusig2SweepRequest + (*RequestMusig2SweepResponse)(nil), // 12: looprpc.RequestMusig2SweepResponse +} +var file_assets_proto_depIdxs = []int32{ + 4, // 0: looprpc.ListAvailableAssetsResponse.assets:type_name -> looprpc.AssetInfo + 0, // 1: looprpc.AssetsSwapServer.QuoteAssetLoopOut:input_type -> looprpc.QuoteAssetLoopOutRequest + 2, // 2: looprpc.AssetsSwapServer.ListAvailableAssets:input_type -> looprpc.ListAvailableAssetsRequest + 5, // 3: looprpc.AssetsSwapServer.RequestAssetLoopOut:input_type -> looprpc.RequestAssetLoopOutRequest + 7, // 4: looprpc.AssetsSwapServer.PollAssetLoopOutProof:input_type -> looprpc.PollAssetLoopOutProofRequest + 9, // 5: looprpc.AssetsSwapServer.RequestAssetBuy:input_type -> looprpc.RequestAssetBuyRequest + 11, // 6: looprpc.AssetsSwapServer.RequestMusig2Sweep:input_type -> looprpc.RequestMusig2SweepRequest + 1, // 7: looprpc.AssetsSwapServer.QuoteAssetLoopOut:output_type -> looprpc.QuoteAssetLoopOutResponse + 3, // 8: looprpc.AssetsSwapServer.ListAvailableAssets:output_type -> looprpc.ListAvailableAssetsResponse + 6, // 9: looprpc.AssetsSwapServer.RequestAssetLoopOut:output_type -> looprpc.RequestAssetLoopOutResponse + 8, // 10: looprpc.AssetsSwapServer.PollAssetLoopOutProof:output_type -> looprpc.PollAssetLoopOutProofResponse + 10, // 11: looprpc.AssetsSwapServer.RequestAssetBuy:output_type -> looprpc.RequestAssetBuyResponse + 12, // 12: looprpc.AssetsSwapServer.RequestMusig2Sweep:output_type -> looprpc.RequestMusig2SweepResponse + 7, // [7:13] is the sub-list for method output_type + 1, // [1:7] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_assets_proto_init() } +func file_assets_proto_init() { + if File_assets_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_assets_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*QuoteAssetLoopOutRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_assets_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*QuoteAssetLoopOutResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_assets_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListAvailableAssetsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_assets_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListAvailableAssetsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_assets_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AssetInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_assets_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RequestAssetLoopOutRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_assets_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RequestAssetLoopOutResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_assets_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PollAssetLoopOutProofRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_assets_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PollAssetLoopOutProofResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_assets_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RequestAssetBuyRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_assets_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RequestAssetBuyResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_assets_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RequestMusig2SweepRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_assets_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RequestMusig2SweepResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_assets_proto_rawDesc, + NumEnums: 0, + NumMessages: 13, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_assets_proto_goTypes, + DependencyIndexes: file_assets_proto_depIdxs, + MessageInfos: file_assets_proto_msgTypes, + }.Build() + File_assets_proto = out.File + file_assets_proto_rawDesc = nil + file_assets_proto_goTypes = nil + file_assets_proto_depIdxs = nil +} diff --git a/swapserverrpc/assets.proto b/swapserverrpc/assets.proto new file mode 100644 index 000000000..30c72a7dc --- /dev/null +++ b/swapserverrpc/assets.proto @@ -0,0 +1,133 @@ +syntax = "proto3"; + +// We can't change this to swapserverrpc, it would be a breaking change because +// the package name is also contained in the HTTP URIs and old clients would +// call the wrong endpoints. Luckily with the go_package option we can have +// different golang and RPC package names to fix protobuf namespace conflicts. +package looprpc; + +option go_package = "github.com/lightninglabs/loop/swapserverrpc"; + +service AssetsSwapServer { + // QuoteAssetLoopOut requests a quote for an asset loop out swap from the + // server. + rpc QuoteAssetLoopOut (QuoteAssetLoopOutRequest) + returns (QuoteAssetLoopOutResponse); + + // ListAvailableAssets returns the list of assets that the server supports. + rpc ListAvailableAssets (ListAvailableAssetsRequest) + returns (ListAvailableAssetsResponse); + + // RequestAssetLoopOut requests an asset loop out swap from the server. + rpc RequestAssetLoopOut (RequestAssetLoopOutRequest) + returns (RequestAssetLoopOutResponse); + + // PollAssetLoopOutProof requests the server to poll for the proof of the + // asset loop out swap. + rpc PollAssetLoopOutProof (PollAssetLoopOutProofRequest) + returns (PollAssetLoopOutProofResponse); + + // RequestAssetBuy requests an asset buy swap from the server. This + // requires an already confirmed asset output on chain. + rpc RequestAssetBuy (RequestAssetBuyRequest) + returns (RequestAssetBuyResponse); + + // RequestMusig2Sweep requests a musig2 sweep from the server. + rpc RequestMusig2Sweep (RequestMusig2SweepRequest) + returns (RequestMusig2SweepResponse); +} + +message QuoteAssetLoopOutRequest { + // amount is the amount of the asset to loop out. + uint64 amount = 1; + + // asset is the asset to loop out. + bytes asset = 2; +} + +message QuoteAssetLoopOutResponse { + // fixed_prepay_amt is the fixed prepay amount of the swap. + uint64 fixed_prepay_amt = 1; + + // swap_fee_rate is the fee rate that is added to the swap invoice. + double swap_fee_rate = 2; + + // current_sats_per_asset_unit is the sats per asset unit of the swap. + uint64 current_sats_per_asset_unit = 3; +} + +message ListAvailableAssetsRequest { +} + +message ListAvailableAssetsResponse { + // assets is the list of assets that the server supports. + repeated AssetInfo assets = 1; +} + +message AssetInfo { + bytes asset_id = 1; + uint64 current_sats_per_asset_unit = 2; +} + +message RequestAssetLoopOutRequest { + // amount is the amount of the asset to loop out. + uint64 amount = 1; + + // receiver_key is the public key of the receiver. + bytes receiver_key = 2; + + // requested_asset is the asset to loop out. + bytes requested_asset = 3; +} + +message RequestAssetLoopOutResponse { + // swap_hash is the main identifier of the swap. + bytes swap_hash = 1; + + // prepay_invoice is the invoice to pay to start the swap. On accepted + // the server will publish the htlc output. + string prepay_invoice = 2; + + // expiry is the expiry of the htlc output. + int64 expiry = 3; + + // sender_pubkey is the public key of the sender. + bytes sender_pubkey = 4; +} + +message PollAssetLoopOutProofRequest { + // swap_hash is the main identifier of the swap. + bytes swap_hash = 1; +} + +message PollAssetLoopOutProofResponse { + // raw_proof_file is the raw proof file of the swap. + bytes raw_proof_file = 1; +} + +message RequestAssetBuyRequest { + // swap_hash is the main identifier of the swap. + bytes swap_hash = 1; +} + +message RequestAssetBuyResponse { + // swap_invoice is the invoice to pay to receive the preimage to claim the + // asset. + string swap_invoice = 1; +} + +message RequestMusig2SweepRequest { + // swap_hash is the main identifier of the swap. + bytes swap_hash = 1; + // digest is that the client wants the server to sign. + bytes digest = 2; + // receiver_nonce is the nonce of the receiver. + bytes receiver_nonce = 3; +} + +message RequestMusig2SweepResponse { + // sender_nonce is the nonce of the sender. + bytes sender_nonce = 1; + // sender_sig is the signature of the sender. + bytes sender_sig = 2; +} diff --git a/swapserverrpc/assets_grpc.pb.go b/swapserverrpc/assets_grpc.pb.go new file mode 100644 index 000000000..957bd57f7 --- /dev/null +++ b/swapserverrpc/assets_grpc.pb.go @@ -0,0 +1,299 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. + +package swapserverrpc + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// AssetsSwapServerClient is the client API for AssetsSwapServer service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type AssetsSwapServerClient interface { + // QuoteAssetLoopOut requests a quote for an asset loop out swap from the + // server. + QuoteAssetLoopOut(ctx context.Context, in *QuoteAssetLoopOutRequest, opts ...grpc.CallOption) (*QuoteAssetLoopOutResponse, error) + // ListAvailableAssets returns the list of assets that the server supports. + ListAvailableAssets(ctx context.Context, in *ListAvailableAssetsRequest, opts ...grpc.CallOption) (*ListAvailableAssetsResponse, error) + // RequestAssetLoopOut requests an asset loop out swap from the server. + RequestAssetLoopOut(ctx context.Context, in *RequestAssetLoopOutRequest, opts ...grpc.CallOption) (*RequestAssetLoopOutResponse, error) + // PollAssetLoopOutProof requests the server to poll for the proof of the + // asset loop out swap. + PollAssetLoopOutProof(ctx context.Context, in *PollAssetLoopOutProofRequest, opts ...grpc.CallOption) (*PollAssetLoopOutProofResponse, error) + // RequestAssetBuy requests an asset buy swap from the server. This + // requires an already confirmed asset output on chain. + RequestAssetBuy(ctx context.Context, in *RequestAssetBuyRequest, opts ...grpc.CallOption) (*RequestAssetBuyResponse, error) + // RequestMusig2Sweep requests a musig2 sweep from the server. + RequestMusig2Sweep(ctx context.Context, in *RequestMusig2SweepRequest, opts ...grpc.CallOption) (*RequestMusig2SweepResponse, error) +} + +type assetsSwapServerClient struct { + cc grpc.ClientConnInterface +} + +func NewAssetsSwapServerClient(cc grpc.ClientConnInterface) AssetsSwapServerClient { + return &assetsSwapServerClient{cc} +} + +func (c *assetsSwapServerClient) QuoteAssetLoopOut(ctx context.Context, in *QuoteAssetLoopOutRequest, opts ...grpc.CallOption) (*QuoteAssetLoopOutResponse, error) { + out := new(QuoteAssetLoopOutResponse) + err := c.cc.Invoke(ctx, "/looprpc.AssetsSwapServer/QuoteAssetLoopOut", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *assetsSwapServerClient) ListAvailableAssets(ctx context.Context, in *ListAvailableAssetsRequest, opts ...grpc.CallOption) (*ListAvailableAssetsResponse, error) { + out := new(ListAvailableAssetsResponse) + err := c.cc.Invoke(ctx, "/looprpc.AssetsSwapServer/ListAvailableAssets", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *assetsSwapServerClient) RequestAssetLoopOut(ctx context.Context, in *RequestAssetLoopOutRequest, opts ...grpc.CallOption) (*RequestAssetLoopOutResponse, error) { + out := new(RequestAssetLoopOutResponse) + err := c.cc.Invoke(ctx, "/looprpc.AssetsSwapServer/RequestAssetLoopOut", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *assetsSwapServerClient) PollAssetLoopOutProof(ctx context.Context, in *PollAssetLoopOutProofRequest, opts ...grpc.CallOption) (*PollAssetLoopOutProofResponse, error) { + out := new(PollAssetLoopOutProofResponse) + err := c.cc.Invoke(ctx, "/looprpc.AssetsSwapServer/PollAssetLoopOutProof", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *assetsSwapServerClient) RequestAssetBuy(ctx context.Context, in *RequestAssetBuyRequest, opts ...grpc.CallOption) (*RequestAssetBuyResponse, error) { + out := new(RequestAssetBuyResponse) + err := c.cc.Invoke(ctx, "/looprpc.AssetsSwapServer/RequestAssetBuy", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *assetsSwapServerClient) RequestMusig2Sweep(ctx context.Context, in *RequestMusig2SweepRequest, opts ...grpc.CallOption) (*RequestMusig2SweepResponse, error) { + out := new(RequestMusig2SweepResponse) + err := c.cc.Invoke(ctx, "/looprpc.AssetsSwapServer/RequestMusig2Sweep", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// AssetsSwapServerServer is the server API for AssetsSwapServer service. +// All implementations must embed UnimplementedAssetsSwapServerServer +// for forward compatibility +type AssetsSwapServerServer interface { + // QuoteAssetLoopOut requests a quote for an asset loop out swap from the + // server. + QuoteAssetLoopOut(context.Context, *QuoteAssetLoopOutRequest) (*QuoteAssetLoopOutResponse, error) + // ListAvailableAssets returns the list of assets that the server supports. + ListAvailableAssets(context.Context, *ListAvailableAssetsRequest) (*ListAvailableAssetsResponse, error) + // RequestAssetLoopOut requests an asset loop out swap from the server. + RequestAssetLoopOut(context.Context, *RequestAssetLoopOutRequest) (*RequestAssetLoopOutResponse, error) + // PollAssetLoopOutProof requests the server to poll for the proof of the + // asset loop out swap. + PollAssetLoopOutProof(context.Context, *PollAssetLoopOutProofRequest) (*PollAssetLoopOutProofResponse, error) + // RequestAssetBuy requests an asset buy swap from the server. This + // requires an already confirmed asset output on chain. + RequestAssetBuy(context.Context, *RequestAssetBuyRequest) (*RequestAssetBuyResponse, error) + // RequestMusig2Sweep requests a musig2 sweep from the server. + RequestMusig2Sweep(context.Context, *RequestMusig2SweepRequest) (*RequestMusig2SweepResponse, error) + mustEmbedUnimplementedAssetsSwapServerServer() +} + +// UnimplementedAssetsSwapServerServer must be embedded to have forward compatible implementations. +type UnimplementedAssetsSwapServerServer struct { +} + +func (UnimplementedAssetsSwapServerServer) QuoteAssetLoopOut(context.Context, *QuoteAssetLoopOutRequest) (*QuoteAssetLoopOutResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method QuoteAssetLoopOut not implemented") +} +func (UnimplementedAssetsSwapServerServer) ListAvailableAssets(context.Context, *ListAvailableAssetsRequest) (*ListAvailableAssetsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListAvailableAssets not implemented") +} +func (UnimplementedAssetsSwapServerServer) RequestAssetLoopOut(context.Context, *RequestAssetLoopOutRequest) (*RequestAssetLoopOutResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method RequestAssetLoopOut not implemented") +} +func (UnimplementedAssetsSwapServerServer) PollAssetLoopOutProof(context.Context, *PollAssetLoopOutProofRequest) (*PollAssetLoopOutProofResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method PollAssetLoopOutProof not implemented") +} +func (UnimplementedAssetsSwapServerServer) RequestAssetBuy(context.Context, *RequestAssetBuyRequest) (*RequestAssetBuyResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method RequestAssetBuy not implemented") +} +func (UnimplementedAssetsSwapServerServer) RequestMusig2Sweep(context.Context, *RequestMusig2SweepRequest) (*RequestMusig2SweepResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method RequestMusig2Sweep not implemented") +} +func (UnimplementedAssetsSwapServerServer) mustEmbedUnimplementedAssetsSwapServerServer() {} + +// UnsafeAssetsSwapServerServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to AssetsSwapServerServer will +// result in compilation errors. +type UnsafeAssetsSwapServerServer interface { + mustEmbedUnimplementedAssetsSwapServerServer() +} + +func RegisterAssetsSwapServerServer(s grpc.ServiceRegistrar, srv AssetsSwapServerServer) { + s.RegisterService(&AssetsSwapServer_ServiceDesc, srv) +} + +func _AssetsSwapServer_QuoteAssetLoopOut_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QuoteAssetLoopOutRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AssetsSwapServerServer).QuoteAssetLoopOut(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/looprpc.AssetsSwapServer/QuoteAssetLoopOut", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AssetsSwapServerServer).QuoteAssetLoopOut(ctx, req.(*QuoteAssetLoopOutRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AssetsSwapServer_ListAvailableAssets_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListAvailableAssetsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AssetsSwapServerServer).ListAvailableAssets(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/looprpc.AssetsSwapServer/ListAvailableAssets", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AssetsSwapServerServer).ListAvailableAssets(ctx, req.(*ListAvailableAssetsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AssetsSwapServer_RequestAssetLoopOut_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RequestAssetLoopOutRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AssetsSwapServerServer).RequestAssetLoopOut(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/looprpc.AssetsSwapServer/RequestAssetLoopOut", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AssetsSwapServerServer).RequestAssetLoopOut(ctx, req.(*RequestAssetLoopOutRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AssetsSwapServer_PollAssetLoopOutProof_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PollAssetLoopOutProofRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AssetsSwapServerServer).PollAssetLoopOutProof(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/looprpc.AssetsSwapServer/PollAssetLoopOutProof", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AssetsSwapServerServer).PollAssetLoopOutProof(ctx, req.(*PollAssetLoopOutProofRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AssetsSwapServer_RequestAssetBuy_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RequestAssetBuyRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AssetsSwapServerServer).RequestAssetBuy(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/looprpc.AssetsSwapServer/RequestAssetBuy", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AssetsSwapServerServer).RequestAssetBuy(ctx, req.(*RequestAssetBuyRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AssetsSwapServer_RequestMusig2Sweep_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RequestMusig2SweepRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AssetsSwapServerServer).RequestMusig2Sweep(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/looprpc.AssetsSwapServer/RequestMusig2Sweep", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AssetsSwapServerServer).RequestMusig2Sweep(ctx, req.(*RequestMusig2SweepRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// AssetsSwapServer_ServiceDesc is the grpc.ServiceDesc for AssetsSwapServer service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var AssetsSwapServer_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "looprpc.AssetsSwapServer", + HandlerType: (*AssetsSwapServerServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "QuoteAssetLoopOut", + Handler: _AssetsSwapServer_QuoteAssetLoopOut_Handler, + }, + { + MethodName: "ListAvailableAssets", + Handler: _AssetsSwapServer_ListAvailableAssets_Handler, + }, + { + MethodName: "RequestAssetLoopOut", + Handler: _AssetsSwapServer_RequestAssetLoopOut_Handler, + }, + { + MethodName: "PollAssetLoopOutProof", + Handler: _AssetsSwapServer_PollAssetLoopOutProof_Handler, + }, + { + MethodName: "RequestAssetBuy", + Handler: _AssetsSwapServer_RequestAssetBuy_Handler, + }, + { + MethodName: "RequestMusig2Sweep", + Handler: _AssetsSwapServer_RequestMusig2Sweep_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "assets.proto", +} diff --git a/utils/listeners.go b/utils/listeners.go new file mode 100644 index 000000000..54716d8d3 --- /dev/null +++ b/utils/listeners.go @@ -0,0 +1,257 @@ +package utils + +import ( + "context" + "sync" + + "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lightninglabs/lndclient" + "github.com/lightningnetwork/lnd/chainntnfs" + "github.com/lightningnetwork/lnd/lntypes" +) + +// ExpiryManager is a manager for block height expiry events. +type ExpiryManager struct { + chainNotifier lndclient.ChainNotifierClient + + expiryHeightMap map[[32]byte]int32 + expiryFuncMap map[[32]byte]func() + + currentBlockHeight int32 + + sync.Mutex +} + +// NewExpiryManager creates a new expiry manager. +func NewExpiryManager( + chainNotifier lndclient.ChainNotifierClient) *ExpiryManager { + + return &ExpiryManager{ + chainNotifier: chainNotifier, + expiryHeightMap: make(map[[32]byte]int32), + expiryFuncMap: make(map[[32]byte]func()), + } +} + +// Start starts the expiry manager and listens for block height notifications. +func (e *ExpiryManager) Start(ctx context.Context, startingBlockHeight int32, +) error { + + e.Lock() + e.currentBlockHeight = startingBlockHeight + e.Unlock() + + log.Debugf("Starting expiry manager at height %d", startingBlockHeight) + defer log.Debugf("Expiry manager stopped") + + blockHeightChan, errChan, err := e.chainNotifier.RegisterBlockEpochNtfn( + ctx, + ) + if err != nil { + return err + } + + for { + select { + case blockHeight := <-blockHeightChan: + + log.Debugf("Received block height %d", blockHeight) + + e.Lock() + e.currentBlockHeight = blockHeight + e.Unlock() + + e.checkExpiry(blockHeight) + + case err := <-errChan: + log.Debugf("Expiry manager error") + return err + + case <-ctx.Done(): + log.Debugf("Expiry manager stopped") + return nil + } + } +} + +// GetBlockHeight returns the current block height. +func (e *ExpiryManager) GetBlockHeight() int32 { + e.Lock() + defer e.Unlock() + + return e.currentBlockHeight +} + +// checkExpiry checks if any swaps have expired and calls the expiry function if +// they have. +func (e *ExpiryManager) checkExpiry(blockHeight int32) { + e.Lock() + defer e.Unlock() + + for swapHash, expiryHeight := range e.expiryHeightMap { + if blockHeight >= expiryHeight { + expiryFunc := e.expiryFuncMap[swapHash] + go expiryFunc() + + delete(e.expiryHeightMap, swapHash) + delete(e.expiryFuncMap, swapHash) + } + } +} + +// SubscribeExpiry subscribes to an expiry event for a swap. If the expiry height +// has already been reached, the expiryFunc is not called and the function +// returns true. Otherwise, the expiryFunc is called when the expiry height is +// reached and the function returns false. +func (e *ExpiryManager) SubscribeExpiry(swapHash [32]byte, + expiryHeight int32, expiryFunc func()) bool { + + e.Lock() + defer e.Unlock() + + if e.currentBlockHeight >= expiryHeight { + return true + } + + log.Debugf("Subscribing to expiry for swap %x at height %d", + swapHash, expiryHeight) + + e.expiryHeightMap[swapHash] = expiryHeight + e.expiryFuncMap[swapHash] = expiryFunc + + return false +} + +// SubscribeInvoiceManager is a manager for invoice subscription events. +type SubscribeInvoiceManager struct { + invoicesClient lndclient.InvoicesClient + + subscribers map[[32]byte]struct{} + + sync.Mutex +} + +// NewSubscribeInvoiceManager creates a new subscribe invoice manager. +func NewSubscribeInvoiceManager( + invoicesClient lndclient.InvoicesClient) *SubscribeInvoiceManager { + + return &SubscribeInvoiceManager{ + invoicesClient: invoicesClient, + subscribers: make(map[[32]byte]struct{}), + } +} + +// SubscribeInvoice subscribes to invoice events for a swap hash. The update +// callback is called when the invoice is updated and the error callback is +// called when an error occurs. +func (s *SubscribeInvoiceManager) SubscribeInvoice(ctx context.Context, + invoiceHash lntypes.Hash, callback func(lndclient.InvoiceUpdate, error), +) error { + + s.Lock() + defer s.Unlock() + // If we already have a subscriber for this swap hash, return early. + if _, ok := s.subscribers[invoiceHash]; ok { + return nil + } + + log.Debugf("Subscribing to invoice %v", invoiceHash) + + updateChan, errChan, err := s.invoicesClient.SubscribeSingleInvoice( + ctx, invoiceHash, + ) + if err != nil { + return err + } + + s.subscribers[invoiceHash] = struct{}{} + + go func() { + for { + select { + case update := <-updateChan: + callback(update, nil) + + case err := <-errChan: + callback(lndclient.InvoiceUpdate{}, err) + delete(s.subscribers, invoiceHash) + return + + case <-ctx.Done(): + delete(s.subscribers, invoiceHash) + return + } + } + }() + + return nil +} + +// TxSubscribeConfirmationManager is a manager for transaction confirmation +// subscription events. +type TxSubscribeConfirmationManager struct { + chainNotifier lndclient.ChainNotifierClient + + subscribers map[[32]byte]struct{} + + sync.Mutex +} + +// NewTxSubscribeConfirmationManager creates a new transaction confirmation +// subscription manager. +func NewTxSubscribeConfirmationManager(chainNtfn lndclient.ChainNotifierClient, +) *TxSubscribeConfirmationManager { + + return &TxSubscribeConfirmationManager{ + chainNotifier: chainNtfn, + subscribers: make(map[[32]byte]struct{}), + } +} + +// SubscribeTxConfirmation subscribes to transaction confirmation events for a +// swap hash. The callback is called when the transaction is confirmed or an +// error occurs. +func (t *TxSubscribeConfirmationManager) SubscribeTxConfirmation( + ctx context.Context, swapHash lntypes.Hash, txid *chainhash.Hash, + pkscript []byte, numConfs int32, heightHint int32, + cb func(*chainntnfs.TxConfirmation, error)) error { + + t.Lock() + defer t.Unlock() + + // If we already have a subscriber for this swap hash, return early. + if _, ok := t.subscribers[swapHash]; ok { + return nil + } + + log.Debugf("Subscribing to tx confirmation for swap %v", swapHash) + + confChan, errChan, err := t.chainNotifier.RegisterConfirmationsNtfn( + ctx, txid, pkscript, numConfs, heightHint, + ) + if err != nil { + return err + } + + t.subscribers[swapHash] = struct{}{} + + go func() { + for { + select { + case conf := <-confChan: + cb(conf, nil) + + case err := <-errChan: + cb(nil, err) + delete(t.subscribers, swapHash) + return + + case <-ctx.Done(): + delete(t.subscribers, swapHash) + return + } + } + }() + + return nil +} diff --git a/utils/log.go b/utils/log.go new file mode 100644 index 000000000..0185117e1 --- /dev/null +++ b/utils/log.go @@ -0,0 +1,26 @@ +package utils + +import ( + "github.com/btcsuite/btclog" + "github.com/lightningnetwork/lnd/build" +) + +// Subsystem defines the sub system name of this package. +const Subsystem = "UTILS" + +// log is a logger that is initialized with no output filters. This +// means the package will not perform any logging by default until the caller +// requests it. +var log btclog.Logger + +// The default amount of logging is none. +func init() { + UseLogger(build.NewSubLogger(Subsystem, nil)) +} + +// UseLogger uses a specified Logger to output package logging info. +// This should be used in preference to SetLogWriter if the caller is also +// using btclog. +func UseLogger(logger btclog.Logger) { + log = logger +}