Documentation ¶
Index ¶
- Constants
- Variables
- func DisableLog()
- func HealthCheck(cfg *lncfg.RemoteSigner, timeout time.Duration) func() error
- func UseLogger(logger btclog.Logger)
- type RPCKeyRing
- func (r *RPCKeyRing) ComputeInputScript(tx *wire.MsgTx, signDesc *input.SignDescriptor) (*input.Script, error)
- func (r *RPCKeyRing) DeriveKey(keyLoc keychain.KeyLocator) (keychain.KeyDescriptor, error)
- func (r *RPCKeyRing) DeriveNextKey(keyFam keychain.KeyFamily) (keychain.KeyDescriptor, error)
- func (r *RPCKeyRing) DerivePrivKey(_ keychain.KeyDescriptor) (*btcec.PrivateKey, error)
- func (r *RPCKeyRing) ECDH(keyDesc keychain.KeyDescriptor, pubKey *btcec.PublicKey) ([32]byte, error)
- func (r *RPCKeyRing) FinalizePsbt(packet *psbt.Packet, _ string) error
- func (r *RPCKeyRing) MuSig2Cleanup(sessionID input.MuSig2SessionID) error
- func (r *RPCKeyRing) MuSig2CombineSig(sessionID input.MuSig2SessionID, partialSigs []*musig2.PartialSignature) (*schnorr.Signature, bool, error)
- func (r *RPCKeyRing) MuSig2CreateSession(bipVersion input.MuSig2Version, keyLoc keychain.KeyLocator, ...) (*input.MuSig2SessionInfo, error)
- func (r *RPCKeyRing) MuSig2RegisterNonces(sessionID input.MuSig2SessionID, pubNonces [][musig2.PubNonceSize]byte) (bool, error)
- func (r *RPCKeyRing) MuSig2Sign(sessionID input.MuSig2SessionID, msg [sha256.Size]byte, cleanUp bool) (*musig2.PartialSignature, error)
- func (r *RPCKeyRing) NewAddress(addrType lnwallet.AddressType, change bool, account string) (btcutil.Address, error)
- func (r *RPCKeyRing) SendOutputs(outputs []*wire.TxOut, feeRate chainfee.SatPerKWeight, minConfs int32, ...) (*wire.MsgTx, error)
- func (r *RPCKeyRing) SignMessage(keyLoc keychain.KeyLocator, msg []byte, doubleHash bool) (*ecdsa.Signature, error)
- func (r *RPCKeyRing) SignMessageCompact(keyLoc keychain.KeyLocator, msg []byte, doubleHash bool) ([]byte, error)
- func (r *RPCKeyRing) SignMessageSchnorr(keyLoc keychain.KeyLocator, msg []byte, doubleHash bool, taprootTweak []byte, ...) (*schnorr.Signature, error)
- func (r *RPCKeyRing) SignOutputRaw(tx *wire.MsgTx, signDesc *input.SignDescriptor) (input.Signature, error)
- func (r *RPCKeyRing) SignPsbt(packet *psbt.Packet) ([]uint32, error)
Constants ¶
const Subsystem = "RPWL"
Subsystem defines the logging code for this subsystem.
Variables ¶
var ( // ErrRemoteSigningPrivateKeyNotAvailable is the error that is returned // if an operation is requested from the RPC wallet that is not // supported in remote signing mode. ErrRemoteSigningPrivateKeyNotAvailable = errors.New("deriving " + "private key is not supported by RPC based key ring") )
Functions ¶
func DisableLog ¶
func DisableLog()
DisableLog disables all library log output. Logging output is disabled by default until UseLogger is called.
func HealthCheck ¶
func HealthCheck(cfg *lncfg.RemoteSigner, timeout time.Duration) func() error
HealthCheck returns a health check function for the given remote signing configuration.
Types ¶
type RPCKeyRing ¶
type RPCKeyRing struct { // WalletController is the embedded wallet controller of the watch-only // base wallet. We need to overwrite/shadow certain of the implemented // methods to make sure we can mirror them to the remote wallet. lnwallet.WalletController // contains filtered or unexported fields }
RPCKeyRing is an implementation of the SecretKeyRing interface that uses a local watch-only wallet for keeping track of addresses and transactions but delegates any signing or ECDH operations to a remote node through RPC.
func NewRPCKeyRing ¶
func NewRPCKeyRing(watchOnlyKeyRing keychain.SecretKeyRing, watchOnlyWalletController lnwallet.WalletController, remoteSigner *lncfg.RemoteSigner, netParams *chaincfg.Params) (*RPCKeyRing, error)
NewRPCKeyRing creates a new remote signing secret key ring that uses the given watch-only base wallet to keep track of addresses and transactions but delegates any signing or ECDH operations to the remove signer through RPC.
func (*RPCKeyRing) ComputeInputScript ¶
func (r *RPCKeyRing) ComputeInputScript(tx *wire.MsgTx, signDesc *input.SignDescriptor) (*input.Script, error)
ComputeInputScript generates a complete InputIndex for the passed transaction with the signature as defined within the passed SignDescriptor. This method should be capable of generating the proper input script for both regular p2wkh output and p2wkh outputs nested within a regular p2sh output.
NOTE: This method will ignore any tweak parameters set within the passed SignDescriptor as it assumes a set of typical script templates (p2wkh, np2wkh, BIP0086 p2tr, etc).
NOTE: This method is part of the input.Signer interface.
func (*RPCKeyRing) DeriveKey ¶
func (r *RPCKeyRing) DeriveKey( keyLoc keychain.KeyLocator) (keychain.KeyDescriptor, error)
DeriveKey attempts to derive an arbitrary key specified by the passed KeyLocator. This may be used in several recovery scenarios, or when manually rotating something like our current default node key.
NOTE: This method is part of the keychain.KeyRing interface.
func (*RPCKeyRing) DeriveNextKey ¶
func (r *RPCKeyRing) DeriveNextKey( keyFam keychain.KeyFamily) (keychain.KeyDescriptor, error)
DeriveNextKey attempts to derive the *next* key within the key family (account in BIP43) specified. This method should return the next external child within this branch.
NOTE: This method is part of the keychain.KeyRing interface.
func (*RPCKeyRing) DerivePrivKey ¶
func (r *RPCKeyRing) DerivePrivKey(_ keychain.KeyDescriptor) (*btcec.PrivateKey, error)
DerivePrivKey attempts to derive the private key that corresponds to the passed key descriptor. If the public key is set, then this method will perform an in-order scan over the key set, with a max of MaxKeyRangeScan keys. In order for this to work, the caller MUST set the KeyFamily within the partially populated KeyLocator.
NOTE: This method is part of the keychain.SecretKeyRing interface.
func (*RPCKeyRing) ECDH ¶
func (r *RPCKeyRing) ECDH(keyDesc keychain.KeyDescriptor, pubKey *btcec.PublicKey) ([32]byte, error)
ECDH performs a scalar multiplication (ECDH-like operation) between the target key descriptor and remote public key. The output returned will be the sha256 of the resulting shared point serialized in compressed format. If k is our private key, and P is the public key, we perform the following operation:
sx := k*P s := sha256(sx.SerializeCompressed())
NOTE: This method is part of the keychain.ECDHRing interface.
func (*RPCKeyRing) FinalizePsbt ¶
func (r *RPCKeyRing) FinalizePsbt(packet *psbt.Packet, _ string) error
FinalizePsbt expects a partial transaction with all inputs and outputs fully declared and tries to sign all inputs that belong to the specified account. Lnd must be the last signer of the transaction. That means, if there are any unsigned non-witness inputs or inputs without UTXO information attached or inputs without witness data that do not belong to lnd's wallet, this method will fail. If no error is returned, the PSBT is ready to be extracted and the final TX within to be broadcast.
NOTE: This method does NOT publish the transaction after it's been finalized successfully.
NOTE: This is a part of the WalletController interface.
NOTE: We need to overwrite this method because we need to redirect the call to ComputeInputScript to the RPC key ring's implementation. If we forward the call to the default WalletController implementation, we get an error since that wallet is watch-only. If we forward the call to the remote signer, we get an error because the signer doesn't know the UTXO information required in ComputeInputScript.
TODO(guggero): Refactor btcwallet to accept ComputeInputScript as a function parameter in FinalizePsbt so we can get rid of this code duplication.
func (*RPCKeyRing) MuSig2Cleanup ¶
func (r *RPCKeyRing) MuSig2Cleanup(sessionID input.MuSig2SessionID) error
MuSig2Cleanup removes a session from memory to free up resources.
func (*RPCKeyRing) MuSig2CombineSig ¶
func (r *RPCKeyRing) MuSig2CombineSig(sessionID input.MuSig2SessionID, partialSigs []*musig2.PartialSignature) (*schnorr.Signature, bool, error)
MuSig2CombineSig combines the given partial signature(s) with the local one, if it already exists. Once a partial signature of all participants is registered, the final signature will be combined and returned.
func (*RPCKeyRing) MuSig2CreateSession ¶
func (r *RPCKeyRing) MuSig2CreateSession(bipVersion input.MuSig2Version, keyLoc keychain.KeyLocator, pubKeys []*btcec.PublicKey, tweaks *input.MuSig2Tweaks, otherNonces [][musig2.PubNonceSize]byte, localNonces *musig2.Nonces) (*input.MuSig2SessionInfo, error)
MuSig2CreateSession creates a new MuSig2 signing session using the local key identified by the key locator. The complete list of all public keys of all signing parties must be provided, including the public key of the local signing key. If nonces of other parties are already known, they can be submitted as well to reduce the number of method calls necessary later on.
func (*RPCKeyRing) MuSig2RegisterNonces ¶
func (r *RPCKeyRing) MuSig2RegisterNonces(sessionID input.MuSig2SessionID, pubNonces [][musig2.PubNonceSize]byte) (bool, error)
MuSig2RegisterNonces registers one or more public nonces of other signing participants for a session identified by its ID. This method returns true once we have all nonces for all other signing participants.
func (*RPCKeyRing) MuSig2Sign ¶
func (r *RPCKeyRing) MuSig2Sign(sessionID input.MuSig2SessionID, msg [sha256.Size]byte, cleanUp bool) (*musig2.PartialSignature, error)
MuSig2Sign creates a partial signature using the local signing key that was specified when the session was created. This can only be called when all public nonces of all participants are known and have been registered with the session. If this node isn't responsible for combining all the partial signatures, then the cleanup parameter should be set, indicating that the session can be removed from memory once the signature was produced.
func (*RPCKeyRing) NewAddress ¶
func (r *RPCKeyRing) NewAddress(addrType lnwallet.AddressType, change bool, account string) (btcutil.Address, error)
NewAddress returns the next external or internal address for the wallet dictated by the value of the `change` parameter. If change is true, then an internal address should be used, otherwise an external address should be returned. The type of address returned is dictated by the wallet's capabilities, and may be of type: p2sh, p2wkh, p2wsh, etc. The account parameter must be non-empty as it determines which account the address should be generated from.
func (*RPCKeyRing) SendOutputs ¶
func (r *RPCKeyRing) SendOutputs(outputs []*wire.TxOut, feeRate chainfee.SatPerKWeight, minConfs int32, label string, strategy basewallet.CoinSelectionStrategy) (*wire.MsgTx, error)
SendOutputs funds, signs, and broadcasts a Bitcoin transaction paying out to the specified outputs. In the case the wallet has insufficient funds, or the outputs are non-standard, a non-nil error will be returned.
NOTE: This method requires the global coin selection lock to be held.
NOTE: This is a part of the WalletController interface.
NOTE: This method only signs with BIP49/84 keys.
func (*RPCKeyRing) SignMessage ¶
func (r *RPCKeyRing) SignMessage(keyLoc keychain.KeyLocator, msg []byte, doubleHash bool) (*ecdsa.Signature, error)
SignMessage attempts to sign a target message with the private key described in the key locator. If the target private key is unable to be found, then an error will be returned. The actual digest signed is the single or double SHA-256 of the passed message.
NOTE: This method is part of the keychain.MessageSignerRing interface.
func (*RPCKeyRing) SignMessageCompact ¶
func (r *RPCKeyRing) SignMessageCompact(keyLoc keychain.KeyLocator, msg []byte, doubleHash bool) ([]byte, error)
SignMessageCompact signs the given message, single or double SHA256 hashing it first, with the private key described in the key locator and returns the signature in the compact, public key recoverable format.
NOTE: This method is part of the keychain.MessageSignerRing interface.
func (*RPCKeyRing) SignMessageSchnorr ¶
func (r *RPCKeyRing) SignMessageSchnorr(keyLoc keychain.KeyLocator, msg []byte, doubleHash bool, taprootTweak []byte, tag []byte) (*schnorr.Signature, error)
SignMessageSchnorr attempts to sign a target message with the private key described in the key locator. If the target private key is unable to be found, then an error will be returned. The actual digest signed is the single or double SHA-256 of the passed message.
NOTE: This method is part of the keychain.MessageSignerRing interface.
func (*RPCKeyRing) SignOutputRaw ¶
func (r *RPCKeyRing) SignOutputRaw(tx *wire.MsgTx, signDesc *input.SignDescriptor) (input.Signature, error)
SignOutputRaw generates a signature for the passed transaction according to the data within the passed SignDescriptor.
NOTE: The resulting signature should be void of a sighash byte.
NOTE: This method is part of the input.Signer interface.
NOTE: This method only signs with BIP1017 (internal) keys!
func (*RPCKeyRing) SignPsbt ¶
func (r *RPCKeyRing) SignPsbt(packet *psbt.Packet) ([]uint32, error)
SignPsbt expects a partial transaction with all inputs and outputs fully declared and tries to sign all unsigned inputs that have all required fields (UTXO information, BIP32 derivation information, witness or sig scripts) set. If no error is returned, the PSBT is ready to be given to the next signer or to be finalized if lnd was the last signer.
NOTE: This RPC only signs inputs (and only those it can sign), it does not perform any other tasks (such as coin selection, UTXO locking or input/output/fee value validation, PSBT finalization). Any input that is incomplete will be skipped.