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:
- GET
/wallet/unspent
to receive a list of spendable outputs - Construct an unsigned transaction using the outputs
- Use
siac wallet sign
to sign the transaction - POST
/tpool/raw
to broadcast the transaction
wrt 3, 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.