@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,716 @@
1
+ import {decode as bolt11Decode, PaymentRequestObject, TagsObject} from "@atomiqlabs/bolt11";
2
+ import {ToBTCLNSwap} from "./ToBTCLNSwap";
3
+ import {IToBTCDefinition, IToBTCWrapper} from "../IToBTCWrapper";
4
+ import {UserError} from "../../../../errors/UserError";
5
+ import {ChainSwapType, ChainType, SwapCommitState, SwapCommitStateType} from "@atomiqlabs/base";
6
+ import {Intermediary} from "../../../../intermediaries/Intermediary";
7
+ import {ISwapWrapperOptions, WrapperCtorTokens} from "../../../ISwapWrapper";
8
+ import {ISwapPrice} from "../../../../prices/abstract/ISwapPrice";
9
+ import {EventEmitter} from "events";
10
+ import {IntermediaryError} from "../../../../errors/IntermediaryError";
11
+ import {SwapType} from "../../../../enums/SwapType";
12
+ import {extendAbortController, throwIfUndefined} from "../../../../utils/Utils";
13
+ import {IntermediaryAPI, ToBTCLNResponseType} from "../../../../intermediaries/apis/IntermediaryAPI";
14
+ import {RequestError} from "../../../../errors/RequestError";
15
+ import {LNURL, LNURLPaySuccessAction} from "../../../../lnurl/LNURL";
16
+ import {IToBTCSwapInit, ToBTCSwapState} from "../IToBTCSwap";
17
+ import {UnifiedSwapEventListener} from "../../../../events/UnifiedSwapEventListener";
18
+ import {UnifiedSwapStorage} from "../../../../storage/UnifiedSwapStorage";
19
+ import {ISwap} from "../../../ISwap";
20
+ import {sha256} from "@noble/hashes/sha2";
21
+ import {AmountData} from "../../../../types/AmountData";
22
+ import {LNURLPayParamsWithUrl} from "../../../../types/lnurl/LNURLPay";
23
+ import {tryWithRetries} from "../../../../utils/RetryUtils";
24
+ import {AllOptional, AllRequired} from "../../../../utils/TypeUtils";
25
+
26
+ export type LightningWalletCallback = (valueSats: number, abortSignal?: AbortSignal) => Promise<string>;
27
+ export type InvoiceCreateService = {
28
+ getInvoice: LightningWalletCallback,
29
+ minMsats?: bigint,
30
+ maxMSats?: bigint
31
+ };
32
+
33
+ export function isInvoiceCreateService(obj: any): obj is InvoiceCreateService {
34
+ return typeof(obj)==="object" &&
35
+ typeof(obj.getInvoice)==="function" &&
36
+ (obj.minMsats==null || typeof(obj.minMsats)==="bigint") &&
37
+ (obj.maxMSats==null || typeof(obj.maxMSats)==="bigint");
38
+ }
39
+
40
+ export type ToBTCLNOptions = {
41
+ expirySeconds?: number,
42
+ maxFee?: bigint | Promise<bigint>,
43
+ expiryTimestamp?: bigint,
44
+ maxRoutingPPM?: bigint,
45
+ maxRoutingBaseFee?: bigint
46
+ }
47
+
48
+ export type ToBTCLNWrapperOptions = ISwapWrapperOptions & {
49
+ lightningBaseFee: number,
50
+ lightningFeePPM: number,
51
+ paymentTimeoutSeconds: number
52
+ };
53
+
54
+ export type ToBTCLNDefinition<T extends ChainType> = IToBTCDefinition<T, ToBTCLNWrapper<T>, ToBTCLNSwap<T>>;
55
+
56
+ export class ToBTCLNWrapper<T extends ChainType> extends IToBTCWrapper<T, ToBTCLNDefinition<T>, ToBTCLNWrapperOptions> {
57
+ public readonly TYPE = SwapType.TO_BTCLN;
58
+ public readonly swapDeserializer = ToBTCLNSwap;
59
+
60
+ constructor(
61
+ chainIdentifier: string,
62
+ unifiedStorage: UnifiedSwapStorage<T>,
63
+ unifiedChainEvents: UnifiedSwapEventListener<T>,
64
+ chain: T["ChainInterface"],
65
+ contract: T["Contract"],
66
+ prices: ISwapPrice,
67
+ tokens: WrapperCtorTokens,
68
+ swapDataDeserializer: new (data: any) => T["Data"],
69
+ options?: AllOptional<ToBTCLNWrapperOptions>,
70
+ events?: EventEmitter<{swapState: [ISwap]}>
71
+ ) {
72
+ super(
73
+ chainIdentifier, unifiedStorage, unifiedChainEvents, chain, contract, prices, tokens, swapDataDeserializer,
74
+ {
75
+ paymentTimeoutSeconds: options?.paymentTimeoutSeconds ?? 4*24*60*60,
76
+ lightningBaseFee: options?.lightningBaseFee ?? 10,
77
+ lightningFeePPM: options?.lightningFeePPM ?? 2000
78
+ },
79
+ events
80
+ );
81
+ }
82
+
83
+ private toRequiredSwapOptions(amountData: AmountData, options?: ToBTCLNOptions, pricePreFetchPromise?: Promise<bigint | undefined>, abortSignal?: AbortSignal): AllRequired<ToBTCLNOptions> {
84
+ const expirySeconds = options?.expirySeconds ?? this.options.paymentTimeoutSeconds;
85
+ const maxRoutingBaseFee = options?.maxRoutingBaseFee ?? BigInt(this.options.lightningBaseFee);
86
+ const maxRoutingPPM = options?.maxRoutingPPM ?? BigInt(this.options.lightningFeePPM);
87
+
88
+ let maxFee: bigint | Promise<bigint>;
89
+ if(options?.maxFee!=null) {
90
+ maxFee = options.maxFee;
91
+ } else if(amountData.exactIn) {
92
+ if(pricePreFetchPromise!=null) {
93
+ maxFee = pricePreFetchPromise
94
+ .then(val => this.prices.getFromBtcSwapAmount(this.chainIdentifier, maxRoutingBaseFee, amountData.token, abortSignal, val))
95
+ .then(_maxBaseFee => this.calculateFeeForAmount(amountData.amount, _maxBaseFee, maxRoutingPPM))
96
+ } else {
97
+ maxFee = this.prices.getFromBtcSwapAmount(this.chainIdentifier, maxRoutingBaseFee, amountData.token, abortSignal)
98
+ .then(_maxBaseFee => this.calculateFeeForAmount(amountData.amount, _maxBaseFee, maxRoutingPPM))
99
+ }
100
+ } else {
101
+ maxFee = this.calculateFeeForAmount(amountData.amount, maxRoutingBaseFee, maxRoutingPPM)
102
+ }
103
+
104
+ return {
105
+ expirySeconds,
106
+ expiryTimestamp: options?.expiryTimestamp ?? BigInt(Math.floor(Date.now()/1000)+expirySeconds),
107
+ maxRoutingBaseFee,
108
+ maxRoutingPPM,
109
+ maxFee
110
+ }
111
+ }
112
+
113
+ private async checkPaymentHashWasPaid(paymentHash: string) {
114
+ const swaps = await this.unifiedStorage.query(
115
+ [[{key: "type", value: this.TYPE}, {key: "paymentHash", value: paymentHash}]],
116
+ (obj: any) => new this.swapDeserializer(this, obj)
117
+ );
118
+
119
+ for(let value of swaps) {
120
+ if(value.state===ToBTCSwapState.CLAIMED || value.state===ToBTCSwapState.SOFT_CLAIMED)
121
+ throw new UserError("Lightning invoice was already paid!");
122
+ }
123
+ }
124
+
125
+ /**
126
+ * Calculates maximum lightning network routing fee based on amount
127
+ *
128
+ * @param amount BTC amount of the swap in satoshis
129
+ * @param overrideBaseFee Override wrapper's default base fee
130
+ * @param overrideFeePPM Override wrapper's default PPM
131
+ * @private
132
+ * @returns Maximum lightning routing fee in sats
133
+ */
134
+ private calculateFeeForAmount(amount: bigint, overrideBaseFee?: bigint, overrideFeePPM?: bigint) : bigint {
135
+ return BigInt(overrideBaseFee ?? this.options.lightningBaseFee)
136
+ + (amount * BigInt(overrideFeePPM ?? this.options.lightningFeePPM) / 1000000n);
137
+ }
138
+
139
+ /**
140
+ * Verifies returned LP data
141
+ *
142
+ * @param signer
143
+ * @param resp Response as returned by the LP
144
+ * @param parsedPr Parsed bolt11 lightning invoice
145
+ * @param token Smart chain token to be used in the swap
146
+ * @param lp
147
+ * @param options Swap options as passed to the swap create function
148
+ * @param data Parsed swap data returned by the LP
149
+ * @param requiredTotal Required total to be paid on the input (for exactIn swaps)
150
+ * @private
151
+ * @throws {IntermediaryError} In case the response is not valid
152
+ */
153
+ private async verifyReturnedData(
154
+ signer: string,
155
+ resp: ToBTCLNResponseType,
156
+ parsedPr: PaymentRequestObject & {tagsObject: TagsObject},
157
+ token: string,
158
+ lp: Intermediary,
159
+ options: AllRequired<ToBTCLNOptions>,
160
+ data: T["Data"],
161
+ requiredTotal?: bigint
162
+ ): Promise<void> {
163
+ if(resp.routingFeeSats > await options.maxFee) throw new IntermediaryError("Invalid max fee sats returned");
164
+
165
+ if(requiredTotal!=null && resp.total !== requiredTotal)
166
+ throw new IntermediaryError("Invalid data returned - total amount");
167
+
168
+ if(parsedPr.tagsObject.payment_hash==null) throw new Error("Swap invoice doesn't contain payment hash field!");
169
+ const claimHash = this.contract.getHashForHtlc(Buffer.from(parsedPr.tagsObject.payment_hash, "hex"));
170
+
171
+ if(
172
+ data.getAmount() !== resp.total ||
173
+ !Buffer.from(data.getClaimHash(), "hex").equals(claimHash) ||
174
+ data.getExpiry() !== options.expiryTimestamp ||
175
+ data.getType()!==ChainSwapType.HTLC ||
176
+ !data.isPayIn() ||
177
+ !data.isToken(token) ||
178
+ !data.isClaimer(lp.getAddress(this.chainIdentifier)) ||
179
+ !data.isOfferer(signer) ||
180
+ data.getTotalDeposit() !== 0n
181
+ ) {
182
+ throw new IntermediaryError("Invalid data returned");
183
+ }
184
+ }
185
+
186
+ /**
187
+ * Returns the quote/swap from a given intermediary
188
+ *
189
+ * @param signer Smartchain signer initiating the swap
190
+ * @param amountData
191
+ * @param lp Intermediary
192
+ * @param pr bolt11 lightning network invoice
193
+ * @param parsedPr Parsed bolt11 lightning network invoice
194
+ * @param options Options as passed to the swap create function
195
+ * @param preFetches
196
+ * @param abort Abort signal or controller, if AbortController is passed it is used as-is, when AbortSignal is passed
197
+ * it is extended with extendAbortController and then used
198
+ * @param additionalParams Additional params that should be sent to the LP
199
+ * @private
200
+ */
201
+ private async getIntermediaryQuote(
202
+ signer: string,
203
+ amountData: Omit<AmountData, "amount">,
204
+ lp: Intermediary,
205
+ pr: string,
206
+ parsedPr: PaymentRequestObject & {tagsObject: TagsObject},
207
+ options: AllRequired<ToBTCLNOptions>,
208
+ preFetches: {
209
+ feeRatePromise: Promise<string | undefined>,
210
+ pricePreFetchPromise: Promise<bigint | undefined>,
211
+ usdPricePrefetchPromise: Promise<number | undefined>,
212
+ signDataPrefetchPromise?: Promise<T["PreFetchVerification"] | undefined>
213
+ },
214
+ abort: AbortSignal | AbortController,
215
+ additionalParams?: Record<string, any>,
216
+ ) {
217
+ if(lp.services[SwapType.TO_BTCLN]==null) throw new Error("LP service for processing to btcln swaps not found!");
218
+
219
+ const abortController = abort instanceof AbortController ? abort : extendAbortController(abort);
220
+ const reputationPromise = this.preFetchIntermediaryReputation(amountData, lp, abortController);
221
+
222
+ try {
223
+ const {signDataPromise, resp} = await tryWithRetries(async(retryCount: number) => {
224
+ const {signDataPrefetch, response} = IntermediaryAPI.initToBTCLN(this.chainIdentifier, lp.url, {
225
+ offerer: signer,
226
+ pr,
227
+ maxFee: await options.maxFee,
228
+ expiryTimestamp: options.expiryTimestamp,
229
+ token: amountData.token,
230
+ feeRate: throwIfUndefined(preFetches.feeRatePromise),
231
+ additionalParams
232
+ }, this.options.postRequestTimeout, abortController.signal, retryCount>0 ? false : undefined);
233
+
234
+ return {
235
+ signDataPromise: preFetches.signDataPrefetchPromise ?? this.preFetchSignData(signDataPrefetch),
236
+ resp: await response
237
+ };
238
+ }, undefined, e => e instanceof RequestError, abortController.signal);
239
+
240
+ if(parsedPr.millisatoshis==null) throw new Error("Swap invoice doesn't have msat amount field!");
241
+ const amountOut: bigint = (BigInt(parsedPr.millisatoshis) + 999n) / 1000n;
242
+ const totalFee: bigint = resp.swapFee + resp.maxFee;
243
+ const data: T["Data"] = new this.swapDataDeserializer(resp.data);
244
+ data.setOfferer(signer);
245
+
246
+ await this.verifyReturnedData(signer, resp, parsedPr, amountData.token, lp, options, data);
247
+
248
+ const [pricingInfo, signatureExpiry, reputation] = await Promise.all([
249
+ this.verifyReturnedPrice(
250
+ lp.services[SwapType.TO_BTCLN], true, amountOut, data.getAmount(),
251
+ amountData.token, {networkFee: resp.maxFee},
252
+ preFetches.pricePreFetchPromise, preFetches.usdPricePrefetchPromise, abortController.signal
253
+ ),
254
+ this.verifyReturnedSignature(
255
+ signer, data, resp, preFetches.feeRatePromise, signDataPromise, abortController.signal
256
+ ),
257
+ reputationPromise
258
+ ]);
259
+ abortController.signal.throwIfAborted();
260
+
261
+ if(reputation!=null) lp.reputation[amountData.token.toString()] = reputation;
262
+
263
+ const swapFeeBtc = resp.swapFee * amountOut / (data.getAmount() - totalFee);
264
+
265
+ const quote = new ToBTCLNSwap<T>(this, {
266
+ pricingInfo,
267
+ url: lp.url,
268
+ expiry: signatureExpiry,
269
+ swapFee: resp.swapFee,
270
+ swapFeeBtc,
271
+ feeRate: (await preFetches.feeRatePromise)!,
272
+ signatureData: resp,
273
+ data,
274
+ networkFee: resp.maxFee,
275
+ networkFeeBtc: resp.routingFeeSats,
276
+ confidence: resp.confidence,
277
+ pr,
278
+ exactIn: false
279
+ } as IToBTCSwapInit<T["Data"]>);
280
+ await quote._save();
281
+ return quote;
282
+ } catch (e) {
283
+ abortController.abort(e);
284
+ throw e;
285
+ }
286
+ }
287
+
288
+ /**
289
+ * Returns a newly created swap, paying for 'bolt11PayRequest' - a bitcoin LN invoice
290
+ *
291
+ * @param signer Smartchain signer's address initiating the swap
292
+ * @param bolt11PayRequest BOLT11 payment request (bitcoin lightning invoice) you wish to pay
293
+ * @param amountData Amount of token & amount to swap
294
+ * @param lps LPs (liquidity providers) to get the quotes from
295
+ * @param options Quote options
296
+ * @param additionalParams Additional parameters sent to the LP when creating the swap
297
+ * @param abortSignal Abort signal for aborting the process
298
+ * @param preFetches Existing pre-fetches for the swap (only used internally for LNURL swaps)
299
+ */
300
+ async create(
301
+ signer: string,
302
+ bolt11PayRequest: string,
303
+ amountData: Omit<AmountData, "amount">,
304
+ lps: Intermediary[],
305
+ options?: ToBTCLNOptions,
306
+ additionalParams?: Record<string, any>,
307
+ abortSignal?: AbortSignal,
308
+ preFetches?: {
309
+ feeRatePromise: Promise<string | undefined>,
310
+ pricePreFetchPromise: Promise<bigint | undefined>,
311
+ usdPricePrefetchPromise: Promise<number | undefined>,
312
+ signDataPrefetchPromise?: Promise<T["PreFetchVerification"] | undefined>
313
+ }
314
+ ): Promise<{
315
+ quote: Promise<ToBTCLNSwap<T>>,
316
+ intermediary: Intermediary
317
+ }[]> {
318
+ const parsedPr = bolt11Decode(bolt11PayRequest);
319
+ if(parsedPr.millisatoshis==null) throw new UserError("Must be an invoice with amount");
320
+ const amountOut: bigint = (BigInt(parsedPr.millisatoshis) + 999n) / 1000n;
321
+
322
+ const expirySeconds = options?.expirySeconds ?? this.options.paymentTimeoutSeconds;
323
+ const maxRoutingBaseFee = options?.maxRoutingBaseFee ?? BigInt(this.options.lightningBaseFee);
324
+ const maxRoutingPPM = options?.maxRoutingPPM ?? BigInt(this.options.lightningFeePPM);
325
+
326
+ const _options: AllRequired<ToBTCLNOptions> = {
327
+ expirySeconds,
328
+ expiryTimestamp: options?.expiryTimestamp ?? BigInt(Math.floor(Date.now()/1000)+expirySeconds),
329
+ maxRoutingBaseFee,
330
+ maxRoutingPPM,
331
+ maxFee: options?.maxFee ?? this.calculateFeeForAmount(amountOut, maxRoutingBaseFee, maxRoutingPPM)
332
+ }
333
+
334
+ if(parsedPr.tagsObject.payment_hash==null) throw new Error("Provided lightning invoice doesn't contain payment hash field!");
335
+ await this.checkPaymentHashWasPaid(parsedPr.tagsObject.payment_hash);
336
+
337
+ const claimHash = this.contract.getHashForHtlc(Buffer.from(parsedPr.tagsObject.payment_hash, "hex"));
338
+
339
+ const _abortController = extendAbortController(abortSignal);
340
+ const _preFetches = preFetches ?? {
341
+ pricePreFetchPromise: this.preFetchPrice(amountData, _abortController.signal),
342
+ feeRatePromise: this.preFetchFeeRate(signer, amountData, claimHash.toString("hex"), _abortController),
343
+ usdPricePrefetchPromise: this.preFetchUsdPrice(_abortController.signal),
344
+ signDataPrefetchPromise: this.contract.preFetchBlockDataForSignatures==null ? this.preFetchSignData(Promise.resolve(true)) : undefined
345
+ };
346
+
347
+ return lps.map(lp => {
348
+ return {
349
+ intermediary: lp,
350
+ quote: this.getIntermediaryQuote(signer, amountData, lp, bolt11PayRequest, parsedPr, _options, _preFetches, _abortController.signal, additionalParams)
351
+ }
352
+ });
353
+ }
354
+
355
+ /**
356
+ * Parses and fetches lnurl pay params from the specified lnurl
357
+ *
358
+ * @param lnurl LNURL to be parsed and fetched
359
+ * @param abortSignal
360
+ * @private
361
+ * @throws {UserError} if the LNURL is invalid or if it's not a LNURL-pay
362
+ */
363
+ private async getLNURLPay(lnurl: string | LNURLPayParamsWithUrl, abortSignal: AbortSignal): Promise<LNURLPayParamsWithUrl> {
364
+ if(typeof(lnurl)!=="string") return lnurl;
365
+
366
+ const res = await LNURL.getLNURL(lnurl, true, this.options.getRequestTimeout, abortSignal);
367
+ if(res==null) throw new UserError("Invalid LNURL");
368
+ if(res.tag!=="payRequest") throw new UserError("Not a LNURL-pay");
369
+ return res;
370
+ }
371
+
372
+ /**
373
+ * Returns the quote/swap from the given LP
374
+ *
375
+ * @param signer Smartchain signer's address initiating the swap
376
+ * @param amountData
377
+ * @param invoiceCreateService Service for creating fixed amount invoices
378
+ * @param lp Intermediary
379
+ * @param dummyPr Dummy minimum value bolt11 lightning invoice returned from the LNURL-pay
380
+ * @param options Options as passed to the swap create function
381
+ * @param preFetches
382
+ * @param abortSignal
383
+ * @param additionalParams Additional params to be sent to the intermediary
384
+ * @private
385
+ */
386
+ private async getIntermediaryQuoteExactIn(
387
+ signer: string,
388
+ amountData: AmountData,
389
+ invoiceCreateService: InvoiceCreateService,
390
+ lp: Intermediary,
391
+ dummyPr: string,
392
+ options: AllRequired<ToBTCLNOptions> & {comment?: string},
393
+ preFetches: {
394
+ feeRatePromise: Promise<string | undefined>,
395
+ pricePreFetchPromise: Promise<bigint | undefined>,
396
+ usdPricePrefetchPromise: Promise<number | undefined>
397
+ },
398
+ abortSignal: AbortSignal,
399
+ additionalParams?: Record<string, any>,
400
+ ) {
401
+ if(lp.services[SwapType.TO_BTCLN]==null) throw new Error("LP service for processing to btcln swaps not found!");
402
+
403
+ const abortController = extendAbortController(abortSignal);
404
+ const reputationPromise = this.preFetchIntermediaryReputation(amountData, lp, abortController);
405
+
406
+ try {
407
+ const {signDataPromise, prepareResp} = await tryWithRetries(async(retryCount: number) => {
408
+ const {signDataPrefetch, response} = IntermediaryAPI.prepareToBTCLNExactIn(this.chainIdentifier, lp.url, {
409
+ token: amountData.token,
410
+ offerer: signer,
411
+ pr: dummyPr,
412
+ amount: amountData.amount,
413
+ maxFee: await options.maxFee,
414
+ expiryTimestamp: options.expiryTimestamp,
415
+ additionalParams
416
+ }, this.options.postRequestTimeout, abortController.signal, retryCount>0 ? false : undefined);
417
+
418
+ return {
419
+ signDataPromise: this.preFetchSignData(signDataPrefetch),
420
+ prepareResp: await response
421
+ };
422
+ }, undefined, e => e instanceof RequestError, abortController.signal);
423
+
424
+ if(prepareResp.amount <= 0n)
425
+ throw new IntermediaryError("Invalid amount returned (zero or negative)");
426
+
427
+ if(invoiceCreateService.minMsats!=null) {
428
+ if(prepareResp.amount < invoiceCreateService.minMsats / 1000n) throw new UserError("Amount less than minimum");
429
+ }
430
+ if(invoiceCreateService.maxMSats!=null) {
431
+ if(prepareResp.amount > invoiceCreateService.maxMSats / 1000n) throw new UserError("Amount more than maximum");
432
+ }
433
+
434
+ const invoice = await invoiceCreateService.getInvoice(Number(prepareResp.amount), abortController.signal);
435
+ const parsedInvoice = bolt11Decode(invoice);
436
+
437
+ const resp = await tryWithRetries(
438
+ (retryCount: number) => IntermediaryAPI.initToBTCLNExactIn(lp.url, {
439
+ pr: invoice,
440
+ reqId: prepareResp.reqId,
441
+ feeRate: throwIfUndefined(preFetches.feeRatePromise),
442
+ additionalParams
443
+ }, this.options.postRequestTimeout, abortController.signal, retryCount>0 ? false : undefined),
444
+ undefined, RequestError, abortController.signal
445
+ );
446
+
447
+ if(parsedInvoice.millisatoshis==null) throw new Error("Swap invoice doesn't have msat amount field!");
448
+ const amountOut: bigint = (BigInt(parsedInvoice.millisatoshis) + 999n) / 1000n;
449
+ const totalFee: bigint = resp.swapFee + resp.maxFee;
450
+ const data: T["Data"] = new this.swapDataDeserializer(resp.data);
451
+ data.setOfferer(signer);
452
+
453
+ await this.verifyReturnedData(signer, resp, parsedInvoice, amountData.token, lp, options, data, amountData.amount);
454
+
455
+ const [pricingInfo, signatureExpiry, reputation] = await Promise.all([
456
+ this.verifyReturnedPrice(
457
+ lp.services[SwapType.TO_BTCLN], true, prepareResp.amount, data.getAmount(),
458
+ amountData.token, {networkFee: resp.maxFee},
459
+ preFetches.pricePreFetchPromise, preFetches.usdPricePrefetchPromise, abortSignal
460
+ ),
461
+ this.verifyReturnedSignature(
462
+ signer, data, resp, preFetches.feeRatePromise, signDataPromise, abortController.signal
463
+ ),
464
+ reputationPromise
465
+ ]);
466
+ abortController.signal.throwIfAborted();
467
+
468
+ if(reputation!=null) lp.reputation[amountData.token.toString()] = reputation;
469
+
470
+ const swapFeeBtc = resp.swapFee * amountOut / (data.getAmount() - totalFee);
471
+
472
+ const quote = new ToBTCLNSwap<T>(this, {
473
+ pricingInfo,
474
+ url: lp.url,
475
+ expiry: signatureExpiry,
476
+ swapFee: resp.swapFee,
477
+ swapFeeBtc,
478
+ feeRate: (await preFetches.feeRatePromise)!,
479
+ signatureData: resp,
480
+ data,
481
+ networkFee: resp.maxFee,
482
+ networkFeeBtc: resp.routingFeeSats,
483
+ confidence: resp.confidence,
484
+ pr: invoice,
485
+ exactIn: true
486
+ } as IToBTCSwapInit<T["Data"]>);
487
+ await quote._save();
488
+ return quote;
489
+ } catch (e) {
490
+ abortController.abort(e);
491
+ throw e;
492
+ }
493
+ }
494
+
495
+ /**
496
+ * Returns a newly created swap, allowing exactIn swaps with invoice creation service
497
+ *
498
+ * @param signer Smartchain signer's address initiating the swap
499
+ * @param invoiceCreateServicePromise
500
+ * @param amountData Amount of token & amount to swap
501
+ * @param lps LPs (liquidity providers/intermediaries) to get the quotes from
502
+ * @param options Quote options
503
+ * @param additionalParams Additional parameters sent to the intermediary when creating the swap
504
+ * @param abortSignal Abort signal for aborting the process
505
+ */
506
+ async createViaInvoiceCreateService(
507
+ signer: string,
508
+ invoiceCreateServicePromise: Promise<InvoiceCreateService>,
509
+ amountData: AmountData,
510
+ lps: Intermediary[],
511
+ options?: ToBTCLNOptions,
512
+ additionalParams?: Record<string, any>,
513
+ abortSignal?: AbortSignal
514
+ ): Promise<{
515
+ quote: Promise<ToBTCLNSwap<T>>,
516
+ intermediary: Intermediary
517
+ }[]> {
518
+ if(!this.isInitialized) throw new Error("Not initialized, call init() first!");
519
+
520
+ const _abortController = extendAbortController(abortSignal);
521
+ const pricePreFetchPromise: Promise<bigint | undefined> = this.preFetchPrice(amountData, _abortController.signal);
522
+ const usdPricePrefetchPromise: Promise<number | undefined> = this.preFetchUsdPrice(_abortController.signal);
523
+ const feeRatePromise: Promise<string | undefined> = this.preFetchFeeRate(signer, amountData, undefined, _abortController);
524
+ const signDataPrefetchPromise: Promise<T["PreFetchVerification"] | undefined> | undefined = this.contract.preFetchBlockDataForSignatures==null ?
525
+ this.preFetchSignData(Promise.resolve(true)) :
526
+ undefined;
527
+
528
+ const _options = this.toRequiredSwapOptions(amountData, options, pricePreFetchPromise, _abortController.signal);
529
+
530
+ try {
531
+ const invoiceCreateService = await invoiceCreateServicePromise;
532
+
533
+ if(amountData.exactIn) {
534
+ const dummyInvoice = await invoiceCreateService.getInvoice(
535
+ invoiceCreateService.minMsats==null ? 1 : Number(invoiceCreateService.minMsats/1000n),
536
+ _abortController.signal
537
+ );
538
+
539
+ return lps.map(lp => {
540
+ return {
541
+ quote: this.getIntermediaryQuoteExactIn(signer, amountData, invoiceCreateService, lp, dummyInvoice, _options, {
542
+ pricePreFetchPromise,
543
+ usdPricePrefetchPromise,
544
+ feeRatePromise
545
+ }, _abortController.signal, additionalParams),
546
+ intermediary: lp
547
+ }
548
+ })
549
+ } else {
550
+ if(invoiceCreateService.minMsats!=null) {
551
+ if(amountData.amount < invoiceCreateService.minMsats / 1000n) throw new UserError("Amount less than minimum");
552
+ }
553
+ if(invoiceCreateService.maxMSats!=null) {
554
+ if(amountData.amount > invoiceCreateService.maxMSats / 1000n) throw new UserError("Amount more than maximum");
555
+ }
556
+
557
+ const invoice = await invoiceCreateService.getInvoice(Number(amountData.amount), _abortController.signal);
558
+
559
+ return (await this.create(signer, invoice, amountData, lps, options, additionalParams, _abortController.signal, {
560
+ feeRatePromise,
561
+ pricePreFetchPromise,
562
+ usdPricePrefetchPromise,
563
+ signDataPrefetchPromise
564
+ }));
565
+ }
566
+ } catch (e) {
567
+ _abortController.abort(e);
568
+ throw e;
569
+ }
570
+ }
571
+
572
+ /**
573
+ * Returns a newly created swap, paying for 'lnurl' - a lightning LNURL-pay
574
+ *
575
+ * @param signer Smartchain signer's address initiating the swap
576
+ * @param lnurl LMURL-pay you wish to pay
577
+ * @param amountData Amount of token & amount to swap
578
+ * @param lps LPs (liquidity providers/intermediaries) to get the quotes from
579
+ * @param options Quote options
580
+ * @param additionalParams Additional parameters sent to the intermediary when creating the swap
581
+ * @param abortSignal Abort signal for aborting the process
582
+ */
583
+ async createViaLNURL(
584
+ signer: string,
585
+ lnurl: string | LNURLPayParamsWithUrl,
586
+ amountData: AmountData,
587
+ lps: Intermediary[],
588
+ options?: ToBTCLNOptions & {comment?: string},
589
+ additionalParams?: Record<string, any>,
590
+ abortSignal?: AbortSignal
591
+ ): Promise<{
592
+ quote: Promise<ToBTCLNSwap<T>>,
593
+ intermediary: Intermediary
594
+ }[]> {
595
+ let successActions: {[pr: string]: LNURLPaySuccessAction} = {};
596
+
597
+ const _abortController = extendAbortController(abortSignal);
598
+ const invoiceCreateService = (async() => {
599
+ let payRequest: LNURLPayParamsWithUrl = await this.getLNURLPay(lnurl, _abortController.signal);
600
+
601
+ if(
602
+ options?.comment!=null &&
603
+ (payRequest.commentAllowed==null || options.comment.length>payRequest.commentAllowed)
604
+ ) throw new UserError("Comment not allowed or too long");
605
+
606
+ return {
607
+ getInvoice: async (amountSats: number, abortSignal?: AbortSignal) => {
608
+ const {invoice, successAction} = await LNURL.useLNURLPay(
609
+ payRequest, BigInt(amountSats), options?.comment,
610
+ this.options.getRequestTimeout, abortSignal
611
+ );
612
+ if(successAction!=null) successActions[invoice] = successAction;
613
+ return invoice;
614
+ },
615
+ minMsats: BigInt(payRequest.minSendable),
616
+ maxMsats: BigInt(payRequest.maxSendable),
617
+ url: payRequest.url
618
+ }
619
+ })();
620
+
621
+ const quotes = await this.createViaInvoiceCreateService(
622
+ signer,
623
+ invoiceCreateService,
624
+ amountData,
625
+ lps,
626
+ options,
627
+ additionalParams,
628
+ _abortController.signal
629
+ );
630
+ _abortController.signal.throwIfAborted();
631
+
632
+ const resolved = await invoiceCreateService;
633
+ _abortController.signal.throwIfAborted();
634
+
635
+ return quotes.map(value => ({
636
+ quote: value.quote.then(quote => {
637
+ quote.lnurl = resolved.url;
638
+ const quoteAddress = quote.getOutputAddress();
639
+ if(quoteAddress!=null) {
640
+ const successAction = successActions[quoteAddress];
641
+ if(successAction!=null) quote.successAction = successAction;
642
+ }
643
+ return quote;
644
+ }),
645
+ intermediary: value.intermediary
646
+ }));
647
+ }
648
+
649
+ async recoverFromSwapDataAndState(
650
+ init: {data: T["Data"], getInitTxId: () => Promise<string>, getTxBlock: () => Promise<{blockTime: number, blockHeight: number}>},
651
+ state: SwapCommitState,
652
+ lp?: Intermediary
653
+ ): Promise<ToBTCLNSwap<T> | null> {
654
+ const data = init.data;
655
+
656
+ let paymentHash = data.getHTLCHashHint();
657
+ let secret: string | undefined;
658
+ if(state.type===SwapCommitStateType.PAID) {
659
+ secret = await state.getClaimResult();
660
+ paymentHash = Buffer.from(sha256(Buffer.from(secret, "hex"))).toString("hex");
661
+ }
662
+
663
+ const swap = new ToBTCLNSwap(this, {
664
+ pricingInfo: {
665
+ isValid: true,
666
+ satsBaseFee: 0n,
667
+ swapPriceUSatPerToken: 100_000_000_000_000n,
668
+ realPriceUSatPerToken: 100_000_000_000_000n,
669
+ differencePPM: 0n,
670
+ feePPM: 0n,
671
+ },
672
+ url: lp?.url,
673
+ expiry: 0,
674
+ swapFee: 0n,
675
+ swapFeeBtc: 0n,
676
+ feeRate: "",
677
+ signatureData: undefined,
678
+ data,
679
+ networkFee: 0n,
680
+ networkFeeBtc: 0n,
681
+ confidence: 0,
682
+ pr: paymentHash,
683
+ exactIn: false
684
+ } as IToBTCSwapInit<T["Data"]>);
685
+ swap.commitTxId = await init.getInitTxId();
686
+ const blockData = await init.getTxBlock();
687
+ swap.createdAt = blockData.blockTime * 1000;
688
+ swap._setInitiated();
689
+
690
+ switch(state.type) {
691
+ case SwapCommitStateType.PAID:
692
+ secret ??= await state.getClaimResult();
693
+ await swap._setPaymentResult({secret}, false);
694
+ swap.claimTxId = await state.getClaimTxId();
695
+ swap.state = ToBTCSwapState.CLAIMED;
696
+ break;
697
+ case SwapCommitStateType.NOT_COMMITED:
698
+ case SwapCommitStateType.EXPIRED:
699
+ if(state.getRefundTxId==null) return null;
700
+ swap.refundTxId = await state.getRefundTxId();
701
+ swap.state = ToBTCSwapState.REFUNDED;
702
+ break;
703
+ case SwapCommitStateType.COMMITED:
704
+ swap.state = ToBTCSwapState.COMMITED;
705
+ //Try to fetch refund signature
706
+ if(lp!=null) await swap._sync(false, false, state);
707
+ break;
708
+ case SwapCommitStateType.REFUNDABLE:
709
+ swap.state = ToBTCSwapState.REFUNDABLE;
710
+ break;
711
+ }
712
+ await swap._save();
713
+ return swap;
714
+ }
715
+
716
+ }