@atomicfinance/bitcoin-wallet-provider 4.0.3 → 4.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (230) hide show
  1. package/.turbo/turbo-build.log +3 -0
  2. package/CHANGELOG.md +31 -0
  3. package/LICENSE +674 -0
  4. package/dist/BitcoinWalletProvider.d.ts +8 -11
  5. package/dist/BitcoinWalletProvider.js +18 -10
  6. package/dist/BitcoinWalletProvider.js.map +1 -1
  7. package/lib/BitcoinWalletProvider.ts +0 -2
  8. package/package.json +14 -13
  9. package/.turbo/turbo-lint.log +0 -1
  10. package/.turbo/turbo-test.log +0 -0
  11. package/.yalc/@node-dlc/core/.nyc_output/687a3c14-9765-45fd-a1fe-f7db3d56fee4.json +0 -1
  12. package/.yalc/@node-dlc/core/.nyc_output/processinfo/687a3c14-9765-45fd-a1fe-f7db3d56fee4.json +0 -1
  13. package/.yalc/@node-dlc/core/.nyc_output/processinfo/index.json +0 -1
  14. package/.yalc/@node-dlc/core/README.md +0 -11
  15. package/.yalc/@node-dlc/core/__tests__/core.spec.ts +0 -7
  16. package/.yalc/@node-dlc/core/__tests__/dlc/CETCalculator.spec.ts +0 -1029
  17. package/.yalc/@node-dlc/core/__tests__/dlc/CoinSelect.spec.ts +0 -179
  18. package/.yalc/@node-dlc/core/__tests__/dlc/PolynomialPayoutCurve.spec.ts +0 -345
  19. package/.yalc/@node-dlc/core/__tests__/dlc/TxBuilder.spec.ts +0 -424
  20. package/.yalc/@node-dlc/core/__tests__/dlc/finance/Builder.spec.ts +0 -492
  21. package/.yalc/@node-dlc/core/__tests__/dlc/finance/CoveredCall.spec.ts +0 -112
  22. package/.yalc/@node-dlc/core/__tests__/dlc/finance/CsoInfo.spec.ts +0 -1124
  23. package/.yalc/@node-dlc/core/__tests__/dlc/finance/LongCall.spec.ts +0 -55
  24. package/.yalc/@node-dlc/core/__tests__/dlc/finance/LongPut.spec.ts +0 -55
  25. package/.yalc/@node-dlc/core/__tests__/dlc/finance/OptionInfo.spec.ts +0 -226
  26. package/.yalc/@node-dlc/core/__tests__/dlc/finance/ShortPut.spec.ts +0 -62
  27. package/.yalc/@node-dlc/core/__tests__/tsconfig.json +0 -8
  28. package/.yalc/@node-dlc/core/__tests__/utils/precision.spec.ts +0 -40
  29. package/.yalc/@node-dlc/core/coverage/lcov-report/base.css +0 -224
  30. package/.yalc/@node-dlc/core/coverage/lcov-report/block-navigation.js +0 -79
  31. package/.yalc/@node-dlc/core/coverage/lcov-report/favicon.png +0 -0
  32. package/.yalc/@node-dlc/core/coverage/lcov-report/index.html +0 -171
  33. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/AsyncProcessingQueue.ts.html +0 -269
  34. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/Base32.ts.html +0 -86
  35. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/BigIntUtils.ts.html +0 -86
  36. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/BitField.ts.html +0 -86
  37. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/ChannelId.ts.html +0 -86
  38. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/LinkedList.ts.html +0 -413
  39. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/LinkedListNode.ts.html +0 -122
  40. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/Queue.ts.html +0 -188
  41. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/ShortChannelId.ts.html +0 -86
  42. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/ShortChannelIdUtils.ts.html +0 -107
  43. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/CETCalculator.ts.html +0 -1430
  44. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/CoinSelect.ts.html +0 -431
  45. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/HyperbolaPayoutCurve.ts.html +0 -644
  46. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/PolynomialPayoutCurve.ts.html +0 -878
  47. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/TxBuilder.ts.html +0 -1088
  48. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/TxFinalizer.ts.html +0 -731
  49. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/finance/Builder.ts.html +0 -2270
  50. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/finance/CoveredCall.ts.html +0 -410
  51. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/finance/CsoInfo.ts.html +0 -1574
  52. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/finance/LinearPayout.ts.html +0 -362
  53. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/finance/LongCall.ts.html +0 -302
  54. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/finance/LongPut.ts.html +0 -302
  55. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/finance/OptionInfo.ts.html +0 -626
  56. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/finance/ShortPut.ts.html +0 -305
  57. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/finance/index.html +0 -216
  58. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/index.html +0 -186
  59. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/index.html +0 -261
  60. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/index.ts.html +0 -278
  61. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/lightning/ChannelId.ts.html +0 -242
  62. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/lightning/ChannelKeys.ts.html +0 -407
  63. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/lightning/CommitmentNumber.ts.html +0 -362
  64. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/lightning/CommitmentSecret.ts.html +0 -203
  65. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/lightning/CommitmentSecretStore.ts.html +0 -332
  66. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/lightning/Htlc.ts.html +0 -236
  67. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/lightning/HtlcDirection.ts.html +0 -131
  68. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/lightning/ScriptFactory.ts.html +0 -530
  69. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/lightning/TxFactory.ts.html +0 -1094
  70. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/lightning/index.html +0 -231
  71. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/utils/BigIntUtils.ts.html +0 -272
  72. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/utils/Precision.ts.html +0 -149
  73. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/utils/index.html +0 -126
  74. package/.yalc/@node-dlc/core/coverage/lcov-report/prettify.css +0 -1
  75. package/.yalc/@node-dlc/core/coverage/lcov-report/prettify.js +0 -2
  76. package/.yalc/@node-dlc/core/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  77. package/.yalc/@node-dlc/core/coverage/lcov-report/sorter.js +0 -170
  78. package/.yalc/@node-dlc/core/coverage/lcov.info +0 -2426
  79. package/.yalc/@node-dlc/core/dist/AsyncProcessingQueue.d.ts +0 -22
  80. package/.yalc/@node-dlc/core/dist/AsyncProcessingQueue.js +0 -55
  81. package/.yalc/@node-dlc/core/dist/AsyncProcessingQueue.js.map +0 -1
  82. package/.yalc/@node-dlc/core/dist/Base32.d.ts +0 -1
  83. package/.yalc/@node-dlc/core/dist/Base32.js +0 -7
  84. package/.yalc/@node-dlc/core/dist/Base32.js.map +0 -1
  85. package/.yalc/@node-dlc/core/dist/BigIntUtils.d.ts +0 -1
  86. package/.yalc/@node-dlc/core/dist/BigIntUtils.js +0 -8
  87. package/.yalc/@node-dlc/core/dist/BigIntUtils.js.map +0 -1
  88. package/.yalc/@node-dlc/core/dist/BitField.d.ts +0 -1
  89. package/.yalc/@node-dlc/core/dist/BitField.js +0 -7
  90. package/.yalc/@node-dlc/core/dist/BitField.js.map +0 -1
  91. package/.yalc/@node-dlc/core/dist/ChannelId.d.ts +0 -1
  92. package/.yalc/@node-dlc/core/dist/ChannelId.js +0 -7
  93. package/.yalc/@node-dlc/core/dist/ChannelId.js.map +0 -1
  94. package/.yalc/@node-dlc/core/dist/LinkedList.d.ts +0 -30
  95. package/.yalc/@node-dlc/core/dist/LinkedList.js +0 -104
  96. package/.yalc/@node-dlc/core/dist/LinkedList.js.map +0 -1
  97. package/.yalc/@node-dlc/core/dist/LinkedListNode.d.ts +0 -9
  98. package/.yalc/@node-dlc/core/dist/LinkedListNode.js +0 -15
  99. package/.yalc/@node-dlc/core/dist/LinkedListNode.js.map +0 -1
  100. package/.yalc/@node-dlc/core/dist/Queue.d.ts +0 -22
  101. package/.yalc/@node-dlc/core/dist/Queue.js +0 -38
  102. package/.yalc/@node-dlc/core/dist/Queue.js.map +0 -1
  103. package/.yalc/@node-dlc/core/dist/ShortChannelId.d.ts +0 -1
  104. package/.yalc/@node-dlc/core/dist/ShortChannelId.js +0 -7
  105. package/.yalc/@node-dlc/core/dist/ShortChannelId.js.map +0 -1
  106. package/.yalc/@node-dlc/core/dist/ShortChannelIdUtils.d.ts +0 -1
  107. package/.yalc/@node-dlc/core/dist/ShortChannelIdUtils.js +0 -12
  108. package/.yalc/@node-dlc/core/dist/ShortChannelIdUtils.js.map +0 -1
  109. package/.yalc/@node-dlc/core/dist/dlc/CETCalculator.d.ts +0 -50
  110. package/.yalc/@node-dlc/core/dist/dlc/CETCalculator.js +0 -332
  111. package/.yalc/@node-dlc/core/dist/dlc/CETCalculator.js.map +0 -1
  112. package/.yalc/@node-dlc/core/dist/dlc/CoinSelect.d.ts +0 -23
  113. package/.yalc/@node-dlc/core/dist/dlc/CoinSelect.js +0 -77
  114. package/.yalc/@node-dlc/core/dist/dlc/CoinSelect.js.map +0 -1
  115. package/.yalc/@node-dlc/core/dist/dlc/HyperbolaPayoutCurve.d.ts +0 -20
  116. package/.yalc/@node-dlc/core/dist/dlc/HyperbolaPayoutCurve.js +0 -117
  117. package/.yalc/@node-dlc/core/dist/dlc/HyperbolaPayoutCurve.js.map +0 -1
  118. package/.yalc/@node-dlc/core/dist/dlc/PayoutCurve.d.ts +0 -5
  119. package/.yalc/@node-dlc/core/dist/dlc/PayoutCurve.js +0 -3
  120. package/.yalc/@node-dlc/core/dist/dlc/PayoutCurve.js.map +0 -1
  121. package/.yalc/@node-dlc/core/dist/dlc/PolynomialPayoutCurve.d.ts +0 -52
  122. package/.yalc/@node-dlc/core/dist/dlc/PolynomialPayoutCurve.js +0 -173
  123. package/.yalc/@node-dlc/core/dist/dlc/PolynomialPayoutCurve.js.map +0 -1
  124. package/.yalc/@node-dlc/core/dist/dlc/TxBuilder.d.ts +0 -55
  125. package/.yalc/@node-dlc/core/dist/dlc/TxBuilder.js +0 -217
  126. package/.yalc/@node-dlc/core/dist/dlc/TxBuilder.js.map +0 -1
  127. package/.yalc/@node-dlc/core/dist/dlc/TxFinalizer.d.ts +0 -40
  128. package/.yalc/@node-dlc/core/dist/dlc/TxFinalizer.js +0 -146
  129. package/.yalc/@node-dlc/core/dist/dlc/TxFinalizer.js.map +0 -1
  130. package/.yalc/@node-dlc/core/dist/dlc/finance/Builder.d.ts +0 -193
  131. package/.yalc/@node-dlc/core/dist/dlc/finance/Builder.js +0 -422
  132. package/.yalc/@node-dlc/core/dist/dlc/finance/Builder.js.map +0 -1
  133. package/.yalc/@node-dlc/core/dist/dlc/finance/CoveredCall.d.ts +0 -13
  134. package/.yalc/@node-dlc/core/dist/dlc/finance/CoveredCall.js +0 -67
  135. package/.yalc/@node-dlc/core/dist/dlc/finance/CoveredCall.js.map +0 -1
  136. package/.yalc/@node-dlc/core/dist/dlc/finance/CsoInfo.d.ts +0 -114
  137. package/.yalc/@node-dlc/core/dist/dlc/finance/CsoInfo.js +0 -290
  138. package/.yalc/@node-dlc/core/dist/dlc/finance/CsoInfo.js.map +0 -1
  139. package/.yalc/@node-dlc/core/dist/dlc/finance/LinearPayout.d.ts +0 -6
  140. package/.yalc/@node-dlc/core/dist/dlc/finance/LinearPayout.js +0 -79
  141. package/.yalc/@node-dlc/core/dist/dlc/finance/LinearPayout.js.map +0 -1
  142. package/.yalc/@node-dlc/core/dist/dlc/finance/LongCall.d.ts +0 -13
  143. package/.yalc/@node-dlc/core/dist/dlc/finance/LongCall.js +0 -47
  144. package/.yalc/@node-dlc/core/dist/dlc/finance/LongCall.js.map +0 -1
  145. package/.yalc/@node-dlc/core/dist/dlc/finance/LongPut.d.ts +0 -13
  146. package/.yalc/@node-dlc/core/dist/dlc/finance/LongPut.js +0 -47
  147. package/.yalc/@node-dlc/core/dist/dlc/finance/LongPut.js.map +0 -1
  148. package/.yalc/@node-dlc/core/dist/dlc/finance/OptionInfo.d.ts +0 -20
  149. package/.yalc/@node-dlc/core/dist/dlc/finance/OptionInfo.js +0 -101
  150. package/.yalc/@node-dlc/core/dist/dlc/finance/OptionInfo.js.map +0 -1
  151. package/.yalc/@node-dlc/core/dist/dlc/finance/ShortPut.d.ts +0 -12
  152. package/.yalc/@node-dlc/core/dist/dlc/finance/ShortPut.js +0 -46
  153. package/.yalc/@node-dlc/core/dist/dlc/finance/ShortPut.js.map +0 -1
  154. package/.yalc/@node-dlc/core/dist/index.d.ts +0 -39
  155. package/.yalc/@node-dlc/core/dist/index.js +0 -78
  156. package/.yalc/@node-dlc/core/dist/index.js.map +0 -1
  157. package/.yalc/@node-dlc/core/dist/lightning/ChannelId.d.ts +0 -31
  158. package/.yalc/@node-dlc/core/dist/lightning/ChannelId.js +0 -52
  159. package/.yalc/@node-dlc/core/dist/lightning/ChannelId.js.map +0 -1
  160. package/.yalc/@node-dlc/core/dist/lightning/ChannelKeys.d.ts +0 -55
  161. package/.yalc/@node-dlc/core/dist/lightning/ChannelKeys.js +0 -105
  162. package/.yalc/@node-dlc/core/dist/lightning/ChannelKeys.js.map +0 -1
  163. package/.yalc/@node-dlc/core/dist/lightning/CommitmentNumber.d.ts +0 -55
  164. package/.yalc/@node-dlc/core/dist/lightning/CommitmentNumber.js +0 -76
  165. package/.yalc/@node-dlc/core/dist/lightning/CommitmentNumber.js.map +0 -1
  166. package/.yalc/@node-dlc/core/dist/lightning/CommitmentSecret.d.ts +0 -26
  167. package/.yalc/@node-dlc/core/dist/lightning/CommitmentSecret.js +0 -44
  168. package/.yalc/@node-dlc/core/dist/lightning/CommitmentSecret.js.map +0 -1
  169. package/.yalc/@node-dlc/core/dist/lightning/CommitmentSecretStore.d.ts +0 -41
  170. package/.yalc/@node-dlc/core/dist/lightning/CommitmentSecretStore.js +0 -79
  171. package/.yalc/@node-dlc/core/dist/lightning/CommitmentSecretStore.js.map +0 -1
  172. package/.yalc/@node-dlc/core/dist/lightning/Htlc.d.ts +0 -46
  173. package/.yalc/@node-dlc/core/dist/lightning/Htlc.js +0 -46
  174. package/.yalc/@node-dlc/core/dist/lightning/Htlc.js.map +0 -1
  175. package/.yalc/@node-dlc/core/dist/lightning/HtlcDirection.d.ts +0 -16
  176. package/.yalc/@node-dlc/core/dist/lightning/HtlcDirection.js +0 -21
  177. package/.yalc/@node-dlc/core/dist/lightning/HtlcDirection.js.map +0 -1
  178. package/.yalc/@node-dlc/core/dist/lightning/ScriptFactory.d.ts +0 -76
  179. package/.yalc/@node-dlc/core/dist/lightning/ScriptFactory.js +0 -102
  180. package/.yalc/@node-dlc/core/dist/lightning/ScriptFactory.js.map +0 -1
  181. package/.yalc/@node-dlc/core/dist/lightning/TxFactory.d.ts +0 -83
  182. package/.yalc/@node-dlc/core/dist/lightning/TxFactory.js +0 -222
  183. package/.yalc/@node-dlc/core/dist/lightning/TxFactory.js.map +0 -1
  184. package/.yalc/@node-dlc/core/dist/utils/BigIntUtils.d.ts +0 -9
  185. package/.yalc/@node-dlc/core/dist/utils/BigIntUtils.js +0 -59
  186. package/.yalc/@node-dlc/core/dist/utils/BigIntUtils.js.map +0 -1
  187. package/.yalc/@node-dlc/core/dist/utils/Precision.d.ts +0 -13
  188. package/.yalc/@node-dlc/core/dist/utils/Precision.js +0 -28
  189. package/.yalc/@node-dlc/core/dist/utils/Precision.js.map +0 -1
  190. package/.yalc/@node-dlc/core/lib/AsyncProcessingQueue.ts +0 -63
  191. package/.yalc/@node-dlc/core/lib/Base32.ts +0 -2
  192. package/.yalc/@node-dlc/core/lib/BigIntUtils.ts +0 -2
  193. package/.yalc/@node-dlc/core/lib/BitField.ts +0 -2
  194. package/.yalc/@node-dlc/core/lib/ChannelId.ts +0 -2
  195. package/.yalc/@node-dlc/core/lib/LinkedList.ts +0 -111
  196. package/.yalc/@node-dlc/core/lib/LinkedListNode.ts +0 -14
  197. package/.yalc/@node-dlc/core/lib/Queue.ts +0 -36
  198. package/.yalc/@node-dlc/core/lib/ShortChannelId.ts +0 -2
  199. package/.yalc/@node-dlc/core/lib/ShortChannelIdUtils.ts +0 -9
  200. package/.yalc/@node-dlc/core/lib/dlc/CETCalculator.ts +0 -450
  201. package/.yalc/@node-dlc/core/lib/dlc/CoinSelect.ts +0 -117
  202. package/.yalc/@node-dlc/core/lib/dlc/HyperbolaPayoutCurve.ts +0 -188
  203. package/.yalc/@node-dlc/core/lib/dlc/PayoutCurve.ts +0 -6
  204. package/.yalc/@node-dlc/core/lib/dlc/PolynomialPayoutCurve.ts +0 -266
  205. package/.yalc/@node-dlc/core/lib/dlc/TxBuilder.ts +0 -336
  206. package/.yalc/@node-dlc/core/lib/dlc/TxFinalizer.ts +0 -217
  207. package/.yalc/@node-dlc/core/lib/dlc/finance/Builder.ts +0 -730
  208. package/.yalc/@node-dlc/core/lib/dlc/finance/CoveredCall.ts +0 -110
  209. package/.yalc/@node-dlc/core/lib/dlc/finance/CsoInfo.ts +0 -498
  210. package/.yalc/@node-dlc/core/lib/dlc/finance/LinearPayout.ts +0 -94
  211. package/.yalc/@node-dlc/core/lib/dlc/finance/LongCall.ts +0 -74
  212. package/.yalc/@node-dlc/core/lib/dlc/finance/LongPut.ts +0 -74
  213. package/.yalc/@node-dlc/core/lib/dlc/finance/OptionInfo.ts +0 -182
  214. package/.yalc/@node-dlc/core/lib/dlc/finance/ShortPut.ts +0 -75
  215. package/.yalc/@node-dlc/core/lib/index.ts +0 -66
  216. package/.yalc/@node-dlc/core/lib/lightning/ChannelId.ts +0 -54
  217. package/.yalc/@node-dlc/core/lib/lightning/ChannelKeys.ts +0 -109
  218. package/.yalc/@node-dlc/core/lib/lightning/CommitmentNumber.ts +0 -94
  219. package/.yalc/@node-dlc/core/lib/lightning/CommitmentSecret.ts +0 -41
  220. package/.yalc/@node-dlc/core/lib/lightning/CommitmentSecretStore.ts +0 -84
  221. package/.yalc/@node-dlc/core/lib/lightning/Htlc.ts +0 -52
  222. package/.yalc/@node-dlc/core/lib/lightning/HtlcDirection.ts +0 -17
  223. package/.yalc/@node-dlc/core/lib/lightning/ScriptFactory.ts +0 -150
  224. package/.yalc/@node-dlc/core/lib/lightning/TxFactory.ts +0 -338
  225. package/.yalc/@node-dlc/core/lib/utils/BigIntUtils.ts +0 -64
  226. package/.yalc/@node-dlc/core/lib/utils/Precision.ts +0 -23
  227. package/.yalc/@node-dlc/core/package.json +0 -38
  228. package/.yalc/@node-dlc/core/tsconfig.json +0 -8
  229. package/.yalc/@node-dlc/core/yalc.sig +0 -1
  230. package/yalc.lock +0 -10
@@ -1,336 +0,0 @@
1
- /**
2
- * DLC Transaction Builder with support for "exact amount" DLC scenarios.
3
- *
4
- * Key improvements:
5
- * - Dust filtering: Only creates change outputs above DUST_LIMIT (1000 sats)
6
- * - No-change support: Enables splicing with exact UTXO amounts
7
- * - Max collateral calculation: Helper for determining exact amounts
8
- *
9
- * This matches the C++ layer behavior and fixes issues with DLC splicing
10
- * where users want to use exact UTXO amounts without change outputs.
11
- */
12
-
13
- import {
14
- LockTime,
15
- OutPoint,
16
- Script,
17
- Tx,
18
- TxBuilder,
19
- Value,
20
- } from '@node-dlc/bitcoin';
21
- import {
22
- DlcAcceptWithoutSigs,
23
- DlcOffer,
24
- FundingInput,
25
- MessageType,
26
- } from '@node-dlc/messaging';
27
- import Decimal from 'decimal.js';
28
-
29
- import { DualFundingTxFinalizer } from './TxFinalizer';
30
-
31
- // Dust limit matching C++ implementation (1000 satoshis)
32
- export const DUST_LIMIT = BigInt(1000);
33
-
34
- export class DlcTxBuilder {
35
- constructor(
36
- readonly dlcOffer: DlcOffer,
37
- readonly dlcAccept: DlcAcceptWithoutSigs,
38
- ) {}
39
-
40
- public buildFundingTransaction(): Tx {
41
- const txBuilder = new BatchDlcTxBuilder([this.dlcOffer], [this.dlcAccept]);
42
- return txBuilder.buildFundingTransaction();
43
- }
44
- }
45
-
46
- export class BatchDlcTxBuilder {
47
- constructor(
48
- readonly dlcOffers: DlcOffer[],
49
- readonly dlcAccepts: DlcAcceptWithoutSigs[],
50
- ) {}
51
-
52
- /**
53
- * Calculates the maximum collateral that can be used given a set of funding inputs
54
- * for exact-amount DLC scenarios (no change outputs).
55
- *
56
- * @param fundingInputs The inputs to be used for funding
57
- * @param feeRatePerVb Fee rate in satoshis per virtual byte
58
- * @param numContracts Number of DLC contracts being created (default: 1)
59
- * @returns Maximum collateral amount in satoshis
60
- *
61
- * @example
62
- * ```typescript
63
- * // Calculate max collateral for DLC splicing scenario
64
- * const dlcFundingInput = getDlcFundingInput(); // 970,332 sats
65
- * const additionalInput = getAdditionalInput(); // 100,000 sats
66
- * const inputs = [dlcFundingInput, additionalInput];
67
- *
68
- * const maxCollateral = BatchDlcTxBuilder.calculateMaxCollateral(
69
- * inputs,
70
- * BigInt(1), // 1 sat/vB fee rate
71
- * 1 // Single DLC contract
72
- * );
73
- *
74
- * // Use maxCollateral in DLC offer to ensure exact amount with no change
75
- * const dlcOffer = createDlcOffer(contractInfo, maxCollateral, ...);
76
- * ```
77
- */
78
- public static calculateMaxCollateral(
79
- fundingInputs: FundingInput[],
80
- feeRatePerVb: bigint,
81
- numContracts = 1,
82
- ): bigint {
83
- // Calculate total input value
84
- const totalInputValue = fundingInputs.reduce((total, input) => {
85
- return total + input.prevTx.outputs[input.prevTxVout].value.sats;
86
- }, BigInt(0));
87
-
88
- // Create a temporary finalizer to calculate fees
89
- const fakeSPK = Buffer.from(
90
- '0014663117d27e78eb432505180654e603acb30e8a4a',
91
- 'hex',
92
- );
93
- const finalizer = new DualFundingTxFinalizer(
94
- fundingInputs,
95
- fakeSPK,
96
- fakeSPK,
97
- [], // No accepter inputs for single-funded scenario
98
- fakeSPK,
99
- fakeSPK,
100
- feeRatePerVb,
101
- numContracts,
102
- );
103
-
104
- // For exact-amount scenarios, we need to account for:
105
- // 1. Future fees (for CET/refund transactions)
106
- // 2. Funding transaction fees
107
- const futureFee = finalizer.offerFutureFee;
108
- const fundingFee = finalizer.offerFundingFee;
109
-
110
- // Maximum collateral is input value minus all fees
111
- const maxCollateral = totalInputValue - futureFee - fundingFee;
112
-
113
- // Ensure we don't return negative values
114
- return maxCollateral > BigInt(0) ? maxCollateral : BigInt(0);
115
- }
116
-
117
- public buildFundingTransaction(): Tx {
118
- const tx = new TxBuilder();
119
- tx.version = 2;
120
- tx.locktime = LockTime.zero();
121
-
122
- if (this.dlcOffers.length !== this.dlcAccepts.length)
123
- throw Error('DlcOffers and DlcAccepts must be the same length');
124
- if (this.dlcOffers.length === 0) throw Error('DlcOffers must not be empty');
125
- if (this.dlcAccepts.length === 0)
126
- throw Error('DlcAccepts must not be empty');
127
-
128
- // Ensure all DLC offers and accepts have the same funding inputs
129
- this.ensureSameFundingInputs();
130
-
131
- const multisigScripts: Script[] = [];
132
- for (let i = 0; i < this.dlcOffers.length; i++) {
133
- const offer = this.dlcOffers[i];
134
- const accept = this.dlcAccepts[i];
135
-
136
- multisigScripts.push(
137
- Buffer.compare(offer.fundingPubkey, accept.fundingPubkey) === -1
138
- ? Script.p2msLock(2, offer.fundingPubkey, accept.fundingPubkey)
139
- : Script.p2msLock(2, accept.fundingPubkey, offer.fundingPubkey),
140
- );
141
- }
142
-
143
- const witScripts = multisigScripts.map((multisigScript) =>
144
- Script.p2wshLock(multisigScript),
145
- );
146
-
147
- const finalizer = new DualFundingTxFinalizer(
148
- this.dlcOffers[0].fundingInputs,
149
- this.dlcOffers[0].payoutSpk,
150
- this.dlcOffers[0].changeSpk,
151
- this.dlcAccepts[0].fundingInputs,
152
- this.dlcAccepts[0].payoutSpk,
153
- this.dlcAccepts[0].changeSpk,
154
- this.dlcOffers[0].feeRatePerVb,
155
- this.dlcOffers.length,
156
- );
157
-
158
- this.dlcOffers[0].fundingInputs.forEach((input) => {
159
- if (input.type !== MessageType.FundingInput)
160
- throw new Error('Input is not a funding input');
161
- });
162
- const offerFundingInputs: FundingInput[] = this.dlcOffers[0].fundingInputs.map(
163
- (input) => input as FundingInput,
164
- );
165
-
166
- const offerTotalFunding = offerFundingInputs.reduce((total, input) => {
167
- return total + input.prevTx.outputs[input.prevTxVout].value.sats;
168
- }, BigInt(0));
169
-
170
- const acceptTotalFunding = this.dlcAccepts[0].fundingInputs.reduce(
171
- (total, input) => {
172
- return total + input.prevTx.outputs[input.prevTxVout].value.sats;
173
- },
174
- BigInt(0),
175
- );
176
-
177
- const fundingInputs: FundingInput[] = [
178
- ...offerFundingInputs,
179
- ...this.dlcAccepts[0].fundingInputs,
180
- ];
181
-
182
- fundingInputs.sort(
183
- (a, b) => Number(a.inputSerialId) - Number(b.inputSerialId),
184
- );
185
-
186
- fundingInputs.forEach((input) => {
187
- tx.addInput(
188
- OutPoint.fromString(
189
- `${input.prevTx.txId.toString()}:${input.prevTxVout}`,
190
- ),
191
- );
192
- });
193
-
194
- const offerInput = this.dlcOffers.reduce(
195
- (total, offer) => total + offer.offerCollateral,
196
- BigInt(0),
197
- );
198
- const acceptInput = this.dlcAccepts.reduce(
199
- (total, accept) => total + accept.acceptCollateral,
200
- BigInt(0),
201
- );
202
-
203
- const totalInputs = this.dlcOffers.map((offer, i) => {
204
- const offerInput = offer.offerCollateral;
205
- const acceptInput = this.dlcAccepts[i].acceptCollateral;
206
- return offerInput + acceptInput;
207
- });
208
-
209
- const fundingValues = totalInputs.map((totalInput) => {
210
- const offerFutureFeePerOffer = new Decimal(
211
- finalizer.offerFutureFee.toString(),
212
- )
213
- .div(this.dlcOffers.length)
214
- .ceil()
215
- .toNumber();
216
- const acceptFutureFeePerAccept = new Decimal(
217
- finalizer.acceptFutureFee.toString(),
218
- )
219
- .div(this.dlcAccepts.length)
220
- .ceil()
221
- .toNumber();
222
-
223
- return (
224
- totalInput +
225
- Value.fromSats(offerFutureFeePerOffer).sats +
226
- Value.fromSats(acceptFutureFeePerAccept).sats
227
- );
228
- });
229
-
230
- const offerChangeValue =
231
- offerTotalFunding - offerInput - finalizer.offerFees;
232
- const acceptChangeValue =
233
- acceptTotalFunding - acceptInput - finalizer.acceptFees;
234
-
235
- // Validate that we have sufficient funds
236
- if (offerChangeValue < BigInt(0)) {
237
- throw new Error(
238
- `Insufficient funds for offerer: need ${
239
- offerInput + finalizer.offerFees
240
- } sats, have ${offerTotalFunding} sats`,
241
- );
242
- }
243
-
244
- // In single-funded DLCs, if accepter has no inputs, they don't pay fees
245
- // This matches the C++ layer behavior where parties with no inputs have zero fees
246
- if (acceptChangeValue < BigInt(0) && acceptTotalFunding > BigInt(0)) {
247
- throw new Error(
248
- `Insufficient funds for accepter: need ${
249
- acceptInput + finalizer.acceptFees
250
- } sats, have ${acceptTotalFunding} sats`,
251
- );
252
- }
253
-
254
- const outputs: Output[] = [];
255
- witScripts.forEach((witScript, i) => {
256
- outputs.push({
257
- value: Value.fromSats(Number(fundingValues[i])),
258
- script: witScript,
259
- serialId: this.dlcOffers[i].fundOutputSerialId,
260
- });
261
- });
262
-
263
- // Dust filtering: Only create change outputs if they're above dust threshold
264
- // This matches the C++ implementation and enables "exact amount" DLC scenarios
265
- // where all input value goes into the DLC funding output with no change
266
- if (offerChangeValue >= DUST_LIMIT) {
267
- outputs.push({
268
- value: Value.fromSats(Number(offerChangeValue)),
269
- script: Script.p2wpkhLock(this.dlcOffers[0].changeSpk.slice(2)),
270
- serialId: this.dlcOffers[0].changeSerialId,
271
- });
272
- }
273
-
274
- if (acceptChangeValue >= DUST_LIMIT) {
275
- outputs.push({
276
- value: Value.fromSats(Number(acceptChangeValue)),
277
- script: Script.p2wpkhLock(this.dlcAccepts[0].changeSpk.slice(2)),
278
- serialId: this.dlcAccepts[0].changeSerialId,
279
- });
280
- }
281
-
282
- outputs.sort((a, b) => Number(a.serialId) - Number(b.serialId));
283
-
284
- outputs.forEach((output) => {
285
- tx.addOutput(output.value, output.script);
286
- });
287
-
288
- return tx.toTx();
289
- }
290
-
291
- private ensureSameFundingInputs(): void {
292
- // Check for offers
293
- const referenceOfferInputs = this.dlcOffers[0].fundingInputs.map((input) =>
294
- input.serialize().toString('hex'),
295
- );
296
- for (let i = 1; i < this.dlcOffers.length; i++) {
297
- const currentInputs = this.dlcOffers[i].fundingInputs.map((input) =>
298
- input.serialize().toString('hex'),
299
- );
300
- if (!this.arraysEqual(referenceOfferInputs, currentInputs)) {
301
- throw new Error(
302
- `Funding inputs for offer ${i} do not match the first offer's funding inputs.`,
303
- );
304
- }
305
- }
306
-
307
- // Check for accepts
308
- const referenceAcceptInputs = this.dlcAccepts[0].fundingInputs.map(
309
- (input) => input.serialize().toString('hex'),
310
- );
311
- for (let i = 1; i < this.dlcAccepts.length; i++) {
312
- const currentInputs = this.dlcAccepts[i].fundingInputs.map((input) =>
313
- input.serialize().toString('hex'),
314
- );
315
- if (!this.arraysEqual(referenceAcceptInputs, currentInputs)) {
316
- throw new Error(
317
- `Funding inputs for accept ${i} do not match the first accept's funding inputs.`,
318
- );
319
- }
320
- }
321
- }
322
-
323
- private arraysEqual(arr1: string[], arr2: string[]): boolean {
324
- if (arr1.length !== arr2.length) return false;
325
- for (let i = 0; i < arr1.length; i++) {
326
- if (arr1[i] !== arr2[i]) return false;
327
- }
328
- return true;
329
- }
330
- }
331
-
332
- interface Output {
333
- value: Value;
334
- script: Script;
335
- serialId: bigint;
336
- }
@@ -1,217 +0,0 @@
1
- import { FundingInput, MessageType } from '@node-dlc/messaging';
2
- import { Decimal } from 'decimal.js';
3
-
4
- const BATCH_FUND_TX_BASE_WEIGHT = 42;
5
- const FUNDING_OUTPUT_SIZE = 43;
6
-
7
- export class DualFundingTxFinalizer {
8
- constructor(
9
- readonly offerInputs: FundingInput[],
10
- readonly offerPayoutSPK: Buffer,
11
- readonly offerChangeSPK: Buffer,
12
- readonly acceptInputs: FundingInput[],
13
- readonly acceptPayoutSPK: Buffer,
14
- readonly acceptChangeSPK: Buffer,
15
- readonly feeRate: bigint,
16
- readonly numContracts = 1,
17
- ) {}
18
-
19
- private computeFees(
20
- _inputs: FundingInput[],
21
- payoutSPK: Buffer,
22
- changeSPK: Buffer,
23
- numContracts: number,
24
- ): IFees {
25
- // If no inputs, return zero fees (matches C++ layer behavior for single-funded DLCs)
26
- if (_inputs.length === 0) {
27
- return { futureFee: BigInt(0), fundingFee: BigInt(0) };
28
- }
29
-
30
- _inputs.forEach((input) => {
31
- if (input.type !== MessageType.FundingInput) {
32
- console.error('input', input);
33
- throw new Error('Input is not a funding input');
34
- }
35
- });
36
- const inputs: FundingInput[] = _inputs.map(
37
- (input) => input as FundingInput,
38
- );
39
- // https://github.com/discreetlogcontracts/dlcspecs/blob/8ee4bbe816c9881c832b1ce320b9f14c72e3506f/Transactions.md#expected-weight-of-the-contract-execution-or-refund-transaction
40
- const futureFeeWeight = 249 + 4 * payoutSPK.length;
41
- const futureFeeVBytes = new Decimal(futureFeeWeight)
42
- .times(numContracts)
43
- .div(4)
44
- .ceil()
45
- .toNumber();
46
- const futureFee = this.feeRate * BigInt(futureFeeVBytes);
47
-
48
- // https://github.com/discreetlogcontracts/dlcspecs/blob/8ee4bbe816c9881c832b1ce320b9f14c72e3506f/Transactions.md#expected-weight-of-the-funding-transaction
49
- const inputWeight = inputs.reduce((total, input) => {
50
- return total + 164 + input.maxWitnessLen + input.scriptSigLength();
51
- }, 0);
52
- const contractWeight =
53
- (BATCH_FUND_TX_BASE_WEIGHT + FUNDING_OUTPUT_SIZE * numContracts * 4) / 2;
54
- const outputWeight = 36 + 4 * changeSPK.length + contractWeight;
55
- const weight = outputWeight + inputWeight;
56
- const vbytes = new Decimal(weight).div(4).ceil().toNumber();
57
- const fundingFee = this.feeRate * BigInt(vbytes);
58
-
59
- return { futureFee, fundingFee };
60
- }
61
-
62
- private getOfferFees(): IFees {
63
- return this.computeFees(
64
- this.offerInputs,
65
- this.offerPayoutSPK,
66
- this.offerChangeSPK,
67
- this.numContracts,
68
- );
69
- }
70
-
71
- private getAcceptFees(): IFees {
72
- return this.computeFees(
73
- this.acceptInputs,
74
- this.acceptPayoutSPK,
75
- this.acceptChangeSPK,
76
- this.numContracts,
77
- );
78
- }
79
-
80
- public get offerFees(): bigint {
81
- const { futureFee, fundingFee } = this.getOfferFees();
82
- return futureFee + fundingFee;
83
- }
84
-
85
- public get offerFutureFee(): bigint {
86
- return this.getOfferFees().futureFee;
87
- }
88
-
89
- public get offerFundingFee(): bigint {
90
- return this.getOfferFees().fundingFee;
91
- }
92
-
93
- public get acceptFees(): bigint {
94
- const { futureFee, fundingFee } = this.getAcceptFees();
95
- return futureFee + fundingFee;
96
- }
97
-
98
- public get acceptFutureFee(): bigint {
99
- return this.getAcceptFees().futureFee;
100
- }
101
-
102
- public get acceptFundingFee(): bigint {
103
- return this.getAcceptFees().fundingFee;
104
- }
105
- }
106
-
107
- export class DualClosingTxFinalizer {
108
- constructor(
109
- readonly initiatorInputs: FundingInput[],
110
- readonly offerPayoutSPK: Buffer,
111
- readonly acceptPayoutSPK: Buffer,
112
- readonly feeRate: bigint,
113
- ) {}
114
-
115
- private computeFees(payoutSPK: Buffer, _inputs: FundingInput[] = []): bigint {
116
- _inputs.forEach((input) => {
117
- if (input.type !== MessageType.FundingInput)
118
- throw new Error('Input is not a funding input');
119
- });
120
- const inputs: FundingInput[] = _inputs.map(
121
- (input) => input as FundingInput,
122
- );
123
- // https://gist.github.com/matthewjablack/08c36baa513af9377508111405b22e03
124
- const inputWeight = inputs.reduce((total, input) => {
125
- return total + 164 + input.maxWitnessLen + input.scriptSigLength();
126
- }, 0);
127
- const outputWeight = 36 + 4 * payoutSPK.length;
128
- const weight = 213 + outputWeight + inputWeight;
129
- const vbytes = new Decimal(weight).div(4).ceil().toNumber();
130
- const fee = this.feeRate * BigInt(vbytes);
131
-
132
- return fee;
133
- }
134
-
135
- private getOfferInitiatorFees(): bigint {
136
- return this.computeFees(this.offerPayoutSPK, this.initiatorInputs);
137
- }
138
-
139
- private getOfferReciprocatorFees(): bigint {
140
- return this.computeFees(this.offerPayoutSPK);
141
- }
142
-
143
- private getAcceptInitiatorFees(): bigint {
144
- return this.computeFees(this.acceptPayoutSPK, this.initiatorInputs);
145
- }
146
-
147
- private getAcceptReciprocatorFees(): bigint {
148
- return this.computeFees(this.acceptPayoutSPK);
149
- }
150
-
151
- public get offerInitiatorFees(): bigint {
152
- return this.getOfferInitiatorFees();
153
- }
154
-
155
- public get offerReciprocatorFees(): bigint {
156
- return this.getOfferReciprocatorFees();
157
- }
158
-
159
- public get acceptInitiatorFees(): bigint {
160
- return this.getAcceptInitiatorFees();
161
- }
162
-
163
- public get acceptReciprocatorFees(): bigint {
164
- return this.getAcceptReciprocatorFees();
165
- }
166
- }
167
-
168
- interface IFees {
169
- futureFee: bigint;
170
- fundingFee: bigint;
171
- }
172
-
173
- export const getFinalizer = (
174
- feeRate: bigint,
175
- offerInputs?: FundingInput[],
176
- acceptInputs?: FundingInput[],
177
- numContracts?: number,
178
- ): DualFundingTxFinalizer => {
179
- const input = new FundingInput();
180
- input.maxWitnessLen = 108;
181
- input.redeemScript = Buffer.from('', 'hex');
182
-
183
- const fakeSPK = Buffer.from(
184
- '0014663117d27e78eb432505180654e603acb30e8a4a',
185
- 'hex',
186
- );
187
-
188
- offerInputs = offerInputs || Array.from({ length: 1 }, () => input);
189
-
190
- acceptInputs = acceptInputs || Array.from({ length: 1 }, () => input);
191
-
192
- return new DualFundingTxFinalizer(
193
- offerInputs,
194
- fakeSPK,
195
- fakeSPK,
196
- acceptInputs,
197
- fakeSPK,
198
- fakeSPK,
199
- feeRate,
200
- numContracts,
201
- );
202
- };
203
-
204
- export const getFinalizerByCount = (
205
- feeRate: bigint,
206
- numOfferInputs: number,
207
- numAcceptInputs: number,
208
- numContracts: number,
209
- ): DualFundingTxFinalizer => {
210
- const input = new FundingInput();
211
- input.maxWitnessLen = 108;
212
- input.redeemScript = Buffer.from('', 'hex');
213
-
214
- const offerInputs = Array.from({ length: numOfferInputs }, () => input);
215
- const acceptInputs = Array.from({ length: numAcceptInputs }, () => input);
216
- return getFinalizer(feeRate, offerInputs, acceptInputs, numContracts);
217
- };