@atomicfinance/bitcoin-wallet-provider 4.2.8 → 4.3.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 (226) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/.turbo/turbo-lint$colon$fix.log +4 -0
  3. package/.turbo/turbo-lint.log +5 -0
  4. package/.turbo/turbo-test.log +0 -0
  5. package/.yalc/@node-dlc/core/.nyc_output/687a3c14-9765-45fd-a1fe-f7db3d56fee4.json +1 -0
  6. package/.yalc/@node-dlc/core/.nyc_output/processinfo/687a3c14-9765-45fd-a1fe-f7db3d56fee4.json +1 -0
  7. package/.yalc/@node-dlc/core/.nyc_output/processinfo/index.json +1 -0
  8. package/.yalc/@node-dlc/core/README.md +11 -0
  9. package/.yalc/@node-dlc/core/__tests__/core.spec.ts +7 -0
  10. package/.yalc/@node-dlc/core/__tests__/dlc/CETCalculator.spec.ts +1029 -0
  11. package/.yalc/@node-dlc/core/__tests__/dlc/CoinSelect.spec.ts +179 -0
  12. package/.yalc/@node-dlc/core/__tests__/dlc/PolynomialPayoutCurve.spec.ts +345 -0
  13. package/.yalc/@node-dlc/core/__tests__/dlc/TxBuilder.spec.ts +424 -0
  14. package/.yalc/@node-dlc/core/__tests__/dlc/finance/Builder.spec.ts +492 -0
  15. package/.yalc/@node-dlc/core/__tests__/dlc/finance/CoveredCall.spec.ts +112 -0
  16. package/.yalc/@node-dlc/core/__tests__/dlc/finance/CsoInfo.spec.ts +1124 -0
  17. package/.yalc/@node-dlc/core/__tests__/dlc/finance/LongCall.spec.ts +55 -0
  18. package/.yalc/@node-dlc/core/__tests__/dlc/finance/LongPut.spec.ts +55 -0
  19. package/.yalc/@node-dlc/core/__tests__/dlc/finance/OptionInfo.spec.ts +226 -0
  20. package/.yalc/@node-dlc/core/__tests__/dlc/finance/ShortPut.spec.ts +62 -0
  21. package/.yalc/@node-dlc/core/__tests__/tsconfig.json +8 -0
  22. package/.yalc/@node-dlc/core/__tests__/utils/precision.spec.ts +40 -0
  23. package/.yalc/@node-dlc/core/coverage/lcov-report/base.css +224 -0
  24. package/.yalc/@node-dlc/core/coverage/lcov-report/block-navigation.js +79 -0
  25. package/.yalc/@node-dlc/core/coverage/lcov-report/favicon.png +0 -0
  26. package/.yalc/@node-dlc/core/coverage/lcov-report/index.html +171 -0
  27. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/AsyncProcessingQueue.ts.html +269 -0
  28. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/Base32.ts.html +86 -0
  29. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/BigIntUtils.ts.html +86 -0
  30. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/BitField.ts.html +86 -0
  31. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/ChannelId.ts.html +86 -0
  32. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/LinkedList.ts.html +413 -0
  33. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/LinkedListNode.ts.html +122 -0
  34. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/Queue.ts.html +188 -0
  35. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/ShortChannelId.ts.html +86 -0
  36. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/ShortChannelIdUtils.ts.html +107 -0
  37. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/CETCalculator.ts.html +1430 -0
  38. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/CoinSelect.ts.html +431 -0
  39. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/HyperbolaPayoutCurve.ts.html +644 -0
  40. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/PolynomialPayoutCurve.ts.html +878 -0
  41. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/TxBuilder.ts.html +1088 -0
  42. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/TxFinalizer.ts.html +731 -0
  43. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/finance/Builder.ts.html +2270 -0
  44. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/finance/CoveredCall.ts.html +410 -0
  45. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/finance/CsoInfo.ts.html +1574 -0
  46. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/finance/LinearPayout.ts.html +362 -0
  47. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/finance/LongCall.ts.html +302 -0
  48. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/finance/LongPut.ts.html +302 -0
  49. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/finance/OptionInfo.ts.html +626 -0
  50. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/finance/ShortPut.ts.html +305 -0
  51. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/finance/index.html +216 -0
  52. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/index.html +186 -0
  53. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/index.html +261 -0
  54. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/index.ts.html +278 -0
  55. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/lightning/ChannelId.ts.html +242 -0
  56. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/lightning/ChannelKeys.ts.html +407 -0
  57. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/lightning/CommitmentNumber.ts.html +362 -0
  58. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/lightning/CommitmentSecret.ts.html +203 -0
  59. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/lightning/CommitmentSecretStore.ts.html +332 -0
  60. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/lightning/Htlc.ts.html +236 -0
  61. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/lightning/HtlcDirection.ts.html +131 -0
  62. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/lightning/ScriptFactory.ts.html +530 -0
  63. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/lightning/TxFactory.ts.html +1094 -0
  64. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/lightning/index.html +231 -0
  65. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/utils/BigIntUtils.ts.html +272 -0
  66. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/utils/Precision.ts.html +149 -0
  67. package/.yalc/@node-dlc/core/coverage/lcov-report/lib/utils/index.html +126 -0
  68. package/.yalc/@node-dlc/core/coverage/lcov-report/prettify.css +1 -0
  69. package/.yalc/@node-dlc/core/coverage/lcov-report/prettify.js +2 -0
  70. package/.yalc/@node-dlc/core/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  71. package/.yalc/@node-dlc/core/coverage/lcov-report/sorter.js +170 -0
  72. package/.yalc/@node-dlc/core/coverage/lcov.info +2426 -0
  73. package/.yalc/@node-dlc/core/dist/AsyncProcessingQueue.d.ts +22 -0
  74. package/.yalc/@node-dlc/core/dist/AsyncProcessingQueue.js +55 -0
  75. package/.yalc/@node-dlc/core/dist/AsyncProcessingQueue.js.map +1 -0
  76. package/.yalc/@node-dlc/core/dist/Base32.d.ts +1 -0
  77. package/.yalc/@node-dlc/core/dist/Base32.js +7 -0
  78. package/.yalc/@node-dlc/core/dist/Base32.js.map +1 -0
  79. package/.yalc/@node-dlc/core/dist/BigIntUtils.d.ts +1 -0
  80. package/.yalc/@node-dlc/core/dist/BigIntUtils.js +8 -0
  81. package/.yalc/@node-dlc/core/dist/BigIntUtils.js.map +1 -0
  82. package/.yalc/@node-dlc/core/dist/BitField.d.ts +1 -0
  83. package/.yalc/@node-dlc/core/dist/BitField.js +7 -0
  84. package/.yalc/@node-dlc/core/dist/BitField.js.map +1 -0
  85. package/.yalc/@node-dlc/core/dist/ChannelId.d.ts +1 -0
  86. package/.yalc/@node-dlc/core/dist/ChannelId.js +7 -0
  87. package/.yalc/@node-dlc/core/dist/ChannelId.js.map +1 -0
  88. package/.yalc/@node-dlc/core/dist/LinkedList.d.ts +30 -0
  89. package/.yalc/@node-dlc/core/dist/LinkedList.js +104 -0
  90. package/.yalc/@node-dlc/core/dist/LinkedList.js.map +1 -0
  91. package/.yalc/@node-dlc/core/dist/LinkedListNode.d.ts +9 -0
  92. package/.yalc/@node-dlc/core/dist/LinkedListNode.js +15 -0
  93. package/.yalc/@node-dlc/core/dist/LinkedListNode.js.map +1 -0
  94. package/.yalc/@node-dlc/core/dist/Queue.d.ts +22 -0
  95. package/.yalc/@node-dlc/core/dist/Queue.js +38 -0
  96. package/.yalc/@node-dlc/core/dist/Queue.js.map +1 -0
  97. package/.yalc/@node-dlc/core/dist/ShortChannelId.d.ts +1 -0
  98. package/.yalc/@node-dlc/core/dist/ShortChannelId.js +7 -0
  99. package/.yalc/@node-dlc/core/dist/ShortChannelId.js.map +1 -0
  100. package/.yalc/@node-dlc/core/dist/ShortChannelIdUtils.d.ts +1 -0
  101. package/.yalc/@node-dlc/core/dist/ShortChannelIdUtils.js +12 -0
  102. package/.yalc/@node-dlc/core/dist/ShortChannelIdUtils.js.map +1 -0
  103. package/.yalc/@node-dlc/core/dist/dlc/CETCalculator.d.ts +50 -0
  104. package/.yalc/@node-dlc/core/dist/dlc/CETCalculator.js +332 -0
  105. package/.yalc/@node-dlc/core/dist/dlc/CETCalculator.js.map +1 -0
  106. package/.yalc/@node-dlc/core/dist/dlc/CoinSelect.d.ts +23 -0
  107. package/.yalc/@node-dlc/core/dist/dlc/CoinSelect.js +77 -0
  108. package/.yalc/@node-dlc/core/dist/dlc/CoinSelect.js.map +1 -0
  109. package/.yalc/@node-dlc/core/dist/dlc/HyperbolaPayoutCurve.d.ts +20 -0
  110. package/.yalc/@node-dlc/core/dist/dlc/HyperbolaPayoutCurve.js +117 -0
  111. package/.yalc/@node-dlc/core/dist/dlc/HyperbolaPayoutCurve.js.map +1 -0
  112. package/.yalc/@node-dlc/core/dist/dlc/PayoutCurve.d.ts +5 -0
  113. package/.yalc/@node-dlc/core/dist/dlc/PayoutCurve.js +3 -0
  114. package/.yalc/@node-dlc/core/dist/dlc/PayoutCurve.js.map +1 -0
  115. package/.yalc/@node-dlc/core/dist/dlc/PolynomialPayoutCurve.d.ts +52 -0
  116. package/.yalc/@node-dlc/core/dist/dlc/PolynomialPayoutCurve.js +173 -0
  117. package/.yalc/@node-dlc/core/dist/dlc/PolynomialPayoutCurve.js.map +1 -0
  118. package/.yalc/@node-dlc/core/dist/dlc/TxBuilder.d.ts +55 -0
  119. package/.yalc/@node-dlc/core/dist/dlc/TxBuilder.js +217 -0
  120. package/.yalc/@node-dlc/core/dist/dlc/TxBuilder.js.map +1 -0
  121. package/.yalc/@node-dlc/core/dist/dlc/TxFinalizer.d.ts +40 -0
  122. package/.yalc/@node-dlc/core/dist/dlc/TxFinalizer.js +146 -0
  123. package/.yalc/@node-dlc/core/dist/dlc/TxFinalizer.js.map +1 -0
  124. package/.yalc/@node-dlc/core/dist/dlc/finance/Builder.d.ts +193 -0
  125. package/.yalc/@node-dlc/core/dist/dlc/finance/Builder.js +422 -0
  126. package/.yalc/@node-dlc/core/dist/dlc/finance/Builder.js.map +1 -0
  127. package/.yalc/@node-dlc/core/dist/dlc/finance/CoveredCall.d.ts +13 -0
  128. package/.yalc/@node-dlc/core/dist/dlc/finance/CoveredCall.js +67 -0
  129. package/.yalc/@node-dlc/core/dist/dlc/finance/CoveredCall.js.map +1 -0
  130. package/.yalc/@node-dlc/core/dist/dlc/finance/CsoInfo.d.ts +114 -0
  131. package/.yalc/@node-dlc/core/dist/dlc/finance/CsoInfo.js +290 -0
  132. package/.yalc/@node-dlc/core/dist/dlc/finance/CsoInfo.js.map +1 -0
  133. package/.yalc/@node-dlc/core/dist/dlc/finance/LinearPayout.d.ts +6 -0
  134. package/.yalc/@node-dlc/core/dist/dlc/finance/LinearPayout.js +79 -0
  135. package/.yalc/@node-dlc/core/dist/dlc/finance/LinearPayout.js.map +1 -0
  136. package/.yalc/@node-dlc/core/dist/dlc/finance/LongCall.d.ts +13 -0
  137. package/.yalc/@node-dlc/core/dist/dlc/finance/LongCall.js +47 -0
  138. package/.yalc/@node-dlc/core/dist/dlc/finance/LongCall.js.map +1 -0
  139. package/.yalc/@node-dlc/core/dist/dlc/finance/LongPut.d.ts +13 -0
  140. package/.yalc/@node-dlc/core/dist/dlc/finance/LongPut.js +47 -0
  141. package/.yalc/@node-dlc/core/dist/dlc/finance/LongPut.js.map +1 -0
  142. package/.yalc/@node-dlc/core/dist/dlc/finance/OptionInfo.d.ts +20 -0
  143. package/.yalc/@node-dlc/core/dist/dlc/finance/OptionInfo.js +101 -0
  144. package/.yalc/@node-dlc/core/dist/dlc/finance/OptionInfo.js.map +1 -0
  145. package/.yalc/@node-dlc/core/dist/dlc/finance/ShortPut.d.ts +12 -0
  146. package/.yalc/@node-dlc/core/dist/dlc/finance/ShortPut.js +46 -0
  147. package/.yalc/@node-dlc/core/dist/dlc/finance/ShortPut.js.map +1 -0
  148. package/.yalc/@node-dlc/core/dist/index.d.ts +39 -0
  149. package/.yalc/@node-dlc/core/dist/index.js +78 -0
  150. package/.yalc/@node-dlc/core/dist/index.js.map +1 -0
  151. package/.yalc/@node-dlc/core/dist/lightning/ChannelId.d.ts +31 -0
  152. package/.yalc/@node-dlc/core/dist/lightning/ChannelId.js +52 -0
  153. package/.yalc/@node-dlc/core/dist/lightning/ChannelId.js.map +1 -0
  154. package/.yalc/@node-dlc/core/dist/lightning/ChannelKeys.d.ts +55 -0
  155. package/.yalc/@node-dlc/core/dist/lightning/ChannelKeys.js +105 -0
  156. package/.yalc/@node-dlc/core/dist/lightning/ChannelKeys.js.map +1 -0
  157. package/.yalc/@node-dlc/core/dist/lightning/CommitmentNumber.d.ts +55 -0
  158. package/.yalc/@node-dlc/core/dist/lightning/CommitmentNumber.js +76 -0
  159. package/.yalc/@node-dlc/core/dist/lightning/CommitmentNumber.js.map +1 -0
  160. package/.yalc/@node-dlc/core/dist/lightning/CommitmentSecret.d.ts +26 -0
  161. package/.yalc/@node-dlc/core/dist/lightning/CommitmentSecret.js +44 -0
  162. package/.yalc/@node-dlc/core/dist/lightning/CommitmentSecret.js.map +1 -0
  163. package/.yalc/@node-dlc/core/dist/lightning/CommitmentSecretStore.d.ts +41 -0
  164. package/.yalc/@node-dlc/core/dist/lightning/CommitmentSecretStore.js +79 -0
  165. package/.yalc/@node-dlc/core/dist/lightning/CommitmentSecretStore.js.map +1 -0
  166. package/.yalc/@node-dlc/core/dist/lightning/Htlc.d.ts +46 -0
  167. package/.yalc/@node-dlc/core/dist/lightning/Htlc.js +46 -0
  168. package/.yalc/@node-dlc/core/dist/lightning/Htlc.js.map +1 -0
  169. package/.yalc/@node-dlc/core/dist/lightning/HtlcDirection.d.ts +16 -0
  170. package/.yalc/@node-dlc/core/dist/lightning/HtlcDirection.js +21 -0
  171. package/.yalc/@node-dlc/core/dist/lightning/HtlcDirection.js.map +1 -0
  172. package/.yalc/@node-dlc/core/dist/lightning/ScriptFactory.d.ts +76 -0
  173. package/.yalc/@node-dlc/core/dist/lightning/ScriptFactory.js +102 -0
  174. package/.yalc/@node-dlc/core/dist/lightning/ScriptFactory.js.map +1 -0
  175. package/.yalc/@node-dlc/core/dist/lightning/TxFactory.d.ts +83 -0
  176. package/.yalc/@node-dlc/core/dist/lightning/TxFactory.js +222 -0
  177. package/.yalc/@node-dlc/core/dist/lightning/TxFactory.js.map +1 -0
  178. package/.yalc/@node-dlc/core/dist/utils/BigIntUtils.d.ts +9 -0
  179. package/.yalc/@node-dlc/core/dist/utils/BigIntUtils.js +59 -0
  180. package/.yalc/@node-dlc/core/dist/utils/BigIntUtils.js.map +1 -0
  181. package/.yalc/@node-dlc/core/dist/utils/Precision.d.ts +13 -0
  182. package/.yalc/@node-dlc/core/dist/utils/Precision.js +28 -0
  183. package/.yalc/@node-dlc/core/dist/utils/Precision.js.map +1 -0
  184. package/.yalc/@node-dlc/core/lib/AsyncProcessingQueue.ts +63 -0
  185. package/.yalc/@node-dlc/core/lib/Base32.ts +2 -0
  186. package/.yalc/@node-dlc/core/lib/BigIntUtils.ts +2 -0
  187. package/.yalc/@node-dlc/core/lib/BitField.ts +2 -0
  188. package/.yalc/@node-dlc/core/lib/ChannelId.ts +2 -0
  189. package/.yalc/@node-dlc/core/lib/LinkedList.ts +111 -0
  190. package/.yalc/@node-dlc/core/lib/LinkedListNode.ts +14 -0
  191. package/.yalc/@node-dlc/core/lib/Queue.ts +36 -0
  192. package/.yalc/@node-dlc/core/lib/ShortChannelId.ts +2 -0
  193. package/.yalc/@node-dlc/core/lib/ShortChannelIdUtils.ts +9 -0
  194. package/.yalc/@node-dlc/core/lib/dlc/CETCalculator.ts +450 -0
  195. package/.yalc/@node-dlc/core/lib/dlc/CoinSelect.ts +117 -0
  196. package/.yalc/@node-dlc/core/lib/dlc/HyperbolaPayoutCurve.ts +188 -0
  197. package/.yalc/@node-dlc/core/lib/dlc/PayoutCurve.ts +6 -0
  198. package/.yalc/@node-dlc/core/lib/dlc/PolynomialPayoutCurve.ts +266 -0
  199. package/.yalc/@node-dlc/core/lib/dlc/TxBuilder.ts +336 -0
  200. package/.yalc/@node-dlc/core/lib/dlc/TxFinalizer.ts +217 -0
  201. package/.yalc/@node-dlc/core/lib/dlc/finance/Builder.ts +730 -0
  202. package/.yalc/@node-dlc/core/lib/dlc/finance/CoveredCall.ts +110 -0
  203. package/.yalc/@node-dlc/core/lib/dlc/finance/CsoInfo.ts +498 -0
  204. package/.yalc/@node-dlc/core/lib/dlc/finance/LinearPayout.ts +94 -0
  205. package/.yalc/@node-dlc/core/lib/dlc/finance/LongCall.ts +74 -0
  206. package/.yalc/@node-dlc/core/lib/dlc/finance/LongPut.ts +74 -0
  207. package/.yalc/@node-dlc/core/lib/dlc/finance/OptionInfo.ts +182 -0
  208. package/.yalc/@node-dlc/core/lib/dlc/finance/ShortPut.ts +75 -0
  209. package/.yalc/@node-dlc/core/lib/index.ts +66 -0
  210. package/.yalc/@node-dlc/core/lib/lightning/ChannelId.ts +54 -0
  211. package/.yalc/@node-dlc/core/lib/lightning/ChannelKeys.ts +109 -0
  212. package/.yalc/@node-dlc/core/lib/lightning/CommitmentNumber.ts +94 -0
  213. package/.yalc/@node-dlc/core/lib/lightning/CommitmentSecret.ts +41 -0
  214. package/.yalc/@node-dlc/core/lib/lightning/CommitmentSecretStore.ts +84 -0
  215. package/.yalc/@node-dlc/core/lib/lightning/Htlc.ts +52 -0
  216. package/.yalc/@node-dlc/core/lib/lightning/HtlcDirection.ts +17 -0
  217. package/.yalc/@node-dlc/core/lib/lightning/ScriptFactory.ts +150 -0
  218. package/.yalc/@node-dlc/core/lib/lightning/TxFactory.ts +338 -0
  219. package/.yalc/@node-dlc/core/lib/utils/BigIntUtils.ts +64 -0
  220. package/.yalc/@node-dlc/core/lib/utils/Precision.ts +23 -0
  221. package/.yalc/@node-dlc/core/package.json +38 -0
  222. package/.yalc/@node-dlc/core/tsconfig.json +8 -0
  223. package/.yalc/@node-dlc/core/yalc.sig +1 -0
  224. package/CHANGELOG.md +23 -0
  225. package/package.json +7 -7
  226. package/yalc.lock +10 -0
@@ -0,0 +1,492 @@
1
+ import { Value } from '@node-dlc/bitcoin';
2
+ import {
3
+ ContractDescriptorV1,
4
+ ContractInfoV0,
5
+ OracleAnnouncement,
6
+ PayoutFunctionV0,
7
+ } from '@node-dlc/messaging';
8
+ import { BitcoinNetworks } from 'bitcoin-networks';
9
+ import { expect } from 'chai';
10
+ import sinon from 'sinon';
11
+
12
+ import {
13
+ buildCoveredCallOrderOffer,
14
+ buildCustomStrategyOrderOffer,
15
+ buildLongCallOrderOffer,
16
+ buildLongPutOrderOffer,
17
+ buildRoundingIntervalsFromIntervals,
18
+ buildShortPutOrderOffer,
19
+ computeRoundingModulus,
20
+ UNIT_MULTIPLIER,
21
+ } from '../../../lib/dlc/finance/Builder';
22
+
23
+ describe('OrderOffer Builder', () => {
24
+ describe('buildCoveredCallOrderOffer', () => {
25
+ const strikePrice = 50000;
26
+ const contractSize = Value.fromSats(100000000);
27
+ const premium = Value.fromSats(25000);
28
+ const threeXPremium = Value.fromSats(75000);
29
+ const totalCollateral = contractSize;
30
+ const oracleAnnouncementBuf = Buffer.from(
31
+ 'fdd824fd02ab1efe41fa42ea1dcd103a0251929dd2b192d2daece8a4ce4d81f68a183b750d92d6f02d796965dc79adf4e7786e08f861a1ecc897afbba2dab9cff6eb0a81937eb8b005b07acf849ad2cec22107331dedbf5a607654fad4eafe39c278e27dde68fdd822fd02450011f9313f1edd903fab297d5350006b669506eb0ffda0bb58319b4df89ac24e14fd15f9791dc78d1596b06f4969bdb37d9e394dc9fedaa18d694027fa32b5ea2a5e60080c58e13727367c3a4ce1ad65dfb3c7e3ca1ea912b0299f6e383bab2875058aa96a1c74633130af6fbd008788de6ac9db76da4ecc7303383cc1a49f525316413850f7e3ac385019d560e84c5b3a3e9ae6c83f59fe4286ddfd23ea46d7ae04610a175cd28a9bf5f574e245c3dfe230dc4b0adf4daaea96780e594f6464f676505f4b74cfe3ffc33415a23de795bf939ce64c0c02033bbfc6c9ff26fb478943a1ece775f38f5db067ca4b2a9168b40792398def9164bfe5c46838472dc3c162af16c811b7a116e9417d5bccb9e5b8a5d7d26095aba993696188c3f85a02f7ab8d12ada171c352785eb63417228c7e248909fc2d673e1bb453140bf8bf429375819afb5e9556663b76ff09c2a7ba9779855ffddc6d360cb459cf8c42a2b949d0de19fe96163d336fd66a4ce2f1791110e679572a20036ffae50204ef520c01058ff4bef28218d1c0e362ee3694ad8b2ae83a51c86c4bc1630ed6202a158810096726f809fc828fafdcf053496affdf887ae8c54b6ca4323ccecf6a51121c4f0c60e790536dab41b221db1c6b35065dc19a9d31cf75901aa35eefecbb6fefd07296cda13cb34ce3b58eba20a0eb8f9614994ec7fee3cc290e30e6b1e3211ae1f3a85b6de6abdbb77d6d9ed33a1cee3bd5cd93a71f12c9c45e385d744ad0e7286660305100fdd80a11000200076274632f75736400000000001109425443205072696365',
32
+ 'hex',
33
+ );
34
+
35
+ const oracleAnnouncement = OracleAnnouncement.deserialize(
36
+ oracleAnnouncementBuf,
37
+ );
38
+
39
+ it('should build a covered call OrderOffer correctly', () => {
40
+ sinon.stub(Date.prototype, 'getTime').returns(Date.UTC(2021, 1, 5));
41
+
42
+ const orderOffer = buildCoveredCallOrderOffer(
43
+ oracleAnnouncement,
44
+ contractSize,
45
+ strikePrice,
46
+ premium,
47
+ 12,
48
+ 10000,
49
+ 'bitcoin',
50
+ );
51
+
52
+ expect(() => orderOffer.validate()).to.not.throw(Error);
53
+ });
54
+
55
+ it('should build a short put OrderOffer correctly', () => {
56
+ const orderOffer = buildShortPutOrderOffer(
57
+ oracleAnnouncement,
58
+ contractSize,
59
+ strikePrice,
60
+ totalCollateral,
61
+ premium,
62
+ 12,
63
+ 10000,
64
+ 'bitcoin',
65
+ );
66
+
67
+ expect(() => orderOffer.validate()).to.not.throw(Error);
68
+ });
69
+
70
+ it('should build a long call OrderOffer correctly', () => {
71
+ const orderOffer = buildLongCallOrderOffer(
72
+ oracleAnnouncement,
73
+ contractSize,
74
+ strikePrice,
75
+ threeXPremium,
76
+ premium,
77
+ 12,
78
+ 10000,
79
+ 'bitcoin',
80
+ );
81
+
82
+ expect(() => orderOffer.validate()).to.not.throw(Error);
83
+ });
84
+
85
+ it('should build a long put OrderOffer correctly', () => {
86
+ const orderOffer = buildLongPutOrderOffer(
87
+ oracleAnnouncement,
88
+ contractSize,
89
+ strikePrice,
90
+ threeXPremium,
91
+ premium,
92
+ 12,
93
+ 10000,
94
+ 'bitcoin',
95
+ );
96
+
97
+ expect(() => orderOffer.validate()).to.not.throw(Error);
98
+ });
99
+
100
+ it('should fail to build an OrderOffer with an invalid oracleAnnouncement', () => {
101
+ oracleAnnouncement.announcementSig = Buffer.from('deadbeef', 'hex');
102
+
103
+ const orderOffer = buildShortPutOrderOffer(
104
+ oracleAnnouncement,
105
+ contractSize,
106
+ strikePrice,
107
+ totalCollateral,
108
+ premium,
109
+ 12,
110
+ 10000,
111
+ 'bitcoin',
112
+ );
113
+
114
+ expect(() => orderOffer.validate()).to.throw(Error);
115
+ });
116
+ });
117
+
118
+ describe('buildCustomStrategyOrderOffer', () => {
119
+ const contractSizes: Value[] = [
120
+ Value.fromBitcoin(1),
121
+ Value.fromBitcoin(0.1),
122
+ Value.fromBitcoin(0.5),
123
+ Value.fromBitcoin(1.5),
124
+ Value.fromBitcoin(2),
125
+ ];
126
+
127
+ const defaultContractSize = Value.fromBitcoin(1);
128
+
129
+ const maxLoss = Value.fromBitcoin(0.2);
130
+ const maxGain = Value.fromBitcoin(0.04);
131
+ const feeRate = 2n;
132
+
133
+ const highestPrecisionRounding = Value.fromSats(10000);
134
+ const highPrecisionRounding = Value.fromSats(25000);
135
+ const mediumPrecisionRounding = Value.fromSats(100000);
136
+ const lowPrecisionRounding = Value.fromSats(200000);
137
+
138
+ const network = BitcoinNetworks.bitcoin;
139
+
140
+ const oracleAnnouncementBuf = Buffer.from(
141
+ 'fdd824fd032e4a2b121973a7d2be4784fb6fb0c7b97405b757fb078b58bb729756a7372bf1bdc05c373472fc57fde0a07dcdad027f48f313fa1e349ab8bb936472735fce5221ff9c4885aa0c5987046ada7e729dac33591777a37af8bf14dedb95997d0c7d4bfdd822fd02c800154a2b121973a7d2be4784fb6fb0c7b97405b757fb078b58bb729756a7372bf1bdd7cb55eee59faac9a590e7d3bab782276daa0744786aaff3f69a1e51de99012339492f00198932d8057eb6742bd5245e37fd22b44e0bfaa68577ce5654b478786eb7dc091559699292dc060ee82864cffd863eb8fa876682099af34a8f3eab9174773231e6950b077df212df3fc91c199c34200cd8ce00f1c8a050ad471bfc1478e90d06bd77f11fc3804435556ed5dc1eb19b95a978f595ba127ea225c4662e22ea614cab60054d9b21da904cd9eac5b514a6a011de635ad08e0c72766a7bbc9144df24fe6bf3e0d631a61a1da27e93c6f4ea6829795f4c63628747415a41ffe199129639d7a6c430184aa925b9ab224c9180b64c86959bd7abc9ffa08fe4421952114839d5120f4ea9c9437364b4956b25a141aeefbc30d3e6cc811f9424d266671dc330b7f3d00f1f7a521e14697a0259499e6cc8fa0da13a095279f827cfe2cf11508c6d8d1405f6cb337d68fbe29fde5acbb094ff397c14c24f084ac6ef466b1d85d5160de41ed8ed435ab52f948788dc45406e07f02683c9822431d91d95a04e11e4fdb521485aa8737bdd8c67cfefd0d103f86005491181e704adafc7f49cc9700ce8cffda9c9b265bc64ed19b42d4b5e4449f6b0da81342923c45f37b1381b3a29b9acce9818f4ec6af0ecbddc063e64868f350281054d13599e6e35d503532b6fa9c0db85db703dde1de21142b351ecce626128f98ddb5dab11f669c16de45d3dd054786aa5e3fb6369114b97bee6c26d21be0f71258dfa3e8ec8b8890719eef8e817b69072f74325088781a50b4cd5fe74493828dfe9cb21b698901e48f9f4d7b70a636794feae500aac237add2630bad1257b0cac1b71a8fcd5dbd7540a84ccac5d48b76afae2b3dfe3ea8eb8cd6e67febb6a1433504329948e426064108cfdd80a0e00020004626974730000000000150f73747261746567794f7574636f6d65',
142
+ 'hex',
143
+ );
144
+
145
+ const oracleAnnouncement = OracleAnnouncement.deserialize(
146
+ oracleAnnouncementBuf,
147
+ );
148
+
149
+ const unit = 'bits';
150
+
151
+ for (const contractSize of contractSizes) {
152
+ it(`should build a CSO OrderOffer with contract size ${contractSize.bitcoin} BTC correctly`, () => {
153
+ const roundingIntervals = buildRoundingIntervalsFromIntervals(
154
+ contractSize,
155
+ [
156
+ { beginInterval: 0n, rounding: lowPrecisionRounding },
157
+ { beginInterval: 750000n, rounding: mediumPrecisionRounding },
158
+ { beginInterval: 850000n, rounding: highPrecisionRounding },
159
+ { beginInterval: 950000n, rounding: highestPrecisionRounding },
160
+ ],
161
+ );
162
+
163
+ const orderOffer = buildCustomStrategyOrderOffer(
164
+ oracleAnnouncement,
165
+ contractSize,
166
+ maxLoss,
167
+ maxGain,
168
+ feeRate,
169
+ roundingIntervals,
170
+ network,
171
+ );
172
+
173
+ const payoutCurvePieces = (((orderOffer.contractInfo as ContractInfoV0)
174
+ .contractDescriptor as ContractDescriptorV1)
175
+ .payoutFunction as PayoutFunctionV0).payoutFunctionPieces;
176
+
177
+ expect(() => orderOffer.validate()).to.not.throw(Error);
178
+ expect(orderOffer.contractInfo.totalCollateral).to.equal(
179
+ contractSize.sats,
180
+ );
181
+ expect(orderOffer.offerCollateralSatoshis).to.equal(
182
+ contractSize.sats - (contractSize.sats * maxGain.sats) / BigInt(1e8),
183
+ );
184
+ expect(payoutCurvePieces[0].endPoint.eventOutcome).to.equal(
185
+ (defaultContractSize.sats - maxLoss.sats) /
186
+ BigInt(UNIT_MULTIPLIER[unit]),
187
+ );
188
+ expect(payoutCurvePieces[1].endPoint.eventOutcome).to.equal(
189
+ (defaultContractSize.sats + maxGain.sats) /
190
+ BigInt(UNIT_MULTIPLIER[unit]),
191
+ );
192
+ expect(payoutCurvePieces[0].endPoint.outcomePayout).to.equal(
193
+ contractSize.sats -
194
+ (maxLoss.sats * contractSize.sats) / BigInt(1e8) -
195
+ (maxGain.sats * contractSize.sats) / BigInt(1e8),
196
+ );
197
+ expect(payoutCurvePieces[1].endPoint.outcomePayout).to.equal(
198
+ contractSize.sats,
199
+ );
200
+ });
201
+ }
202
+
203
+ it('should build a CSO OrderOffer and shift the payout curve correctly for offeror fees', () => {
204
+ const contractSize = contractSizes[0];
205
+
206
+ const roundingIntervals = buildRoundingIntervalsFromIntervals(
207
+ contractSize,
208
+ [
209
+ { beginInterval: 0n, rounding: lowPrecisionRounding },
210
+ { beginInterval: 750000n, rounding: mediumPrecisionRounding },
211
+ { beginInterval: 850000n, rounding: highPrecisionRounding },
212
+ { beginInterval: 950000n, rounding: highestPrecisionRounding },
213
+ ],
214
+ );
215
+
216
+ const offerFees = Value.fromSats(10000);
217
+
218
+ const orderOffer = buildCustomStrategyOrderOffer(
219
+ oracleAnnouncement,
220
+ contractSize,
221
+ maxLoss,
222
+ maxGain,
223
+ feeRate,
224
+ roundingIntervals,
225
+ network,
226
+ 'offeror',
227
+ offerFees,
228
+ );
229
+
230
+ const payoutCurvePieces = (((orderOffer.contractInfo as ContractInfoV0)
231
+ .contractDescriptor as ContractDescriptorV1)
232
+ .payoutFunction as PayoutFunctionV0).payoutFunctionPieces;
233
+
234
+ expect(() => orderOffer.validate()).to.not.throw(Error);
235
+ expect(orderOffer.contractInfo.totalCollateral).to.equal(
236
+ contractSize.sats,
237
+ );
238
+ expect(orderOffer.offerCollateralSatoshis).to.equal(
239
+ contractSize.sats - (contractSize.sats * maxGain.sats) / BigInt(1e8),
240
+ );
241
+ expect(payoutCurvePieces[0].endPoint.eventOutcome).to.equal(
242
+ (defaultContractSize.sats - maxLoss.sats + offerFees.sats) /
243
+ BigInt(UNIT_MULTIPLIER[unit]),
244
+ );
245
+ expect(payoutCurvePieces[1].endPoint.eventOutcome).to.equal(
246
+ (defaultContractSize.sats + maxGain.sats + offerFees.sats) /
247
+ BigInt(UNIT_MULTIPLIER[unit]),
248
+ );
249
+ expect(payoutCurvePieces[0].endPoint.outcomePayout).to.equal(
250
+ contractSize.sats -
251
+ (maxLoss.sats * contractSize.sats) / BigInt(1e8) -
252
+ (maxGain.sats * contractSize.sats) / BigInt(1e8),
253
+ );
254
+ expect(payoutCurvePieces[1].endPoint.outcomePayout).to.equal(
255
+ contractSize.sats,
256
+ );
257
+ });
258
+
259
+ it('should build a CSO OrderOffer and shift the payout curve correctly for acceptor fees', () => {
260
+ const acceptFees = Value.fromSats(10000);
261
+
262
+ const contractSize = contractSizes[0];
263
+
264
+ const roundingIntervals = buildRoundingIntervalsFromIntervals(
265
+ contractSize,
266
+ [
267
+ { beginInterval: 0n, rounding: lowPrecisionRounding },
268
+ { beginInterval: 750000n, rounding: mediumPrecisionRounding },
269
+ { beginInterval: 850000n, rounding: highPrecisionRounding },
270
+ { beginInterval: 950000n, rounding: highestPrecisionRounding },
271
+ ],
272
+ );
273
+
274
+ const orderOffer = buildCustomStrategyOrderOffer(
275
+ oracleAnnouncement,
276
+ contractSize,
277
+ maxLoss,
278
+ maxGain,
279
+ feeRate,
280
+ roundingIntervals,
281
+ network,
282
+ 'acceptor',
283
+ acceptFees,
284
+ );
285
+
286
+ const payoutCurvePieces = (((orderOffer.contractInfo as ContractInfoV0)
287
+ .contractDescriptor as ContractDescriptorV1)
288
+ .payoutFunction as PayoutFunctionV0).payoutFunctionPieces;
289
+
290
+ expect(() => orderOffer.validate()).to.not.throw(Error);
291
+ expect(orderOffer.contractInfo.totalCollateral).to.equal(
292
+ contractSize.sats,
293
+ );
294
+ expect(orderOffer.offerCollateralSatoshis).to.equal(
295
+ contractSize.sats - (contractSize.sats * maxGain.sats) / BigInt(1e8),
296
+ );
297
+ expect(payoutCurvePieces[0].endPoint.eventOutcome).to.equal(
298
+ (defaultContractSize.sats - maxLoss.sats - acceptFees.sats) /
299
+ BigInt(UNIT_MULTIPLIER[unit]),
300
+ );
301
+ expect(payoutCurvePieces[1].endPoint.eventOutcome).to.equal(
302
+ (defaultContractSize.sats + maxGain.sats - acceptFees.sats) /
303
+ BigInt(UNIT_MULTIPLIER[unit]),
304
+ );
305
+ expect(payoutCurvePieces[0].endPoint.outcomePayout).to.equal(
306
+ contractSize.sats -
307
+ (maxLoss.sats * contractSize.sats) / BigInt(1e8) -
308
+ (maxGain.sats * contractSize.sats) / BigInt(1e8),
309
+ );
310
+ expect(payoutCurvePieces[1].endPoint.outcomePayout).to.equal(
311
+ contractSize.sats,
312
+ );
313
+ });
314
+
315
+ it('should fail to build a CSO OrderOffer with contractSize 0', () => {
316
+ const contractSize = Value.zero();
317
+
318
+ const roundingIntervals = buildRoundingIntervalsFromIntervals(
319
+ contractSize,
320
+ [
321
+ { beginInterval: 0n, rounding: lowPrecisionRounding },
322
+ { beginInterval: 750000n, rounding: mediumPrecisionRounding },
323
+ { beginInterval: 850000n, rounding: highPrecisionRounding },
324
+ { beginInterval: 950000n, rounding: highestPrecisionRounding },
325
+ ],
326
+ );
327
+
328
+ try {
329
+ buildCustomStrategyOrderOffer(
330
+ oracleAnnouncement,
331
+ contractSize,
332
+ maxLoss,
333
+ maxGain,
334
+ feeRate,
335
+ roundingIntervals,
336
+ network,
337
+ );
338
+ // If the function call does not throw, fail the test
339
+ expect.fail(
340
+ 'Expected buildCustomStrategyOrderOffer to throw an error due to contractSize being 0',
341
+ );
342
+ } catch (error) {
343
+ // Assert that the error message is as expected
344
+ expect(error.message).to.equal('contractSize must be greater than 0');
345
+ }
346
+ });
347
+
348
+ it('should fail to build a CSO OrderOffer with an invalid oracleAnnouncement', () => {
349
+ const contractSize = contractSizes[0];
350
+
351
+ const roundingIntervals = buildRoundingIntervalsFromIntervals(
352
+ contractSize,
353
+ [
354
+ { beginInterval: 0n, rounding: lowPrecisionRounding },
355
+ { beginInterval: 750000n, rounding: mediumPrecisionRounding },
356
+ { beginInterval: 850000n, rounding: highPrecisionRounding },
357
+ { beginInterval: 950000n, rounding: highestPrecisionRounding },
358
+ ],
359
+ );
360
+
361
+ oracleAnnouncement.announcementSig = Buffer.from(
362
+ 'deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef',
363
+ 'hex',
364
+ );
365
+
366
+ const skipValidation = true;
367
+
368
+ const orderOffer = buildCustomStrategyOrderOffer(
369
+ oracleAnnouncement,
370
+ contractSize,
371
+ maxLoss,
372
+ maxGain,
373
+ feeRate,
374
+ roundingIntervals,
375
+ network,
376
+ undefined,
377
+ undefined,
378
+ undefined,
379
+ undefined,
380
+ undefined,
381
+ skipValidation,
382
+ );
383
+
384
+ expect(() => orderOffer.validate()).to.throw(Error);
385
+ });
386
+ });
387
+
388
+ describe('computeRoundingModulus', () => {
389
+ describe('with satoshi inputs (existing functionality)', () => {
390
+ it('should properly compute the rounding modulus for 0.0001 BTC', () => {
391
+ const modulus = computeRoundingModulus(BigInt(100000), BigInt(10000));
392
+ expect(modulus).to.equal(BigInt(10));
393
+ });
394
+
395
+ it('should properly compute the rounding modulus for 1 BTC', () => {
396
+ const modulus = computeRoundingModulus(
397
+ BigInt(100000),
398
+ BigInt(100000000),
399
+ );
400
+ expect(modulus).to.equal(BigInt(100000));
401
+ });
402
+
403
+ it('should properly compute the rounding modulus for 1.25 BTC', () => {
404
+ const modulus = computeRoundingModulus(BigInt(5000), BigInt(125000000));
405
+ expect(modulus).to.equal(BigInt(6250));
406
+ });
407
+
408
+ it('should properly compute the rounding modulus for 0.9 BTC', () => {
409
+ const modulus = computeRoundingModulus(
410
+ BigInt(100000),
411
+ BigInt(90000000),
412
+ );
413
+ expect(modulus).to.equal(BigInt(90000));
414
+ });
415
+ });
416
+
417
+ describe('with bitcoin amount inputs (new functionality)', () => {
418
+ it('should properly compute the rounding modulus for 0.001 BTC rounding with 0.1 BTC contract size', () => {
419
+ const modulus = computeRoundingModulus(0.001, 0.1); // 0.001 BTC rounding, 0.1 BTC contract
420
+ expect(modulus).to.equal(BigInt(10000)); // (0.001 * 1e8) * (0.1 * 1e8) / 1e8 = 10000
421
+ });
422
+
423
+ it('should properly compute the rounding modulus for 0.0001 BTC rounding with 1 BTC contract size', () => {
424
+ const modulus = computeRoundingModulus(0.0001, 1); // 0.0001 BTC rounding, 1 BTC contract
425
+ expect(modulus).to.equal(BigInt(10000)); // (0.0001 * 1e8) * (1 * 1e8) / 1e8 = 10000
426
+ });
427
+
428
+ it('should properly compute the rounding modulus for 0.001 BTC rounding with 1.5 BTC contract size', () => {
429
+ const modulus = computeRoundingModulus(0.001, 1.5); // 0.001 BTC rounding, 1.5 BTC contract
430
+ expect(modulus).to.equal(BigInt(150000)); // (0.001 * 1e8) * (1.5 * 1e8) / 1e8 = 150000
431
+ });
432
+
433
+ it('should properly compute the rounding modulus for 0.0005 BTC rounding with 0.5 BTC contract size', () => {
434
+ const modulus = computeRoundingModulus(0.0005, 0.5); // 0.0005 BTC rounding, 0.5 BTC contract
435
+ expect(modulus).to.equal(BigInt(25000)); // (0.0005 * 1e8) * (0.5 * 1e8) / 1e8 = 25000
436
+ });
437
+
438
+ it('should handle fractional bitcoin amounts correctly', () => {
439
+ const modulus = computeRoundingModulus(0.00001, 0.12345); // Very small amounts
440
+ expect(modulus).to.equal(BigInt(123)); // (0.00001 * 1e8) * (0.12345 * 1e8) / 1e8 = 123.45 -> 123 (rounded down)
441
+ });
442
+ });
443
+
444
+ describe('with Value object inputs', () => {
445
+ it('should properly compute the rounding modulus with Value objects', () => {
446
+ const rounding = Value.fromBitcoin(0.001);
447
+ const contractSize = Value.fromBitcoin(1);
448
+ const modulus = computeRoundingModulus(rounding, contractSize);
449
+ expect(modulus).to.equal(BigInt(100000)); // (0.001 * 1e8) * (1 * 1e8) / 1e8 = 100000
450
+ });
451
+
452
+ it('should properly compute the rounding modulus with mixed Value and number inputs', () => {
453
+ const rounding = Value.fromBitcoin(0.001);
454
+ const contractSize = 1.5; // number input
455
+ const modulus = computeRoundingModulus(rounding, contractSize);
456
+ expect(modulus).to.equal(BigInt(150000)); // (0.001 * 1e8) * (1.5 * 1e8) / 1e8 = 150000
457
+ });
458
+ });
459
+
460
+ describe('with BigInt inputs', () => {
461
+ it('should properly compute the rounding modulus with BigInt inputs', () => {
462
+ const modulus = computeRoundingModulus(
463
+ BigInt(100000),
464
+ BigInt(100000000),
465
+ );
466
+ expect(modulus).to.equal(BigInt(100000));
467
+ });
468
+
469
+ it('should properly compute the rounding modulus with mixed BigInt and number inputs', () => {
470
+ const modulus = computeRoundingModulus(BigInt(100000), 1); // BigInt rounding, number contract size
471
+ expect(modulus).to.equal(BigInt(100000)); // 100000 * (1 * 1e8) / 1e8 = 100000
472
+ });
473
+ });
474
+
475
+ describe('edge cases', () => {
476
+ it('should handle zero rounding correctly', () => {
477
+ const modulus = computeRoundingModulus(0, 1);
478
+ expect(modulus).to.equal(BigInt(0));
479
+ });
480
+
481
+ it('should handle zero contract size correctly', () => {
482
+ const modulus = computeRoundingModulus(0.001, 0);
483
+ expect(modulus).to.equal(BigInt(0));
484
+ });
485
+
486
+ it('should handle very small bitcoin amounts', () => {
487
+ const modulus = computeRoundingModulus(0.00000001, 0.00000001); // 1 satoshi each
488
+ expect(modulus).to.equal(BigInt(0)); // (1 * 1) / 1e8 = 0 (rounded down)
489
+ });
490
+ });
491
+ });
492
+ });
@@ -0,0 +1,112 @@
1
+ import { HyperbolaPayoutCurvePiece } from '@node-dlc/messaging';
2
+ import { expect } from 'chai';
3
+
4
+ import { CoveredCall } from '../../../lib/dlc/finance/CoveredCall';
5
+ import { HyperbolaPayoutCurve } from '../../../lib/dlc/HyperbolaPayoutCurve';
6
+
7
+ describe('CoveredCall', () => {
8
+ describe('1BTC-50k-base2-20digit curve', () => {
9
+ const strikePrice = BigInt(50000);
10
+ const contractSize = BigInt(10) ** BigInt(8);
11
+ const oracleBase = 2;
12
+ const oracleDigits = 20;
13
+
14
+ const { maxOutcome, totalCollateral, payoutCurve } = CoveredCall.buildCurve(
15
+ strikePrice,
16
+ contractSize,
17
+ oracleBase,
18
+ oracleDigits,
19
+ );
20
+
21
+ describe('payout', () => {
22
+ it('should be a negative past max outcome', () => {
23
+ expect(
24
+ payoutCurve.getPayout(maxOutcome + BigInt(1)).toNumber(),
25
+ ).to.be.lessThan(0);
26
+ });
27
+
28
+ it('should be equal to totalCollateral at strike price', () => {
29
+ expect(payoutCurve.getPayout(strikePrice).toNumber()).to.equal(
30
+ Number(totalCollateral),
31
+ );
32
+ });
33
+ });
34
+
35
+ describe('buildPayoutFunction', () => {
36
+ it('should build payout function', () => {
37
+ const {
38
+ payoutFunction,
39
+ totalCollateral,
40
+ } = CoveredCall.buildPayoutFunction(4000n, 1000000n, 2, 17);
41
+
42
+ // Test basic structure
43
+ expect(payoutFunction).to.not.be.undefined;
44
+ expect(totalCollateral).to.not.be.undefined;
45
+
46
+ // Test payout function structure
47
+ expect(payoutFunction.payoutFunctionPieces).to.have.length(1);
48
+ expect(payoutFunction.lastEndpoint).to.not.be.undefined;
49
+
50
+ // Test the payout function piece
51
+ const piece = payoutFunction.payoutFunctionPieces[0];
52
+ expect(piece.endPoint).to.not.be.undefined;
53
+ expect(piece.payoutCurvePiece).to.not.be.undefined;
54
+
55
+ // Test end point values - should be at maxOutcome (2^17 - 1 = 131071)
56
+ const maxOutcome = BigInt(2 ** 17 - 1); // 131071
57
+ expect(piece.endPoint.eventOutcome).to.equal(maxOutcome);
58
+ expect(piece.endPoint.outcomePayout).to.equal(0n);
59
+ expect(piece.endPoint.extraPrecision).to.equal(0);
60
+
61
+ // Test last endpoint matches the piece endpoint
62
+ expect(payoutFunction.lastEndpoint.eventOutcome).to.equal(maxOutcome);
63
+ expect(payoutFunction.lastEndpoint.outcomePayout).to.equal(0n);
64
+ expect(payoutFunction.lastEndpoint.extraPrecision).to.equal(0);
65
+
66
+ // Test hyperbola curve piece properties
67
+ const curvePiece = piece.payoutCurvePiece as HyperbolaPayoutCurvePiece;
68
+ expect(curvePiece.usePositivePiece).to.equal(true);
69
+ expect(curvePiece.leftEndPoint).to.not.be.undefined;
70
+ expect(curvePiece.rightEndPoint).to.not.be.undefined;
71
+
72
+ // Test left endpoint (start of curve)
73
+ expect(curvePiece.leftEndPoint.eventOutcome).to.equal(0n);
74
+ expect(curvePiece.leftEndPoint.outcomePayout).to.equal(totalCollateral);
75
+ expect(curvePiece.leftEndPoint.extraPrecision).to.equal(0);
76
+
77
+ // Test right endpoint (end of curve)
78
+ expect(curvePiece.rightEndPoint.eventOutcome).to.equal(maxOutcome);
79
+ expect(curvePiece.rightEndPoint.outcomePayout).to.equal(0n);
80
+ expect(curvePiece.rightEndPoint.extraPrecision).to.equal(0);
81
+
82
+ // Test hyperbola parameters
83
+ expect(curvePiece.a.toNumber()).to.equal(1);
84
+ expect(curvePiece.b.toNumber()).to.equal(0);
85
+ expect(curvePiece.c.toNumber()).to.equal(0);
86
+ expect(curvePiece.d.toNumber()).to.equal(4000000000); // strikePrice * contractSize
87
+ expect(curvePiece.translateOutcome.toNumber()).to.equal(0);
88
+
89
+ // Test total collateral is reasonable (should be less than contract size)
90
+ expect(Number(totalCollateral)).to.be.greaterThan(0);
91
+ expect(Number(totalCollateral)).to.be.lessThan(1000000); // less than contractSize
92
+
93
+ // For a covered call with strike=4000, contractSize=1000000:
94
+ // At maxOutcome, payout should be ~0, so most collateral is retained
95
+ expect(Number(totalCollateral)).to.be.greaterThan(900000); // Should retain most collateral
96
+ });
97
+ });
98
+
99
+ it('should serialize and deserialize properly', () => {
100
+ const payout = payoutCurve.getPayout(strikePrice);
101
+
102
+ const _tlv = payoutCurve.toPayoutCurvePiece().serialize();
103
+ const pf = HyperbolaPayoutCurvePiece.deserialize(_tlv);
104
+
105
+ const deserializedCurve = HyperbolaPayoutCurve.fromPayoutCurvePiece(pf);
106
+
107
+ expect(payout.toNumber()).to.be.eq(
108
+ deserializedCurve.getPayout(strikePrice).toNumber(),
109
+ );
110
+ });
111
+ });
112
+ });