1
0

signSharedTx.ts 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. /* Import modules. */
  2. import BCHJS from '@psf/bch-js'
  3. import { Transaction } from 'bitcoinjs-lib'
  4. import { mnemonicToSeed } from '@nexajs/hdnode'
  5. import { encodeNullData } from '@nexajs/script'
  6. import { utf8ToBin } from '@nexajs/utils'
  7. /* Initialize BCHJS. */
  8. const bchjs = new BCHJS()
  9. /* Initialize constants. */
  10. const HUSH_PROTOCOL_ID = 0x48555348
  11. /**
  12. * Build Shared Transaction
  13. *
  14. * Combine all participating inputs and outputs into one (signed) transaction.
  15. */
  16. export default function (_sessionid, _inputs, _outputs) {
  17. console.log('SIGN SHARED TX', _sessionid, _inputs, _outputs)
  18. /* Initialize locals. */
  19. // let accountIdx
  20. // let addressIdx
  21. // let changeIdx
  22. // let childNode
  23. let data
  24. let ecPair
  25. // let ownedInputs
  26. let protocolId
  27. let msg
  28. // let rawTx
  29. let redeemScript
  30. let script
  31. let wif
  32. /* Initialize transaction builde.r */
  33. const transactionBuilder = new bchjs.TransactionBuilder()
  34. console.log('DO WE HAVE FUSION INPUTS??', this.fusionInputs)
  35. /* Initialize our addresses. */
  36. const ourAddresses = []
  37. /* Handle fusion inputs. */
  38. Object.keys(this.fusionInputs).forEach(_outpoint => {
  39. const ourInput = this.fusionInputs[_outpoint]
  40. console.log('OUR INPUT', ourInput)
  41. ourAddresses.push(ourInput.address)
  42. })
  43. console.log('OUR ADDRESSES', ourAddresses)
  44. /* Initialize address index. */
  45. // addressIdx = 0
  46. /* Initialize owned inputs. */
  47. // ownedInputs = []
  48. /* Handle inputs. */
  49. _inputs.forEach(_input => {
  50. /* Add input. */
  51. transactionBuilder.addInput(_input.tx_hash, _input.tx_pos)
  52. // console.log('VALIDATING (SELF) INPUT', _input)
  53. // /* Validate (our) address. */
  54. // if (ourAddresses.includes(_input.address)) {
  55. // ownedInputs.push(addressIdx)
  56. // }
  57. // addressIdx++
  58. })
  59. // console.log('OUR INPUTS INDEX', ownedInputs)
  60. /* Set protocol ID. */
  61. protocolId = 'HUSH'
  62. /* Set protocol message. */
  63. msg = '4fa84224-be56-49ba-830a-fa3b6774eb01'
  64. script = [
  65. utf8ToBin(protocolId),
  66. utf8ToBin(msg),
  67. // utf8ToBin(_sessionid),
  68. ]
  69. // console.log('my SCRIPT', script)
  70. // console.log('encodeNullData', encodeNullData(script))
  71. // Compile the script array into a bitcoin-compliant hex encoded string.
  72. // const data = bchjs.Script.encode(script)
  73. data = Buffer.from(encodeNullData(script))
  74. // console.log('OP_RETURN (data)', data)
  75. // Add the OP_RETURN output.
  76. transactionBuilder.addOutput(data, 0)
  77. /* Handle outputs. */
  78. _outputs.forEach(_output => {
  79. /* Add output. */
  80. transactionBuilder.addOutput(_output.address, _output.value)
  81. })
  82. /* Convert mnemonic to seed. */
  83. // const seed = mnemonicToSeed(_mnemonic)
  84. /* Conver to seed buffer. */
  85. // FIXME Migrate to TypedArrays.
  86. // const seedBuffer = Buffer.from(seed, 'hex')
  87. /* Generate master node. */
  88. // const masterNode = bchjs.HDNode.fromSeed(seedBuffer)
  89. // FIXME Identify our owned inputs.
  90. // ownedInputs = [ 0, 1, 2, 3, 4, 5, 6 ]
  91. for (let i = 0; i < _inputs.length; i++) {
  92. const input = _inputs[i]
  93. console.log('AN INPUT---', input)
  94. const address = input.address
  95. console.log('INPUT ADDR', address)
  96. /* Verify input ownership. */
  97. // if (!ownedInputs.includes(i)) {
  98. // if (typeof input.wif === 'undefined' || input.wif === null) {
  99. if (!ourAddresses.includes(address)) {
  100. continue
  101. }
  102. /* Set account index. */
  103. // accountIdx = 0
  104. // accountIdx = HUSH_PROTOCOL_ID
  105. /* Set change index. */
  106. // changeIdx = 0
  107. /* Set address index. */
  108. // addressIdx = _inputs[i].address_idx
  109. // console.log('ADDRESS IDX')
  110. /* Generate child node. */
  111. // childNode = masterNode
  112. // .derivePath(`m/44'/145'/${accountIdx}'/${changeIdx}/${addressIdx}`)
  113. /* Generate wallet import format (WIF). */
  114. // wif = bchjs.HDNode.toWIF(childNode)
  115. /* Set WIF. */
  116. wif = this.getWifForAddress(address)
  117. console.log('BCH WIF', wif)
  118. /* Generate elliptic pair. */
  119. ecPair = bchjs.ECPair.fromWIF(wif)
  120. console.log('SIGNING!', i, redeemScript, input.value)
  121. /* Sign (our own) input. */
  122. transactionBuilder.sign(
  123. i,
  124. ecPair,
  125. redeemScript,
  126. Transaction.SIGHASH_ALL,
  127. input.value,
  128. )
  129. }
  130. /* Generate (incomplete) transaction. */
  131. const transaction = transactionBuilder.transaction.buildIncomplete()
  132. // console.log('TRANSACTION', transaction)
  133. /* Convert to (raw) hex. */
  134. // rawTx = tx.toHex()
  135. /* Return raw (hex) transaction. */
  136. return transaction
  137. }