github.com/mit-dci/lit@v0.0.0-20221102210550-8c3d3b49f2ce/qln/basewallet.go (about)

     1  package qln
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/mit-dci/lit/btcutil/chaincfg/chainhash"
     7  	"github.com/mit-dci/lit/coinparam"
     8  	"github.com/mit-dci/lit/crypto/koblitz"
     9  	"github.com/mit-dci/lit/lnutil"
    10  	"github.com/mit-dci/lit/portxo"
    11  	"github.com/mit-dci/lit/uspv"
    12  	"github.com/mit-dci/lit/wire"
    13  )
    14  
    15  // The UWallet interface are the functions needed to work with the LnNode
    16  // Verbs are from the perspective of the LnNode, not the underlying wallet
    17  type UWallet interface {
    18  	// Ask for a pubkey based on a bip32 path
    19  	GetPub(k portxo.KeyGen) *koblitz.PublicKey
    20  
    21  	// Have GetPriv for now.  Maybe later get rid of this and have
    22  	// the underlying wallet sign?
    23  	GetPriv(k portxo.KeyGen) (*koblitz.PrivateKey, error)
    24  
    25  	// Send a tx out to the network.  Maybe could replace?  Maybe not.
    26  	// Needed for channel break / cooperative close.  Maybe grabs.
    27  
    28  	// export the chainhook that the UWallet uses, for pushTx and fullblock
    29  	ExportHook() uspv.ChainHook
    30  
    31  	PushTx(tx *wire.MsgTx) error
    32  
    33  	// ExportUtxo gives a utxo to the underlying wallet; that wallet saves it
    34  	// and can spend it later.  Doesn't return errors; error will exist only in
    35  	// base wallet.
    36  	ExportUtxo(txo *portxo.PorTxo)
    37  
    38  	// MaybeSend makes an unsigned tx, populated with inputs and outputs.
    39  	// The specified txouts are in there somewhere.
    40  	// Only segwit txins are in the generated tx. (txid won't change)
    41  	// There's probably an extra change txout in there which is OK.
    42  	// The inputs are "frozen" until ReallySend / NahDontSend / program restart.
    43  	// Retruns the txid, and then the txout indexes of the specified txos.
    44  	// The outpoints returned will all have the same hash (txid)
    45  	// So if you (as usual) just give one txo, you basically get back an outpoint.
    46  	MaybeSend(txos []*wire.TxOut, onlyWit bool) ([]*wire.OutPoint, error)
    47  
    48  	// ReallySend really sends the transaction specified previously in MaybeSend.
    49  	// Underlying wallet does all needed signing.
    50  	// Once you call ReallySend, the outpoint is tracked and responses are
    51  	// sent through LetMeKnow
    52  	ReallySend(txid *chainhash.Hash) error
    53  
    54  	// NahDontSend cancels the MaybeSend transaction.
    55  	NahDontSend(txid *chainhash.Hash) error
    56  
    57  	// Return a new address
    58  	NewAdr() ([20]byte, error)
    59  
    60  	// Dump all the utxos in the sub wallet
    61  	UtxoDump() ([]*portxo.PorTxo, error)
    62  
    63  	// Dump all the addresses the sub wallet is watching
    64  	AdrDump() ([][20]byte, error)
    65  
    66  	// Return current height the wallet is synced to
    67  	CurrentHeight() int32
    68  
    69  	// This is redundand... just use UtxoDump and figure it out yourself.
    70  	// Feels like helper functions shouldn't be in the interface.
    71  	// how much utxo the wallet has -- only confirmed segwit outputs
    72  	//	HowMuchWitConf() int64
    73  
    74  	// How much utxo the sub wallet has, including non-segwit, unconfirmed, immature
    75  	//	HowMuchTotal() int64
    76  
    77  	// WatchThis tells the basewallet to watch an outpoint
    78  	WatchThis(wire.OutPoint) error
    79  
    80  	// StopWatchingThis tells the basewallet to stop watching an outpoint
    81  	StopWatchingThis(wire.OutPoint) error
    82  
    83  	// LetMeKnow opens the chan where OutPointEvent flows from the underlying
    84  	// wallet up to the LN module.
    85  	LetMeKnow() chan lnutil.OutPointEvent
    86  
    87  	// LetMeKnowHeight opens the chan where the blockheight flows from the underlying
    88  	// wallet up to the LN module. Used for monitoring HTLC timeouts
    89  	LetMeKnowHeight() chan lnutil.HeightEvent
    90  
    91  	// Ask for network parameters
    92  	Params() *coinparam.Params
    93  
    94  	// Get current fee rate.
    95  	Fee() int64
    96  
    97  	// Set fee rate
    98  	SetFee(int64) int64
    99  
   100  	// ===== TESTING / SPAMMING ONLY, these funcs will not be in the real interface
   101  	// Sweep sends lots of txs (uint32 of them) to the specified address.
   102  	Sweep([]byte, uint32) ([]*chainhash.Hash, error)
   103  
   104  	PickUtxos(amtWanted, outputByteSize,
   105  		feePerByte int64, ow bool) (portxo.TxoSliceByBip69, int64, error)
   106  
   107  	SignMyInputs(tx *wire.MsgTx) error
   108  
   109  	DirectSendTx(tx *wire.MsgTx) error
   110  }
   111  
   112  // GetUsePub gets a pubkey from the base wallet, but first modifies
   113  // the "use" step
   114  func (nd *LitNode) GetUsePub(k portxo.KeyGen, use uint32) (pubArr [33]byte, err error) {
   115  	coin := k.Step[1] & 0x7fffffff // de-assert MSB
   116  	if nd.SubWallet[coin] == nil {
   117  		err = fmt.Errorf("coin type %d not in wallet", k.Step[1]&0x7fffffff)
   118  		return // fail if that wallet isn't attached
   119  	}
   120  	k.Step[2] = use
   121  	pub := nd.SubWallet[coin].GetPub(k)
   122  	copy(pubArr[:], pub.SerializeCompressed())
   123  	return
   124  }
   125  
   126  // GetElkremRoot returns the Elkrem root for a given key path
   127  // gets the use-pub for elkrems and hashes it.
   128  // A little weird because it's a "pub" key you shouldn't reveal.
   129  // either do this or export privkeys... or signing empty txs or something.
   130  func (nd *LitNode) GetElkremRoot(k portxo.KeyGen) (chainhash.Hash, error) {
   131  	pubArr, err := nd.GetUsePub(k, UseChannelElkrem)
   132  	if err != nil {
   133  		var empty [32]byte
   134  		return empty, err
   135  	}
   136  	return chainhash.DoubleHashH(pubArr[:]), nil
   137  }