Unspendable keys in descriptors

I’m now implementing Taproot support in Liana. Ideally i’d like to derive unspendable internal keys in a way which would be forward compatible with an eventual standard used in wallet policies. This way, once support is implemented in signing devices, our users won’t have to “verify” a meaningless internal key on their device’s screen. A friendlier “no keypath spend” UX could be presented.

It seems the less ugly way of getting all 4 properties is what Salvatore suggests in s4 (in the simpler version). From a wallet policy, the unspendable internal key is an xpub/<0;1>/* such as:

  • The xpub’s key is the NUMS suggested in BIP341: H = lift_x(0x50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0).
  • The xpub’s chaincode is the sha256 of the concatenation of the key part (as a compressed pubkey) of all the xpubs in the wallet policy. (In the wallet policy standard all key expressions must be xpubs with derivation path of the form /<m;n>/*.) “Left to right” order as they appear in the string representation, which is just a depth-first search.

Of course, this can also be expressed in descriptors using unspend(computed chaincode)/<0;1>/* as the internal key.