Skip to content

Commit

Permalink
swaps: initial swaps support, including partial proposals
Browse files Browse the repository at this point in the history
User views and verifies a passed wallet inputs/outputs summary.
Sufficient input and output details must be passed for Jade to be able
to verify those summaries are correct.

Initially, only accept either:
a) a swap proposal with exactly one input and one output, both for the
wallet, and in different assets - expect sighash SINGLE|ANYONECANPAY
b) a completed swap, expect sighash ALL
  • Loading branch information
JamieDriver committed May 16, 2023
1 parent fa36d77 commit a1186ed
Show file tree
Hide file tree
Showing 11 changed files with 946 additions and 58 deletions.
20 changes: 18 additions & 2 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1591,7 +1591,22 @@ Request to sign liquid transaction inputs.
"vbf": "6ec064a68075a278bfca4a10f777c730116e9ba02fbb343a237c847e4d2fbf53"
},
null
]
],
"additional_info": {
"tx_type": "swap",
"wallet_input_summary": [
{
"asset_id": "144c654344aa716d6f3abcc1ca90e5641e4e2a7f633bc09fe3baf64585819a49",
"satoshi": 1000000,
}
],
"wallet_output_summary": [
{
"asset_id": "38fca2d939696061a8f76d4e6b5eecd54e3b4221c846f24a6b279e79952850a5",
"satoshi": 50000000
}
]
}
}
}
Expand All @@ -1600,6 +1615,7 @@ Request to sign liquid transaction inputs.
* 'trusted_commitments' must be passed in for each blinded output. Where an output is not blinded (eg. fee output) null may be passed.
* 'trusted_commitments' entries passed in here can be obtained using the get_commitments_request_, with the relevant 'blinding_key' added (which would originally be obtained from get_blinding_key_request_).
* NOTE: as of Jade fw v0.1.34, external blinding is supported, in which case the 'trusted_commitments' can be constructed by the host application. Note the 'asset_id' byte-order is that consistent with the registry data, but the 'abf' and 'vbf' fields need to be in the byte-order in which they would be used in the blinding (which may be reversed).
* 'additional_info' is only required for advanced transaction types such as asset swaps, and can be omitted for vanilla 'send payment' type transactions. If included, it contains the net movements of assets into and out of the wallet (ie. sum of inputs minus change outputs, and sum of non-change outputs per asset)

.. _sign_liquid_tx_legacy_reply:

Expand Down Expand Up @@ -1644,7 +1660,7 @@ A batch of 'tx_input' messages should be sent to Jade - one for each tx input, a
* 'is_witness', 'script', 'path' and 'sighash' are as in sign_tx_legacy_input_request_.
* In addition, if a signature is required for this input and 'is_witness' is 'true', then the input utxo 'value_commitment' must be passed.
* NOTE: no 'input_tx' is needed.

* For advanced tx types, eg swaps, with blinded inputs, we pass the unblinding info here. ie. asset_id, abf, asset_generator, value and vbf - these are as in the 'commitments' data in sign_liquid_tx_legacy_request_.
Once the entire batch (of 'tx_input' messages) has been sent, processed and confirmed on Jade, a batch of replies are sent.

.. _sign_liquid_tx_legacy_input_reply:
Expand Down
32 changes: 28 additions & 4 deletions jadepy/jade.py
Original file line number Diff line number Diff line change
Expand Up @@ -1266,7 +1266,7 @@ def _send_tx_inputs(self, base_id, inputs, use_ae_signatures):
host_ae_entropy_values = []
for txinput in inputs:
# ae-protocol - do not send the host entropy immediately
txinput = txinput.copy() # shallow copy
txinput = txinput.copy() if txinput else {} # shallow copy
host_ae_entropy_values.append(txinput.pop('ae_host_entropy', None))

base_id += 1
Expand Down Expand Up @@ -1298,6 +1298,9 @@ def _send_tx_inputs(self, base_id, inputs, use_ae_signatures):
# Send all n inputs
requests = []
for txinput in inputs:
if txinput is None:
txinput = {}

base_id += 1
msg_id = str(base_id)
request = self.jade.build_request(msg_id, 'tx_input', txinput)
Expand All @@ -1317,7 +1320,7 @@ def _send_tx_inputs(self, base_id, inputs, use_ae_signatures):
return signatures

def sign_liquid_tx(self, network, txn, inputs, commitments, change, use_ae_signatures=False,
asset_info=None):
asset_info=None, additional_info=None):
"""
RPC call to sign a liquid transaction.
Expand All @@ -1344,6 +1347,15 @@ def sign_liquid_tx(self, network, txn, inputs, commitments, change, use_ae_signa
ae_host_commitment, 32-bytes - The host-commitment for Anti-Exfil signatures
ae_host_entropy, 32-bytes - The host-entropy for Anti-Exfil signatures
These are only required for advanced transactions, eg. swaps, and only when the
inputs need unblinding.
Not needed for vanilla send-payment/redeposit etc:
abf, 32-bytes - asset blinding factor
asset_id, 32-bytes - the unblinded asset-id
asset_generator, 33-bytes - the (blinded) asset-generator
vbf, 32-bytes - the value blinding factor
value, int - the unblinded sats value of the input
If not signing this input a null or an empty dict can be passed.
commitments : [dict]
Expand All @@ -1366,14 +1378,25 @@ def sign_liquid_tx(self, network, txn, inputs, commitments, change, use_ae_signa
Whether to use the anti-exfil protocol to generate the signatures.
Defaults to False.
asset_info : [dict]
asset_info : [dict], optional
Any asset-registry data relevant to the assets being transacted, such that Jade can
display a meaningful name, issuer, ticker etc. rather than just asset-id.
At the very least must contain 'asset_id', 'contract' and 'issuance_prevout' items,
exactly as in the registry data. NOTE: asset_info for the network policy-asset is
not required.
Defaults to None.
additional_info: dict, optional
Extra data about the transaction. Only required for advanced transactions, eg. swaps.
Not needed for vanilla send-payment/redeposit etc:
tx_type, str: 'swap' indicates the tx represents an asset-swap proposal or transaction.
wallet_input_summary, dict: a list of entries containing 'asset_id' (32-bytes) and
'satoshi' (int) showing net movement of assets out of the wallet (ie. sum of wallet
inputs per asset, minus any change outputs).
wallet_output_summary, dict: a list of entries containing 'asset_id' (32-bytes) and
'satoshi' (int) showing net movement of assets into the wallet (ie. sum of wallet
outputs per asset, excluding any change outputs).
Returns
-------
1. if use_ae_signatures is False
Expand All @@ -1397,7 +1420,8 @@ def sign_liquid_tx(self, network, txn, inputs, commitments, change, use_ae_signa
'trusted_commitments': commitments,
'use_ae_signatures': use_ae_signatures,
'change': change,
'asset_info': asset_info}
'asset_info': asset_info,
'additional_info': additional_info}

reply = self._jadeRpc('sign_liquid_tx', params, str(base_id))
assert reply
Expand Down
Loading

0 comments on commit a1186ed

Please sign in to comment.