@atomicfinance/bitcoin-wallet-provider 4.2.6 → 4.2.8

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 (226) hide show
  1. package/.turbo/turbo-build.log +4 -5
  2. package/CHANGELOG.md +24 -0
  3. package/package.json +7 -7
  4. package/.turbo/turbo-lint$colon$fix.log +0 -4
  5. package/.turbo/turbo-lint.log +0 -5
  6. package/.turbo/turbo-test.log +0 -0
  7. package/.yalc/@node-dlc/core/.nyc_output/687a3c14-9765-45fd-a1fe-f7db3d56fee4.json +0 -1
  8. package/.yalc/@node-dlc/core/.nyc_output/processinfo/687a3c14-9765-45fd-a1fe-f7db3d56fee4.json +0 -1
  9. package/.yalc/@node-dlc/core/.nyc_output/processinfo/index.json +0 -1
  10. package/.yalc/@node-dlc/core/README.md +0 -11
  11. package/.yalc/@node-dlc/core/__tests__/core.spec.ts +0 -7
  12. package/.yalc/@node-dlc/core/__tests__/dlc/CETCalculator.spec.ts +0 -1029
  13. package/.yalc/@node-dlc/core/__tests__/dlc/CoinSelect.spec.ts +0 -179
  14. package/.yalc/@node-dlc/core/__tests__/dlc/PolynomialPayoutCurve.spec.ts +0 -345
  15. package/.yalc/@node-dlc/core/__tests__/dlc/TxBuilder.spec.ts +0 -424
  16. package/.yalc/@node-dlc/core/__tests__/dlc/finance/Builder.spec.ts +0 -492
  17. package/.yalc/@node-dlc/core/__tests__/dlc/finance/CoveredCall.spec.ts +0 -112
  18. package/.yalc/@node-dlc/core/__tests__/dlc/finance/CsoInfo.spec.ts +0 -1124
  19. package/.yalc/@node-dlc/core/__tests__/dlc/finance/LongCall.spec.ts +0 -55
  20. package/.yalc/@node-dlc/core/__tests__/dlc/finance/LongPut.spec.ts +0 -55
  21. package/.yalc/@node-dlc/core/__tests__/dlc/finance/OptionInfo.spec.ts +0 -226
  22. package/.yalc/@node-dlc/core/__tests__/dlc/finance/ShortPut.spec.ts +0 -62
  23. package/.yalc/@node-dlc/core/__tests__/tsconfig.json +0 -8
  24. package/.yalc/@node-dlc/core/__tests__/utils/precision.spec.ts +0 -40
  25. package/.yalc/@node-dlc/core/coverage/lcov-report/base.css +0 -224
  26. package/.yalc/@node-dlc/core/coverage/lcov-report/block-navigation.js +0 -79
  27. package/.yalc/@node-dlc/core/coverage/lcov-report/favicon.png +0 -0
  28. package/.yalc/@node-dlc/core/coverage/lcov-report/index.html +0 -171
  29. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/AsyncProcessingQueue.ts.html +0 -269
  30. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/Base32.ts.html +0 -86
  31. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/BigIntUtils.ts.html +0 -86
  32. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/BitField.ts.html +0 -86
  33. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/ChannelId.ts.html +0 -86
  34. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/LinkedList.ts.html +0 -413
  35. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/LinkedListNode.ts.html +0 -122
  36. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/Queue.ts.html +0 -188
  37. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/ShortChannelId.ts.html +0 -86
  38. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/ShortChannelIdUtils.ts.html +0 -107
  39. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/CETCalculator.ts.html +0 -1430
  40. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/CoinSelect.ts.html +0 -431
  41. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/HyperbolaPayoutCurve.ts.html +0 -644
  42. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/PolynomialPayoutCurve.ts.html +0 -878
  43. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/TxBuilder.ts.html +0 -1088
  44. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/TxFinalizer.ts.html +0 -731
  45. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/finance/Builder.ts.html +0 -2270
  46. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/finance/CoveredCall.ts.html +0 -410
  47. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/finance/CsoInfo.ts.html +0 -1574
  48. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/finance/LinearPayout.ts.html +0 -362
  49. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/finance/LongCall.ts.html +0 -302
  50. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/finance/LongPut.ts.html +0 -302
  51. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/finance/OptionInfo.ts.html +0 -626
  52. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/finance/ShortPut.ts.html +0 -305
  53. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/finance/index.html +0 -216
  54. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/index.html +0 -186
  55. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/index.html +0 -261
  56. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/index.ts.html +0 -278
  57. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/lightning/ChannelId.ts.html +0 -242
  58. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/lightning/ChannelKeys.ts.html +0 -407
  59. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/lightning/CommitmentNumber.ts.html +0 -362
  60. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/lightning/CommitmentSecret.ts.html +0 -203
  61. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/lightning/CommitmentSecretStore.ts.html +0 -332
  62. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/lightning/Htlc.ts.html +0 -236
  63. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/lightning/HtlcDirection.ts.html +0 -131
  64. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/lightning/ScriptFactory.ts.html +0 -530
  65. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/lightning/TxFactory.ts.html +0 -1094
  66. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/lightning/index.html +0 -231
  67. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/utils/BigIntUtils.ts.html +0 -272
  68. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/utils/Precision.ts.html +0 -149
  69. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/utils/index.html +0 -126
  70. package/.yalc/@node-dlc/core/coverage/lcov-report/prettify.css +0 -1
  71. package/.yalc/@node-dlc/core/coverage/lcov-report/prettify.js +0 -2
  72. package/.yalc/@node-dlc/core/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  73. package/.yalc/@node-dlc/core/coverage/lcov-report/sorter.js +0 -170
  74. package/.yalc/@node-dlc/core/coverage/lcov.info +0 -2426
  75. package/.yalc/@node-dlc/core/dist/AsyncProcessingQueue.d.ts +0 -22
  76. package/.yalc/@node-dlc/core/dist/AsyncProcessingQueue.js +0 -55
  77. package/.yalc/@node-dlc/core/dist/AsyncProcessingQueue.js.map +0 -1
  78. package/.yalc/@node-dlc/core/dist/Base32.d.ts +0 -1
  79. package/.yalc/@node-dlc/core/dist/Base32.js +0 -7
  80. package/.yalc/@node-dlc/core/dist/Base32.js.map +0 -1
  81. package/.yalc/@node-dlc/core/dist/BigIntUtils.d.ts +0 -1
  82. package/.yalc/@node-dlc/core/dist/BigIntUtils.js +0 -8
  83. package/.yalc/@node-dlc/core/dist/BigIntUtils.js.map +0 -1
  84. package/.yalc/@node-dlc/core/dist/BitField.d.ts +0 -1
  85. package/.yalc/@node-dlc/core/dist/BitField.js +0 -7
  86. package/.yalc/@node-dlc/core/dist/BitField.js.map +0 -1
  87. package/.yalc/@node-dlc/core/dist/ChannelId.d.ts +0 -1
  88. package/.yalc/@node-dlc/core/dist/ChannelId.js +0 -7
  89. package/.yalc/@node-dlc/core/dist/ChannelId.js.map +0 -1
  90. package/.yalc/@node-dlc/core/dist/LinkedList.d.ts +0 -30
  91. package/.yalc/@node-dlc/core/dist/LinkedList.js +0 -104
  92. package/.yalc/@node-dlc/core/dist/LinkedList.js.map +0 -1
  93. package/.yalc/@node-dlc/core/dist/LinkedListNode.d.ts +0 -9
  94. package/.yalc/@node-dlc/core/dist/LinkedListNode.js +0 -15
  95. package/.yalc/@node-dlc/core/dist/LinkedListNode.js.map +0 -1
  96. package/.yalc/@node-dlc/core/dist/Queue.d.ts +0 -22
  97. package/.yalc/@node-dlc/core/dist/Queue.js +0 -38
  98. package/.yalc/@node-dlc/core/dist/Queue.js.map +0 -1
  99. package/.yalc/@node-dlc/core/dist/ShortChannelId.d.ts +0 -1
  100. package/.yalc/@node-dlc/core/dist/ShortChannelId.js +0 -7
  101. package/.yalc/@node-dlc/core/dist/ShortChannelId.js.map +0 -1
  102. package/.yalc/@node-dlc/core/dist/ShortChannelIdUtils.d.ts +0 -1
  103. package/.yalc/@node-dlc/core/dist/ShortChannelIdUtils.js +0 -12
  104. package/.yalc/@node-dlc/core/dist/ShortChannelIdUtils.js.map +0 -1
  105. package/.yalc/@node-dlc/core/dist/dlc/CETCalculator.d.ts +0 -50
  106. package/.yalc/@node-dlc/core/dist/dlc/CETCalculator.js +0 -332
  107. package/.yalc/@node-dlc/core/dist/dlc/CETCalculator.js.map +0 -1
  108. package/.yalc/@node-dlc/core/dist/dlc/CoinSelect.d.ts +0 -23
  109. package/.yalc/@node-dlc/core/dist/dlc/CoinSelect.js +0 -77
  110. package/.yalc/@node-dlc/core/dist/dlc/CoinSelect.js.map +0 -1
  111. package/.yalc/@node-dlc/core/dist/dlc/HyperbolaPayoutCurve.d.ts +0 -20
  112. package/.yalc/@node-dlc/core/dist/dlc/HyperbolaPayoutCurve.js +0 -117
  113. package/.yalc/@node-dlc/core/dist/dlc/HyperbolaPayoutCurve.js.map +0 -1
  114. package/.yalc/@node-dlc/core/dist/dlc/PayoutCurve.d.ts +0 -5
  115. package/.yalc/@node-dlc/core/dist/dlc/PayoutCurve.js +0 -3
  116. package/.yalc/@node-dlc/core/dist/dlc/PayoutCurve.js.map +0 -1
  117. package/.yalc/@node-dlc/core/dist/dlc/PolynomialPayoutCurve.d.ts +0 -52
  118. package/.yalc/@node-dlc/core/dist/dlc/PolynomialPayoutCurve.js +0 -173
  119. package/.yalc/@node-dlc/core/dist/dlc/PolynomialPayoutCurve.js.map +0 -1
  120. package/.yalc/@node-dlc/core/dist/dlc/TxBuilder.d.ts +0 -55
  121. package/.yalc/@node-dlc/core/dist/dlc/TxBuilder.js +0 -217
  122. package/.yalc/@node-dlc/core/dist/dlc/TxBuilder.js.map +0 -1
  123. package/.yalc/@node-dlc/core/dist/dlc/TxFinalizer.d.ts +0 -40
  124. package/.yalc/@node-dlc/core/dist/dlc/TxFinalizer.js +0 -146
  125. package/.yalc/@node-dlc/core/dist/dlc/TxFinalizer.js.map +0 -1
  126. package/.yalc/@node-dlc/core/dist/dlc/finance/Builder.d.ts +0 -193
  127. package/.yalc/@node-dlc/core/dist/dlc/finance/Builder.js +0 -422
  128. package/.yalc/@node-dlc/core/dist/dlc/finance/Builder.js.map +0 -1
  129. package/.yalc/@node-dlc/core/dist/dlc/finance/CoveredCall.d.ts +0 -13
  130. package/.yalc/@node-dlc/core/dist/dlc/finance/CoveredCall.js +0 -67
  131. package/.yalc/@node-dlc/core/dist/dlc/finance/CoveredCall.js.map +0 -1
  132. package/.yalc/@node-dlc/core/dist/dlc/finance/CsoInfo.d.ts +0 -114
  133. package/.yalc/@node-dlc/core/dist/dlc/finance/CsoInfo.js +0 -290
  134. package/.yalc/@node-dlc/core/dist/dlc/finance/CsoInfo.js.map +0 -1
  135. package/.yalc/@node-dlc/core/dist/dlc/finance/LinearPayout.d.ts +0 -6
  136. package/.yalc/@node-dlc/core/dist/dlc/finance/LinearPayout.js +0 -79
  137. package/.yalc/@node-dlc/core/dist/dlc/finance/LinearPayout.js.map +0 -1
  138. package/.yalc/@node-dlc/core/dist/dlc/finance/LongCall.d.ts +0 -13
  139. package/.yalc/@node-dlc/core/dist/dlc/finance/LongCall.js +0 -47
  140. package/.yalc/@node-dlc/core/dist/dlc/finance/LongCall.js.map +0 -1
  141. package/.yalc/@node-dlc/core/dist/dlc/finance/LongPut.d.ts +0 -13
  142. package/.yalc/@node-dlc/core/dist/dlc/finance/LongPut.js +0 -47
  143. package/.yalc/@node-dlc/core/dist/dlc/finance/LongPut.js.map +0 -1
  144. package/.yalc/@node-dlc/core/dist/dlc/finance/OptionInfo.d.ts +0 -20
  145. package/.yalc/@node-dlc/core/dist/dlc/finance/OptionInfo.js +0 -101
  146. package/.yalc/@node-dlc/core/dist/dlc/finance/OptionInfo.js.map +0 -1
  147. package/.yalc/@node-dlc/core/dist/dlc/finance/ShortPut.d.ts +0 -12
  148. package/.yalc/@node-dlc/core/dist/dlc/finance/ShortPut.js +0 -46
  149. package/.yalc/@node-dlc/core/dist/dlc/finance/ShortPut.js.map +0 -1
  150. package/.yalc/@node-dlc/core/dist/index.d.ts +0 -39
  151. package/.yalc/@node-dlc/core/dist/index.js +0 -78
  152. package/.yalc/@node-dlc/core/dist/index.js.map +0 -1
  153. package/.yalc/@node-dlc/core/dist/lightning/ChannelId.d.ts +0 -31
  154. package/.yalc/@node-dlc/core/dist/lightning/ChannelId.js +0 -52
  155. package/.yalc/@node-dlc/core/dist/lightning/ChannelId.js.map +0 -1
  156. package/.yalc/@node-dlc/core/dist/lightning/ChannelKeys.d.ts +0 -55
  157. package/.yalc/@node-dlc/core/dist/lightning/ChannelKeys.js +0 -105
  158. package/.yalc/@node-dlc/core/dist/lightning/ChannelKeys.js.map +0 -1
  159. package/.yalc/@node-dlc/core/dist/lightning/CommitmentNumber.d.ts +0 -55
  160. package/.yalc/@node-dlc/core/dist/lightning/CommitmentNumber.js +0 -76
  161. package/.yalc/@node-dlc/core/dist/lightning/CommitmentNumber.js.map +0 -1
  162. package/.yalc/@node-dlc/core/dist/lightning/CommitmentSecret.d.ts +0 -26
  163. package/.yalc/@node-dlc/core/dist/lightning/CommitmentSecret.js +0 -44
  164. package/.yalc/@node-dlc/core/dist/lightning/CommitmentSecret.js.map +0 -1
  165. package/.yalc/@node-dlc/core/dist/lightning/CommitmentSecretStore.d.ts +0 -41
  166. package/.yalc/@node-dlc/core/dist/lightning/CommitmentSecretStore.js +0 -79
  167. package/.yalc/@node-dlc/core/dist/lightning/CommitmentSecretStore.js.map +0 -1
  168. package/.yalc/@node-dlc/core/dist/lightning/Htlc.d.ts +0 -46
  169. package/.yalc/@node-dlc/core/dist/lightning/Htlc.js +0 -46
  170. package/.yalc/@node-dlc/core/dist/lightning/Htlc.js.map +0 -1
  171. package/.yalc/@node-dlc/core/dist/lightning/HtlcDirection.d.ts +0 -16
  172. package/.yalc/@node-dlc/core/dist/lightning/HtlcDirection.js +0 -21
  173. package/.yalc/@node-dlc/core/dist/lightning/HtlcDirection.js.map +0 -1
  174. package/.yalc/@node-dlc/core/dist/lightning/ScriptFactory.d.ts +0 -76
  175. package/.yalc/@node-dlc/core/dist/lightning/ScriptFactory.js +0 -102
  176. package/.yalc/@node-dlc/core/dist/lightning/ScriptFactory.js.map +0 -1
  177. package/.yalc/@node-dlc/core/dist/lightning/TxFactory.d.ts +0 -83
  178. package/.yalc/@node-dlc/core/dist/lightning/TxFactory.js +0 -222
  179. package/.yalc/@node-dlc/core/dist/lightning/TxFactory.js.map +0 -1
  180. package/.yalc/@node-dlc/core/dist/utils/BigIntUtils.d.ts +0 -9
  181. package/.yalc/@node-dlc/core/dist/utils/BigIntUtils.js +0 -59
  182. package/.yalc/@node-dlc/core/dist/utils/BigIntUtils.js.map +0 -1
  183. package/.yalc/@node-dlc/core/dist/utils/Precision.d.ts +0 -13
  184. package/.yalc/@node-dlc/core/dist/utils/Precision.js +0 -28
  185. package/.yalc/@node-dlc/core/dist/utils/Precision.js.map +0 -1
  186. package/.yalc/@node-dlc/core/lib/AsyncProcessingQueue.ts +0 -63
  187. package/.yalc/@node-dlc/core/lib/Base32.ts +0 -2
  188. package/.yalc/@node-dlc/core/lib/BigIntUtils.ts +0 -2
  189. package/.yalc/@node-dlc/core/lib/BitField.ts +0 -2
  190. package/.yalc/@node-dlc/core/lib/ChannelId.ts +0 -2
  191. package/.yalc/@node-dlc/core/lib/LinkedList.ts +0 -111
  192. package/.yalc/@node-dlc/core/lib/LinkedListNode.ts +0 -14
  193. package/.yalc/@node-dlc/core/lib/Queue.ts +0 -36
  194. package/.yalc/@node-dlc/core/lib/ShortChannelId.ts +0 -2
  195. package/.yalc/@node-dlc/core/lib/ShortChannelIdUtils.ts +0 -9
  196. package/.yalc/@node-dlc/core/lib/dlc/CETCalculator.ts +0 -450
  197. package/.yalc/@node-dlc/core/lib/dlc/CoinSelect.ts +0 -117
  198. package/.yalc/@node-dlc/core/lib/dlc/HyperbolaPayoutCurve.ts +0 -188
  199. package/.yalc/@node-dlc/core/lib/dlc/PayoutCurve.ts +0 -6
  200. package/.yalc/@node-dlc/core/lib/dlc/PolynomialPayoutCurve.ts +0 -266
  201. package/.yalc/@node-dlc/core/lib/dlc/TxBuilder.ts +0 -336
  202. package/.yalc/@node-dlc/core/lib/dlc/TxFinalizer.ts +0 -217
  203. package/.yalc/@node-dlc/core/lib/dlc/finance/Builder.ts +0 -730
  204. package/.yalc/@node-dlc/core/lib/dlc/finance/CoveredCall.ts +0 -110
  205. package/.yalc/@node-dlc/core/lib/dlc/finance/CsoInfo.ts +0 -498
  206. package/.yalc/@node-dlc/core/lib/dlc/finance/LinearPayout.ts +0 -94
  207. package/.yalc/@node-dlc/core/lib/dlc/finance/LongCall.ts +0 -74
  208. package/.yalc/@node-dlc/core/lib/dlc/finance/LongPut.ts +0 -74
  209. package/.yalc/@node-dlc/core/lib/dlc/finance/OptionInfo.ts +0 -182
  210. package/.yalc/@node-dlc/core/lib/dlc/finance/ShortPut.ts +0 -75
  211. package/.yalc/@node-dlc/core/lib/index.ts +0 -66
  212. package/.yalc/@node-dlc/core/lib/lightning/ChannelId.ts +0 -54
  213. package/.yalc/@node-dlc/core/lib/lightning/ChannelKeys.ts +0 -109
  214. package/.yalc/@node-dlc/core/lib/lightning/CommitmentNumber.ts +0 -94
  215. package/.yalc/@node-dlc/core/lib/lightning/CommitmentSecret.ts +0 -41
  216. package/.yalc/@node-dlc/core/lib/lightning/CommitmentSecretStore.ts +0 -84
  217. package/.yalc/@node-dlc/core/lib/lightning/Htlc.ts +0 -52
  218. package/.yalc/@node-dlc/core/lib/lightning/HtlcDirection.ts +0 -17
  219. package/.yalc/@node-dlc/core/lib/lightning/ScriptFactory.ts +0 -150
  220. package/.yalc/@node-dlc/core/lib/lightning/TxFactory.ts +0 -338
  221. package/.yalc/@node-dlc/core/lib/utils/BigIntUtils.ts +0 -64
  222. package/.yalc/@node-dlc/core/lib/utils/Precision.ts +0 -23
  223. package/.yalc/@node-dlc/core/package.json +0 -38
  224. package/.yalc/@node-dlc/core/tsconfig.json +0 -8
  225. package/.yalc/@node-dlc/core/yalc.sig +0 -1
  226. 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
- };