Add support for offline transaction signing
This mostly addresses #1927 (closed).
I will make a follow-up PR shortly that adds support for watch-only wallets. In the meantime, you can simulate a watch-only wallet by creating a normal wallet and then locking it. (done in this PR instead)
The basic process is:
/wallet/unspentto receive a list of spendable outputs
- Construct an unsigned transaction using the outputs
siac wallet signto sign the transaction
/tpool/rawto broadcast the transaction
siac wallet sign does not require
siad; it's completely self-contained. The downside of this is that you need to regenerate a bunch of keys from the seed, and you pay that cost every time you sign a transaction. For wallets that have <10000 addresses, this cost should be barely noticeable, but for larger wallets, there is also a
/wallet/sign endpoint that will perform the same signing operation using the keys already in memory.
Lastly, there's the question of how to encode the transactions.
/tpool/raw expects base64-encoded binary, but that isn't a very convenient format for constructing transactions. I figured that JSON was a better choice for that, so
siac wallet sign and
/wallet/sign both expect the transaction to be JSON.
Oh, one more thing: the
/sign endpoint expects the JSON to be in the request body, not the query params. This seemed natural given the complex structure of the arguments, but I'm open to changing it.