@atomiqlabs/sdk 7.0.12 → 8.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (364) hide show
  1. package/README.md +45 -29
  2. package/dist/SmartChainAssets.d.ts +11 -3
  3. package/dist/SmartChainAssets.js +7 -3
  4. package/dist/bitcoin/BitcoinRpcWithAddressIndex.d.ts +68 -0
  5. package/dist/bitcoin/BitcoinRpcWithAddressIndex.js +2 -0
  6. package/dist/bitcoin/LightningNetworkApi.d.ts +12 -0
  7. package/dist/bitcoin/LightningNetworkApi.js +2 -0
  8. package/dist/bitcoin/coinselect2/accumulative.d.ts +6 -0
  9. package/dist/bitcoin/coinselect2/accumulative.js +52 -0
  10. package/dist/bitcoin/coinselect2/blackjack.d.ts +6 -0
  11. package/dist/bitcoin/coinselect2/blackjack.js +38 -0
  12. package/dist/bitcoin/coinselect2/index.d.ts +19 -0
  13. package/dist/bitcoin/coinselect2/index.js +69 -0
  14. package/dist/bitcoin/coinselect2/utils.d.ts +71 -0
  15. package/dist/bitcoin/coinselect2/utils.js +123 -0
  16. package/dist/bitcoin/mempool/MempoolApi.d.ts +350 -0
  17. package/dist/bitcoin/mempool/MempoolApi.js +311 -0
  18. package/dist/bitcoin/mempool/MempoolBitcoinBlock.d.ts +44 -0
  19. package/dist/bitcoin/mempool/MempoolBitcoinBlock.js +48 -0
  20. package/dist/bitcoin/mempool/MempoolBitcoinRpc.d.ts +119 -0
  21. package/dist/bitcoin/mempool/MempoolBitcoinRpc.js +361 -0
  22. package/dist/bitcoin/mempool/synchronizer/MempoolBtcRelaySynchronizer.d.ts +22 -0
  23. package/dist/bitcoin/mempool/synchronizer/MempoolBtcRelaySynchronizer.js +105 -0
  24. package/dist/bitcoin/wallet/BitcoinWallet.d.ts +93 -0
  25. package/dist/bitcoin/wallet/BitcoinWallet.js +273 -0
  26. package/dist/bitcoin/wallet/IBitcoinWallet.d.ts +28 -0
  27. package/dist/bitcoin/wallet/IBitcoinWallet.js +20 -0
  28. package/dist/bitcoin/wallet/MinimalBitcoinWalletInterface.d.ts +21 -0
  29. package/dist/bitcoin/wallet/MinimalBitcoinWalletInterface.js +2 -0
  30. package/dist/bitcoin/wallet/MinimalLightningNetworkWalletInterface.d.ts +7 -0
  31. package/dist/bitcoin/wallet/MinimalLightningNetworkWalletInterface.js +2 -0
  32. package/dist/bitcoin/wallet/SingleAddressBitcoinWallet.d.ts +40 -0
  33. package/dist/bitcoin/wallet/SingleAddressBitcoinWallet.js +86 -0
  34. package/dist/enums/FeeType.d.ts +8 -0
  35. package/dist/enums/FeeType.js +12 -0
  36. package/dist/enums/SwapAmountType.d.ts +8 -0
  37. package/dist/enums/SwapAmountType.js +12 -0
  38. package/dist/enums/SwapDirection.d.ts +8 -0
  39. package/dist/enums/SwapDirection.js +12 -0
  40. package/dist/enums/SwapType.d.ts +14 -0
  41. package/dist/enums/SwapType.js +18 -0
  42. package/dist/errors/IntermediaryError.d.ts +9 -0
  43. package/dist/errors/IntermediaryError.js +26 -0
  44. package/dist/errors/PaymentAuthError.d.ts +11 -0
  45. package/dist/errors/PaymentAuthError.js +23 -0
  46. package/dist/errors/RequestError.d.ts +18 -0
  47. package/dist/errors/RequestError.js +46 -0
  48. package/dist/errors/UserError.d.ts +7 -0
  49. package/dist/errors/UserError.js +15 -0
  50. package/dist/events/UnifiedSwapEventListener.d.ts +23 -0
  51. package/dist/events/UnifiedSwapEventListener.js +130 -0
  52. package/dist/http/HttpUtils.d.ts +27 -0
  53. package/dist/http/HttpUtils.js +91 -0
  54. package/dist/http/paramcoders/IParamReader.d.ts +8 -0
  55. package/dist/http/paramcoders/IParamReader.js +2 -0
  56. package/dist/http/paramcoders/ParamDecoder.d.ts +44 -0
  57. package/dist/http/paramcoders/ParamDecoder.js +132 -0
  58. package/dist/http/paramcoders/ParamEncoder.d.ts +20 -0
  59. package/dist/http/paramcoders/ParamEncoder.js +31 -0
  60. package/dist/http/paramcoders/SchemaVerifier.d.ts +26 -0
  61. package/dist/http/paramcoders/SchemaVerifier.js +145 -0
  62. package/dist/http/paramcoders/client/ResponseParamDecoder.d.ts +11 -0
  63. package/dist/http/paramcoders/client/ResponseParamDecoder.js +57 -0
  64. package/dist/http/paramcoders/client/StreamParamEncoder.d.ts +13 -0
  65. package/dist/http/paramcoders/client/StreamParamEncoder.js +26 -0
  66. package/dist/http/paramcoders/client/StreamingFetchPromise.d.ts +16 -0
  67. package/dist/http/paramcoders/client/StreamingFetchPromise.js +174 -0
  68. package/dist/index.d.ts +82 -4
  69. package/dist/index.js +128 -4
  70. package/dist/intermediaries/Intermediary.d.ts +111 -0
  71. package/dist/intermediaries/Intermediary.js +115 -0
  72. package/dist/intermediaries/IntermediaryDiscovery.d.ts +166 -0
  73. package/dist/intermediaries/IntermediaryDiscovery.js +390 -0
  74. package/dist/intermediaries/apis/IntermediaryAPI.d.ts +436 -0
  75. package/dist/intermediaries/apis/IntermediaryAPI.js +600 -0
  76. package/dist/intermediaries/apis/TrustedIntermediaryAPI.d.ts +154 -0
  77. package/dist/intermediaries/apis/TrustedIntermediaryAPI.js +136 -0
  78. package/dist/lnurl/LNURL.d.ts +102 -0
  79. package/dist/lnurl/LNURL.js +321 -0
  80. package/dist/prices/RedundantSwapPrice.d.ts +89 -0
  81. package/dist/prices/RedundantSwapPrice.js +202 -0
  82. package/dist/prices/SingleSwapPrice.d.ts +31 -0
  83. package/dist/prices/SingleSwapPrice.js +41 -0
  84. package/dist/prices/SwapPriceWithChain.d.ts +70 -0
  85. package/dist/prices/SwapPriceWithChain.js +91 -0
  86. package/dist/prices/abstract/ICachedSwapPrice.d.ts +28 -0
  87. package/dist/prices/abstract/ICachedSwapPrice.js +62 -0
  88. package/dist/prices/abstract/IPriceProvider.d.ts +81 -0
  89. package/dist/prices/abstract/IPriceProvider.js +74 -0
  90. package/dist/prices/abstract/ISwapPrice.d.ts +117 -0
  91. package/dist/prices/abstract/ISwapPrice.js +219 -0
  92. package/dist/prices/providers/BinancePriceProvider.d.ts +16 -0
  93. package/dist/prices/providers/BinancePriceProvider.js +23 -0
  94. package/dist/prices/providers/CoinGeckoPriceProvider.d.ts +17 -0
  95. package/dist/prices/providers/CoinGeckoPriceProvider.js +23 -0
  96. package/dist/prices/providers/CoinPaprikaPriceProvider.d.ts +19 -0
  97. package/dist/prices/providers/CoinPaprikaPriceProvider.js +23 -0
  98. package/dist/prices/providers/CustomPriceProvider.d.ts +13 -0
  99. package/dist/prices/providers/CustomPriceProvider.js +24 -0
  100. package/dist/prices/providers/KrakenPriceProvider.d.ts +29 -0
  101. package/dist/prices/providers/KrakenPriceProvider.js +36 -0
  102. package/dist/prices/providers/OKXPriceProvider.d.ts +28 -0
  103. package/dist/prices/providers/OKXPriceProvider.js +23 -0
  104. package/dist/prices/providers/abstract/ExchangePriceProvider.d.ts +14 -0
  105. package/dist/prices/providers/abstract/ExchangePriceProvider.js +18 -0
  106. package/dist/prices/providers/abstract/HttpPriceProvider.d.ts +7 -0
  107. package/dist/prices/providers/abstract/HttpPriceProvider.js +12 -0
  108. package/dist/storage/IUnifiedStorage.d.ts +73 -0
  109. package/dist/storage/IUnifiedStorage.js +2 -0
  110. package/dist/storage/UnifiedSwapStorage.d.ts +82 -0
  111. package/dist/storage/UnifiedSwapStorage.js +83 -0
  112. package/dist/storage-browser/IndexedDBUnifiedStorage.d.ts +39 -0
  113. package/dist/storage-browser/IndexedDBUnifiedStorage.js +275 -0
  114. package/dist/{storage → storage-browser}/LocalStorageManager.d.ts +1 -0
  115. package/dist/{storage → storage-browser}/LocalStorageManager.js +2 -1
  116. package/dist/swapper/Swapper.d.ts +533 -0
  117. package/dist/swapper/Swapper.js +1566 -0
  118. package/dist/swapper/SwapperFactory.d.ts +87 -0
  119. package/dist/{SwapperFactory.js → swapper/SwapperFactory.js} +37 -19
  120. package/dist/swapper/SwapperUtils.d.ts +153 -0
  121. package/dist/swapper/SwapperUtils.js +420 -0
  122. package/dist/swapper/SwapperWithChain.d.ts +214 -0
  123. package/dist/swapper/SwapperWithChain.js +315 -0
  124. package/dist/swapper/SwapperWithSigner.d.ts +178 -0
  125. package/dist/swapper/SwapperWithSigner.js +172 -0
  126. package/dist/swaps/IAddressSwap.d.ts +13 -0
  127. package/dist/swaps/IAddressSwap.js +13 -0
  128. package/dist/swaps/IBTCWalletSwap.d.ts +55 -0
  129. package/dist/swaps/IBTCWalletSwap.js +17 -0
  130. package/dist/swaps/IClaimableSwap.d.ts +17 -0
  131. package/dist/swaps/IClaimableSwap.js +14 -0
  132. package/dist/swaps/IClaimableSwapWrapper.d.ts +5 -0
  133. package/dist/swaps/IClaimableSwapWrapper.js +2 -0
  134. package/dist/swaps/IRefundableSwap.d.ts +17 -0
  135. package/dist/swaps/IRefundableSwap.js +13 -0
  136. package/dist/swaps/ISwap.d.ts +207 -0
  137. package/dist/swaps/ISwap.js +264 -0
  138. package/dist/swaps/ISwapWithGasDrop.d.ts +15 -0
  139. package/dist/swaps/ISwapWithGasDrop.js +11 -0
  140. package/dist/swaps/ISwapWrapper.d.ts +153 -0
  141. package/dist/swaps/ISwapWrapper.js +227 -0
  142. package/dist/swaps/escrow_swaps/IEscrowSelfInitSwap.d.ts +53 -0
  143. package/dist/swaps/escrow_swaps/IEscrowSelfInitSwap.js +116 -0
  144. package/dist/swaps/escrow_swaps/IEscrowSwap.d.ts +70 -0
  145. package/dist/swaps/escrow_swaps/IEscrowSwap.js +132 -0
  146. package/dist/swaps/escrow_swaps/IEscrowSwapWrapper.d.ts +85 -0
  147. package/dist/swaps/escrow_swaps/IEscrowSwapWrapper.js +122 -0
  148. package/dist/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.d.ts +86 -0
  149. package/dist/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.js +115 -0
  150. package/dist/swaps/escrow_swaps/frombtc/IFromBTCSelfInitSwap.d.ts +93 -0
  151. package/dist/swaps/escrow_swaps/frombtc/IFromBTCSelfInitSwap.js +121 -0
  152. package/dist/swaps/escrow_swaps/frombtc/IFromBTCWrapper.d.ts +45 -0
  153. package/dist/swaps/escrow_swaps/frombtc/IFromBTCWrapper.js +65 -0
  154. package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.d.ts +263 -0
  155. package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.js +933 -0
  156. package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.d.ts +110 -0
  157. package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.js +307 -0
  158. package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.d.ts +236 -0
  159. package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.js +898 -0
  160. package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.d.ts +125 -0
  161. package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.js +393 -0
  162. package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.d.ts +245 -0
  163. package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.js +841 -0
  164. package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.d.ts +120 -0
  165. package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.js +294 -0
  166. package/dist/swaps/escrow_swaps/tobtc/IToBTCSwap.d.ts +228 -0
  167. package/dist/swaps/escrow_swaps/tobtc/IToBTCSwap.js +721 -0
  168. package/dist/swaps/escrow_swaps/tobtc/IToBTCWrapper.d.ts +37 -0
  169. package/dist/swaps/escrow_swaps/tobtc/IToBTCWrapper.js +93 -0
  170. package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNSwap.d.ts +86 -0
  171. package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNSwap.js +213 -0
  172. package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.d.ts +170 -0
  173. package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.js +520 -0
  174. package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCSwap.d.ts +50 -0
  175. package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCSwap.js +109 -0
  176. package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.d.ts +93 -0
  177. package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.js +217 -0
  178. package/dist/swaps/spv_swaps/SpvFromBTCSwap.d.ts +315 -0
  179. package/dist/swaps/spv_swaps/SpvFromBTCSwap.js +1098 -0
  180. package/dist/swaps/spv_swaps/SpvFromBTCWrapper.d.ts +125 -0
  181. package/dist/swaps/spv_swaps/SpvFromBTCWrapper.js +631 -0
  182. package/dist/swaps/trusted/ln/LnForGasSwap.d.ts +107 -0
  183. package/dist/swaps/trusted/ln/LnForGasSwap.js +343 -0
  184. package/dist/swaps/trusted/ln/LnForGasWrapper.d.ts +21 -0
  185. package/dist/swaps/trusted/ln/LnForGasWrapper.js +62 -0
  186. package/dist/swaps/trusted/onchain/OnchainForGasSwap.d.ts +164 -0
  187. package/dist/swaps/trusted/onchain/OnchainForGasSwap.js +520 -0
  188. package/dist/swaps/trusted/onchain/OnchainForGasWrapper.d.ts +48 -0
  189. package/dist/swaps/trusted/onchain/OnchainForGasWrapper.js +74 -0
  190. package/dist/types/AmountData.d.ts +9 -0
  191. package/dist/types/AmountData.js +2 -0
  192. package/dist/types/CustomPriceFunction.d.ts +5 -0
  193. package/dist/types/CustomPriceFunction.js +2 -0
  194. package/dist/types/PriceInfoType.d.ts +28 -0
  195. package/dist/types/PriceInfoType.js +57 -0
  196. package/dist/types/SwapExecutionAction.d.ts +7 -0
  197. package/dist/types/SwapExecutionAction.js +2 -0
  198. package/dist/types/SwapWithSigner.d.ts +14 -0
  199. package/dist/types/SwapWithSigner.js +40 -0
  200. package/dist/types/Token.d.ts +53 -0
  201. package/dist/types/Token.js +58 -0
  202. package/dist/types/TokenAmount.d.ts +57 -0
  203. package/dist/types/TokenAmount.js +47 -0
  204. package/dist/types/fees/Fee.d.ts +49 -0
  205. package/dist/types/fees/Fee.js +2 -0
  206. package/dist/types/fees/FeeBreakdown.d.ts +10 -0
  207. package/dist/types/fees/FeeBreakdown.js +2 -0
  208. package/dist/types/fees/PercentagePPM.d.ts +15 -0
  209. package/dist/types/fees/PercentagePPM.js +17 -0
  210. package/dist/types/lnurl/LNURLPay.d.ts +54 -0
  211. package/dist/types/lnurl/LNURLPay.js +28 -0
  212. package/dist/types/lnurl/LNURLWithdraw.d.ts +42 -0
  213. package/dist/types/lnurl/LNURLWithdraw.js +24 -0
  214. package/dist/utils/AutomaticClockDriftCorrection.d.ts +1 -0
  215. package/dist/utils/AutomaticClockDriftCorrection.js +70 -0
  216. package/dist/utils/BitcoinUtils.d.ts +13 -0
  217. package/dist/utils/BitcoinUtils.js +98 -0
  218. package/dist/utils/BitcoinWalletUtils.d.ts +7 -0
  219. package/dist/utils/BitcoinWalletUtils.js +14 -0
  220. package/dist/utils/Logger.d.ts +7 -0
  221. package/dist/utils/Logger.js +12 -0
  222. package/dist/utils/RetryUtils.d.ts +21 -0
  223. package/dist/utils/RetryUtils.js +66 -0
  224. package/dist/utils/SwapUtils.d.ts +31 -0
  225. package/dist/utils/SwapUtils.js +18 -0
  226. package/dist/{Utils.d.ts → utils/TimeoutUtils.d.ts} +9 -3
  227. package/dist/utils/TimeoutUtils.js +55 -0
  228. package/dist/utils/TokenUtils.d.ts +11 -0
  229. package/dist/utils/TokenUtils.js +29 -0
  230. package/dist/utils/TypeUtils.d.ts +7 -0
  231. package/dist/utils/TypeUtils.js +2 -0
  232. package/dist/utils/Utils.d.ts +57 -0
  233. package/dist/utils/Utils.js +178 -0
  234. package/package.json +14 -6
  235. package/src/SmartChainAssets.ts +11 -3
  236. package/src/bitcoin/BitcoinRpcWithAddressIndex.ts +87 -0
  237. package/src/bitcoin/LightningNetworkApi.ts +16 -0
  238. package/src/bitcoin/coinselect2/accumulative.ts +68 -0
  239. package/src/bitcoin/coinselect2/blackjack.ts +49 -0
  240. package/src/bitcoin/coinselect2/index.ts +92 -0
  241. package/src/bitcoin/coinselect2/utils.ts +189 -0
  242. package/src/bitcoin/mempool/MempoolApi.ts +554 -0
  243. package/src/bitcoin/mempool/MempoolBitcoinBlock.ts +88 -0
  244. package/src/bitcoin/mempool/MempoolBitcoinRpc.ts +437 -0
  245. package/src/bitcoin/mempool/synchronizer/MempoolBtcRelaySynchronizer.ts +134 -0
  246. package/src/bitcoin/wallet/BitcoinWallet.ts +375 -0
  247. package/src/bitcoin/wallet/IBitcoinWallet.ts +44 -0
  248. package/src/bitcoin/wallet/MinimalBitcoinWalletInterface.ts +19 -0
  249. package/src/bitcoin/wallet/MinimalLightningNetworkWalletInterface.ts +7 -0
  250. package/src/bitcoin/wallet/SingleAddressBitcoinWallet.ts +108 -0
  251. package/src/enums/FeeType.ts +9 -0
  252. package/src/enums/SwapAmountType.ts +9 -0
  253. package/src/enums/SwapDirection.ts +9 -0
  254. package/src/enums/SwapType.ts +15 -0
  255. package/src/errors/IntermediaryError.ts +24 -0
  256. package/src/errors/PaymentAuthError.ts +26 -0
  257. package/src/errors/RequestError.ts +51 -0
  258. package/src/errors/UserError.ts +14 -0
  259. package/src/events/UnifiedSwapEventListener.ts +171 -0
  260. package/src/http/HttpUtils.ts +92 -0
  261. package/src/http/paramcoders/IParamReader.ts +10 -0
  262. package/src/http/paramcoders/ParamDecoder.ts +142 -0
  263. package/src/http/paramcoders/ParamEncoder.ts +37 -0
  264. package/src/http/paramcoders/SchemaVerifier.ts +153 -0
  265. package/src/http/paramcoders/client/ResponseParamDecoder.ts +58 -0
  266. package/src/http/paramcoders/client/StreamParamEncoder.ts +29 -0
  267. package/src/http/paramcoders/client/StreamingFetchPromise.ts +193 -0
  268. package/src/index.ts +102 -4
  269. package/src/intermediaries/Intermediary.ts +204 -0
  270. package/src/intermediaries/IntermediaryDiscovery.ts +485 -0
  271. package/src/intermediaries/apis/IntermediaryAPI.ts +940 -0
  272. package/src/intermediaries/apis/TrustedIntermediaryAPI.ts +257 -0
  273. package/src/lnurl/LNURL.ts +403 -0
  274. package/src/prices/RedundantSwapPrice.ts +245 -0
  275. package/src/prices/SingleSwapPrice.ts +47 -0
  276. package/src/prices/SwapPriceWithChain.ts +157 -0
  277. package/src/prices/abstract/ICachedSwapPrice.ts +86 -0
  278. package/src/prices/abstract/IPriceProvider.ts +128 -0
  279. package/src/prices/abstract/ISwapPrice.ts +328 -0
  280. package/src/prices/providers/BinancePriceProvider.ts +41 -0
  281. package/src/prices/providers/CoinGeckoPriceProvider.ts +40 -0
  282. package/src/prices/providers/CoinPaprikaPriceProvider.ts +44 -0
  283. package/src/prices/providers/CustomPriceProvider.ts +29 -0
  284. package/src/prices/providers/KrakenPriceProvider.ts +74 -0
  285. package/src/prices/providers/OKXPriceProvider.ts +53 -0
  286. package/src/prices/providers/abstract/ExchangePriceProvider.ts +29 -0
  287. package/src/prices/providers/abstract/HttpPriceProvider.ts +15 -0
  288. package/src/storage/IUnifiedStorage.ts +83 -0
  289. package/src/storage/UnifiedSwapStorage.ts +104 -0
  290. package/src/storage-browser/IndexedDBUnifiedStorage.ts +328 -0
  291. package/src/{storage → storage-browser}/LocalStorageManager.ts +2 -1
  292. package/src/swapper/Swapper.ts +2107 -0
  293. package/src/{SwapperFactory.ts → swapper/SwapperFactory.ts} +113 -72
  294. package/src/swapper/SwapperUtils.ts +510 -0
  295. package/src/swapper/SwapperWithChain.ts +464 -0
  296. package/src/swapper/SwapperWithSigner.ts +300 -0
  297. package/src/swaps/IAddressSwap.ts +20 -0
  298. package/src/swaps/IBTCWalletSwap.ts +77 -0
  299. package/src/swaps/IClaimableSwap.ts +30 -0
  300. package/src/swaps/IClaimableSwapWrapper.ts +9 -0
  301. package/src/swaps/IRefundableSwap.ts +29 -0
  302. package/src/swaps/ISwap.ts +490 -0
  303. package/src/swaps/ISwapWithGasDrop.ts +19 -0
  304. package/src/swaps/ISwapWrapper.ts +344 -0
  305. package/src/swaps/escrow_swaps/IEscrowSelfInitSwap.ts +168 -0
  306. package/src/swaps/escrow_swaps/IEscrowSwap.ts +197 -0
  307. package/src/swaps/escrow_swaps/IEscrowSwapWrapper.ts +210 -0
  308. package/src/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.ts +150 -0
  309. package/src/swaps/escrow_swaps/frombtc/IFromBTCSelfInitSwap.ts +219 -0
  310. package/src/swaps/escrow_swaps/frombtc/IFromBTCWrapper.ts +84 -0
  311. package/src/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.ts +1082 -0
  312. package/src/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.ts +429 -0
  313. package/src/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.ts +1078 -0
  314. package/src/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.ts +549 -0
  315. package/src/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.ts +974 -0
  316. package/src/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.ts +443 -0
  317. package/src/swaps/escrow_swaps/tobtc/IToBTCSwap.ts +860 -0
  318. package/src/swaps/escrow_swaps/tobtc/IToBTCWrapper.ts +104 -0
  319. package/src/swaps/escrow_swaps/tobtc/ln/ToBTCLNSwap.ts +256 -0
  320. package/src/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.ts +716 -0
  321. package/src/swaps/escrow_swaps/tobtc/onchain/ToBTCSwap.ts +151 -0
  322. package/src/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.ts +299 -0
  323. package/src/swaps/spv_swaps/SpvFromBTCSwap.ts +1394 -0
  324. package/src/swaps/spv_swaps/SpvFromBTCWrapper.ts +796 -0
  325. package/src/swaps/trusted/ln/LnForGasSwap.ts +402 -0
  326. package/src/swaps/trusted/ln/LnForGasWrapper.ts +70 -0
  327. package/src/swaps/trusted/onchain/OnchainForGasSwap.ts +633 -0
  328. package/src/swaps/trusted/onchain/OnchainForGasWrapper.ts +110 -0
  329. package/src/types/AmountData.ts +9 -0
  330. package/src/types/CustomPriceFunction.ts +5 -0
  331. package/src/types/PriceInfoType.ts +67 -0
  332. package/src/types/SwapExecutionAction.ts +8 -0
  333. package/src/types/SwapWithSigner.ts +57 -0
  334. package/src/types/Token.ts +90 -0
  335. package/src/types/TokenAmount.ts +110 -0
  336. package/src/types/fees/Fee.ts +55 -0
  337. package/src/types/fees/FeeBreakdown.ts +11 -0
  338. package/src/types/fees/PercentagePPM.ts +24 -0
  339. package/src/types/lnurl/LNURLPay.ts +72 -0
  340. package/src/types/lnurl/LNURLWithdraw.ts +55 -0
  341. package/src/utils/AutomaticClockDriftCorrection.ts +71 -0
  342. package/src/utils/BitcoinUtils.ts +86 -0
  343. package/src/utils/BitcoinWalletUtils.ts +16 -0
  344. package/src/utils/Logger.ts +15 -0
  345. package/src/utils/RetryUtils.ts +71 -0
  346. package/src/utils/SwapUtils.ts +38 -0
  347. package/src/utils/TimeoutUtils.ts +50 -0
  348. package/src/utils/TokenUtils.ts +25 -0
  349. package/src/utils/TypeUtils.ts +9 -0
  350. package/src/utils/Utils.ts +182 -0
  351. package/dist/SwapperFactory.d.ts +0 -52
  352. package/dist/Utils.js +0 -37
  353. package/dist/fs-storage/FileSystemStorageManager.d.ts +0 -15
  354. package/dist/fs-storage/FileSystemStorageManager.js +0 -60
  355. package/dist/fs-storage/index.d.ts +0 -1
  356. package/dist/fs-storage/index.js +0 -17
  357. package/src/SmartChainAssets.js +0 -75
  358. package/src/SwapperFactory.js +0 -120
  359. package/src/Utils.js +0 -37
  360. package/src/Utils.ts +0 -31
  361. package/src/fs-storage/FileSystemStorageManager.ts +0 -71
  362. package/src/fs-storage/index.ts +0 -1
  363. package/src/index.js +0 -21
  364. package/src/storage/LocalStorageManager.js +0 -72
@@ -0,0 +1,841 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FromBTCSwap = exports.isFromBTCSwapInit = exports.FromBTCSwapState = void 0;
4
+ const IFromBTCSelfInitSwap_1 = require("../IFromBTCSelfInitSwap");
5
+ const SwapType_1 = require("../../../../enums/SwapType");
6
+ const base_1 = require("@atomiqlabs/base");
7
+ const buffer_1 = require("buffer");
8
+ const Utils_1 = require("../../../../utils/Utils");
9
+ const BitcoinUtils_1 = require("../../../../utils/BitcoinUtils");
10
+ const IBitcoinWallet_1 = require("../../../../bitcoin/wallet/IBitcoinWallet");
11
+ const btc_signer_1 = require("@scure/btc-signer");
12
+ const SingleAddressBitcoinWallet_1 = require("../../../../bitcoin/wallet/SingleAddressBitcoinWallet");
13
+ const IEscrowSelfInitSwap_1 = require("../../IEscrowSelfInitSwap");
14
+ const TokenAmount_1 = require("../../../../types/TokenAmount");
15
+ const Token_1 = require("../../../../types/Token");
16
+ const Logger_1 = require("../../../../utils/Logger");
17
+ const BitcoinWalletUtils_1 = require("../../../../utils/BitcoinWalletUtils");
18
+ /**
19
+ * State enum for FromBTC swaps
20
+ * @category Swaps
21
+ */
22
+ var FromBTCSwapState;
23
+ (function (FromBTCSwapState) {
24
+ FromBTCSwapState[FromBTCSwapState["FAILED"] = -4] = "FAILED";
25
+ FromBTCSwapState[FromBTCSwapState["EXPIRED"] = -3] = "EXPIRED";
26
+ FromBTCSwapState[FromBTCSwapState["QUOTE_EXPIRED"] = -2] = "QUOTE_EXPIRED";
27
+ FromBTCSwapState[FromBTCSwapState["QUOTE_SOFT_EXPIRED"] = -1] = "QUOTE_SOFT_EXPIRED";
28
+ FromBTCSwapState[FromBTCSwapState["PR_CREATED"] = 0] = "PR_CREATED";
29
+ FromBTCSwapState[FromBTCSwapState["CLAIM_COMMITED"] = 1] = "CLAIM_COMMITED";
30
+ FromBTCSwapState[FromBTCSwapState["BTC_TX_CONFIRMED"] = 2] = "BTC_TX_CONFIRMED";
31
+ FromBTCSwapState[FromBTCSwapState["CLAIM_CLAIMED"] = 3] = "CLAIM_CLAIMED";
32
+ })(FromBTCSwapState = exports.FromBTCSwapState || (exports.FromBTCSwapState = {}));
33
+ function isFromBTCSwapInit(obj) {
34
+ return typeof (obj.address) === "string" &&
35
+ typeof (obj.amount) === "bigint" &&
36
+ typeof (obj.data) === "object" &&
37
+ typeof (obj.requiredConfirmations) === "number" &&
38
+ (0, IEscrowSelfInitSwap_1.isIEscrowSelfInitSwapInit)(obj);
39
+ }
40
+ exports.isFromBTCSwapInit = isFromBTCSwapInit;
41
+ class FromBTCSwap extends IFromBTCSelfInitSwap_1.IFromBTCSelfInitSwap {
42
+ constructor(wrapper, initOrObject) {
43
+ if (isFromBTCSwapInit(initOrObject) && initOrObject.url != null)
44
+ initOrObject.url += "/frombtc";
45
+ super(wrapper, initOrObject);
46
+ this.inputToken = Token_1.BitcoinTokens.BTC;
47
+ this.TYPE = SwapType_1.SwapType.FROM_BTC;
48
+ if (isFromBTCSwapInit(initOrObject)) {
49
+ this.state = FromBTCSwapState.PR_CREATED;
50
+ this.data = initOrObject.data;
51
+ this.feeRate = initOrObject.feeRate;
52
+ this.address = initOrObject.address;
53
+ this.amount = initOrObject.amount;
54
+ this.requiredConfirmations = initOrObject.requiredConfirmations;
55
+ }
56
+ else {
57
+ this.address = initOrObject.address;
58
+ this.amount = BigInt(initOrObject.amount);
59
+ this.senderAddress = initOrObject.senderAddress;
60
+ this.txId = initOrObject.txId;
61
+ this.vout = initOrObject.vout;
62
+ this.requiredConfirmations = initOrObject.requiredConfirmations ?? this.data.getConfirmationsHint();
63
+ }
64
+ this.tryRecomputeSwapPrice();
65
+ this.logger = (0, Logger_1.getLogger)("FromBTC(" + this.getIdentifierHashString() + "): ");
66
+ }
67
+ getSwapData() {
68
+ return this.data;
69
+ }
70
+ upgradeVersion() {
71
+ if (this.version == null) {
72
+ switch (this.state) {
73
+ case -2:
74
+ this.state = FromBTCSwapState.FAILED;
75
+ break;
76
+ case -1:
77
+ this.state = FromBTCSwapState.QUOTE_EXPIRED;
78
+ break;
79
+ case 0:
80
+ this.state = FromBTCSwapState.PR_CREATED;
81
+ break;
82
+ case 1:
83
+ this.state = FromBTCSwapState.CLAIM_COMMITED;
84
+ break;
85
+ case 2:
86
+ this.state = FromBTCSwapState.BTC_TX_CONFIRMED;
87
+ break;
88
+ case 3:
89
+ this.state = FromBTCSwapState.CLAIM_CLAIMED;
90
+ break;
91
+ }
92
+ this.version = 1;
93
+ }
94
+ }
95
+ //////////////////////////////
96
+ //// Getters & utils
97
+ /**
98
+ * Returns bitcoin address where the on-chain BTC should be sent to
99
+ */
100
+ getAddress() {
101
+ if (this.state === FromBTCSwapState.PR_CREATED)
102
+ throw new Error("Cannot get bitcoin address of non-committed swap");
103
+ return this.address;
104
+ }
105
+ /**
106
+ * Unsafe bitcoin hyperlink getter, returns the address even before the swap is committed!
107
+ *
108
+ * @private
109
+ */
110
+ _getHyperlink() {
111
+ return "bitcoin:" + this.address + "?amount=" + encodeURIComponent((Number(this.amount) / 100000000).toString(10));
112
+ }
113
+ getHyperlink() {
114
+ if (this.state === FromBTCSwapState.PR_CREATED)
115
+ throw new Error("Cannot get bitcoin address of non-committed swap");
116
+ return this._getHyperlink();
117
+ }
118
+ getInputAddress() {
119
+ return this.senderAddress ?? null;
120
+ }
121
+ getInputTxId() {
122
+ return this.txId ?? null;
123
+ }
124
+ /**
125
+ * Returns timeout time (in UNIX milliseconds) when the on-chain address will expire and no funds should be sent
126
+ * to that address anymore
127
+ */
128
+ getTimeoutTime() {
129
+ return Number(this.wrapper.getOnchainSendTimeout(this.data, this.requiredConfirmations)) * 1000;
130
+ }
131
+ requiresAction() {
132
+ return this.isClaimable() || (this.state === FromBTCSwapState.CLAIM_COMMITED && this.getTimeoutTime() > Date.now() && this.txId == null);
133
+ }
134
+ isFinished() {
135
+ return this.state === FromBTCSwapState.CLAIM_CLAIMED || this.state === FromBTCSwapState.QUOTE_EXPIRED || this.state === FromBTCSwapState.FAILED;
136
+ }
137
+ isClaimable() {
138
+ return this.state === FromBTCSwapState.BTC_TX_CONFIRMED;
139
+ }
140
+ isSuccessful() {
141
+ return this.state === FromBTCSwapState.CLAIM_CLAIMED;
142
+ }
143
+ isFailed() {
144
+ return this.state === FromBTCSwapState.FAILED || this.state === FromBTCSwapState.EXPIRED;
145
+ }
146
+ isQuoteExpired() {
147
+ return this.state === FromBTCSwapState.QUOTE_EXPIRED;
148
+ }
149
+ isQuoteSoftExpired() {
150
+ return this.state === FromBTCSwapState.QUOTE_EXPIRED || this.state === FromBTCSwapState.QUOTE_SOFT_EXPIRED;
151
+ }
152
+ canCommit() {
153
+ if (this.state !== FromBTCSwapState.PR_CREATED)
154
+ return false;
155
+ const expiry = this.wrapper.getOnchainSendTimeout(this.data, this.requiredConfirmations);
156
+ const currentTimestamp = BigInt(Math.floor(Date.now() / 1000));
157
+ return (expiry - currentTimestamp) >= this.wrapper.options.minSendWindow;
158
+ }
159
+ //////////////////////////////
160
+ //// Amounts & fees
161
+ getInputToken() {
162
+ return Token_1.BitcoinTokens.BTC;
163
+ }
164
+ getInput() {
165
+ return (0, TokenAmount_1.toTokenAmount)(this.amount, this.inputToken, this.wrapper.prices);
166
+ }
167
+ /**
168
+ * Returns claimer bounty, acting as a reward for watchtowers to claim the swap automatically
169
+ */
170
+ getClaimerBounty() {
171
+ return (0, TokenAmount_1.toTokenAmount)(this.data.getClaimerBounty(), this.wrapper.tokens[this.data.getDepositToken()], this.wrapper.prices);
172
+ }
173
+ //////////////////////////////
174
+ //// Bitcoin tx
175
+ getRequiredConfirmationsCount() {
176
+ return this.requiredConfirmations;
177
+ }
178
+ /**
179
+ * Checks whether a bitcoin payment was already made, returns the payment or null when no payment has been made.
180
+ */
181
+ async getBitcoinPayment() {
182
+ const txoHashHint = this.data.getTxoHashHint();
183
+ if (txoHashHint == null)
184
+ throw new Error("Swap data don't include the txo hash hint! Cannot check btc transaction!");
185
+ const result = await this.wrapper.btcRpc.checkAddressTxos(this.address, buffer_1.Buffer.from(txoHashHint, "hex"));
186
+ if (result == null)
187
+ return null;
188
+ return {
189
+ inputAddresses: result.tx.inputAddresses,
190
+ txId: result.tx.txid,
191
+ vout: result.vout,
192
+ confirmations: result.tx.confirmations ?? 0,
193
+ targetConfirmations: this.requiredConfirmations
194
+ };
195
+ }
196
+ /**
197
+ * For internal use! Used to set the txId of the bitcoin payment from the on-chain events listener
198
+ *
199
+ * @param txId
200
+ */
201
+ async _setBitcoinTxId(txId) {
202
+ if (this.txId !== txId || this.address == null || this.vout == null || this.senderAddress == null || this.amount == null) {
203
+ const btcTx = await this.wrapper.btcRpc.getTransaction(txId);
204
+ if (btcTx == null)
205
+ return;
206
+ const txoHashHint = this.data.getTxoHashHint();
207
+ if (txoHashHint != null) {
208
+ const expectedTxoHash = buffer_1.Buffer.from(txoHashHint, "hex");
209
+ const vout = btcTx.outs.findIndex(out => (0, Utils_1.getTxoHash)(out.scriptPubKey.hex, out.value).equals(expectedTxoHash));
210
+ if (vout !== -1) {
211
+ this.vout = vout;
212
+ //If amount or address are not known, parse them from the bitcoin tx
213
+ // this can happen if the swap is recovered from on-chain data and
214
+ // hence doesn't contain the address and amount data
215
+ if (this.amount == null)
216
+ this.amount = BigInt(btcTx.outs[vout].value);
217
+ if (this.address == null)
218
+ try {
219
+ const addressData = btc_signer_1.OutScript.decode(buffer_1.Buffer.from(btcTx.outs[vout].scriptPubKey.hex, "hex"));
220
+ this.address = (0, btc_signer_1.Address)(this.wrapper.options.bitcoinNetwork).encode(addressData);
221
+ }
222
+ catch (e) {
223
+ this.logger.warn("_setBitcoinTxId(): Failed to parse address from output script: ", e);
224
+ }
225
+ }
226
+ }
227
+ if (btcTx.inputAddresses != null) {
228
+ this.senderAddress = btcTx.inputAddresses[0];
229
+ }
230
+ }
231
+ this.txId = txId;
232
+ }
233
+ /**
234
+ * Waits till the bitcoin transaction confirms and swap becomes claimable
235
+ *
236
+ * @param updateCallback Callback called when txId is found, and also called with subsequent confirmations
237
+ * @param checkIntervalSeconds How often to check the bitcoin transaction
238
+ * @param abortSignal Abort signal
239
+ * @throws {Error} if in invalid state (must be CLAIM_COMMITED)
240
+ */
241
+ async waitForBitcoinTransaction(updateCallback, checkIntervalSeconds, abortSignal) {
242
+ if (this.state !== FromBTCSwapState.CLAIM_COMMITED && this.state !== FromBTCSwapState.EXPIRED)
243
+ throw new Error("Must be in COMMITED state!");
244
+ const txoHashHint = this.data.getTxoHashHint();
245
+ if (txoHashHint == null)
246
+ throw new Error("Swap data don't include the txo hash hint! Cannot check btc transaction!");
247
+ const result = await this.wrapper.btcRpc.waitForAddressTxo(this.address, buffer_1.Buffer.from(txoHashHint, "hex"), this.requiredConfirmations, (btcTx, vout, txEtaMs) => {
248
+ if (updateCallback != null)
249
+ updateCallback(btcTx?.txid, btcTx == null ? undefined : (btcTx?.confirmations ?? 0), this.requiredConfirmations, txEtaMs);
250
+ if (btcTx != null && btcTx.txid !== this.txId) {
251
+ this.txId = btcTx.txid;
252
+ this.vout = vout;
253
+ if (btcTx.inputAddresses != null)
254
+ this.senderAddress = btcTx.inputAddresses[0];
255
+ this._saveAndEmit().catch(e => {
256
+ this.logger.error("waitForBitcoinTransaction(): Failed to save swap from within waitForAddressTxo callback:", e);
257
+ });
258
+ }
259
+ }, abortSignal, checkIntervalSeconds);
260
+ if (abortSignal != null)
261
+ abortSignal.throwIfAborted();
262
+ this.txId = result.tx.txid;
263
+ this.vout = result.vout;
264
+ if (result.tx.inputAddresses != null)
265
+ this.senderAddress = result.tx.inputAddresses[0];
266
+ if (this.state !== FromBTCSwapState.CLAIM_CLAIMED &&
267
+ this.state !== FromBTCSwapState.FAILED) {
268
+ this.state = FromBTCSwapState.BTC_TX_CONFIRMED;
269
+ }
270
+ await this._saveAndEmit();
271
+ return result.tx.txid;
272
+ }
273
+ /**
274
+ * Returns the PSBT that is already funded with wallet's UTXOs (runs a coin-selection algorithm to choose UTXOs to use),
275
+ * also returns inputs indices that need to be signed by the wallet before submitting the PSBT back to the SDK with
276
+ * `swap.submitPsbt()`
277
+ *
278
+ * @param _bitcoinWallet Sender's bitcoin wallet
279
+ * @param feeRate Optional fee rate for the transaction, needs to be at least as big as {minimumBtcFeeRate} field
280
+ * @param additionalOutputs additional outputs to add to the PSBT - can be used to collect fees from users
281
+ */
282
+ getFundedPsbt(_bitcoinWallet, feeRate, additionalOutputs) {
283
+ if (this.state !== FromBTCSwapState.CLAIM_COMMITED)
284
+ throw new Error("Swap not committed yet, please initiate the swap first with commit() call!");
285
+ return this._getFundedPsbt(_bitcoinWallet, feeRate, additionalOutputs);
286
+ }
287
+ async _getFundedPsbt(_bitcoinWallet, feeRate, additionalOutputs) {
288
+ let bitcoinWallet;
289
+ if ((0, IBitcoinWallet_1.isIBitcoinWallet)(_bitcoinWallet)) {
290
+ bitcoinWallet = _bitcoinWallet;
291
+ }
292
+ else {
293
+ bitcoinWallet = new SingleAddressBitcoinWallet_1.SingleAddressBitcoinWallet(this.wrapper.btcRpc, this.wrapper.options.bitcoinNetwork, _bitcoinWallet);
294
+ }
295
+ //TODO: Maybe re-introduce fee rate check here if passed from the user
296
+ if (feeRate == null) {
297
+ feeRate = await bitcoinWallet.getFeeRate();
298
+ }
299
+ const basePsbt = new btc_signer_1.Transaction({
300
+ allowUnknownOutputs: true,
301
+ allowLegacyWitnessUtxo: true
302
+ });
303
+ basePsbt.addOutput({
304
+ amount: this.amount,
305
+ script: (0, BitcoinUtils_1.toOutputScript)(this.wrapper.options.bitcoinNetwork, this.address)
306
+ });
307
+ if (additionalOutputs != null)
308
+ additionalOutputs.forEach(output => {
309
+ basePsbt.addOutput({
310
+ amount: output.amount,
311
+ script: output.outputScript ?? (0, BitcoinUtils_1.toOutputScript)(this.wrapper.options.bitcoinNetwork, output.address)
312
+ });
313
+ });
314
+ const psbt = await bitcoinWallet.fundPsbt(basePsbt, feeRate);
315
+ //Sign every input
316
+ const signInputs = [];
317
+ for (let i = 0; i < psbt.inputsLength; i++) {
318
+ signInputs.push(i);
319
+ }
320
+ const serializedPsbt = buffer_1.Buffer.from(psbt.toPSBT());
321
+ return {
322
+ psbt,
323
+ psbtHex: serializedPsbt.toString("hex"),
324
+ psbtBase64: serializedPsbt.toString("base64"),
325
+ signInputs
326
+ };
327
+ }
328
+ /**
329
+ * Submits a PSBT signed by the wallet back to the SDK
330
+ *
331
+ * @param _psbt A psbt - either a Transaction object or a hex or base64 encoded PSBT string
332
+ */
333
+ async submitPsbt(_psbt) {
334
+ const psbt = (0, BitcoinUtils_1.parsePsbtTransaction)(_psbt);
335
+ if (this.state !== FromBTCSwapState.CLAIM_COMMITED)
336
+ throw new Error("Swap not committed yet, please initiate the swap first with commit() call!");
337
+ //Ensure not expired
338
+ if (this.getTimeoutTime() < Date.now()) {
339
+ throw new Error("Swap address expired!");
340
+ }
341
+ const output0 = psbt.getOutput(0);
342
+ if (output0.amount !== this.amount)
343
+ throw new Error("PSBT output amount invalid, expected: " + this.amount + " got: " + output0.amount);
344
+ const expectedOutputScript = (0, BitcoinUtils_1.toOutputScript)(this.wrapper.options.bitcoinNetwork, this.address);
345
+ if (output0.script == null || !expectedOutputScript.equals(output0.script))
346
+ throw new Error("PSBT output script invalid!");
347
+ if (!psbt.isFinal)
348
+ psbt.finalize();
349
+ return await this.wrapper.btcRpc.sendRawTransaction(buffer_1.Buffer.from(psbt.toBytes(true, true)).toString("hex"));
350
+ }
351
+ async estimateBitcoinFee(_bitcoinWallet, feeRate) {
352
+ const bitcoinWallet = (0, BitcoinWalletUtils_1.toBitcoinWallet)(_bitcoinWallet, this.wrapper.btcRpc, this.wrapper.options.bitcoinNetwork);
353
+ const txFee = await bitcoinWallet.getTransactionFee(this.address, this.amount, feeRate);
354
+ if (txFee == null)
355
+ return null;
356
+ return (0, TokenAmount_1.toTokenAmount)(BigInt(txFee), Token_1.BitcoinTokens.BTC, this.wrapper.prices);
357
+ }
358
+ async sendBitcoinTransaction(wallet, feeRate) {
359
+ if (this.state !== FromBTCSwapState.CLAIM_COMMITED)
360
+ throw new Error("Swap not committed yet, please initiate the swap first with commit() call!");
361
+ //Ensure not expired
362
+ if (this.getTimeoutTime() < Date.now()) {
363
+ throw new Error("Swap address expired!");
364
+ }
365
+ if ((0, IBitcoinWallet_1.isIBitcoinWallet)(wallet)) {
366
+ return await wallet.sendTransaction(this.address, this.amount, feeRate);
367
+ }
368
+ else {
369
+ const { psbt, psbtHex, psbtBase64, signInputs } = await this.getFundedPsbt(wallet, feeRate);
370
+ const signedPsbt = await wallet.signPsbt({
371
+ psbt, psbtHex, psbtBase64
372
+ }, signInputs);
373
+ return await this.submitPsbt(signedPsbt);
374
+ }
375
+ }
376
+ //////////////////////////////
377
+ //// Execution
378
+ /**
379
+ * Executes the swap with the provided bitcoin wallet,
380
+ *
381
+ * @param dstSigner Signer on the destination network, needs to have the same address as the one specified when
382
+ * quote was created, this is required for legacy swaps because the destination wallet needs to actively open
383
+ * a bitcoin swap address to which the BTC is then sent, this means that the address also needs to have enough
384
+ * native tokens to pay for gas on the destination network
385
+ * @param wallet Bitcoin wallet to use to sign the bitcoin transaction, can also be null - then the execution waits
386
+ * till a transaction is received from an external wallet
387
+ * @param callbacks Callbacks to track the progress of the swap
388
+ * @param options Optional options for the swap like feeRate, AbortSignal, and timeouts/intervals
389
+ *
390
+ * @returns {boolean} Whether a swap was settled automatically by swap watchtowers or requires manual claim by the
391
+ * user, in case `false` is returned the user should call `swap.claim()` to settle the swap on the destination manually
392
+ */
393
+ async execute(dstSigner, wallet, callbacks, options) {
394
+ if (this.state === FromBTCSwapState.FAILED)
395
+ throw new Error("Swap failed!");
396
+ if (this.state === FromBTCSwapState.EXPIRED)
397
+ throw new Error("Swap address expired!");
398
+ if (this.state === FromBTCSwapState.QUOTE_EXPIRED || this.state === FromBTCSwapState.QUOTE_SOFT_EXPIRED)
399
+ throw new Error("Swap quote expired!");
400
+ if (this.state === FromBTCSwapState.CLAIM_CLAIMED)
401
+ throw new Error("Swap already settled!");
402
+ if (this.state === FromBTCSwapState.PR_CREATED) {
403
+ await this.commit(dstSigner, options?.abortSignal, undefined, callbacks?.onDestinationCommitSent);
404
+ }
405
+ if (this.state === FromBTCSwapState.CLAIM_COMMITED) {
406
+ if (wallet != null) {
407
+ const bitcoinPaymentSent = await this.getBitcoinPayment();
408
+ if (bitcoinPaymentSent == null) {
409
+ //Send btc tx
410
+ const txId = await this.sendBitcoinTransaction(wallet, options?.feeRate);
411
+ if (callbacks?.onSourceTransactionSent != null)
412
+ callbacks.onSourceTransactionSent(txId);
413
+ }
414
+ }
415
+ const txId = await this.waitForBitcoinTransaction(callbacks?.onSourceTransactionConfirmationStatus, options?.btcTxCheckIntervalSeconds, options?.abortSignal);
416
+ if (callbacks?.onSourceTransactionConfirmed != null)
417
+ callbacks.onSourceTransactionConfirmed(txId);
418
+ }
419
+ // @ts-ignore
420
+ if (this.state === FromBTCSwapState.CLAIM_CLAIMED)
421
+ return true;
422
+ if (this.state === FromBTCSwapState.BTC_TX_CONFIRMED) {
423
+ const success = await this.waitTillClaimed(options?.maxWaitTillAutomaticSettlementSeconds ?? 60, options?.abortSignal);
424
+ if (success && callbacks?.onSwapSettled != null)
425
+ callbacks.onSwapSettled(this.getOutputTxId());
426
+ return success;
427
+ }
428
+ throw new Error("Invalid state reached!");
429
+ }
430
+ async txsExecute(options) {
431
+ if (this.state === FromBTCSwapState.PR_CREATED) {
432
+ if (!await this.verifyQuoteValid())
433
+ throw new Error("Quote already expired or close to expiry!");
434
+ if (this.getTimeoutTime() < Date.now())
435
+ throw new Error("Swap address already expired or close to expiry!");
436
+ return [
437
+ {
438
+ name: "Commit",
439
+ description: `Opens up the bitcoin swap address on the ${this.chainIdentifier} side`,
440
+ chain: this.chainIdentifier,
441
+ txs: await this.txsCommit(options?.skipChecks)
442
+ },
443
+ {
444
+ name: "Payment",
445
+ description: "Send funds to the bitcoin swap address",
446
+ chain: "BITCOIN",
447
+ txs: [
448
+ options?.bitcoinWallet == null ? {
449
+ address: this.address,
450
+ amount: Number(this.amount),
451
+ hyperlink: this._getHyperlink(),
452
+ type: "ADDRESS"
453
+ } : {
454
+ ...await this.getFundedPsbt(options.bitcoinWallet),
455
+ type: "FUNDED_PSBT"
456
+ }
457
+ ]
458
+ }
459
+ ];
460
+ }
461
+ if (this.state === FromBTCSwapState.CLAIM_COMMITED) {
462
+ if (this.getTimeoutTime() < Date.now())
463
+ throw new Error("Swap address already expired or close to expiry!");
464
+ return [
465
+ {
466
+ name: "Payment",
467
+ description: "Send funds to the bitcoin swap address",
468
+ chain: "BITCOIN",
469
+ txs: [
470
+ options?.bitcoinWallet == null ? {
471
+ address: this.address,
472
+ amount: Number(this.amount),
473
+ hyperlink: this._getHyperlink(),
474
+ type: "ADDRESS"
475
+ } : {
476
+ ...await this.getFundedPsbt(options.bitcoinWallet),
477
+ type: "FUNDED_PSBT"
478
+ }
479
+ ]
480
+ }
481
+ ];
482
+ }
483
+ throw new Error("Invalid swap state to obtain execution txns, required PR_CREATED or CLAIM_COMMITED");
484
+ }
485
+ //////////////////////////////
486
+ //// Commit
487
+ /**
488
+ * Commits the swap on-chain, locking the tokens from the intermediary in a PTLC
489
+ *
490
+ * @param _signer Signer to sign the transactions with, must be the same as used in the initialization
491
+ * @param abortSignal Abort signal to stop waiting for the transaction confirmation and abort
492
+ * @param skipChecks Skip checks like making sure init signature is still valid and swap wasn't commited yet
493
+ * (this is handled when swap is created (quoted), if you commit right after quoting, you can use skipChecks=true)
494
+ * @param onBeforeTxSent
495
+ * @throws {Error} If invalid signer is provided that doesn't match the swap data
496
+ */
497
+ async commit(_signer, abortSignal, skipChecks, onBeforeTxSent) {
498
+ const signer = (0, base_1.isAbstractSigner)(_signer) ? _signer : await this.wrapper.chain.wrapSigner(_signer);
499
+ this.checkSigner(signer);
500
+ let txCount = 0;
501
+ const txs = await this.txsCommit(skipChecks);
502
+ const result = await this.wrapper.chain.sendAndConfirm(signer, txs, true, abortSignal, undefined, (txId) => {
503
+ txCount++;
504
+ if (onBeforeTxSent != null && txCount === txs.length)
505
+ onBeforeTxSent(txId);
506
+ return Promise.resolve();
507
+ });
508
+ this.commitTxId = result[result.length - 1];
509
+ if (this.state === FromBTCSwapState.PR_CREATED || this.state === FromBTCSwapState.QUOTE_SOFT_EXPIRED) {
510
+ await this._saveAndEmit(FromBTCSwapState.CLAIM_COMMITED);
511
+ }
512
+ return this.commitTxId;
513
+ }
514
+ async waitTillCommited(abortSignal) {
515
+ if (this.state === FromBTCSwapState.CLAIM_COMMITED || this.state === FromBTCSwapState.CLAIM_CLAIMED)
516
+ return Promise.resolve();
517
+ if (this.state !== FromBTCSwapState.PR_CREATED && this.state !== FromBTCSwapState.QUOTE_SOFT_EXPIRED)
518
+ throw new Error("Invalid state");
519
+ const abortController = (0, Utils_1.extendAbortController)(abortSignal);
520
+ const result = await Promise.race([
521
+ this.watchdogWaitTillCommited(undefined, abortController.signal),
522
+ this.waitTillState(FromBTCSwapState.CLAIM_COMMITED, "gte", abortController.signal).then(() => 0)
523
+ ]);
524
+ abortController.abort();
525
+ if (result === 0)
526
+ this.logger.debug("waitTillCommited(): Resolved from state changed");
527
+ if (result === true)
528
+ this.logger.debug("waitTillCommited(): Resolved from watchdog - commited");
529
+ if (result === false) {
530
+ this.logger.debug("waitTillCommited(): Resolved from watchdog - signature expired");
531
+ if (this.state === FromBTCSwapState.PR_CREATED || this.state === FromBTCSwapState.QUOTE_SOFT_EXPIRED) {
532
+ await this._saveAndEmit(FromBTCSwapState.QUOTE_EXPIRED);
533
+ }
534
+ return;
535
+ }
536
+ if (this.state === FromBTCSwapState.PR_CREATED || this.state === FromBTCSwapState.QUOTE_SOFT_EXPIRED) {
537
+ await this._saveAndEmit(FromBTCSwapState.CLAIM_COMMITED);
538
+ }
539
+ }
540
+ //////////////////////////////
541
+ //// Claim
542
+ /**
543
+ * Returns transactions required to claim the swap on-chain (and possibly also sync the bitcoin light client)
544
+ * after a bitcoin transaction was sent and confirmed
545
+ *
546
+ * @throws {Error} If the swap is in invalid state (must be BTC_TX_CONFIRMED)
547
+ */
548
+ async txsClaim(_signer) {
549
+ let signer = undefined;
550
+ if (_signer != null) {
551
+ if (typeof (_signer) === "string") {
552
+ signer = _signer;
553
+ }
554
+ else if ((0, base_1.isAbstractSigner)(_signer)) {
555
+ signer = _signer;
556
+ }
557
+ else {
558
+ signer = await this.wrapper.chain.wrapSigner(_signer);
559
+ }
560
+ }
561
+ if (this.state !== FromBTCSwapState.BTC_TX_CONFIRMED)
562
+ throw new Error("Must be in BTC_TX_CONFIRMED state!");
563
+ if (this.txId == null || this.vout == null)
564
+ throw new Error("Bitcoin transaction ID not known!");
565
+ const tx = await this.wrapper.btcRpc.getTransaction(this.txId);
566
+ if (tx == null)
567
+ throw new Error("Bitcoin transaction not found on the network!");
568
+ if (tx.blockhash == null || tx.confirmations == null || tx.blockheight == null || tx.confirmations < this.requiredConfirmations)
569
+ throw new Error("Bitcoin transaction not confirmed yet!");
570
+ return await this.wrapper.contract.txsClaimWithTxData(signer ?? this._getInitiator(), this.data, {
571
+ blockhash: tx.blockhash,
572
+ confirmations: tx.confirmations,
573
+ txid: tx.txid,
574
+ hex: tx.hex,
575
+ height: tx.blockheight
576
+ }, this.requiredConfirmations, this.vout, undefined, this.wrapper.synchronizer, true);
577
+ }
578
+ /**
579
+ * Claims and finishes the swap
580
+ *
581
+ * @param _signer Signer to sign the transactions with, can also be different to the initializer
582
+ * @param abortSignal Abort signal to stop waiting for transaction confirmation
583
+ * @param onBeforeTxSent
584
+ */
585
+ async claim(_signer, abortSignal, onBeforeTxSent) {
586
+ const signer = (0, base_1.isAbstractSigner)(_signer) ? _signer : await this.wrapper.chain.wrapSigner(_signer);
587
+ let txIds;
588
+ try {
589
+ let txCount = 0;
590
+ const txs = await this.txsClaim(signer);
591
+ txIds = await this.wrapper.chain.sendAndConfirm(signer, txs, true, abortSignal, undefined, (txId) => {
592
+ txCount++;
593
+ if (onBeforeTxSent != null && txCount === txs.length)
594
+ onBeforeTxSent(txId);
595
+ return Promise.resolve();
596
+ });
597
+ }
598
+ catch (e) {
599
+ this.logger.info("claim(): Failed to claim ourselves, checking swap claim state...");
600
+ if (this.state === FromBTCSwapState.CLAIM_CLAIMED) {
601
+ this.logger.info("claim(): Transaction state is CLAIM_CLAIMED, swap was successfully claimed by the watchtower");
602
+ return this.claimTxId;
603
+ }
604
+ const status = await this.wrapper.contract.getCommitStatus(this._getInitiator(), this.data);
605
+ if (status?.type === base_1.SwapCommitStateType.PAID) {
606
+ this.logger.info("claim(): Transaction commit status is PAID, swap was successfully claimed by the watchtower");
607
+ if (this.claimTxId == null)
608
+ this.claimTxId = await status.getClaimTxId();
609
+ const txId = buffer_1.Buffer.from(await status.getClaimResult(), "hex").reverse().toString("hex");
610
+ await this._setBitcoinTxId(txId);
611
+ await this._saveAndEmit(FromBTCSwapState.CLAIM_CLAIMED);
612
+ return this.claimTxId;
613
+ }
614
+ throw e;
615
+ }
616
+ this.claimTxId = txIds[txIds.length - 1];
617
+ if (this.state === FromBTCSwapState.CLAIM_COMMITED || this.state === FromBTCSwapState.BTC_TX_CONFIRMED ||
618
+ this.state === FromBTCSwapState.EXPIRED || this.state === FromBTCSwapState.FAILED) {
619
+ await this._saveAndEmit(FromBTCSwapState.CLAIM_CLAIMED);
620
+ }
621
+ return txIds[txIds.length - 1];
622
+ }
623
+ /**
624
+ * Waits till the swap is successfully claimed
625
+ *
626
+ * @param maxWaitTimeSeconds Maximum time in seconds to wait for the swap to be settled
627
+ * @param abortSignal AbortSignal
628
+ * @throws {Error} If swap is in invalid state (must be BTC_TX_CONFIRMED)
629
+ * @throws {Error} If the LP refunded sooner than we were able to claim
630
+ * @returns {boolean} whether the swap was claimed in time or not
631
+ */
632
+ async waitTillClaimed(maxWaitTimeSeconds, abortSignal) {
633
+ if (this.state === FromBTCSwapState.CLAIM_CLAIMED)
634
+ return Promise.resolve(true);
635
+ if (this.state !== FromBTCSwapState.BTC_TX_CONFIRMED)
636
+ throw new Error("Invalid state (not BTC_TX_CONFIRMED)");
637
+ const abortController = (0, Utils_1.extendAbortController)(abortSignal);
638
+ let timedOut = false;
639
+ if (maxWaitTimeSeconds != null) {
640
+ const timeout = setTimeout(() => {
641
+ timedOut = true;
642
+ abortController.abort();
643
+ }, maxWaitTimeSeconds * 1000);
644
+ abortController.signal.addEventListener("abort", () => clearTimeout(timeout));
645
+ }
646
+ let res;
647
+ try {
648
+ res = await Promise.race([
649
+ this.watchdogWaitTillResult(undefined, abortController.signal),
650
+ this.waitTillState(FromBTCSwapState.CLAIM_CLAIMED, "eq", abortController.signal).then(() => 0),
651
+ this.waitTillState(FromBTCSwapState.FAILED, "eq", abortController.signal).then(() => 1),
652
+ ]);
653
+ abortController.abort();
654
+ }
655
+ catch (e) {
656
+ abortController.abort();
657
+ if (timedOut)
658
+ return false;
659
+ throw e;
660
+ }
661
+ if (res === 0) {
662
+ this.logger.debug("waitTillClaimed(): Resolved from state change (CLAIM_CLAIMED)");
663
+ return true;
664
+ }
665
+ if (res === 1) {
666
+ this.logger.debug("waitTillClaimed(): Resolved from state change (FAILED)");
667
+ throw new Error("Offerer refunded during claiming");
668
+ }
669
+ this.logger.debug("waitTillClaimed(): Resolved from watchdog");
670
+ if (res?.type === base_1.SwapCommitStateType.PAID) {
671
+ if (this.state !== FromBTCSwapState.CLAIM_CLAIMED) {
672
+ if (this.claimTxId == null)
673
+ this.claimTxId = await res.getClaimTxId();
674
+ const txId = buffer_1.Buffer.from(await res.getClaimResult(), "hex").reverse().toString("hex");
675
+ await this._setBitcoinTxId(txId);
676
+ await this._saveAndEmit(FromBTCSwapState.CLAIM_CLAIMED);
677
+ }
678
+ }
679
+ if (res?.type === base_1.SwapCommitStateType.NOT_COMMITED || res?.type === base_1.SwapCommitStateType.EXPIRED) {
680
+ if (this.state !== FromBTCSwapState.CLAIM_CLAIMED &&
681
+ this.state !== FromBTCSwapState.FAILED) {
682
+ if (res.getRefundTxId != null)
683
+ this.refundTxId = await res.getRefundTxId();
684
+ await this._saveAndEmit(FromBTCSwapState.FAILED);
685
+ }
686
+ throw new Error("Swap expired while waiting for claim!");
687
+ }
688
+ return true;
689
+ }
690
+ //////////////////////////////
691
+ //// Storage
692
+ serialize() {
693
+ return {
694
+ ...super.serialize(),
695
+ address: this.address,
696
+ amount: this.amount.toString(10),
697
+ requiredConfirmations: this.requiredConfirmations,
698
+ senderAddress: this.senderAddress,
699
+ txId: this.txId,
700
+ vout: this.vout
701
+ };
702
+ }
703
+ //////////////////////////////
704
+ //// Swap ticks & sync
705
+ /**
706
+ * Checks the swap's state on-chain and compares it to its internal state, updates/changes it according to on-chain
707
+ * data
708
+ *
709
+ * @private
710
+ */
711
+ async syncStateFromChain(quoteDefinitelyExpired, commitStatus) {
712
+ if (this.state === FromBTCSwapState.PR_CREATED || this.state === FromBTCSwapState.QUOTE_SOFT_EXPIRED) {
713
+ const quoteExpired = quoteDefinitelyExpired ?? await this._verifyQuoteDefinitelyExpired(); //Make sure we check for expiry here, to prevent race conditions
714
+ const status = commitStatus ?? await this.wrapper.contract.getCommitStatus(this._getInitiator(), this.data);
715
+ switch (status?.type) {
716
+ case base_1.SwapCommitStateType.COMMITED:
717
+ this.state = FromBTCSwapState.CLAIM_COMMITED;
718
+ return true;
719
+ case base_1.SwapCommitStateType.EXPIRED:
720
+ if (this.refundTxId == null && status.getRefundTxId)
721
+ this.refundTxId = await status.getRefundTxId();
722
+ this.state = FromBTCSwapState.QUOTE_EXPIRED;
723
+ return true;
724
+ case base_1.SwapCommitStateType.PAID:
725
+ if (this.claimTxId == null)
726
+ this.claimTxId = await status.getClaimTxId();
727
+ const txId = buffer_1.Buffer.from(await status.getClaimResult(), "hex").reverse().toString("hex");
728
+ await this._setBitcoinTxId(txId);
729
+ this.state = FromBTCSwapState.CLAIM_CLAIMED;
730
+ return true;
731
+ }
732
+ if (quoteExpired) {
733
+ this.state = FromBTCSwapState.QUOTE_EXPIRED;
734
+ return true;
735
+ }
736
+ return false;
737
+ }
738
+ if (this.state === FromBTCSwapState.CLAIM_COMMITED || this.state === FromBTCSwapState.BTC_TX_CONFIRMED || this.state === FromBTCSwapState.EXPIRED) {
739
+ const status = commitStatus ?? await this.wrapper.contract.getCommitStatus(this._getInitiator(), this.data);
740
+ switch (status?.type) {
741
+ case base_1.SwapCommitStateType.PAID:
742
+ if (this.claimTxId == null)
743
+ this.claimTxId = await status.getClaimTxId();
744
+ const txId = buffer_1.Buffer.from(await status.getClaimResult(), "hex").reverse().toString("hex");
745
+ await this._setBitcoinTxId(txId);
746
+ this.state = FromBTCSwapState.CLAIM_CLAIMED;
747
+ return true;
748
+ case base_1.SwapCommitStateType.NOT_COMMITED:
749
+ case base_1.SwapCommitStateType.EXPIRED:
750
+ if (this.refundTxId == null && status.getRefundTxId)
751
+ this.refundTxId = await status.getRefundTxId();
752
+ this.state = FromBTCSwapState.FAILED;
753
+ return true;
754
+ case base_1.SwapCommitStateType.COMMITED:
755
+ const res = await this.getBitcoinPayment();
756
+ if (res != null) {
757
+ let save = false;
758
+ if (this.txId !== res.txId) {
759
+ if (res.inputAddresses != null)
760
+ this.senderAddress = res.inputAddresses[0];
761
+ this.txId = res.txId;
762
+ this.vout = res.vout;
763
+ save = true;
764
+ }
765
+ if (res.confirmations >= this.requiredConfirmations) {
766
+ this.state = FromBTCSwapState.BTC_TX_CONFIRMED;
767
+ save = true;
768
+ }
769
+ return save;
770
+ }
771
+ break;
772
+ }
773
+ }
774
+ return false;
775
+ }
776
+ _shouldFetchCommitStatus() {
777
+ return this.state === FromBTCSwapState.PR_CREATED || this.state === FromBTCSwapState.QUOTE_SOFT_EXPIRED ||
778
+ this.state === FromBTCSwapState.CLAIM_COMMITED || this.state === FromBTCSwapState.BTC_TX_CONFIRMED ||
779
+ this.state === FromBTCSwapState.EXPIRED;
780
+ }
781
+ _shouldFetchExpiryStatus() {
782
+ return this.state === FromBTCSwapState.PR_CREATED || this.state === FromBTCSwapState.QUOTE_SOFT_EXPIRED;
783
+ }
784
+ async _sync(save, quoteDefinitelyExpired, commitStatus) {
785
+ const changed = await this.syncStateFromChain(quoteDefinitelyExpired, commitStatus);
786
+ if (changed && save)
787
+ await this._saveAndEmit();
788
+ return changed;
789
+ }
790
+ async _tick(save) {
791
+ switch (this.state) {
792
+ case FromBTCSwapState.PR_CREATED:
793
+ if (this.expiry < Date.now()) {
794
+ this.state = FromBTCSwapState.QUOTE_SOFT_EXPIRED;
795
+ if (save)
796
+ await this._saveAndEmit();
797
+ return true;
798
+ }
799
+ break;
800
+ case FromBTCSwapState.CLAIM_COMMITED:
801
+ if (this.getTimeoutTime() < Date.now()) {
802
+ this.state = FromBTCSwapState.EXPIRED;
803
+ if (save)
804
+ await this._saveAndEmit();
805
+ return true;
806
+ }
807
+ case FromBTCSwapState.EXPIRED:
808
+ //Check if bitcoin payment was received every 2 minutes
809
+ if (Math.floor(Date.now() / 1000) % 120 === 0) {
810
+ try {
811
+ const res = await this.getBitcoinPayment();
812
+ if (res != null) {
813
+ let shouldSave = false;
814
+ if (this.txId !== res.txId) {
815
+ this.txId = res.txId;
816
+ this.vout = res.vout;
817
+ if (res.inputAddresses != null)
818
+ this.senderAddress = res.inputAddresses[0];
819
+ shouldSave = true;
820
+ }
821
+ if (res.confirmations >= this.requiredConfirmations) {
822
+ this.state = FromBTCSwapState.BTC_TX_CONFIRMED;
823
+ if (save)
824
+ await this._saveAndEmit();
825
+ shouldSave = true;
826
+ }
827
+ if (shouldSave && save)
828
+ await this._saveAndEmit();
829
+ return shouldSave;
830
+ }
831
+ }
832
+ catch (e) {
833
+ this.logger.warn("tickSwap(" + this.getIdentifierHashString() + "): ", e);
834
+ }
835
+ }
836
+ break;
837
+ }
838
+ return false;
839
+ }
840
+ }
841
+ exports.FromBTCSwap = FromBTCSwap;