Closed bigspider closed 1 year ago
About the signing strategy and format: before taproot scripts, "signing a transaction" means "approving it unconditionally"; this is reflected in the typical UX flow, showing to the user all the outputs (except change) and summary information like transaction fees.
The fact that spending a tapscript creates a signature that is only valid for that spending path could allow more fine-grained control that might be useful in certain protocols. For example, a taptree might have an and(Alice, Bob)
leaf and an and(Alice, Carl)
leaf; if Alice is the first signer, by only signing one of the two paths she can effectively (and non-interactively) delegate the final decision to either Bob or Carl.
Another use case for signing only specific paths might be the performance benefit, especially for tap-trees with many unused spending conditions.
For the initial support of tapscripts, it probably makes sense to keep things simple and limit support to the "unconditionally authorize transactions" when signing policies with taptrees; therefore, for each internal key placeholder, the device will sign all the spending paths (including the key-path spend) that contain that internal key placeholder.
When signing for a taproot script path, instead of yielding the current
<input_index> <pubkey_len> <pubkey> <signature>
response, we might yield
<input_index> <pubkey_len> <pubkey> <tapleaf_hash_len = 32> <tapleaf_hash> <signature>
in order to facilitate the client to identify which script path we are spending from; the length of the response makes it unambiguous.
If support for signing individual spending paths is added in the future, we could use vendor-specific fields added by the client in the psbt2 to signal to the device that the signing behavior is not "unconditionally authorize this transaction".
This tracks the work necessary to spend P2TR outputs containing scripts.
Since signatures for the key-path spend and for each tapleaf are distinct, the interface should take that into account; the default behaviour could be to sign for all the valid paths (key path spend + each script, repeating for each internal placeholder).
To be decided:
TODO:
tr(KP, TREE)
policies, for the supported descriptors.Figure out if and how to supportnot standardized yet; this can be added later by extending the language for KEY expressions.tr(<unspendable>,TREE)
tr
:TREE