Signers
In LWK, the management of private keys is delegated to a specialized component called Signer.
The primary tasks of a signer are:
- provide
xpubs, which are used to create wallets - sign transactions
Types of Signers
LWK has two signer types:
- Software Signers: store the private keys in memory. This is the simplest signer to integrate and interact with.
- Hardware Signers: LWK provides specific integrations for hardware wallets, such as the Blockstream Jade. These signers keep the private keys completely isolated from the computer.
While hardware signers are inherently more secure, LWK's design allows you to enhance the security of software signers as well. For example, a software signer can be run on an isolated machine or a mobile app might store the mnemonic (seed) encrypted, only decrypting it when a signature is required.
This guide will focus on software signers. For more details on the supported Jade hardware signer, see the lwk_jade crate.
Create Signer
To create a signer you need a mnemonic.
You can generate a new one with bip39::Mnemonic::generate(12).
Then you can create a software signer with SwSigner::new_with_network().
use lwk_signer::{bip39::Mnemonic, SwSigner};
let mnemonic = Mnemonic::generate(12)?;
let network = lwk_common::Network::TestnetLiquid;
let signer = SwSigner::new_with_network(&mnemonic.to_string(), network)?;
mnemonic = Mnemonic.from_random(12)
network = Network.testnet()
signer = Signer(mnemonic, network)
const mnemonic = lwk.Mnemonic.fromRandom(12);
const network = lwk.Network.testnet();
const signer = new lwk.Signer(mnemonic, network);
mnemonic, err := lwk.MnemonicFromRandom(12)
if err != nil {
log.Fatal(err)
}
network := lwk.NetworkTestnet()
signer, err := lwk.NewSigner(mnemonic, network)
if err != nil {
log.Fatal(err)
}
Get Xpub
Once you have a signer you need to get some an extended public key (xpub),
which can be used to create a wallet that requires signature from the signer.
The xpub is obtained with Signer::keyorigin_xpub(bip, is_mainnet), which also includes the keyorigin information: signer fingerprint and derivation path from master key to the returned xpub, e.g. [ffffffff/84h/1h/0h]xpub....
let bip = lwk_common::Bip::Bip84;
let xpub = signer.keyorigin_xpub(bip, network.is_mainnet());
xpub = signer.keyorigin_xpub(Bip.new_bip84())
const xpub = signer.keyoriginXpub(lwk.Bip.bip84());
xpub, err := signer.KeyoriginXpub(lwk.BipNewBip84())
if err != nil {
log.Fatal(err)
}
For particularly simple cases, such as single sig, you can get the CT descriptor directly from the signer, for instance using Signer::wpkh_slip77_descriptor().
Next: Watch-Only Wallets