txFromComponents.ts 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. /**
  2. * """ Returns the tx and a list of indices matching inputs with components"""
  3. */
  4. export default (all_components, session_hash) => {
  5. input_indices = []
  6. assert len(session_hash) == 32
  7. if Protocol.FUSE_ID is None:
  8. prefix = []
  9. else:
  10. assert len(Protocol.FUSE_ID) == 4
  11. prefix = [4, *Protocol.FUSE_ID]
  12. inputs = []
  13. outputs = [(TYPE_SCRIPT, ScriptOutput(bytes([OpCodes.OP_RETURN, *prefix, 32]) + session_hash), 0)]
  14. for i,compser in enumerate(all_components):
  15. comp = pb.Component()
  16. comp.ParseFromString(compser)
  17. ctype = comp.WhichOneof('component')
  18. if ctype == 'input':
  19. inp = comp.input
  20. if len(inp.prev_txid) != 32:
  21. raise FusionError("bad component prevout")
  22. inputs.append(dict(address = Address.from_P2PKH_hash(hash160(inp.pubkey)),
  23. prevout_hash = inp.prev_txid[::-1].hex(),
  24. prevout_n = inp.prev_index,
  25. num_sig = 1,
  26. signatures = [None],
  27. type = 'p2pkh',
  28. x_pubkeys = [inp.pubkey.hex()],
  29. pubkeys = [inp.pubkey.hex()],
  30. sequence = 0xffffffff,
  31. token_data = None, # Program defensively, in case something does inp['token_data']
  32. value = inp.amount))
  33. input_indices.append(i)
  34. elif ctype == 'output':
  35. out = comp.output
  36. atype, addr = get_address_from_output_script(out.scriptpubkey)
  37. if atype != TYPE_ADDRESS:
  38. raise FusionError("bad component address")
  39. outputs.append((TYPE_ADDRESS, addr, out.amount))
  40. elif ctype != 'blank':
  41. raise FusionError("bad component")
  42. tx = Transaction.from_io(inputs, outputs, locktime=0, sign_schnorr=True)
  43. tx.version = 1
  44. return tx, input_indices
  45. }