Closed dr-orlovsky closed 1 year ago
As mentioned in https://github.com/bitcoin-core/HWI/issues/706#issuecomment-1710194139, HWI does not support miniscript policies for the BitBox02, as the policy has to be sent to the BitBox02, and it is not part of PSBT (yet?) and HWI does not currently provide the API to send it separately. The policy that needs to be sent to the BitBox02 is following this BIP.
The Rust BitBox02 library on the other hand, which is being integrated into Rust async-hwi, does support miniscript policies already and could be a better choice for you.
To get support into HWI, we should open an issue there and discuss with the maintainers what a good way would be. Ideally the policy would be encoded in the PSBT itself, but afaik there is no standard around that yet.
Thank you for all the details. I will do an issue in HWI repo as you have suggested.
However, one more thing: it is not clear for me why we need to send the policy to the BitBox if the policy can be re-constructed using miniscript library from the PSBT_IN_WITNESS_SCRIPT
(for pre-taproot) and PSBT_IN_TAP_LEAF_SCRIPT
(for taproot), which is already present in the PSBT - and together with key derivation fields (like PSBT_GLOBAL_XPUB
, PSBT_IN_BIP32_DERIVATION
, PSBT_IN_TAP_BIP32_DERIVATION
, PSBT_IN_TAP_INTERNAL_KEY
) the wallet ALREADY has all information to register the policy.
So my point is that no additional PSBT fields or call to API to send it separately should be required. The algorithm is the following:
PSBT_IN_WITNESS_SCRIPT
and register it;PSBT_IN_TAP_LEAF_SCRIPT
to reconstruct the full tree, fail with error message.Ok, I have read [all the arguments in the discussion(https://github.com/bitcoin/bips/pull/1389) and see why you need a new "descriptor template" language (next to miniscript, miniscript policy, output descriptor and xkey descriptor languages).
However, I still doubt whether a separate API call or a custom PSBT field is required, since all information to build "descriptor template" and display it to the user in the device UI is already there in PSBT (all my arguments/algorithm from the comment above still apply).
To get support into HWI, we should open an issue there and discuss with the maintainers what a good way would be.
It also seems there is already a WIP implementation for this: https://github.com/bitcoin-core/HWI/pull/647
Isn't PSBT_IN_TAP_LEAF_SCRIPT only part of the tree, but one needs the full tree to reconstruct the full policy?
The BitBox02 also needs the policy to register the wallet on the device before any signing or receiving, and is also needed to display receive addresses, so it must be available on the host anyway.
Each individual PSBT_IN_TAP_LEAF_SCRIPT
represents a single taptree leaf - but PSBT can provide multiple - up to covering all leafs (property is key-mapped, where the key is control block, so you can have many of the keys for the same property). In such way the wallet communicates whole taptree - and if some leaf is missed, that device may notify the user and reject PSBT.
Thus, you do not need custom PSBT structures.
Next, you use tap tree to reconstruct miniscript descriptor - and from it build your policy template and register it.
I prefer the explicit approach the BitBox02 took already. The code complexity and binary bloat to support reconstructing a policy string is significant, including all the multipath <n;m>
that could appear. The compatibility issues would be greater, as PSBTs will not normally contain all leafs.
Furthermore, I am not sure the reconstructed policy will always be unique, and may not match the exact way it is shown in a coordinator wallet (e.g. @1/**
vs @1/<0;1>/*
, etc.). There was also talk about breaking miniscript roundtrips by extending and(X1,X1)
to and(X1,X2,X3,...)
, which would be equivalent to and(...(and(X1,X2),X3),...)
- not sure if that was abandoned or not.
Next, you use tap tree to reconstruct miniscript descriptor - and from it build your policy template and register it.
That is a UX problem as well, if you want to e.g. show in the coordinator wallet that the wallet should be registered, and give it a name, the registration must be separate.
For now the BitBox02 will stick to explicit registration and sending the policy for receive addresses and signing.
Closing this issue for the above reason, and the rest of the issue is about HWI.
I am not sure we are talking about the same thing here.
I assume that you are already using rust-miniscript
in your firmware, thus everything I have described is available out of the box already inside your binary - you just need to call one more method. At the same time asking to add a PSBT field will end up in "standardization hell" and will take forever.
If you are not using rust-miniscript
, everything you said makes perfect sense.
We are using rust-miniscript, but assembling a policy string including multipaths is not part of it. Not sure if even producing the descriptor from the leaf scripts is there or not. Regardless, just because some of the code already exists it does not mean it is not complex or that it does not induce significant bloat. This work is best offloaded to host coordinators, which usually already have the policy.
There are more reasons to prefer the explicit approach. Some of them given above (UX, uniqueness, etc.), but also the BitBox02 streams the transaction but displays which account/policy it spends from in the beginning before any inputs are streamed. If the info is reconstructed from inputs, the signing/streaming API of the BitBox02 would have to be changed significantly.
At the same time asking to add a PSBT field will end up in "standardization hell" and will take forever.
One can send it separately of the PSBT (Liana is doing this for the Ledger and the BitBox02) and how the HWI PR you linked does it, or BIP174 Proprietary keys could be made use of until a standard emerges.
I know it is a feature and not a bug - but maybe there is some way to solve that, since it works for non-timelocked multisigs.
What I get is
Descriptor is
PSBT is
Txid which is being spent:
bb914b46f65746fab2ea477db6176bb9345c635708461ebdaa2e3d8da04dc125:0
Yes, that's mainnet. I do write code and debug it only on mainnet, not testnet. Because that is the way.
And yes, I know, that is a crazy descriptor. Here is what it means:
For debug purposes, here is interpretation of PSBT content: