signFusion.ts 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. /* Import modules. */
  2. import {
  3. encryptForPubkey,
  4. sha256,
  5. } from '@nexajs/crypto'
  6. import { binToHex } from '@nexajs/utils'
  7. import signSharedTx from '../../handlers/signSharedTx.ts'
  8. const DUST_VAL = 546
  9. export default async function () {
  10. /* Initialize locals. */
  11. let blindComponents
  12. let clubWallet
  13. let inputs
  14. let keys
  15. let outpoint
  16. let outputs
  17. let publicKey
  18. // let rawTx
  19. let response
  20. let session
  21. let sessionid
  22. let transaction
  23. // FIXME Where do we get the session ID from??
  24. sessionid = '4fa84224-be56-49ba-830a-fa3b6774eb01'
  25. /* Request session details. */
  26. session = await $fetch(`/v1/fusion/${sessionid}`)
  27. .catch(err => console.error(err))
  28. console.log('SESSION', session)
  29. /* Set inputs. */
  30. inputs = session.inputs
  31. // console.log('INPUTS', inputs)
  32. /* Initialize keys. */
  33. keys = []
  34. /* Handle (input) keys. */
  35. Object.keys(inputs).forEach(_inputid => {
  36. keys.push(_inputid)
  37. })
  38. // console.log('KEYS', keys)
  39. /* Sort (input) keys. */
  40. keys.sort()
  41. // console.log('KEYS (sorted)', keys)
  42. /* Initialize sorted inputs. */
  43. const sortedInputs = []
  44. /* Handle (input) keys. */
  45. keys.forEach(_keyid => {
  46. /* Set input. */
  47. const input = inputs[_keyid]
  48. console.log('HANDLE INPUT', input)
  49. // let addressIdx = 0
  50. // /* Find address index for input. */
  51. // Object.keys(this.fusionInputs).forEach(_outpoint => {
  52. // /* Set fusion input. */
  53. // const fusionInput = this.fusionInputs[_outpoint]
  54. // console.log('FUSION INPUT', fusionInput)
  55. // if (fusionInput.address === input.address) {
  56. // input.address_idx = addressIdx
  57. // console.log('ADDED ADDRESS INDEX', addressIdx)
  58. // // break
  59. // }
  60. // addressIdx++
  61. // })
  62. /* Add input. */
  63. sortedInputs.push(input)
  64. })
  65. // console.log('INPUTS (sorted)', sortedInputs)
  66. outputs = session.outputs
  67. // console.log('OUTPUTS', outputs)
  68. /* Initialize (output) keys. */
  69. keys = []
  70. /* Handle keys. */
  71. Object.keys(outputs).forEach(_outputid => {
  72. keys.push(_outputid)
  73. })
  74. // console.log('KEYS', keys)
  75. /* Sort (output) keys. */
  76. keys.sort()
  77. // console.log('KEYS (sorted)', keys)
  78. /* Initialize sorted outputs. */
  79. const sortedOutputs = []
  80. /* Handle (output) keys. */
  81. keys.forEach(_keyid => {
  82. if (outputs[_keyid].value >= DUST_VAL) {
  83. /* Add input. */
  84. sortedOutputs.push(outputs[_keyid])
  85. }
  86. })
  87. // console.log('OUTPUTS (sorted)', sortedOutputs)
  88. /* Sign shared transaction. */
  89. transaction = signSharedTx.bind(this)(
  90. sessionid, sortedInputs, sortedOutputs)
  91. console.log('(partially) SIGNED TRANSACTION', transaction)
  92. // txObj.ins[1].script = txObj2.ins[1].script
  93. /* Initailize unlocked. */
  94. let unlocked = {}
  95. transaction.ins.forEach(_input => {
  96. console.log('INS (input)', _input)
  97. /* Validate (unlocking) script. */
  98. if (_input.script.length > 0) {
  99. outpoint = sha256(binToHex(_input.hash.reverse()) + ':' + _input.index)
  100. console.log('INS (outpoint)', outpoint)
  101. /* Add input. */
  102. unlocked[outpoint] = {
  103. tx_hash: binToHex(_input.hash.reverse()),
  104. unlocking: binToHex(_input.script),
  105. }
  106. }
  107. })
  108. console.log('UNLOCKED', unlocked)
  109. /* Prepare unlocked (inputs) for encryption. */
  110. unlocked = JSON.stringify(unlocked)
  111. // console.log('FUSION (unlocked)', unlocked)
  112. // TODO Handle any filtering required BEFORE submitting for fusion.
  113. clubWallet = await $fetch('/api/wallet')
  114. .catch(err => console.error(err))
  115. // console.log('CLUB WALLET', clubWallet)
  116. // FIXME Retrieve public key from a "public" endpoint.
  117. publicKey = clubWallet.publicKey
  118. // console.log('CLUB PUBLIC KEY', publicKey)
  119. /* Generate blind components. */
  120. blindComponents = encryptForPubkey(publicKey, unlocked)
  121. // console.log('BLINDED COMPONENTS', blindComponents)
  122. const body = {
  123. authid: binToHex(this.wallet.publicKey),
  124. actionid: 'unlock-components',
  125. unlocked: blindComponents,
  126. }
  127. // console.log('BODY', body)
  128. response = await $fetch('/v1', {
  129. method: 'POST',
  130. body,
  131. })
  132. .catch(err => console.error(err))
  133. console.log('RESPONSE', response)
  134. }