Wiki Home

Taproot support



Introduction

Taproot scripts (P2TR) are a new SegWit version 1 output type that is more efficient in terms of verification computational requirements, it is in many cases cheaper in terms of fees, uses schnorr signatures (which allows us to do some extra magic easierly) and solves few problems that allows for example participate in coinjoins with hardware wallets, among other many goodnesses.

Goal

To support pay-to-taproot in a fullt-transparent way so users can take advantage of the benefits without paying virtually any cost. This is becase supporting pay-to-taproot scripts would allow us to have creaper coinjoins, what is in general a good things; coinjoin with hardware wallets and implement solutions that involve DH key sharing (like SNICKER just to mention one random example)

Scope

End-to-end support needs changes in the compact filters, KeyManager class (KeyChain class and DestinationProvider class), TransactionProcessor class, Hardware wallet integration, CoinjoinClient class, AmountDecomposer class and PayJoinClient class.

Also, it will require tiny changes in WasabiJsonRpcServer class, HdPubKey class, TransactionFactory class, AliceClient class, ArenaClient class.

Finally, quite a lot of things should be removed from the GUI because they are wrong, unconvenient or simply make no sense. However, in some cases we would want to use also some extra information to improve the quality of what we providing.

Receving taproot transactions

It is necessary to be able to generate taproot scripts, ideally for both internal and external usage, what requires changes in the KeyManager. The new script generated must be recognized in the incoming transactions, what requires Compact Filters to include this new script types and in the TransactionProcessor to recognize the received transaction could be relevant. Once these three things are in place the wallet’s balance can be calculated taking into account transactions comming in/going out the wallet.

Auto-upgraded wallets

Current wallet .json files will be upgraded automatically to support taproot by generating m/86h keys by adding new fields TaprootExtPubKey and TaprootAccountKeyPath. In the case of the TaprootExtPubKey field it needs to be generated from the master extended private key which is in protected with a password (at least in many cases) so, it is only possible to do after a correct login because at that moment we know the password to decrypt the key.

Read-Only wallets

Read-only wallets don’t have secret material and for that reason it is impossible to derive the new extended public key. In case of RO wallets generated by importing HWs then it is possible to implement a mechanism for upgrading by querying the device for the taproot extpubkey while in case of simply RO wallets created manually the process of upgrading have to be done manually too.

Sending taproot transactions

The wallet should be able to send transactions containing the new type of script, this means that the fee calculation needs to have the script type into account (the taproot inputs size and the taproot output size) and be able to sign the transaction which hash includes data from spending transaction outputs (such as amounts).

Also, most of the times a transaction uses a change output that could need to consider the script type too. Other algorithms invoved in sending needs to take the script type (or the size/fee) in order to select the combination of coins (manual coinjoin selection should display the script type because it is important in that context)

Coinjoining with taproot

Given a coinjoin is a kind of self-spending transaction, it requires the same changes that we saw above. However there are addictional considerations to take into account regarding to anonscore calculation and input selection involving different script types, as well as cost function.

GUI

The GUI currently display nonsenses like max gap for internal external (segwit) keys and that should be removed. The same happends with output descriptors which should be moved to rpc because it is somehow an advance-user-only feature, at leat for now.

In Wallet Info we are displaying segwit derivation path and extpubkey. We should display the same for taproot scripts.

During recovery process the GUI allows the user to specify a custom derivation path for segwit keys (crazy) and we should remove it. Things like the alert notification after the minimum gap limit is overreached, that was never ported from ww1 and remains an incompleted feature, has to be removed.

The coin selection page/coins viewer would need to display the script type.

Hardware wallets

Currently Wasabi, when imporing wallets from HW only uses the segwit derivation path but that can be improved to cover taproot too. In fact, in the context of future usage of wabisabi by Trezor HW it is important that Wasabi can at least display the same segwit and taproot keys/balance.

Something similar happens with ColdCard wallet because that wallet generates an skeleton Wasabi wallet .json file containing only the segwit path but they could also include the extended key path taproot.

Backward compatibility

By it nature this is not backward compatible in the sense that one you received a taproot payment you cannot downgrade tour wallet without creating confusion on the user. The issues were explained here: https://github.com/zkSNACKs/WalletWasabi/pull/8994#issuecomment-1227348740

Development

The amount of work required to cover all the details is too big to implement in only one Big Bang Pull request so, the idea is to split the development in tree stages:

Supporting taproot internally

To Send, receive and coinjoin with taproot scripts in a fully transparent way comes first. The goal is to have the plumbing working well and no more than that. No changes in UI, no address hardest questions nor small details, only implement what must be implemented.

Coinjoin startegies

Update AmountDecomposer to understand script types and do the same for the coin selection algorithm for coinjoins. Review automatic coin selection for spending (BnB too). Make sure payjoin payments can support taproot (or prevent using taproot). Review Hardware wallet importing code to create the new keymanager fields too.

Update GUI

This consists mostly in removing useless things but also in displaying new info (or move that info somewhere else when it is too messy).

Questions