@atomiqlabs/sdk 8.1.7 → 8.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 (253) hide show
  1. package/dist/bitcoin/wallet/BitcoinWallet.d.ts +41 -5
  2. package/dist/bitcoin/wallet/BitcoinWallet.js +36 -1
  3. package/dist/bitcoin/wallet/IBitcoinWallet.d.ts +52 -2
  4. package/dist/bitcoin/wallet/IBitcoinWallet.js +2 -1
  5. package/dist/bitcoin/wallet/SingleAddressBitcoinWallet.d.ts +42 -7
  6. package/dist/bitcoin/wallet/SingleAddressBitcoinWallet.js +36 -1
  7. package/dist/enums/FeeType.d.ts +7 -0
  8. package/dist/enums/FeeType.js +7 -0
  9. package/dist/enums/SwapAmountType.d.ts +7 -0
  10. package/dist/enums/SwapAmountType.js +7 -0
  11. package/dist/enums/SwapDirection.d.ts +7 -0
  12. package/dist/enums/SwapDirection.js +7 -0
  13. package/dist/enums/SwapType.d.ts +62 -1
  14. package/dist/enums/SwapType.js +62 -1
  15. package/dist/errors/IntermediaryError.d.ts +4 -0
  16. package/dist/errors/IntermediaryError.js +1 -0
  17. package/dist/errors/RequestError.d.ts +15 -1
  18. package/dist/errors/RequestError.js +8 -0
  19. package/dist/errors/UserError.d.ts +1 -0
  20. package/dist/errors/UserError.js +1 -0
  21. package/dist/index.d.ts +4 -5
  22. package/dist/index.js +3 -4
  23. package/dist/intermediaries/Intermediary.d.ts +57 -10
  24. package/dist/intermediaries/Intermediary.js +37 -10
  25. package/dist/intermediaries/IntermediaryDiscovery.d.ts +55 -22
  26. package/dist/intermediaries/IntermediaryDiscovery.js +35 -22
  27. package/dist/prices/RedundantSwapPrice.d.ts +24 -3
  28. package/dist/prices/RedundantSwapPrice.js +21 -1
  29. package/dist/prices/SingleSwapPrice.d.ts +9 -6
  30. package/dist/prices/SingleSwapPrice.js +10 -7
  31. package/dist/prices/SwapPriceWithChain.d.ts +54 -16
  32. package/dist/prices/SwapPriceWithChain.js +58 -20
  33. package/dist/prices/abstract/ISwapPrice.d.ts +94 -45
  34. package/dist/prices/abstract/ISwapPrice.js +103 -55
  35. package/dist/prices/providers/BinancePriceProvider.d.ts +7 -0
  36. package/dist/prices/providers/BinancePriceProvider.js +7 -0
  37. package/dist/prices/providers/CoinGeckoPriceProvider.d.ts +6 -0
  38. package/dist/prices/providers/CoinGeckoPriceProvider.js +6 -0
  39. package/dist/prices/providers/CoinPaprikaPriceProvider.d.ts +6 -0
  40. package/dist/prices/providers/CoinPaprikaPriceProvider.js +6 -0
  41. package/dist/prices/providers/CustomPriceProvider.d.ts +11 -0
  42. package/dist/prices/providers/CustomPriceProvider.js +11 -0
  43. package/dist/prices/providers/KrakenPriceProvider.d.ts +9 -0
  44. package/dist/prices/providers/KrakenPriceProvider.js +9 -0
  45. package/dist/prices/providers/OKXPriceProvider.d.ts +6 -0
  46. package/dist/prices/providers/OKXPriceProvider.js +6 -0
  47. package/dist/prices/providers/abstract/ExchangePriceProvider.d.ts +3 -0
  48. package/dist/prices/providers/abstract/ExchangePriceProvider.js +3 -0
  49. package/dist/storage/IUnifiedStorage.d.ts +19 -7
  50. package/dist/storage/UnifiedSwapStorage.d.ts +33 -3
  51. package/dist/storage/UnifiedSwapStorage.js +29 -1
  52. package/dist/storage-browser/IndexedDBUnifiedStorage.d.ts +31 -7
  53. package/dist/storage-browser/IndexedDBUnifiedStorage.js +29 -6
  54. package/dist/storage-browser/LocalStorageManager.d.ts +25 -1
  55. package/dist/storage-browser/LocalStorageManager.js +25 -1
  56. package/dist/swapper/Swapper.d.ts +303 -222
  57. package/dist/swapper/Swapper.js +376 -344
  58. package/dist/swapper/SwapperFactory.d.ts +41 -17
  59. package/dist/swapper/SwapperFactory.js +23 -2
  60. package/dist/swapper/SwapperUtils.d.ts +75 -28
  61. package/dist/swapper/SwapperUtils.js +107 -60
  62. package/dist/swapper/SwapperWithChain.d.ts +286 -91
  63. package/dist/swapper/SwapperWithChain.js +218 -64
  64. package/dist/swapper/SwapperWithSigner.d.ts +229 -80
  65. package/dist/swapper/SwapperWithSigner.js +190 -44
  66. package/dist/swaps/IAddressSwap.d.ts +10 -1
  67. package/dist/swaps/IAddressSwap.js +2 -1
  68. package/dist/swaps/IBTCWalletSwap.d.ts +24 -6
  69. package/dist/swaps/IBTCWalletSwap.js +2 -1
  70. package/dist/swaps/IClaimableSwap.d.ts +36 -4
  71. package/dist/swaps/IClaimableSwap.js +2 -1
  72. package/dist/swaps/IClaimableSwapWrapper.d.ts +11 -1
  73. package/dist/swaps/IRefundableSwap.d.ts +29 -3
  74. package/dist/swaps/IRefundableSwap.js +2 -1
  75. package/dist/swaps/ISwap.d.ts +159 -21
  76. package/dist/swaps/ISwap.js +90 -33
  77. package/dist/swaps/ISwapWithGasDrop.d.ts +6 -0
  78. package/dist/swaps/ISwapWithGasDrop.js +1 -0
  79. package/dist/swaps/ISwapWrapper.d.ts +157 -48
  80. package/dist/swaps/ISwapWrapper.js +130 -72
  81. package/dist/swaps/escrow_swaps/IEscrowSelfInitSwap.d.ts +49 -6
  82. package/dist/swaps/escrow_swaps/IEscrowSelfInitSwap.js +22 -12
  83. package/dist/swaps/escrow_swaps/IEscrowSwap.d.ts +65 -12
  84. package/dist/swaps/escrow_swaps/IEscrowSwap.js +38 -19
  85. package/dist/swaps/escrow_swaps/IEscrowSwapWrapper.d.ts +39 -9
  86. package/dist/swaps/escrow_swaps/IEscrowSwapWrapper.js +30 -21
  87. package/dist/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.d.ts +31 -15
  88. package/dist/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.js +33 -18
  89. package/dist/swaps/escrow_swaps/frombtc/IFromBTCSelfInitSwap.d.ts +94 -29
  90. package/dist/swaps/escrow_swaps/frombtc/IFromBTCSelfInitSwap.js +90 -27
  91. package/dist/swaps/escrow_swaps/frombtc/IFromBTCWrapper.d.ts +22 -9
  92. package/dist/swaps/escrow_swaps/frombtc/IFromBTCWrapper.js +24 -11
  93. package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.d.ts +275 -58
  94. package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.js +516 -239
  95. package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.d.ts +76 -25
  96. package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.js +131 -49
  97. package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.d.ts +311 -51
  98. package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.js +542 -193
  99. package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.d.ts +87 -26
  100. package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.js +147 -58
  101. package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.d.ts +209 -53
  102. package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.js +449 -242
  103. package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.d.ts +77 -23
  104. package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.js +116 -46
  105. package/dist/swaps/escrow_swaps/tobtc/IToBTCSwap.d.ts +197 -56
  106. package/dist/swaps/escrow_swaps/tobtc/IToBTCSwap.js +326 -189
  107. package/dist/swaps/escrow_swaps/tobtc/IToBTCWrapper.d.ts +30 -5
  108. package/dist/swaps/escrow_swaps/tobtc/IToBTCWrapper.js +44 -19
  109. package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNSwap.d.ts +60 -19
  110. package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNSwap.js +74 -31
  111. package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.d.ts +76 -50
  112. package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.js +106 -101
  113. package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCSwap.d.ts +36 -13
  114. package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCSwap.js +65 -19
  115. package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.d.ts +46 -17
  116. package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.js +82 -27
  117. package/dist/swaps/spv_swaps/SpvFromBTCSwap.d.ts +328 -92
  118. package/dist/swaps/spv_swaps/SpvFromBTCSwap.js +460 -219
  119. package/dist/swaps/spv_swaps/SpvFromBTCWrapper.d.ts +76 -24
  120. package/dist/swaps/spv_swaps/SpvFromBTCWrapper.js +244 -124
  121. package/dist/swaps/trusted/ln/LnForGasSwap.d.ts +146 -18
  122. package/dist/swaps/trusted/ln/LnForGasSwap.js +173 -43
  123. package/dist/swaps/trusted/ln/LnForGasWrapper.d.ts +29 -10
  124. package/dist/swaps/trusted/ln/LnForGasWrapper.js +30 -11
  125. package/dist/swaps/trusted/onchain/OnchainForGasSwap.d.ts +200 -47
  126. package/dist/swaps/trusted/onchain/OnchainForGasSwap.js +230 -78
  127. package/dist/swaps/trusted/onchain/OnchainForGasWrapper.d.ts +34 -12
  128. package/dist/swaps/trusted/onchain/OnchainForGasWrapper.js +33 -14
  129. package/dist/types/AmountData.d.ts +2 -1
  130. package/dist/types/CustomPriceFunction.d.ts +7 -1
  131. package/dist/types/SwapExecutionAction.d.ts +74 -4
  132. package/dist/types/SwapWithSigner.d.ts +4 -1
  133. package/dist/types/SwapWithSigner.js +5 -2
  134. package/dist/types/Token.d.ts +11 -5
  135. package/dist/types/Token.js +6 -3
  136. package/dist/types/TokenAmount.d.ts +3 -0
  137. package/dist/types/TokenAmount.js +2 -0
  138. package/dist/types/fees/Fee.d.ts +2 -1
  139. package/dist/types/fees/FeeBreakdown.d.ts +2 -1
  140. package/dist/types/fees/PercentagePPM.d.ts +2 -0
  141. package/dist/types/fees/PercentagePPM.js +1 -0
  142. package/dist/types/lnurl/LNURLPay.d.ts +14 -6
  143. package/dist/types/lnurl/LNURLPay.js +6 -2
  144. package/dist/types/lnurl/LNURLWithdraw.d.ts +12 -5
  145. package/dist/types/lnurl/LNURLWithdraw.js +6 -2
  146. package/dist/types/wallets/LightningInvoiceCreateService.d.ts +20 -0
  147. package/dist/types/wallets/LightningInvoiceCreateService.js +15 -0
  148. package/dist/types/wallets/MinimalBitcoinWalletInterface.d.ts +3 -1
  149. package/dist/types/wallets/MinimalLightningNetworkWalletInterface.d.ts +3 -1
  150. package/dist/utils/BitcoinUtils.d.ts +1 -0
  151. package/dist/utils/BitcoinUtils.js +5 -1
  152. package/dist/utils/SwapUtils.d.ts +56 -1
  153. package/dist/utils/SwapUtils.js +53 -1
  154. package/dist/utils/TokenUtils.d.ts +10 -2
  155. package/dist/utils/TokenUtils.js +12 -4
  156. package/package.json +3 -3
  157. package/src/bitcoin/wallet/BitcoinWallet.ts +41 -5
  158. package/src/bitcoin/wallet/IBitcoinWallet.ts +57 -2
  159. package/src/bitcoin/wallet/SingleAddressBitcoinWallet.ts +42 -6
  160. package/src/enums/FeeType.ts +7 -0
  161. package/src/enums/SwapAmountType.ts +7 -0
  162. package/src/enums/SwapDirection.ts +7 -0
  163. package/src/enums/SwapType.ts +62 -2
  164. package/src/errors/IntermediaryError.ts +4 -0
  165. package/src/errors/RequestError.ts +15 -1
  166. package/src/errors/UserError.ts +1 -0
  167. package/src/index.ts +6 -5
  168. package/src/intermediaries/Intermediary.ts +57 -10
  169. package/src/intermediaries/IntermediaryDiscovery.ts +60 -27
  170. package/src/prices/RedundantSwapPrice.ts +24 -4
  171. package/src/prices/SingleSwapPrice.ts +10 -7
  172. package/src/prices/SwapPriceWithChain.ts +59 -21
  173. package/src/prices/abstract/ISwapPrice.ts +114 -65
  174. package/src/prices/providers/BinancePriceProvider.ts +7 -0
  175. package/src/prices/providers/CoinGeckoPriceProvider.ts +6 -0
  176. package/src/prices/providers/CoinPaprikaPriceProvider.ts +6 -0
  177. package/src/prices/providers/CustomPriceProvider.ts +11 -0
  178. package/src/prices/providers/KrakenPriceProvider.ts +9 -0
  179. package/src/prices/providers/OKXPriceProvider.ts +6 -0
  180. package/src/prices/providers/abstract/ExchangePriceProvider.ts +3 -0
  181. package/src/storage/IUnifiedStorage.ts +19 -7
  182. package/src/storage/UnifiedSwapStorage.ts +33 -3
  183. package/src/storage-browser/IndexedDBUnifiedStorage.ts +31 -8
  184. package/src/storage-browser/LocalStorageManager.ts +25 -1
  185. package/src/swapper/Swapper.ts +513 -379
  186. package/src/swapper/SwapperFactory.ts +44 -21
  187. package/src/swapper/SwapperUtils.ts +107 -60
  188. package/src/swapper/SwapperWithChain.ts +320 -81
  189. package/src/swapper/SwapperWithSigner.ts +263 -56
  190. package/src/swaps/IAddressSwap.ts +11 -1
  191. package/src/swaps/IBTCWalletSwap.ts +24 -8
  192. package/src/swaps/IClaimableSwap.ts +39 -4
  193. package/src/swaps/IClaimableSwapWrapper.ts +11 -2
  194. package/src/swaps/IRefundableSwap.ts +32 -3
  195. package/src/swaps/ISwap.ts +221 -82
  196. package/src/swaps/ISwapWithGasDrop.ts +6 -0
  197. package/src/swaps/ISwapWrapper.ts +212 -94
  198. package/src/swaps/escrow_swaps/IEscrowSelfInitSwap.ts +62 -18
  199. package/src/swaps/escrow_swaps/IEscrowSwap.ts +83 -37
  200. package/src/swaps/escrow_swaps/IEscrowSwapWrapper.ts +61 -30
  201. package/src/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.ts +37 -19
  202. package/src/swaps/escrow_swaps/frombtc/IFromBTCSelfInitSwap.ts +120 -51
  203. package/src/swaps/escrow_swaps/frombtc/IFromBTCWrapper.ts +24 -11
  204. package/src/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.ts +559 -256
  205. package/src/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.ts +155 -61
  206. package/src/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.ts +590 -226
  207. package/src/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.ts +177 -74
  208. package/src/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.ts +470 -243
  209. package/src/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.ts +141 -59
  210. package/src/swaps/escrow_swaps/tobtc/IToBTCSwap.ts +352 -193
  211. package/src/swaps/escrow_swaps/tobtc/IToBTCWrapper.ts +48 -23
  212. package/src/swaps/escrow_swaps/tobtc/ln/ToBTCLNSwap.ts +86 -39
  213. package/src/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.ts +110 -110
  214. package/src/swaps/escrow_swaps/tobtc/onchain/ToBTCSwap.ts +88 -33
  215. package/src/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.ts +101 -31
  216. package/src/swaps/spv_swaps/SpvFromBTCSwap.ts +534 -263
  217. package/src/swaps/spv_swaps/SpvFromBTCWrapper.ts +289 -148
  218. package/src/swaps/trusted/ln/LnForGasSwap.ts +184 -45
  219. package/src/swaps/trusted/ln/LnForGasWrapper.ts +34 -15
  220. package/src/swaps/trusted/onchain/OnchainForGasSwap.ts +260 -86
  221. package/src/swaps/trusted/onchain/OnchainForGasWrapper.ts +41 -19
  222. package/src/types/AmountData.ts +2 -1
  223. package/src/types/CustomPriceFunction.ts +7 -1
  224. package/src/types/SwapExecutionAction.ts +84 -5
  225. package/src/types/SwapWithSigner.ts +7 -3
  226. package/src/types/Token.ts +12 -5
  227. package/src/types/TokenAmount.ts +3 -0
  228. package/src/types/fees/Fee.ts +2 -1
  229. package/src/types/fees/FeeBreakdown.ts +2 -1
  230. package/src/types/fees/PercentagePPM.ts +2 -0
  231. package/src/types/lnurl/LNURLPay.ts +14 -6
  232. package/src/types/lnurl/LNURLWithdraw.ts +12 -5
  233. package/src/types/wallets/LightningInvoiceCreateService.ts +26 -0
  234. package/src/types/wallets/MinimalBitcoinWalletInterface.ts +3 -1
  235. package/src/types/wallets/MinimalLightningNetworkWalletInterface.ts +3 -1
  236. package/src/utils/BitcoinUtils.ts +5 -0
  237. package/src/utils/SwapUtils.ts +61 -1
  238. package/src/utils/TokenUtils.ts +12 -4
  239. package/dist/bitcoin/BitcoinRpcWithAddressIndex.d.ts +0 -68
  240. package/dist/bitcoin/BitcoinRpcWithAddressIndex.js +0 -2
  241. package/dist/bitcoin/LightningNetworkApi.d.ts +0 -12
  242. package/dist/bitcoin/LightningNetworkApi.js +0 -2
  243. package/dist/bitcoin/mempool/MempoolApi.d.ts +0 -350
  244. package/dist/bitcoin/mempool/MempoolApi.js +0 -311
  245. package/dist/bitcoin/mempool/MempoolBitcoinBlock.d.ts +0 -44
  246. package/dist/bitcoin/mempool/MempoolBitcoinBlock.js +0 -48
  247. package/dist/bitcoin/mempool/MempoolBitcoinRpc.d.ts +0 -119
  248. package/dist/bitcoin/mempool/MempoolBitcoinRpc.js +0 -361
  249. package/dist/bitcoin/mempool/synchronizer/MempoolBtcRelaySynchronizer.d.ts +0 -22
  250. package/dist/bitcoin/mempool/synchronizer/MempoolBtcRelaySynchronizer.js +0 -105
  251. package/dist/errors/PaymentAuthError.d.ts +0 -11
  252. package/dist/errors/PaymentAuthError.js +0 -23
  253. package/src/errors/PaymentAuthError.ts +0 -26
@@ -19,6 +19,7 @@ const Logger_1 = require("../../../../utils/Logger");
19
19
  const TimeoutUtils_1 = require("../../../../utils/TimeoutUtils");
20
20
  const LNURLWithdraw_1 = require("../../../../types/lnurl/LNURLWithdraw");
21
21
  const PriceInfoType_1 = require("../../../../types/PriceInfoType");
22
+ const sha2_1 = require("@noble/hashes/sha2");
22
23
  /**
23
24
  * State enum for FromBTCLNAuto swaps
24
25
  * @category Swaps
@@ -35,10 +36,10 @@ var FromBTCLNAutoSwapState;
35
36
  FromBTCLNAutoSwapState[FromBTCLNAutoSwapState["CLAIM_CLAIMED"] = 3] = "CLAIM_CLAIMED";
36
37
  })(FromBTCLNAutoSwapState = exports.FromBTCLNAutoSwapState || (exports.FromBTCLNAutoSwapState = {}));
37
38
  function isFromBTCLNAutoSwapInit(obj) {
38
- return typeof obj.pr === "string" &&
39
- typeof obj.secret === "string" &&
40
- typeof obj.btcAmountSwap === "bigint" &&
41
- typeof obj.btcAmountGas === "bigint" &&
39
+ return (obj.pr == null || typeof obj.pr === "string") &&
40
+ (obj.secret == null || typeof obj.secret === "string") &&
41
+ (obj.btcAmountSwap == null || typeof obj.btcAmountSwap === "bigint") &&
42
+ (obj.btcAmountGas == null || typeof obj.btcAmountGas === "bigint") &&
42
43
  typeof obj.gasSwapFeeBtc === "bigint" &&
43
44
  typeof obj.gasSwapFee === "bigint" &&
44
45
  (obj.gasPricingInfo == null || (0, PriceInfoType_1.isPriceInfoType)(obj.gasPricingInfo)) &&
@@ -48,21 +49,39 @@ function isFromBTCLNAutoSwapInit(obj) {
48
49
  (0, IEscrowSwap_1.isIEscrowSwapInit)(obj);
49
50
  }
50
51
  exports.isFromBTCLNAutoSwapInit = isFromBTCLNAutoSwapInit;
52
+ /**
53
+ * New escrow based (HTLC) swaps for Bitcoin Lightning -> Smart chain swaps not requiring manual settlement on
54
+ * the destination by the user, and instead letting the LP initiate the escrow. Permissionless watchtower network
55
+ * handles the claiming of HTLC, with the swap secret broadcasted over Nostr. Also adds a possibility for the user
56
+ * to receive a native token on the destination chain as part of the swap (a "gas drop" feature).
57
+ *
58
+ * @category Swaps
59
+ */
51
60
  class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
52
- getSwapData() {
53
- return this.data ?? this.initialSwapData;
61
+ /**
62
+ * Sets the LNURL data for the swap
63
+ *
64
+ * @internal
65
+ */
66
+ _setLNURLData(lnurl, lnurlK1, lnurlCallback) {
67
+ this.lnurl = lnurl;
68
+ this.lnurlK1 = lnurlK1;
69
+ this.lnurlCallback = lnurlCallback;
54
70
  }
55
71
  constructor(wrapper, initOrObject) {
56
72
  if (isFromBTCLNAutoSwapInit(initOrObject) && initOrObject.url != null)
57
73
  initOrObject.url += "/frombtcln_auto";
58
74
  super(wrapper, initOrObject);
59
- this.inputToken = Token_1.BitcoinTokens.BTCLN;
60
75
  this.TYPE = SwapType_1.SwapType.FROM_BTCLN_AUTO;
76
+ /**
77
+ * @internal
78
+ */
79
+ this.inputToken = Token_1.BitcoinTokens.BTCLN;
61
80
  this.lnurlFailSignal = new AbortController();
62
81
  this.prPosted = false;
63
82
  this.broadcastTickCounter = 0;
64
83
  if (isFromBTCLNAutoSwapInit(initOrObject)) {
65
- this.state = FromBTCLNAutoSwapState.PR_CREATED;
84
+ this._state = FromBTCLNAutoSwapState.PR_CREATED;
66
85
  this.pr = initOrObject.pr;
67
86
  this.secret = initOrObject.secret;
68
87
  this.initialSwapData = initOrObject.initialSwapData;
@@ -74,12 +93,13 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
74
93
  this.lnurl = initOrObject.lnurl;
75
94
  this.lnurlK1 = initOrObject.lnurlK1;
76
95
  this.lnurlCallback = initOrObject.lnurlCallback;
96
+ this.usesClaimHashAsId = true;
77
97
  }
78
98
  else {
79
99
  this.pr = initOrObject.pr;
80
100
  this.secret = initOrObject.secret;
81
101
  if (initOrObject.initialSwapData == null) {
82
- this.initialSwapData = this.data;
102
+ this.initialSwapData = this._data;
83
103
  }
84
104
  else {
85
105
  this.initialSwapData = base_1.SwapData.deserialize(initOrObject.initialSwapData);
@@ -89,225 +109,398 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
89
109
  this.gasSwapFeeBtc = (0, Utils_1.toBigInt)(initOrObject.gasSwapFeeBtc);
90
110
  this.gasSwapFee = (0, Utils_1.toBigInt)(initOrObject.gasSwapFee);
91
111
  this.gasPricingInfo = (0, PriceInfoType_1.deserializePriceInfoType)(initOrObject.gasPricingInfo);
92
- this.commitTxId = initOrObject.commitTxId;
93
- this.claimTxId = initOrObject.claimTxId;
112
+ this._commitTxId = initOrObject.commitTxId;
113
+ this._claimTxId = initOrObject.claimTxId;
94
114
  this.lnurl = initOrObject.lnurl;
95
115
  this.lnurlK1 = initOrObject.lnurlK1;
96
116
  this.lnurlCallback = initOrObject.lnurlCallback;
97
117
  this.prPosted = initOrObject.prPosted;
118
+ this.usesClaimHashAsId = initOrObject.usesClaimHashAsId ?? false;
98
119
  }
99
120
  this.tryRecomputeSwapPrice();
100
121
  this.logger = (0, Logger_1.getLogger)("FromBTCLNAuto(" + this.getIdentifierHashString() + "): ");
101
122
  }
123
+ /**
124
+ * @inheritDoc
125
+ * @internal
126
+ */
127
+ getSwapData() {
128
+ return this._data ?? this.initialSwapData;
129
+ }
130
+ /**
131
+ * @inheritDoc
132
+ * @internal
133
+ */
102
134
  upgradeVersion() { }
103
135
  /**
104
- * In case swapFee in BTC is not supplied it recalculates it based on swap price
105
- * @protected
136
+ * @inheritDoc
137
+ * @internal
106
138
  */
107
139
  tryRecomputeSwapPrice() {
108
- if (this.pricingInfo == null)
140
+ if (this.pricingInfo == null || this.btcAmountSwap == null)
109
141
  return;
110
142
  if (this.pricingInfo.swapPriceUSatPerToken == null) {
111
143
  const priceUsdPerBtc = this.pricingInfo.realPriceUsdPerBitcoin;
112
- this.pricingInfo = this.wrapper.prices.recomputePriceInfoReceive(this.chainIdentifier, this.btcAmountSwap, this.pricingInfo.satsBaseFee, this.pricingInfo.feePPM, this.getOutputAmountWithoutFee(), this.getSwapData().getToken());
144
+ this.pricingInfo = this.wrapper._prices.recomputePriceInfoReceive(this.chainIdentifier, this.btcAmountSwap, this.pricingInfo.satsBaseFee, this.pricingInfo.feePPM, this.getOutputAmountWithoutFee(), this.getSwapData().getToken());
113
145
  this.pricingInfo.realPriceUsdPerBitcoin = priceUsdPerBtc;
114
146
  }
115
147
  }
116
148
  //////////////////////////////
117
149
  //// Pricing
150
+ /**
151
+ * @inheritDoc
152
+ */
118
153
  async refreshPriceData() {
119
- if (this.pricingInfo == null)
154
+ if (this.pricingInfo == null || this.btcAmountSwap == null)
120
155
  return;
121
156
  const usdPricePerBtc = this.pricingInfo.realPriceUsdPerBitcoin;
122
- this.pricingInfo = await this.wrapper.prices.isValidAmountReceive(this.chainIdentifier, this.btcAmountSwap, this.pricingInfo.satsBaseFee, this.pricingInfo.feePPM, this.getOutputAmountWithoutFee(), this.getSwapData().getToken());
157
+ this.pricingInfo = await this.wrapper._prices.isValidAmountReceive(this.chainIdentifier, this.btcAmountSwap, this.pricingInfo.satsBaseFee, this.pricingInfo.feePPM, this.getOutputAmountWithoutFee(), this.getSwapData().getToken());
123
158
  this.pricingInfo.realPriceUsdPerBitcoin = usdPricePerBtc;
124
159
  }
125
160
  //////////////////////////////
126
161
  //// Getters & utils
162
+ /**
163
+ * @inheritDoc
164
+ * @internal
165
+ */
127
166
  _getEscrowHash() {
128
167
  //Use claim hash in case the data is not yet known
129
- return this.data == null ? this.initialSwapData?.getClaimHash() : this.data?.getEscrowHash();
168
+ return this._data == null ? this.initialSwapData?.getClaimHash() : this._data?.getEscrowHash();
130
169
  }
170
+ /**
171
+ * @inheritDoc
172
+ * @internal
173
+ */
131
174
  _getInitiator() {
132
175
  return this.getSwapData().getClaimer();
133
176
  }
177
+ /**
178
+ * @inheritDoc
179
+ */
134
180
  getId() {
135
181
  return this.getIdentifierHashString();
136
182
  }
183
+ /**
184
+ * @inheritDoc
185
+ */
137
186
  getOutputAddress() {
138
187
  return this._getInitiator();
139
188
  }
189
+ /**
190
+ * @inheritDoc
191
+ */
140
192
  getOutputTxId() {
141
- return this.claimTxId ?? null;
193
+ return this._claimTxId ?? null;
142
194
  }
195
+ /**
196
+ * @inheritDoc
197
+ */
143
198
  requiresAction() {
144
- return this.state === FromBTCLNAutoSwapState.CLAIM_COMMITED;
199
+ return this._state === FromBTCLNAutoSwapState.CLAIM_COMMITED;
145
200
  }
201
+ /**
202
+ * @inheritDoc
203
+ * @internal
204
+ */
146
205
  getIdentifierHashString() {
147
- const paymentHashBuffer = this.getPaymentHash();
148
- if (this.randomNonce == null)
149
- return paymentHashBuffer?.toString("hex");
150
- return paymentHashBuffer.toString("hex") + this.randomNonce;
206
+ const id = this.usesClaimHashAsId
207
+ ? this.getClaimHash()
208
+ : this.getPaymentHash().toString("hex");
209
+ if (this._randomNonce == null)
210
+ return id;
211
+ return id + this._randomNonce;
151
212
  }
213
+ /**
214
+ * Returns the payment hash of the swap and lightning network invoice, or `null` if not known (i.e. if
215
+ * the swap was recovered from on-chain data, the payment hash might not be known)
216
+ *
217
+ * @internal
218
+ */
152
219
  getPaymentHash() {
153
- const decodedPR = (0, bolt11_1.decode)(this.pr);
154
- if (decodedPR.tagsObject.payment_hash == null)
155
- throw new Error("Swap invoice doesn't contain payment hash field!");
156
- return buffer_1.Buffer.from(decodedPR.tagsObject.payment_hash, "hex");
220
+ if (this.pr == null)
221
+ return null;
222
+ if (this.pr.toLowerCase().startsWith("ln")) {
223
+ const parsed = (0, bolt11_1.decode)(this.pr);
224
+ if (parsed.tagsObject.payment_hash == null)
225
+ throw new Error("Swap invoice has no payment hash field!");
226
+ return buffer_1.Buffer.from(parsed.tagsObject.payment_hash, "hex");
227
+ }
228
+ return buffer_1.Buffer.from(this.pr, "hex");
157
229
  }
230
+ /**
231
+ * @inheritDoc
232
+ */
158
233
  getInputAddress() {
159
- return this.lnurl ?? this.pr;
234
+ return this.lnurl ?? this.pr ?? null;
160
235
  }
236
+ /**
237
+ * @inheritDoc
238
+ */
161
239
  getInputTxId() {
162
- return this.getPaymentHash().toString("hex");
240
+ const paymentHash = this.getPaymentHash();
241
+ if (paymentHash == null)
242
+ return null;
243
+ return paymentHash.toString("hex");
163
244
  }
164
245
  /**
165
246
  * Returns the lightning network BOLT11 invoice that needs to be paid as an input to the swap
166
247
  */
167
248
  getAddress() {
168
- return this.pr;
249
+ return this.pr ?? "";
169
250
  }
251
+ /**
252
+ * @inheritDoc
253
+ */
170
254
  getHyperlink() {
171
- return "lightning:" + this.pr.toUpperCase();
255
+ return this.pr == null ? "" : "lightning:" + this.pr.toUpperCase();
172
256
  }
173
257
  /**
174
258
  * Returns the timeout time (in UNIX milliseconds) when the swap will definitelly be considered as expired
175
259
  * if the LP doesn't make it expired sooner
176
260
  */
177
261
  getDefinitiveExpiryTime() {
262
+ if (this.pr == null || !this.pr.toLowerCase().startsWith("ln"))
263
+ return 0;
178
264
  const decoded = (0, bolt11_1.decode)(this.pr);
179
265
  if (decoded.tagsObject.min_final_cltv_expiry == null)
180
266
  throw new Error("Swap invoice doesn't contain final ctlv delta field!");
181
267
  if (decoded.timeExpireDate == null)
182
268
  throw new Error("Swap invoice doesn't contain expiry date field!");
183
269
  const finalCltvExpiryDelta = decoded.tagsObject.min_final_cltv_expiry ?? 144;
184
- const finalCltvExpiryDelay = finalCltvExpiryDelta * this.wrapper.options.bitcoinBlocktime * this.wrapper.options.safetyFactor;
270
+ const finalCltvExpiryDelay = finalCltvExpiryDelta * this.wrapper._options.bitcoinBlocktime * this.wrapper._options.safetyFactor;
185
271
  return (decoded.timeExpireDate + finalCltvExpiryDelay) * 1000;
186
272
  }
187
273
  /**
188
274
  * Returns timeout time (in UNIX milliseconds) when the swap htlc will expire
189
275
  */
190
276
  getHtlcTimeoutTime() {
191
- return this.data == null ? null : Number(this.wrapper.getHtlcTimeout(this.data)) * 1000;
277
+ return this._data == null ? null : Number(this.wrapper._getHtlcTimeout(this._data)) * 1000;
192
278
  }
279
+ /**
280
+ * @inheritDoc
281
+ */
193
282
  isFinished() {
194
- return this.state === FromBTCLNAutoSwapState.CLAIM_CLAIMED || this.state === FromBTCLNAutoSwapState.QUOTE_EXPIRED || this.state === FromBTCLNAutoSwapState.FAILED;
283
+ return this._state === FromBTCLNAutoSwapState.CLAIM_CLAIMED || this._state === FromBTCLNAutoSwapState.QUOTE_EXPIRED || this._state === FromBTCLNAutoSwapState.FAILED;
195
284
  }
285
+ /**
286
+ * @inheritDoc
287
+ */
196
288
  isClaimable() {
197
- return this.state === FromBTCLNAutoSwapState.CLAIM_COMMITED;
289
+ return this._state === FromBTCLNAutoSwapState.CLAIM_COMMITED;
198
290
  }
291
+ /**
292
+ * @inheritDoc
293
+ */
199
294
  isSuccessful() {
200
- return this.state === FromBTCLNAutoSwapState.CLAIM_CLAIMED;
295
+ return this._state === FromBTCLNAutoSwapState.CLAIM_CLAIMED;
201
296
  }
297
+ /**
298
+ * @inheritDoc
299
+ */
202
300
  isFailed() {
203
- return this.state === FromBTCLNAutoSwapState.FAILED || this.state === FromBTCLNAutoSwapState.EXPIRED;
301
+ return this._state === FromBTCLNAutoSwapState.FAILED || this._state === FromBTCLNAutoSwapState.EXPIRED;
204
302
  }
303
+ /**
304
+ * @inheritDoc
305
+ */
205
306
  isQuoteExpired() {
206
- return this.state === FromBTCLNAutoSwapState.QUOTE_EXPIRED;
307
+ return this._state === FromBTCLNAutoSwapState.QUOTE_EXPIRED;
207
308
  }
309
+ /**
310
+ * @inheritDoc
311
+ */
208
312
  isQuoteSoftExpired() {
209
- return this.state === FromBTCLNAutoSwapState.QUOTE_EXPIRED;
313
+ return this._state === FromBTCLNAutoSwapState.QUOTE_EXPIRED;
210
314
  }
315
+ /**
316
+ * @inheritDoc
317
+ */
211
318
  _verifyQuoteDefinitelyExpired() {
212
319
  return Promise.resolve(this.getDefinitiveExpiryTime() < Date.now());
213
320
  }
214
- verifyQuoteValid() {
321
+ /**
322
+ * @inheritDoc
323
+ */
324
+ _verifyQuoteValid() {
215
325
  return Promise.resolve(this.getQuoteExpiry() > Date.now());
216
326
  }
217
327
  //////////////////////////////
218
328
  //// Amounts & fees
329
+ /**
330
+ * Returns the satoshi amount of the lightning network invoice, or `null` if the lightning network
331
+ * invoice is not known (i.e. when the swap was recovered from on-chain data, the paid invoice
332
+ * cannot be recovered because it is purely off-chain)
333
+ *
334
+ * @internal
335
+ */
219
336
  getLightningInvoiceSats() {
337
+ if (this.pr == null || !this.pr.toLowerCase().startsWith("ln"))
338
+ return null;
220
339
  const parsed = (0, bolt11_1.decode)(this.pr);
221
340
  if (parsed.millisatoshis == null)
222
341
  throw new Error("Swap invoice doesn't contain msat amount field!");
223
342
  return (BigInt(parsed.millisatoshis) + 999n) / 1000n;
224
343
  }
344
+ /**
345
+ * Returns the watchtower fee paid in BTC satoshis, or null if known (i.e. if the swap was recovered from
346
+ * on-chain data)
347
+ *
348
+ * @protected
349
+ */
225
350
  getWatchtowerFeeAmountBtc() {
351
+ if (this.btcAmountGas == null)
352
+ return null;
226
353
  return (this.btcAmountGas - this.gasSwapFeeBtc) * this.getSwapData().getClaimerBounty() / this.getSwapData().getTotalDeposit();
227
354
  }
355
+ /**
356
+ * Returns the input amount for the actual swap (excluding the input amount used to cover the "gas drop"
357
+ * part of the swap), excluding fees
358
+ *
359
+ * @internal
360
+ */
228
361
  getInputSwapAmountWithoutFee() {
362
+ if (this.btcAmountSwap == null)
363
+ return null;
229
364
  return this.btcAmountSwap - this.swapFeeBtc;
230
365
  }
366
+ /**
367
+ * Returns the input amount purely for the "gas drop" part of the swap (this much BTC in sats will be
368
+ * swapped into the native gas token on the destination chain), excluding fees
369
+ *
370
+ * @internal
371
+ */
231
372
  getInputGasAmountWithoutFee() {
373
+ if (this.btcAmountGas == null)
374
+ return null;
232
375
  return this.btcAmountGas - this.gasSwapFeeBtc;
233
376
  }
377
+ /**
378
+ * Get total btc amount in sats on the input, excluding the swap fee and watchtower fee
379
+ *
380
+ * @internal
381
+ */
234
382
  getInputAmountWithoutFee() {
383
+ if (this.btcAmountGas == null || this.btcAmountSwap)
384
+ return null;
235
385
  return this.getInputSwapAmountWithoutFee() + this.getInputGasAmountWithoutFee() - this.getWatchtowerFeeAmountBtc();
236
386
  }
387
+ /**
388
+ * Returns the "would be" output amount if the swap charged no swap fee
389
+ *
390
+ * @internal
391
+ */
237
392
  getOutputAmountWithoutFee() {
238
393
  return this.getSwapData().getAmount() + this.swapFee;
239
394
  }
395
+ /**
396
+ * @inheritDoc
397
+ */
240
398
  getInputToken() {
241
399
  return Token_1.BitcoinTokens.BTCLN;
242
400
  }
401
+ /**
402
+ * @inheritDoc
403
+ */
243
404
  getInput() {
244
- return (0, TokenAmount_1.toTokenAmount)(this.getLightningInvoiceSats(), this.inputToken, this.wrapper.prices, this.pricingInfo);
405
+ return (0, TokenAmount_1.toTokenAmount)(this.getLightningInvoiceSats(), this.inputToken, this.wrapper._prices, this.pricingInfo);
245
406
  }
407
+ /**
408
+ * @inheritDoc
409
+ */
246
410
  getInputWithoutFee() {
247
- return (0, TokenAmount_1.toTokenAmount)(this.getInputAmountWithoutFee(), this.inputToken, this.wrapper.prices, this.pricingInfo);
411
+ return (0, TokenAmount_1.toTokenAmount)(this.getInputAmountWithoutFee(), this.inputToken, this.wrapper._prices, this.pricingInfo);
248
412
  }
413
+ /**
414
+ * @inheritDoc
415
+ */
249
416
  getOutputToken() {
250
- return this.wrapper.tokens[this.getSwapData().getToken()];
417
+ return this.wrapper._tokens[this.getSwapData().getToken()];
251
418
  }
419
+ /**
420
+ * @inheritDoc
421
+ */
252
422
  getOutput() {
253
- return (0, TokenAmount_1.toTokenAmount)(this.getSwapData().getAmount(), this.wrapper.tokens[this.getSwapData().getToken()], this.wrapper.prices, this.pricingInfo);
423
+ return (0, TokenAmount_1.toTokenAmount)(this.getSwapData().getAmount(), this.wrapper._tokens[this.getSwapData().getToken()], this.wrapper._prices, this.pricingInfo);
254
424
  }
425
+ /**
426
+ * @inheritDoc
427
+ */
255
428
  getGasDropOutput() {
256
- return (0, TokenAmount_1.toTokenAmount)(this.getSwapData().getSecurityDeposit() - this.getSwapData().getClaimerBounty(), this.wrapper.tokens[this.getSwapData().getDepositToken()], this.wrapper.prices, this.gasPricingInfo);
429
+ return (0, TokenAmount_1.toTokenAmount)(this.getSwapData().getSecurityDeposit() - this.getSwapData().getClaimerBounty(), this.wrapper._tokens[this.getSwapData().getDepositToken()], this.wrapper._prices, this.gasPricingInfo);
257
430
  }
431
+ /**
432
+ * Returns the swap fee charged by the intermediary (LP) on this swap
433
+ *
434
+ * @internal
435
+ */
258
436
  getSwapFee() {
259
437
  if (this.pricingInfo == null)
260
438
  throw new Error("No pricing info known, cannot estimate fee!");
261
- const outputToken = this.wrapper.tokens[this.getSwapData().getToken()];
439
+ const outputToken = this.wrapper._tokens[this.getSwapData().getToken()];
262
440
  const gasSwapFeeInOutputToken = this.gasSwapFeeBtc
263
441
  * (10n ** BigInt(outputToken.decimals))
264
442
  * 1000000n
265
443
  / this.pricingInfo.swapPriceUSatPerToken;
266
444
  const feeWithoutBaseFee = this.gasSwapFeeBtc + this.swapFeeBtc - this.pricingInfo.satsBaseFee;
267
- const swapFeePPM = feeWithoutBaseFee * 1000000n / (this.getLightningInvoiceSats() - this.swapFeeBtc - this.gasSwapFeeBtc);
268
- const amountInSrcToken = (0, TokenAmount_1.toTokenAmount)(this.swapFeeBtc + this.gasSwapFeeBtc, Token_1.BitcoinTokens.BTCLN, this.wrapper.prices, this.pricingInfo);
445
+ const inputSats = this.getLightningInvoiceSats();
446
+ const swapFeePPM = inputSats != null
447
+ ? feeWithoutBaseFee * 1000000n / (inputSats - this.swapFeeBtc - this.gasSwapFeeBtc)
448
+ : 0n;
449
+ const amountInSrcToken = (0, TokenAmount_1.toTokenAmount)(this.swapFeeBtc + this.gasSwapFeeBtc, Token_1.BitcoinTokens.BTCLN, this.wrapper._prices, this.pricingInfo);
269
450
  return {
270
451
  amountInSrcToken,
271
- amountInDstToken: (0, TokenAmount_1.toTokenAmount)(this.swapFee + gasSwapFeeInOutputToken, outputToken, this.wrapper.prices, this.pricingInfo),
452
+ amountInDstToken: (0, TokenAmount_1.toTokenAmount)(this.swapFee + gasSwapFeeInOutputToken, outputToken, this.wrapper._prices, this.pricingInfo),
272
453
  currentUsdValue: amountInSrcToken.currentUsdValue,
273
454
  pastUsdValue: amountInSrcToken.pastUsdValue,
274
455
  usdValue: amountInSrcToken.usdValue,
275
456
  composition: {
276
- base: (0, TokenAmount_1.toTokenAmount)(this.pricingInfo.satsBaseFee, Token_1.BitcoinTokens.BTCLN, this.wrapper.prices, this.pricingInfo),
457
+ base: (0, TokenAmount_1.toTokenAmount)(this.pricingInfo.satsBaseFee, Token_1.BitcoinTokens.BTCLN, this.wrapper._prices, this.pricingInfo),
277
458
  percentage: (0, PercentagePPM_1.ppmToPercentage)(swapFeePPM)
278
459
  }
279
460
  };
280
461
  }
462
+ /**
463
+ * Returns the fee to be paid to watchtowers on the destination chain to automatically
464
+ * process and settle this swap without requiring any user interaction
465
+ *
466
+ * @internal
467
+ */
281
468
  getWatchtowerFee() {
282
469
  if (this.pricingInfo == null)
283
470
  throw new Error("No pricing info known, cannot estimate fee!");
284
471
  const btcWatchtowerFee = this.getWatchtowerFeeAmountBtc();
285
- const outputToken = this.wrapper.tokens[this.getSwapData().getToken()];
286
- const watchtowerFeeInOutputToken = btcWatchtowerFee
472
+ const outputToken = this.wrapper._tokens[this.getSwapData().getToken()];
473
+ const watchtowerFeeInOutputToken = btcWatchtowerFee == null ? 0n : btcWatchtowerFee
287
474
  * (10n ** BigInt(outputToken.decimals))
288
475
  * 1000000n
289
476
  / this.pricingInfo.swapPriceUSatPerToken;
290
- const amountInSrcToken = (0, TokenAmount_1.toTokenAmount)(btcWatchtowerFee, Token_1.BitcoinTokens.BTCLN, this.wrapper.prices, this.pricingInfo);
477
+ const amountInSrcToken = (0, TokenAmount_1.toTokenAmount)(btcWatchtowerFee, Token_1.BitcoinTokens.BTCLN, this.wrapper._prices, this.pricingInfo);
291
478
  return {
292
479
  amountInSrcToken,
293
- amountInDstToken: (0, TokenAmount_1.toTokenAmount)(watchtowerFeeInOutputToken, outputToken, this.wrapper.prices, this.pricingInfo),
480
+ amountInDstToken: (0, TokenAmount_1.toTokenAmount)(watchtowerFeeInOutputToken, outputToken, this.wrapper._prices, this.pricingInfo),
294
481
  currentUsdValue: amountInSrcToken.currentUsdValue,
295
482
  usdValue: amountInSrcToken.usdValue,
296
483
  pastUsdValue: amountInSrcToken.pastUsdValue
297
484
  };
298
485
  }
486
+ /**
487
+ * @inheritDoc
488
+ */
299
489
  getFee() {
300
490
  const swapFee = this.getSwapFee();
301
491
  const watchtowerFee = this.getWatchtowerFee();
302
- const amountInSrcToken = (0, TokenAmount_1.toTokenAmount)(swapFee.amountInSrcToken.rawAmount + watchtowerFee.amountInSrcToken.rawAmount, Token_1.BitcoinTokens.BTCLN, this.wrapper.prices, this.pricingInfo);
492
+ const amountInSrcToken = (0, TokenAmount_1.toTokenAmount)(swapFee.amountInSrcToken.rawAmount + watchtowerFee.amountInSrcToken.rawAmount, Token_1.BitcoinTokens.BTCLN, this.wrapper._prices, this.pricingInfo);
303
493
  return {
304
494
  amountInSrcToken,
305
- amountInDstToken: (0, TokenAmount_1.toTokenAmount)(swapFee.amountInDstToken.rawAmount + watchtowerFee.amountInDstToken.rawAmount, this.wrapper.tokens[this.getSwapData().getToken()], this.wrapper.prices, this.pricingInfo),
495
+ amountInDstToken: (0, TokenAmount_1.toTokenAmount)(swapFee.amountInDstToken.rawAmount + watchtowerFee.amountInDstToken.rawAmount, this.wrapper._tokens[this.getSwapData().getToken()], this.wrapper._prices, this.pricingInfo),
306
496
  currentUsdValue: amountInSrcToken.currentUsdValue,
307
497
  usdValue: amountInSrcToken.usdValue,
308
498
  pastUsdValue: amountInSrcToken.pastUsdValue
309
499
  };
310
500
  }
501
+ /**
502
+ * @inheritDoc
503
+ */
311
504
  getFeeBreakdown() {
312
505
  return [
313
506
  {
@@ -320,6 +513,11 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
320
513
  }
321
514
  ];
322
515
  }
516
+ isValidSecretPreimage(secret) {
517
+ const paymentHash = buffer_1.Buffer.from((0, sha2_1.sha256)(buffer_1.Buffer.from(secret, "hex")));
518
+ const claimHash = this.wrapper._contract.getHashForHtlc(paymentHash).toString("hex");
519
+ return this.getSwapData().getClaimHash() === claimHash;
520
+ }
323
521
  //////////////////////////////
324
522
  //// Execution
325
523
  /**
@@ -329,22 +527,26 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
329
527
  * link, wallet is not required and the LN invoice can be paid externally as well (just pass null or undefined here)
330
528
  * @param callbacks Callbacks to track the progress of the swap
331
529
  * @param options Optional options for the swap like feeRate, AbortSignal, and timeouts/intervals
530
+ * @param secret A swap secret to broadcast to watchtowers, generally only needed if the swap
531
+ * was recovered from on-chain data, or the pre-image was generated outside the SDK
332
532
  *
333
533
  * @returns {boolean} Whether a swap was settled automatically by swap watchtowers or requires manual claim by the
334
534
  * user, in case `false` is returned the user should call `swap.claim()` to settle the swap on the destination manually
335
535
  */
336
- async execute(walletOrLnurlWithdraw, callbacks, options) {
337
- if (this.state === FromBTCLNAutoSwapState.FAILED)
536
+ async execute(walletOrLnurlWithdraw, callbacks, options, secret) {
537
+ if (this._state === FromBTCLNAutoSwapState.FAILED)
338
538
  throw new Error("Swap failed!");
339
- if (this.state === FromBTCLNAutoSwapState.EXPIRED)
539
+ if (this._state === FromBTCLNAutoSwapState.EXPIRED)
340
540
  throw new Error("Swap HTLC expired!");
341
- if (this.state === FromBTCLNAutoSwapState.QUOTE_EXPIRED || this.state === FromBTCLNAutoSwapState.QUOTE_SOFT_EXPIRED)
541
+ if (this._state === FromBTCLNAutoSwapState.QUOTE_EXPIRED || this._state === FromBTCLNAutoSwapState.QUOTE_SOFT_EXPIRED)
342
542
  throw new Error("Swap quote expired!");
343
- if (this.state === FromBTCLNAutoSwapState.CLAIM_CLAIMED)
543
+ if (this._state === FromBTCLNAutoSwapState.CLAIM_CLAIMED)
344
544
  throw new Error("Swap already settled!");
345
545
  let abortSignal = options?.abortSignal;
346
- if (this.state === FromBTCLNAutoSwapState.PR_CREATED) {
546
+ if (this._state === FromBTCLNAutoSwapState.PR_CREATED) {
347
547
  if (walletOrLnurlWithdraw != null && this.lnurl == null) {
548
+ if (this.pr == null || !this.pr.toLowerCase().startsWith("ln"))
549
+ throw new Error("Input lightning network invoice not available, the swap was probably recovered!");
348
550
  if (typeof (walletOrLnurlWithdraw) === "string" || (0, LNURLWithdraw_1.isLNURLWithdraw)(walletOrLnurlWithdraw)) {
349
551
  await this.settleWithLNURLWithdraw(walletOrLnurlWithdraw);
350
552
  }
@@ -358,24 +560,29 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
358
560
  }
359
561
  }
360
562
  }
361
- if (this.state === FromBTCLNAutoSwapState.PR_CREATED || this.state === FromBTCLNAutoSwapState.PR_PAID) {
563
+ if (this._state === FromBTCLNAutoSwapState.PR_CREATED || this._state === FromBTCLNAutoSwapState.PR_PAID) {
362
564
  const paymentSuccess = await this.waitForPayment(callbacks?.onSourceTransactionReceived, options?.lightningTxCheckIntervalSeconds, abortSignal);
363
565
  if (!paymentSuccess)
364
566
  throw new Error("Failed to receive lightning network payment");
365
567
  }
366
- if (this.state === FromBTCLNAutoSwapState.CLAIM_CLAIMED)
568
+ if (this._state === FromBTCLNAutoSwapState.CLAIM_CLAIMED)
367
569
  return true;
368
- if (this.state === FromBTCLNAutoSwapState.CLAIM_COMMITED) {
369
- const success = await this.waitTillClaimed(options?.maxWaitTillAutomaticSettlementSeconds ?? 60, options?.abortSignal);
570
+ if (this._state === FromBTCLNAutoSwapState.CLAIM_COMMITED) {
571
+ if (this.secret == null && secret == null)
572
+ throw new Error("Tried to wait till settlement, but no secret pre-image is known, please pass the secret pre-image as an argument!");
573
+ const success = await this.waitTillClaimed(options?.maxWaitTillAutomaticSettlementSeconds ?? 60, options?.abortSignal, secret);
370
574
  if (success && callbacks?.onSwapSettled != null)
371
575
  callbacks.onSwapSettled(this.getOutputTxId());
372
576
  return success;
373
577
  }
374
578
  throw new Error("Invalid state reached!");
375
579
  }
580
+ /**
581
+ * @inheritDoc
582
+ */
376
583
  async txsExecute() {
377
- if (this.state === FromBTCLNAutoSwapState.PR_CREATED) {
378
- if (!await this.verifyQuoteValid())
584
+ if (this._state === FromBTCLNAutoSwapState.PR_CREATED) {
585
+ if (!await this._verifyQuoteValid())
379
586
  throw new Error("Quote already expired or close to expiry!");
380
587
  return [
381
588
  {
@@ -384,7 +591,8 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
384
591
  chain: "LIGHTNING",
385
592
  txs: [
386
593
  {
387
- address: this.pr,
594
+ type: "BOLT11_PAYMENT_REQUEST",
595
+ address: this.getAddress(),
388
596
  hyperlink: this.getHyperlink()
389
597
  }
390
598
  ]
@@ -396,25 +604,31 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
396
604
  //////////////////////////////
397
605
  //// Payment
398
606
  /**
399
- * Checks whether the LP received the LN payment and we can continue by committing & claiming the HTLC on-chain
607
+ * Checks whether the LP received the LN payment
400
608
  *
401
609
  * @param save If the new swap state should be saved
610
+ *
611
+ * @internal
402
612
  */
403
613
  async _checkIntermediaryPaymentReceived(save = true) {
404
- if (this.state === FromBTCLNAutoSwapState.PR_PAID ||
405
- this.state === FromBTCLNAutoSwapState.CLAIM_COMMITED ||
406
- this.state === FromBTCLNAutoSwapState.CLAIM_CLAIMED ||
407
- this.state === FromBTCLNAutoSwapState.FAILED)
614
+ if (this._state === FromBTCLNAutoSwapState.PR_PAID ||
615
+ this._state === FromBTCLNAutoSwapState.CLAIM_COMMITED ||
616
+ this._state === FromBTCLNAutoSwapState.CLAIM_CLAIMED ||
617
+ this._state === FromBTCLNAutoSwapState.FAILED ||
618
+ this._state === FromBTCLNAutoSwapState.EXPIRED)
408
619
  return true;
409
- if (this.state === FromBTCLNAutoSwapState.QUOTE_EXPIRED)
620
+ if (this._state === FromBTCLNAutoSwapState.QUOTE_EXPIRED)
410
621
  return false;
411
622
  if (this.url == null)
412
623
  return false;
413
- const resp = await IntermediaryAPI_1.IntermediaryAPI.getInvoiceStatus(this.url, this.getPaymentHash().toString("hex"));
624
+ const paymentHash = this.getPaymentHash();
625
+ if (paymentHash == null)
626
+ throw new Error("Failed to check LP payment received, payment hash not known (probably recovered swap?)");
627
+ const resp = await IntermediaryAPI_1.IntermediaryAPI.getInvoiceStatus(this.url, paymentHash.toString("hex"));
414
628
  switch (resp.code) {
415
629
  case IntermediaryAPI_1.InvoiceStatusResponseCodes.PAID:
416
- const data = new this.wrapper.swapDataDeserializer(resp.data.data);
417
- if (this.state === FromBTCLNAutoSwapState.PR_CREATED || this.state === FromBTCLNAutoSwapState.QUOTE_SOFT_EXPIRED)
630
+ const data = new this.wrapper._swapDataDeserializer(resp.data.data);
631
+ if (this._state === FromBTCLNAutoSwapState.PR_CREATED || this._state === FromBTCLNAutoSwapState.QUOTE_SOFT_EXPIRED)
418
632
  try {
419
633
  await this._saveRealSwapData(data, save);
420
634
  return true;
@@ -422,7 +636,7 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
422
636
  catch (e) { }
423
637
  return null;
424
638
  case IntermediaryAPI_1.InvoiceStatusResponseCodes.EXPIRED:
425
- this.state = FromBTCLNAutoSwapState.QUOTE_EXPIRED;
639
+ this._state = FromBTCLNAutoSwapState.QUOTE_EXPIRED;
426
640
  this.initiated = true;
427
641
  if (save)
428
642
  await this._saveAndEmit();
@@ -431,11 +645,20 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
431
645
  return null;
432
646
  }
433
647
  }
648
+ /**
649
+ * Checks and overrides the swap data for this swap. This is used to set the swap data from
650
+ * on-chain events.
651
+ *
652
+ * @param data Swap data of the escrow swap
653
+ * @param save If the new data should be saved
654
+ *
655
+ * @internal
656
+ */
434
657
  async _saveRealSwapData(data, save) {
435
658
  await this.checkIntermediaryReturnedData(data);
436
- if (this.state === FromBTCLNAutoSwapState.PR_CREATED || this.state === FromBTCLNAutoSwapState.QUOTE_SOFT_EXPIRED) {
437
- this.state = FromBTCLNAutoSwapState.PR_PAID;
438
- this.data = data;
659
+ if (this._state === FromBTCLNAutoSwapState.PR_CREATED || this._state === FromBTCLNAutoSwapState.QUOTE_SOFT_EXPIRED) {
660
+ this._state = FromBTCLNAutoSwapState.PR_PAID;
661
+ this._data = data;
439
662
  this.initiated = true;
440
663
  if (save)
441
664
  await this._saveAndEmit();
@@ -447,9 +670,11 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
447
670
  * Checks the data returned by the intermediary in the payment auth request
448
671
  *
449
672
  * @param data Parsed swap data as returned by the intermediary
450
- * @protected
673
+ *
451
674
  * @throws {IntermediaryError} If the returned are not valid
452
675
  * @throws {Error} If the swap is already committed on-chain
676
+ *
677
+ * @private
453
678
  */
454
679
  async checkIntermediaryReturnedData(data) {
455
680
  if (!data.isPayOut())
@@ -474,32 +699,40 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
474
699
  throw new IntermediaryError_1.IntermediaryError("Invalid deposit token used!");
475
700
  if (data.hasSuccessAction())
476
701
  throw new IntermediaryError_1.IntermediaryError("Invalid has success action");
477
- if (await this.wrapper.contract.isExpired(this._getInitiator(), data))
702
+ if (await this.wrapper._contract.isExpired(this._getInitiator(), data))
478
703
  throw new IntermediaryError_1.IntermediaryError("Not enough time to claim!");
479
- if (this.wrapper.getHtlcTimeout(data) <= (Date.now() / 1000))
704
+ if (this.wrapper._getHtlcTimeout(data) <= (Date.now() / 1000))
480
705
  throw new IntermediaryError_1.IntermediaryError("HTLC expires too soon!");
481
706
  }
482
707
  /**
483
- * Waits till an LN payment is received by the intermediary and client can continue commiting & claiming the HTLC
708
+ * Waits till a lightning network payment is received by the intermediary, and the intermediary
709
+ * initiates the swap HTLC on the smart chain side. After the HTLC is initiated you can wait
710
+ * for an automatic settlement by the watchtowers with the {@link waitTillClaimed} function,
711
+ * or settle manually using the {@link claim} or {@link txsClaim} functions.
712
+ *
713
+ * If this swap is using an LNURL-withdraw link as input, it automatically posts the
714
+ * generated invoice to the LNURL service to pay it.
484
715
  *
485
716
  * @param onPaymentReceived Callback as for when the LP reports having received the ln payment
486
- * @param checkIntervalSeconds How often to poll the intermediary for answer (default 5 seconds)
487
717
  * @param abortSignal Abort signal to stop waiting for payment
718
+ * @param checkIntervalSeconds How often to poll the intermediary for answer (default 5 seconds)
488
719
  */
489
720
  async waitForPayment(onPaymentReceived, checkIntervalSeconds, abortSignal) {
490
721
  checkIntervalSeconds ??= 5;
491
- if (this.state === FromBTCLNAutoSwapState.PR_PAID) {
722
+ if (this._state === FromBTCLNAutoSwapState.PR_PAID) {
492
723
  await this.waitTillCommited(checkIntervalSeconds, abortSignal);
493
724
  }
494
- if (this.state >= FromBTCLNAutoSwapState.CLAIM_COMMITED)
725
+ if (this._state >= FromBTCLNAutoSwapState.CLAIM_COMMITED)
495
726
  return true;
496
- if (this.state !== FromBTCLNAutoSwapState.PR_CREATED)
727
+ if (this._state !== FromBTCLNAutoSwapState.PR_CREATED)
497
728
  throw new Error("Must be in PR_CREATED state!");
498
729
  const abortController = new AbortController();
499
730
  if (abortSignal != null)
500
731
  abortSignal.addEventListener("abort", () => abortController.abort(abortSignal.reason));
501
732
  let save = false;
502
733
  if (this.lnurl != null && this.lnurlK1 != null && this.lnurlCallback != null && !this.prPosted) {
734
+ if (this.pr == null || !this.pr.toLowerCase().startsWith("ln"))
735
+ throw new Error("Input lightning network invoice not available, the swap was probably recovered!");
503
736
  LNURL_1.LNURL.postInvoiceToLNURLWithdraw({ k1: this.lnurlK1, callback: this.lnurlCallback }, this.pr).catch(e => {
504
737
  this.lnurlFailSignal.abort(e);
505
738
  });
@@ -515,11 +748,14 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
515
748
  let lnurlFailListener = () => abortController.abort(this.lnurlFailSignal.signal.reason);
516
749
  this.lnurlFailSignal.signal.addEventListener("abort", lnurlFailListener);
517
750
  this.lnurlFailSignal.signal.throwIfAborted();
518
- if (this.wrapper.messenger.warmup != null)
519
- await this.wrapper.messenger.warmup().catch(e => {
751
+ const paymentHash = this.getPaymentHash();
752
+ if (paymentHash == null)
753
+ throw new Error("Swap payment hash not available, the swap was probably recovered!");
754
+ if (this.wrapper._messenger.warmup != null)
755
+ await this.wrapper._messenger.warmup().catch(e => {
520
756
  this.logger.warn("waitForPayment(): Failed to warmup messenger: ", e);
521
757
  });
522
- if (this.state === FromBTCLNAutoSwapState.PR_CREATED) {
758
+ if (this._state === FromBTCLNAutoSwapState.PR_CREATED) {
523
759
  const promises = [
524
760
  this.waitTillState(FromBTCLNAutoSwapState.PR_PAID, "gte", abortController.signal).then(() => true)
525
761
  ];
@@ -527,17 +763,17 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
527
763
  promises.push((async () => {
528
764
  let resp = { code: IntermediaryAPI_1.InvoiceStatusResponseCodes.PENDING, msg: "" };
529
765
  while (!abortController.signal.aborted && resp.code === IntermediaryAPI_1.InvoiceStatusResponseCodes.PENDING) {
530
- resp = await IntermediaryAPI_1.IntermediaryAPI.getInvoiceStatus(this.url, this.getPaymentHash().toString("hex"));
766
+ resp = await IntermediaryAPI_1.IntermediaryAPI.getInvoiceStatus(this.url, paymentHash.toString("hex"));
531
767
  if (resp.code === IntermediaryAPI_1.InvoiceStatusResponseCodes.PENDING)
532
768
  await (0, TimeoutUtils_1.timeoutPromise)(checkIntervalSeconds * 1000, abortController.signal);
533
769
  }
534
770
  this.lnurlFailSignal.signal.removeEventListener("abort", lnurlFailListener);
535
771
  abortController.signal.throwIfAborted();
536
772
  if (resp.code === IntermediaryAPI_1.InvoiceStatusResponseCodes.PAID) {
537
- const swapData = new this.wrapper.swapDataDeserializer(resp.data.data);
773
+ const swapData = new this.wrapper._swapDataDeserializer(resp.data.data);
538
774
  return await this._saveRealSwapData(swapData, true);
539
775
  }
540
- if (this.state === FromBTCLNAutoSwapState.PR_CREATED || this.state === FromBTCLNAutoSwapState.QUOTE_SOFT_EXPIRED) {
776
+ if (this._state === FromBTCLNAutoSwapState.PR_CREATED || this._state === FromBTCLNAutoSwapState.QUOTE_SOFT_EXPIRED) {
541
777
  if (resp.code === IntermediaryAPI_1.InvoiceStatusResponseCodes.EXPIRED) {
542
778
  await this._saveAndEmit(FromBTCLNAutoSwapState.QUOTE_EXPIRED);
543
779
  }
@@ -551,17 +787,25 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
551
787
  if (onPaymentReceived != null)
552
788
  onPaymentReceived(this.getInputTxId());
553
789
  }
554
- if (this.state === FromBTCLNAutoSwapState.PR_PAID) {
790
+ if (this._state === FromBTCLNAutoSwapState.PR_PAID) {
555
791
  await this.waitTillCommited(checkIntervalSeconds, abortSignal);
556
792
  }
557
- return this.state >= FromBTCLNAutoSwapState.CLAIM_COMMITED;
793
+ return this._state >= FromBTCLNAutoSwapState.CLAIM_COMMITED;
558
794
  }
559
795
  //////////////////////////////
560
796
  //// Commit
797
+ /**
798
+ * Waits till the intermediary (LP) initiates the swap HTLC escrow on the destination smart chain side
799
+ *
800
+ * @param checkIntervalSeconds How often to check via a polling watchdog
801
+ * @param abortSignal Abort signal
802
+ *
803
+ * @internal
804
+ */
561
805
  async waitTillCommited(checkIntervalSeconds, abortSignal) {
562
- if (this.state === FromBTCLNAutoSwapState.CLAIM_COMMITED || this.state === FromBTCLNAutoSwapState.CLAIM_CLAIMED)
806
+ if (this._state === FromBTCLNAutoSwapState.CLAIM_COMMITED || this._state === FromBTCLNAutoSwapState.CLAIM_CLAIMED)
563
807
  return Promise.resolve();
564
- if (this.state !== FromBTCLNAutoSwapState.PR_PAID)
808
+ if (this._state !== FromBTCLNAutoSwapState.PR_PAID)
565
809
  throw new Error("Invalid state");
566
810
  const abortController = (0, Utils_1.extendAbortController)(abortSignal);
567
811
  let result;
@@ -578,70 +822,96 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
578
822
  }
579
823
  if (result === false) {
580
824
  this.logger.debug("waitTillCommited(): Resolved from watchdog - HTLC expired");
581
- if (this.state === FromBTCLNAutoSwapState.PR_PAID) {
825
+ if (this._state === FromBTCLNAutoSwapState.PR_PAID) {
582
826
  await this._saveAndEmit(FromBTCLNAutoSwapState.EXPIRED);
583
827
  }
584
828
  return;
585
829
  }
586
- if (this.state === FromBTCLNAutoSwapState.PR_PAID) {
830
+ if (this._state === FromBTCLNAutoSwapState.PR_PAID) {
587
831
  await this._saveAndEmit(FromBTCLNAutoSwapState.CLAIM_COMMITED);
588
832
  }
589
833
  if (result === 0)
590
834
  this.logger.debug("waitTillCommited(): Resolved from state changed");
591
835
  if (result === true) {
592
836
  this.logger.debug("waitTillCommited(): Resolved from watchdog - commited");
593
- await this._broadcastSecret().catch(e => {
594
- this.logger.error("waitTillCommited(): Error broadcasting swap secret: ", e);
595
- });
837
+ if (this.secret != null)
838
+ await this._broadcastSecret().catch(e => {
839
+ this.logger.error("waitTillCommited(): Error broadcasting swap secret: ", e);
840
+ });
596
841
  }
597
842
  }
598
843
  //////////////////////////////
599
844
  //// Claim
600
845
  /**
601
- * Returns transactions required for claiming the HTLC and finishing the swap by revealing the HTLC secret
602
- * (hash preimage)
846
+ * @inheritDoc
603
847
  *
604
848
  * @param _signer Optional signer address to use for claiming the swap, can also be different from the initializer
605
- * @throws {Error} If in invalid state (must be CLAIM_COMMITED)
849
+ * @param secret A swap secret to use for the claim transaction, generally only needed if the swap
850
+ * was recovered from on-chain data, or the pre-image was generated outside the SDK
851
+ *
852
+ * @throws {Error} If in invalid state (must be {@link FromBTCLNAutoSwapState.CLAIM_COMMITED})
606
853
  */
607
- async txsClaim(_signer) {
608
- if (this.state !== FromBTCLNAutoSwapState.CLAIM_COMMITED)
854
+ async txsClaim(_signer, secret) {
855
+ if (this._state !== FromBTCLNAutoSwapState.CLAIM_COMMITED)
609
856
  throw new Error("Must be in CLAIM_COMMITED state!");
610
- if (this.data == null)
857
+ if (this._data == null)
611
858
  throw new Error("Unknown data, wrong state?");
612
- return await this.wrapper.contract.txsClaimWithSecret(_signer == null ?
859
+ const useSecret = secret ?? this.secret;
860
+ if (useSecret == null)
861
+ throw new Error("Swap secret pre-image not known and not provided, please provide the swap secret pre-image as an argument");
862
+ if (!this.isValidSecretPreimage(useSecret))
863
+ throw new Error("Invalid swap secret pre-image provided!");
864
+ return await this.wrapper._contract.txsClaimWithSecret(_signer == null ?
613
865
  this._getInitiator() :
614
- ((0, base_1.isAbstractSigner)(_signer) ? _signer : await this.wrapper.chain.wrapSigner(_signer)), this.data, this.secret, true, true);
866
+ ((0, base_1.isAbstractSigner)(_signer) ? _signer : await this.wrapper._chain.wrapSigner(_signer)), this._data, useSecret, true, true);
615
867
  }
616
868
  /**
617
- * Claims and finishes the swap
869
+ * @inheritDoc
618
870
  *
619
871
  * @param _signer Signer to sign the transactions with, can also be different to the initializer
620
872
  * @param abortSignal Abort signal to stop waiting for transaction confirmation
873
+ * @param onBeforeTxSent
874
+ * @param secret A swap secret to use for the claim transaction, generally only needed if the swap
875
+ * was recovered from on-chain data, or the pre-image was generated outside the SDK
621
876
  */
622
- async claim(_signer, abortSignal) {
623
- const signer = (0, base_1.isAbstractSigner)(_signer) ? _signer : await this.wrapper.chain.wrapSigner(_signer);
624
- const result = await this.wrapper.chain.sendAndConfirm(signer, await this.txsClaim(), true, abortSignal);
625
- this.claimTxId = result[0];
626
- if (this.state === FromBTCLNAutoSwapState.CLAIM_COMMITED || this.state === FromBTCLNAutoSwapState.EXPIRED || this.state === FromBTCLNAutoSwapState.FAILED) {
877
+ async claim(_signer, abortSignal, onBeforeTxSent, secret) {
878
+ const signer = (0, base_1.isAbstractSigner)(_signer) ? _signer : await this.wrapper._chain.wrapSigner(_signer);
879
+ let txCount = 0;
880
+ const txs = await this.txsClaim(_signer, secret);
881
+ const result = await this.wrapper._chain.sendAndConfirm(signer, txs, true, abortSignal, undefined, (txId) => {
882
+ txCount++;
883
+ if (onBeforeTxSent != null && txCount === 1)
884
+ onBeforeTxSent(txId);
885
+ return Promise.resolve();
886
+ });
887
+ this._claimTxId = result[0];
888
+ if (this._state === FromBTCLNAutoSwapState.CLAIM_COMMITED || this._state === FromBTCLNAutoSwapState.EXPIRED || this._state === FromBTCLNAutoSwapState.FAILED) {
627
889
  await this._saveAndEmit(FromBTCLNAutoSwapState.CLAIM_CLAIMED);
628
890
  }
629
891
  return result[0];
630
892
  }
631
893
  /**
632
- * Waits till the swap is successfully claimed
894
+ * @inheritDoc
633
895
  *
634
896
  * @param maxWaitTimeSeconds Maximum time in seconds to wait for the swap to be settled
635
897
  * @param abortSignal AbortSignal
636
- * @throws {Error} If swap is in invalid state (must be BTC_TX_CONFIRMED)
898
+ * @param secret A swap secret to broadcast to watchtowers, generally only needed if the swap
899
+ * was recovered from on-chain data, or the pre-image was generated outside the SDK
900
+ *
901
+ * @throws {Error} If swap is in invalid state (must be {@link FromBTCLNAutoSwapState.CLAIM_COMMITED})
637
902
  * @throws {Error} If the LP refunded sooner than we were able to claim
638
903
  * @returns {boolean} whether the swap was claimed in time or not
639
904
  */
640
- async waitTillClaimed(maxWaitTimeSeconds, abortSignal) {
641
- if (this.state === FromBTCLNAutoSwapState.CLAIM_CLAIMED)
905
+ async waitTillClaimed(maxWaitTimeSeconds, abortSignal, secret) {
906
+ if (this._state === FromBTCLNAutoSwapState.CLAIM_CLAIMED)
642
907
  return Promise.resolve(true);
643
- if (this.state !== FromBTCLNAutoSwapState.CLAIM_COMMITED)
908
+ if (this._state !== FromBTCLNAutoSwapState.CLAIM_COMMITED)
644
909
  throw new Error("Invalid state (not CLAIM_COMMITED)");
910
+ if (secret != null) {
911
+ if (!this.isValidSecretPreimage(secret))
912
+ throw new Error("Invalid swap secret pre-image provided!");
913
+ this.secret = secret;
914
+ }
645
915
  const abortController = new AbortController();
646
916
  if (abortSignal != null)
647
917
  abortSignal.addEventListener("abort", () => abortController.abort(abortSignal.reason));
@@ -678,14 +948,14 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
678
948
  }
679
949
  this.logger.debug("waitTillClaimed(): Resolved from watchdog");
680
950
  if (res?.type === base_1.SwapCommitStateType.PAID) {
681
- if (this.state !== FromBTCLNAutoSwapState.CLAIM_CLAIMED) {
682
- this.claimTxId = await res.getClaimTxId();
951
+ if (this._state !== FromBTCLNAutoSwapState.CLAIM_CLAIMED) {
952
+ this._claimTxId = await res.getClaimTxId();
683
953
  await this._saveAndEmit(FromBTCLNAutoSwapState.CLAIM_CLAIMED);
684
954
  }
685
955
  }
686
956
  if (res?.type === base_1.SwapCommitStateType.NOT_COMMITED || res?.type === base_1.SwapCommitStateType.EXPIRED) {
687
- if (this.state !== FromBTCLNAutoSwapState.CLAIM_CLAIMED &&
688
- this.state !== FromBTCLNAutoSwapState.FAILED) {
957
+ if (this._state !== FromBTCLNAutoSwapState.CLAIM_CLAIMED &&
958
+ this._state !== FromBTCLNAutoSwapState.FAILED) {
689
959
  await this._saveAndEmit(FromBTCLNAutoSwapState.FAILED);
690
960
  }
691
961
  throw new Error("Swap expired during claiming");
@@ -695,21 +965,29 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
695
965
  //////////////////////////////
696
966
  //// LNURL
697
967
  /**
698
- * Is this an LNURL-withdraw swap?
968
+ * Whether this swap uses an LNURL-withdraw link
699
969
  */
700
970
  isLNURL() {
701
971
  return this.lnurl != null;
702
972
  }
703
973
  /**
704
- * Gets the used LNURL or null if this is not an LNURL-withdraw swap
974
+ * Gets the used LNURL or `null` if this is not an LNURL-withdraw swap
705
975
  */
706
976
  getLNURL() {
707
977
  return this.lnurl ?? null;
708
978
  }
709
979
  /**
710
- * Pay the generated lightning network invoice with LNURL-withdraw
980
+ * Pay the generated lightning network invoice with an LNURL-withdraw link, this
981
+ * is useful when you want to display a lightning payment QR code and also want to
982
+ * allow payments using LNURL-withdraw NFC cards.
983
+ *
984
+ * Note that the swap needs to be created **without** an LNURL to begin with for this function
985
+ * to work. If this swap is already using an LNURL-withdraw link, this function throws.
711
986
  */
712
987
  async settleWithLNURLWithdraw(lnurl) {
988
+ if (this._state !== FromBTCLNAutoSwapState.PR_CREATED &&
989
+ this._state !== FromBTCLNAutoSwapState.QUOTE_SOFT_EXPIRED)
990
+ throw new Error("Must be in PR_CREATED state!");
713
991
  if (this.lnurl != null)
714
992
  throw new Error("Cannot settle LNURL-withdraw swap with different LNURL");
715
993
  let lnurlParams;
@@ -722,6 +1000,8 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
722
1000
  else {
723
1001
  lnurlParams = lnurl.params;
724
1002
  }
1003
+ if (this.pr == null || !this.pr.toLowerCase().startsWith("ln"))
1004
+ throw new Error("Input lightning network invoice not available, the swap was probably recovered!");
725
1005
  LNURL_1.LNURL.useLNURLWithdraw(lnurlParams, this.pr).catch(e => this.lnurlFailSignal.abort(e));
726
1006
  this.lnurl = lnurlParams.url;
727
1007
  this.lnurlCallback = lnurlParams.callback;
@@ -731,12 +1011,15 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
731
1011
  }
732
1012
  //////////////////////////////
733
1013
  //// Storage
1014
+ /**
1015
+ * @inheritDoc
1016
+ */
734
1017
  serialize() {
735
1018
  return {
736
1019
  ...super.serialize(),
737
- data: this.data == null ? null : this.data.serialize(),
738
- commitTxId: this.commitTxId,
739
- claimTxId: this.claimTxId,
1020
+ data: this._data == null ? null : this._data.serialize(),
1021
+ commitTxId: this._commitTxId,
1022
+ claimTxId: this._claimTxId,
740
1023
  btcAmountSwap: this.btcAmountSwap == null ? null : this.btcAmountSwap.toString(10),
741
1024
  btcAmountGas: this.btcAmountGas == null ? null : this.btcAmountGas.toString(10),
742
1025
  gasSwapFeeBtc: this.gasSwapFeeBtc == null ? null : this.gasSwapFeeBtc.toString(10),
@@ -748,7 +1031,8 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
748
1031
  lnurlK1: this.lnurlK1,
749
1032
  lnurlCallback: this.lnurlCallback,
750
1033
  prPosted: this.prPosted,
751
- initialSwapData: this.initialSwapData.serialize()
1034
+ initialSwapData: this.initialSwapData.serialize(),
1035
+ usesClaimHashAsId: this.usesClaimHashAsId
752
1036
  };
753
1037
  }
754
1038
  //////////////////////////////
@@ -760,62 +1044,57 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
760
1044
  * @private
761
1045
  */
762
1046
  async syncStateFromChain(quoteDefinitelyExpired, commitStatus) {
763
- //Check for expiry before the getCommitStatus to prevent race conditions
764
- let quoteExpired = false;
765
- if (this.state === FromBTCLNAutoSwapState.PR_PAID) {
766
- quoteExpired = quoteDefinitelyExpired ?? await this._verifyQuoteDefinitelyExpired();
767
- }
768
- if (this.state === FromBTCLNAutoSwapState.CLAIM_COMMITED || this.state === FromBTCLNAutoSwapState.EXPIRED) {
769
- //Check if it's already successfully paid
770
- commitStatus ??= await this.wrapper.contract.getCommitStatus(this._getInitiator(), this.data);
771
- if (commitStatus?.type === base_1.SwapCommitStateType.PAID) {
772
- if (this.claimTxId == null)
773
- this.claimTxId = await commitStatus.getClaimTxId();
774
- this.state = FromBTCLNAutoSwapState.CLAIM_CLAIMED;
775
- return true;
1047
+ if (this._state === FromBTCLNAutoSwapState.PR_PAID ||
1048
+ this._state === FromBTCLNAutoSwapState.CLAIM_COMMITED ||
1049
+ this._state === FromBTCLNAutoSwapState.EXPIRED) {
1050
+ //Check for expiry before the getCommitStatus to prevent race conditions
1051
+ let quoteExpired = false;
1052
+ if (this._state === FromBTCLNAutoSwapState.PR_PAID) {
1053
+ quoteExpired = quoteDefinitelyExpired ?? await this._verifyQuoteDefinitelyExpired();
776
1054
  }
777
- if (commitStatus?.type === base_1.SwapCommitStateType.NOT_COMMITED || commitStatus?.type === base_1.SwapCommitStateType.EXPIRED) {
778
- this.state = FromBTCLNAutoSwapState.FAILED;
1055
+ //Check if it's already successfully paid
1056
+ commitStatus ??= await this.wrapper._contract.getCommitStatus(this._getInitiator(), this._data);
1057
+ if (commitStatus != null && await this._forciblySetOnchainState(commitStatus))
779
1058
  return true;
780
- }
781
- }
782
- if (this.state === FromBTCLNAutoSwapState.PR_PAID) {
783
- //Check if it's already committed
784
- commitStatus ??= await this.wrapper.contract.getCommitStatus(this._getInitiator(), this.data);
785
- switch (commitStatus?.type) {
786
- case base_1.SwapCommitStateType.COMMITED:
787
- this.state = FromBTCLNAutoSwapState.CLAIM_COMMITED;
788
- return true;
789
- case base_1.SwapCommitStateType.EXPIRED:
790
- this.state = FromBTCLNAutoSwapState.EXPIRED;
791
- return true;
792
- case base_1.SwapCommitStateType.PAID:
793
- if (this.claimTxId == null)
794
- this.claimTxId = await commitStatus.getClaimTxId();
795
- this.state = FromBTCLNAutoSwapState.CLAIM_CLAIMED;
1059
+ if (this._state === FromBTCLNAutoSwapState.PR_PAID) {
1060
+ if (quoteExpired) {
1061
+ this._state = FromBTCLNAutoSwapState.QUOTE_EXPIRED;
796
1062
  return true;
797
- }
798
- if (quoteExpired) {
799
- this.state = FromBTCLNAutoSwapState.QUOTE_EXPIRED;
800
- return true;
1063
+ }
801
1064
  }
802
1065
  }
803
1066
  return false;
804
1067
  }
805
- _shouldFetchCommitStatus() {
806
- return this.state === FromBTCLNAutoSwapState.PR_PAID || this.state === FromBTCLNAutoSwapState.CLAIM_COMMITED || this.state === FromBTCLNAutoSwapState.EXPIRED;
1068
+ /**
1069
+ * @inheritDoc
1070
+ * @internal
1071
+ */
1072
+ _shouldFetchOnchainState() {
1073
+ return this._state === FromBTCLNAutoSwapState.PR_PAID || this._state === FromBTCLNAutoSwapState.CLAIM_COMMITED || this._state === FromBTCLNAutoSwapState.EXPIRED;
807
1074
  }
1075
+ /**
1076
+ * @inheritDoc
1077
+ * @internal
1078
+ */
808
1079
  _shouldFetchExpiryStatus() {
809
- return this.state === FromBTCLNAutoSwapState.PR_PAID;
1080
+ return this._state === FromBTCLNAutoSwapState.PR_PAID;
810
1081
  }
1082
+ /**
1083
+ * @inheritDoc
1084
+ * @internal
1085
+ */
811
1086
  _shouldCheckIntermediary() {
812
- return this.state === FromBTCLNAutoSwapState.PR_CREATED || this.state === FromBTCLNAutoSwapState.QUOTE_SOFT_EXPIRED;
1087
+ return this._state === FromBTCLNAutoSwapState.PR_CREATED || this._state === FromBTCLNAutoSwapState.QUOTE_SOFT_EXPIRED;
813
1088
  }
1089
+ /**
1090
+ * @inheritDoc
1091
+ * @internal
1092
+ */
814
1093
  async _sync(save, quoteDefinitelyExpired, commitStatus, skipLpCheck) {
815
1094
  let changed = false;
816
- if (this.state === FromBTCLNAutoSwapState.PR_CREATED || this.state === FromBTCLNAutoSwapState.QUOTE_SOFT_EXPIRED) {
817
- if (this.state !== FromBTCLNAutoSwapState.QUOTE_SOFT_EXPIRED && this.getQuoteExpiry() < Date.now()) {
818
- this.state = FromBTCLNAutoSwapState.QUOTE_SOFT_EXPIRED;
1095
+ if (this._state === FromBTCLNAutoSwapState.PR_CREATED || this._state === FromBTCLNAutoSwapState.QUOTE_SOFT_EXPIRED) {
1096
+ if (this._state !== FromBTCLNAutoSwapState.QUOTE_SOFT_EXPIRED && this.getQuoteExpiry() < Date.now()) {
1097
+ this._state = FromBTCLNAutoSwapState.QUOTE_SOFT_EXPIRED;
819
1098
  changed ||= true;
820
1099
  }
821
1100
  if (!skipLpCheck)
@@ -827,39 +1106,98 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
827
1106
  catch (e) {
828
1107
  this.logger.error("_sync(): Failed to synchronize swap, error: ", e);
829
1108
  }
830
- if (this.state === FromBTCLNAutoSwapState.PR_CREATED || this.state === FromBTCLNAutoSwapState.QUOTE_SOFT_EXPIRED) {
1109
+ if (this._state === FromBTCLNAutoSwapState.PR_CREATED || this._state === FromBTCLNAutoSwapState.QUOTE_SOFT_EXPIRED) {
831
1110
  if (await this._verifyQuoteDefinitelyExpired()) {
832
- this.state = FromBTCLNAutoSwapState.QUOTE_EXPIRED;
1111
+ this._state = FromBTCLNAutoSwapState.QUOTE_EXPIRED;
833
1112
  changed ||= true;
834
1113
  }
835
1114
  }
836
1115
  }
837
1116
  if (await this.syncStateFromChain(quoteDefinitelyExpired, commitStatus))
838
1117
  changed = true;
1118
+ if (this._state === FromBTCLNAutoSwapState.CLAIM_COMMITED) {
1119
+ const expired = await this.wrapper._contract.isExpired(this._getInitiator(), this._data);
1120
+ if (expired) {
1121
+ this._state = FromBTCLNAutoSwapState.EXPIRED;
1122
+ changed = true;
1123
+ }
1124
+ }
839
1125
  if (save && changed)
840
1126
  await this._saveAndEmit();
841
- if (this.state === FromBTCLNAutoSwapState.CLAIM_COMMITED)
1127
+ if (this._state === FromBTCLNAutoSwapState.CLAIM_COMMITED && this.secret != null)
842
1128
  await this._broadcastSecret().catch(e => {
843
1129
  this.logger.error("_sync(): Error when broadcasting swap secret: ", e);
844
1130
  });
845
1131
  return changed;
846
1132
  }
847
- async _broadcastSecret(noCheckExpiry) {
848
- if (this.state !== FromBTCLNAutoSwapState.CLAIM_COMMITED)
1133
+ /**
1134
+ * @inheritDoc
1135
+ * @internal
1136
+ */
1137
+ async _forciblySetOnchainState(commitStatus) {
1138
+ switch (commitStatus?.type) {
1139
+ case base_1.SwapCommitStateType.PAID:
1140
+ if (this._claimTxId == null)
1141
+ this._claimTxId = await commitStatus.getClaimTxId();
1142
+ if (this.secret == null || this.pr == null)
1143
+ this._setSwapSecret(await commitStatus.getClaimResult());
1144
+ this._state = FromBTCLNAutoSwapState.CLAIM_CLAIMED;
1145
+ return true;
1146
+ case base_1.SwapCommitStateType.NOT_COMMITED:
1147
+ if (this._refundTxId == null && commitStatus.getRefundTxId != null)
1148
+ this._refundTxId = await commitStatus.getRefundTxId();
1149
+ if (this._refundTxId != null) {
1150
+ this._state = FromBTCLNAutoSwapState.FAILED;
1151
+ return true;
1152
+ }
1153
+ break;
1154
+ case base_1.SwapCommitStateType.EXPIRED:
1155
+ if (this._refundTxId == null && commitStatus.getRefundTxId != null)
1156
+ this._refundTxId = await commitStatus.getRefundTxId();
1157
+ this._state = this._refundTxId == null ? FromBTCLNAutoSwapState.QUOTE_EXPIRED : FromBTCLNAutoSwapState.FAILED;
1158
+ return true;
1159
+ case base_1.SwapCommitStateType.COMMITED:
1160
+ if (this._state !== FromBTCLNAutoSwapState.CLAIM_COMMITED && this._state !== FromBTCLNAutoSwapState.EXPIRED) {
1161
+ this._state = FromBTCLNAutoSwapState.CLAIM_COMMITED;
1162
+ return true;
1163
+ }
1164
+ break;
1165
+ }
1166
+ return false;
1167
+ }
1168
+ /**
1169
+ * Broadcasts the swap secret to the underlying data propagation layer (e.g. Nostr by default)
1170
+ *
1171
+ * @param noCheckExpiry Whether a swap expiration check should be skipped broadcasting
1172
+ * @param secret An optional secret pre-image for the swap to broadcast
1173
+ *
1174
+ * @internal
1175
+ */
1176
+ async _broadcastSecret(noCheckExpiry, secret) {
1177
+ if (this._state !== FromBTCLNAutoSwapState.CLAIM_COMMITED)
849
1178
  throw new Error("Must be in CLAIM_COMMITED state to broadcast swap secret!");
850
- if (this.data == null)
1179
+ if (this._data == null)
851
1180
  throw new Error("Unknown data, wrong state?");
1181
+ const useSecret = secret ?? this.secret;
1182
+ if (useSecret == null)
1183
+ throw new Error("Swap secret pre-image not known and not provided, please provide the swap secret pre-image as an argument");
1184
+ if (!this.isValidSecretPreimage(useSecret))
1185
+ throw new Error("Invalid swap secret pre-image provided!");
852
1186
  if (!noCheckExpiry) {
853
- if (await this.wrapper.contract.isExpired(this._getInitiator(), this.data))
1187
+ if (await this.wrapper._contract.isExpired(this._getInitiator(), this._data))
854
1188
  throw new Error("On-chain HTLC already expired!");
855
1189
  }
856
- await this.wrapper.messenger.broadcast(new base_1.SwapClaimWitnessMessage(this.data, this.secret));
1190
+ await this.wrapper._messenger.broadcast(new base_1.SwapClaimWitnessMessage(this._data, useSecret));
857
1191
  }
1192
+ /**
1193
+ * @inheritDoc
1194
+ * @internal
1195
+ */
858
1196
  async _tick(save) {
859
- switch (this.state) {
1197
+ switch (this._state) {
860
1198
  case FromBTCLNAutoSwapState.PR_CREATED:
861
1199
  if (this.getQuoteExpiry() < Date.now()) {
862
- this.state = FromBTCLNAutoSwapState.QUOTE_SOFT_EXPIRED;
1200
+ this._state = FromBTCLNAutoSwapState.QUOTE_SOFT_EXPIRED;
863
1201
  if (save)
864
1202
  await this._saveAndEmit();
865
1203
  return true;
@@ -867,7 +1205,7 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
867
1205
  break;
868
1206
  case FromBTCLNAutoSwapState.QUOTE_SOFT_EXPIRED:
869
1207
  if (this.getDefinitiveExpiryTime() < Date.now()) {
870
- this.state = FromBTCLNAutoSwapState.QUOTE_EXPIRED;
1208
+ this._state = FromBTCLNAutoSwapState.QUOTE_EXPIRED;
871
1209
  if (save)
872
1210
  await this._saveAndEmit();
873
1211
  return true;
@@ -875,16 +1213,16 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
875
1213
  break;
876
1214
  case FromBTCLNAutoSwapState.PR_PAID:
877
1215
  case FromBTCLNAutoSwapState.CLAIM_COMMITED:
878
- const expired = await this.wrapper.contract.isExpired(this._getInitiator(), this.data);
1216
+ const expired = await this.wrapper._contract.isExpired(this._getInitiator(), this._data);
879
1217
  if (expired) {
880
- this.state = FromBTCLNAutoSwapState.EXPIRED;
1218
+ this._state = FromBTCLNAutoSwapState.EXPIRED;
881
1219
  if (save)
882
1220
  await this._saveAndEmit();
883
1221
  return true;
884
1222
  }
885
- if (this.state === FromBTCLNAutoSwapState.CLAIM_COMMITED) {
1223
+ if (this._state === FromBTCLNAutoSwapState.CLAIM_COMMITED) {
886
1224
  //Broadcast the secret over the provided messenger channel
887
- if (this.broadcastTickCounter === 0)
1225
+ if (this.broadcastTickCounter === 0 && this.secret != null)
888
1226
  await this._broadcastSecret(true).catch(e => {
889
1227
  this.logger.warn("_tick(): Error when broadcasting swap secret: ", e);
890
1228
  });
@@ -894,5 +1232,16 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
894
1232
  }
895
1233
  return false;
896
1234
  }
1235
+ /**
1236
+ * Forcibly sets the swap secret pre-image from on-chain data
1237
+ *
1238
+ * @internal
1239
+ */
1240
+ _setSwapSecret(secret) {
1241
+ this.secret = secret;
1242
+ if (this.pr == null) {
1243
+ this.pr = buffer_1.Buffer.from((0, sha2_1.sha256)(buffer_1.Buffer.from(secret, "hex"))).toString("hex");
1244
+ }
1245
+ }
897
1246
  }
898
1247
  exports.FromBTCLNAutoSwap = FromBTCLNAutoSwap;