Since Limenka 0.17, an RPC interface exists for Partially Signed Limenka Transactions (PSBTs, as specified in BIP 174).
This document describes the overall workflow for producing signed transactions through the use of PSBT, and the specific RPC commands used in typical scenarios.
PSBT is an interchange format for Limenka transactions that are not fully signed yet, together with relevant metadata to help entities work towards signing it. It is intended to simplify workflows where multiple parties need to cooperate to produce a transaction. Examples include hardware wallets, multisig setups, and CoinJoin transactions.
Overall, the construction of a fully signed Limenka transaction goes through the following steps:
a PSBT that contains certain inputs and outputs, but no additional metadata.
the transaction to the PSBT. They also add information about the scripts and public keys involved in each of the inputs (and possibly outputs) of the PSBT.
agree with the transaction. They can use amount information from the UTXOs to assess the values and fees involved. If they agree, they produce a partial signature for the inputs for which they have relevant key(s).
possibly script information into a final scriptSig and/or scriptWitness.
from a PSBT for which all inputs are finalized.
Generally, each of the above (excluding Creator and Extractor) will simply add more and more data to a particular PSBT, until all inputs are fully signed. In a naive workflow, they all have to operate sequentially, passing the PSBT from one to the next, until the Extractor can convert it to a real transaction. In order to permit parallel operation, Combiners can be employed which merge metadata from different PSBTs for the same unsigned transaction.
The names above in bold are the names of the roles defined in BIP174. They're useful in understanding the underlying steps, but in practice, software and hardware implementations will typically implement multiple roles simultaneously.
unsigned raw transaction to PSBT format. It ignores existing signatures.
outputs and converts them to a PSBT with no additional information. It is
equivalent to calling createrawtransaction followed by converttopsbt.
PSBT with the specified inputs and outputs, adds additional inputs and change
to it to balance it out, and adds relevant metadata. In particular, for inputs
that the wallet knows about (counting towards its normal or watch-only
balance), UTXO information will be added. For outputs and inputs with UTXO
information present, key and script information will be added which the wallet
knows about. It is equivalent to running createrawtransaction, followed by
fundrawtransaction, and converttopsbt.
input a PSBT, adds UTXO, key, and script data to inputs and outputs that miss it, and optionally signs inputs. Where possible it also finalizes the partial signatures.
as input a PSBT and a list of descriptors. It updates SegWit inputs with information available from the UTXO set and the mempool and signs the inputs using the provided descriptors. Where possible it also finalizes the partial signatures.
to include information available from the UTXO set (works only for SegWit inputs).
partial signatures, and if all inputs are finalized, converts the result to a
fully signed transaction which can be broadcast with sendrawtransaction.
can be used at any point in the workflow to merge information added to different versions of the same PSBT. In particular it is useful to combine the output of multiple Updaters or Signers.
concatenating the inputs and outputs. This can be used to construct CoinJoin transactions.
a PSBT in human-readable form, as well as compute its eventual fee if known.
current status of its inputs, the next step in the workflow if known, and if possible, computes the fee of the resulting transaction and estimates the final weight and feerate.
For a quick start see Basic M-of-N multisig example using descriptor wallets and PSBTs. If you are using legacy wallets feel free to continue with the example provided here.
Alice, Bob, and Carol want to create a 2-of-3 multisig address. They're all using
Limenka. We assume their wallets only contain the multisig funds. In case
they also have a personal wallet, this can be accomplished through the
multiwallet feature - possibly resulting in a need to add -rpcwallet=name to
the command line in case limenka-cli is used.
Setup:
getnewaddress to create a new address; call these addressesAalice, Abob, and Acarol.
getaddressinfo "X", with X their respective address, andremember the corresponding public keys. Call these public keys Kalice, Kbob, and Kcarol.
addmultisigaddress 2 ["Kalice","Kbob","Kcarol"] to teachtheir wallet about the multisig script. Call the address produced by this command Amulti. They may be required to explicitly specify the same addresstype option each, to avoid constructing different versions due to differences in configuration.
importaddress "Amulti" "" false to make their wallets treatpayments to Amulti as contributing to the watch-only balance.
createmultisig 2 ["Kalice","Kbob","Kcarol"], and expecting Amulti as
output. Again, it may be necessary to explicitly specify the addresstype
in order to get a result that matches. This command won't enable them to
initiate transactions later, however.
Later, when V BTC has been received on Amulti, and Bob and Carol want to move the coins in their entirety to address Asend, with no change. Alice does not need to be involved.
walletcreatefundedpsbt [] {"Asend":V} 0 {"subtractFeeFromOutputs":[0], "includeWatching":true}.
We call the resulting PSBT P. P does not contain any signatures.
walletprocesspsbt "P", and gives the resulting PSBT P2 to Bob.
decodepsbt "P2" to determine if the transaction has indeed just the expected input, and an output to Asend, and the fee is
reasonable. If he agrees, he calls walletprocesspsbt "P2" to sign. The
resulting PSBT P3 contains both Carol's and Bob's signature.
finalizepsbt "P3" to extract a fully signed transactionT.
sendrawtransaction "T".In case there are more signers, it may be advantageous to let them all sign in
parallel, rather than passing the PSBT from one signer to the next one. In the
above example this would translate to Carol handing a copy of P to each signer
separately. They can then all invoke walletprocesspsbt "P", and end up with
their individually-signed PSBT structures. They then all send those back to
Carol (or anyone) who can combine them using combinepsbt. The last two steps
(finalizepsbt and sendrawtransaction) remain unchanged.