1
0

buildSharedTx.ts 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  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. const bchjs = new BCHJS()
  8. /**
  9. * Build Shared Transaction
  10. *
  11. * Combine all participating inputs and outputs into one (signed) transaction.
  12. *
  13. * NOTE: ALL inputs are ALREADY signed by their respective participants.
  14. */
  15. export default function (_inputs, _outputs) {
  16. /* Initialize locals. */
  17. let rawTx
  18. let safeBalance
  19. let utxo
  20. const transactionBuilder = new bchjs.TransactionBuilder()
  21. let inputIdx
  22. this.fusionInputs.forEach((_utxo) => {
  23. /* Set UTXO. */
  24. utxo = _utxo
  25. console.log('UTXO', utxo)
  26. inputIdx = 0//utxo.tx_pos
  27. transactionBuilder.addInput(utxo.tx_hash, utxo.tx_pos)
  28. const originalAmount = utxo.value
  29. const remainder = originalAmount - satsNeeded
  30. console.log('REMAINDER', remainder);
  31. if (remainder < 0) {
  32. throw new Error('Selected UTXO does not have enough satoshis')
  33. }
  34. const protocolId = '1337'
  35. const msg = 'building...'
  36. const script = [
  37. utf8ToBin(protocolId),
  38. utf8ToBin(msg),
  39. ]
  40. console.log('my SCRIPT', script)
  41. console.log('encodeNullData', encodeNullData(script))
  42. // Compile the script array into a bitcoin-compliant hex encoded string.
  43. // const data = bchjs.Script.encode(script)
  44. const data = Buffer.from(encodeNullData(script))
  45. console.log('OP_RETURN (data)', data)
  46. // Add the OP_RETURN output.
  47. // transactionBuilder.addOutput(data, 0)
  48. transactionBuilder.addOutput(data, 0)
  49. // Send payment
  50. // transactionBuilder.addOutput(receiver, satsNeeded)
  51. transactionBuilder.addOutput(receiver, paymentAmount)
  52. // Send the BCH change back to the payment part
  53. // transactionBuilder.addOutput(account.address, remainder - 300)
  54. })
  55. /* Initialize redeem script. */
  56. // FIXME Why do we need this??
  57. let redeemScript
  58. /* Convert mnemonic to seed. */
  59. const seed = mnemonicToSeed(this.mnemonic)
  60. /* Conver to seed buffer. */
  61. // FIXME Migrate to TypedArrays.
  62. const seedBuffer = Buffer.from(seed, 'hex')
  63. /* Generate master node. */
  64. const masterNode = bchjs.HDNode.fromSeed(seedBuffer)
  65. /* Set account index. */
  66. const accountIdx = 0
  67. /* Set change index. */
  68. const changeIdx = 0
  69. /* Set address index. */
  70. const addressIdx = 0
  71. /* Generate child node. */
  72. const chidleNode = masterNode
  73. .derivePath(`m/44'/145'/${accountIdx}'/${changeIdx}/${addressIdx}`)
  74. /* Generate wallet import format (WIF). */
  75. const wif = bchjs.HDNode.toWIF(chidleNode)
  76. // console.log('BCH WIF', wif)
  77. /* Generate elliptic pair. */
  78. const ecPair = bchjs.ECPair.fromWIF(wif)
  79. /* Sign transaction. */
  80. transactionBuilder.sign(
  81. inputIdx,
  82. ecPair,
  83. redeemScript,
  84. Transaction.SIGHASH_ALL,
  85. utxo.value,
  86. )
  87. /* Generate (incomplete) transaction. */
  88. const tx = transactionBuilder.transaction.buildIncomplete()
  89. // console.log('TRANSACTION', tx)
  90. /* Convert to (raw) hex. */
  91. rawTx = tx.toHex()
  92. /* Return raw (hex) transaction. */
  93. return rawTx
  94. }