-
Notifications
You must be signed in to change notification settings - Fork 203
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[PoC] Wallet policies (and miniscript support) #647
base: master
Are you sure you want to change the base?
Conversation
Hi Salvatore, I successfully used this PR with simples scripts from Liana, but getting some issue with some more complex one: $ python3 -m hwi --debug --device-type ledger registerpolicy --policy "wsh(or_i(and_v(v:thresh(1,pkh(@0/<8;9>/*),a:pkh(@1/<4;5>/*),a:pkh(@2/<4;5>/*)),older(65535)),or_i(and_v(v:thresh(2,pkh(@0/<6;7>/*),a:pkh(@1/<2;3>*)),older(15001)),or_i(and_v(v:thresh(2,pkh(@0/<4;5>/*),a:pkh(@2/<2;3>/*)),older(15000)),or_d(multi(2,@0/**,@3/**),and_v(v:thresh(3,pkh(@1/**),a:pkh(@2/**),a:pkh(@0/<2;3>/*)),older(1)))))))#lnc99art" --name "Liana" --keys "[\"[9978d14e/84h/0h/0h]zpub6s7PH15YtcVFyEPJjjdNhEjA4n1D77DUhZyU4JZMXsWQ4C8kssYGDrne6jcDTXHRXajxFNTTiCbqpVtqZAhfV37Zm6wcDj4reSujMH3AFgC\",\"[0063c8e2/84h/0h/0h]zpub6rj3eaikqs5UF3gDggHC8inmnYcEFCfSNB3Sja3NkC4bNDURbmGequcC8uPa9GMbcUs7WSBbernhxHgoctjNvmveT5vYQGHQSvSA12g1UwW\",\"[945d917c/84h/0h/0h]zpub6rWPeMxpZS9xpwBadedssZ71UzeutatXnegqqrWkrrSim4BiFrcUdTPtLxtPGpUtBzbiM1ZPaXXVcrhb9Su1ettffQ6B1y5JHcyd4P516rm\",\"[8a491f24/84h/0h/0h]zpub6qaBba3PS8R8k61SueSazVotxKP7iwQ3Gp3c42DTSaWKP5qt6fcSqRjGxw7hRHLP7XaFiEQXDHcKHoZ9rurD9n1SkPFSoYsfP2H7Ch9vbmQ\"]" (keys have been generated for this example) output:
note: i firstly fail to register this policy from Liana before trying with this PR |
@pythcoiner: most likely the reason is that |
i just checked the original keys that throw the errow were |
Fixing those, I was able to register the policy on local tests on NanoS+, so I think it should also work with |
1 + 2 solved my issue, thanks @bigspider! |
@bigspider Unfortunately I found this PR too late. Looks like it's exactly what we need for our project. Apart from the obvious (testing and review), how can we help to move this forward? Would you be willing to rebase so we can test on top of latest master? |
FYI all signing devices supporting miniscript are supported by async-hwi, it should be possible to bind to other languages (or at list to call the cli) |
@guggero Unfortunately, with the little interest over this PR, it has not been feasible to move past the PoC stage when it was proposed. Perhaps now that wallet policies have a BIP number and at least two or more other vendors implemented them, there might be more interest - but at this time, async-hwi is probably the most mature solution. Besides, I can see numerous advantages of a compiled solution (for which it should be feasible to add bindings to pretty much all common languages), over a python implementation. Should there be interest in reviving the work from this PR, perhaps a way to reduce the impact on the public interface would be to encode the BIP-388 policy information inside the PSBT (so the signing API stays |
Hello,
this in an exploratory PR as a proof of concept of how wallet policies could look like in HWI.
Wallet policies were presented to the bitcoin-dev mailing list back in May.
A BIP proposal is in preparation here.
The goals of this PR are to:
Wallet policies are designed to be vendor-agnostic.
In fact, they are ready for miniscript wallets, and they might in my opinion be a convenient, opinionated way of adding miniscript support to HWI.
They are implemented in the Ledger bitcoin app since version 2.1.0, which uses them to support miniscript (on segwit only, at this time).
Implementation details
Not production-ready!
In this PR, I attempted to add wallet policies as a first-class object, while not breaking compatibility with existing code.
The three commit add:
HardwareWalletClient
:can_register_wallet_policies
,register_wallet_policy
,display_wallet_policy_address
,sign_tx_with_wallet_policy
.displayaddress
andsigntx
; addedregisterpolicy
.ledger.py
.For subclasses not implementing wallet policies, a compatibility layer guarantees that if the policy falls back into the supported cases (single-signature, or standard multisignature), calls to functions using wallet policies are automatically converted to the corresponding single-sig or multi-sig function to show addresses or sign transactions.
With this approach, software wallets adopting wallet policies, therefore, could use them directly without using any other
HardwareWalletClient
function without wallet policies.Demo
In the following, I'd like to walk you through an end-to-end demo of wallet policies that can be tested from this PR's branch using the Ledger bitcoin testnet app version 2.1.0 in the speculos emulator; the app will be released in production within a few weeks.
In all the examples with multiple keys, internal keys are the ones with fingerprint
f5acc2fd
, which is the fingerprint for the default seed used by the speculos emulator.The command should be run from the root folder of the HWI repository, or after installing the module from this PR (e.g. with
pip install .
).Screenshots are based on the UX for a Ledger NanoS+ device.
Single-signature
In this example, we use a wallet policy for a standard BIP-86 taproot address. Ledger devices require no registration for standard single-signature policies, so this can be used directly.
Device screen:
Output:
Multisignature
Register policy
Device screen:
Output:
Display address
Device screen:
Output:
Sign a psbt with policy
It is relevant to point out that when using wallet policies, it makes sense to use a more specific action rather than "sign a transaction": in fact, the wallet policy specifies exactly what kind of scripts/inputs should be signed, and similarly, what outputs can match a change address.
This allows hardware wallets to correctly identify internal inputs and outputs.
The necessary information about what exact wallet policy should be used for signing is in fact typically available to the software wallet.
Therefore, the action is "sign a transaction with a certain wallet policy".
Device screen:
Output:
Miniscript
Miniscript policy: a 3-of-3 that becomes a 2-of-3 after 90 days:
thresh(3,pk(key_1),pk(key_2),pk(key_3),older(12960))
.Register policy
Device screen:
Output:
Display address
Device screen:
Output:
Sign a psbt with the policy
Device screen:
Output:
Conclusions
I hope this is interesting and I look forward to hearing your comments about whether (and how) wallet policies could be added to hwi.