@atomiqlabs/sdk 7.0.11 → 8.0.7

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} +40 -22
  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} +116 -75
  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,1566 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Swapper = void 0;
4
+ const base_1 = require("@atomiqlabs/base");
5
+ const ToBTCLNWrapper_1 = require("../swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper");
6
+ const ToBTCWrapper_1 = require("../swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper");
7
+ const FromBTCLNWrapper_1 = require("../swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper");
8
+ const FromBTCWrapper_1 = require("../swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper");
9
+ const IntermediaryDiscovery_1 = require("../intermediaries/IntermediaryDiscovery");
10
+ const bolt11_1 = require("@atomiqlabs/bolt11");
11
+ const IntermediaryError_1 = require("../errors/IntermediaryError");
12
+ const SwapType_1 = require("../enums/SwapType");
13
+ const LnForGasWrapper_1 = require("../swaps/trusted/ln/LnForGasWrapper");
14
+ const events_1 = require("events");
15
+ const Utils_1 = require("../utils/Utils");
16
+ const RequestError_1 = require("../errors/RequestError");
17
+ const SwapperWithChain_1 = require("./SwapperWithChain");
18
+ const OnchainForGasWrapper_1 = require("../swaps/trusted/onchain/OnchainForGasWrapper");
19
+ const utils_1 = require("@scure/btc-signer/utils");
20
+ const UnifiedSwapStorage_1 = require("../storage/UnifiedSwapStorage");
21
+ const UnifiedSwapEventListener_1 = require("../events/UnifiedSwapEventListener");
22
+ const SpvFromBTCWrapper_1 = require("../swaps/spv_swaps/SpvFromBTCWrapper");
23
+ const SwapperUtils_1 = require("./SwapperUtils");
24
+ const FromBTCLNAutoWrapper_1 = require("../swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper");
25
+ const UserError_1 = require("../errors/UserError");
26
+ const AutomaticClockDriftCorrection_1 = require("../utils/AutomaticClockDriftCorrection");
27
+ const SwapUtils_1 = require("../utils/SwapUtils");
28
+ const MempoolBtcRelaySynchronizer_1 = require("../bitcoin/mempool/synchronizer/MempoolBtcRelaySynchronizer");
29
+ const IndexedDBUnifiedStorage_1 = require("../storage-browser/IndexedDBUnifiedStorage");
30
+ const TokenAmount_1 = require("../types/TokenAmount");
31
+ const Token_1 = require("../types/Token");
32
+ const Logger_1 = require("../utils/Logger");
33
+ const LNURLWithdraw_1 = require("../types/lnurl/LNURLWithdraw");
34
+ const LNURLPay_1 = require("../types/lnurl/LNURLPay");
35
+ const RetryUtils_1 = require("../utils/RetryUtils");
36
+ /**
37
+ * Core orchestrator for all swap operations with multi-chain support
38
+ * @category Core
39
+ */
40
+ class Swapper extends events_1.EventEmitter {
41
+ constructor(bitcoinRpc, chainsData, pricing, tokens, messenger, options) {
42
+ super();
43
+ this.logger = (0, Logger_1.getLogger)(this.constructor.name + ": ");
44
+ this.initialized = false;
45
+ this.SwapTypeInfo = {
46
+ [SwapType_1.SwapType.TO_BTC]: {
47
+ requiresInputWallet: true,
48
+ requiresOutputWallet: false,
49
+ supportsGasDrop: false
50
+ },
51
+ [SwapType_1.SwapType.TO_BTCLN]: {
52
+ requiresInputWallet: true,
53
+ requiresOutputWallet: false,
54
+ supportsGasDrop: false
55
+ },
56
+ [SwapType_1.SwapType.FROM_BTC]: {
57
+ requiresInputWallet: false,
58
+ requiresOutputWallet: true,
59
+ supportsGasDrop: false
60
+ },
61
+ [SwapType_1.SwapType.FROM_BTCLN]: {
62
+ requiresInputWallet: false,
63
+ requiresOutputWallet: true,
64
+ supportsGasDrop: false
65
+ },
66
+ [SwapType_1.SwapType.SPV_VAULT_FROM_BTC]: {
67
+ requiresInputWallet: true,
68
+ requiresOutputWallet: false,
69
+ supportsGasDrop: true
70
+ },
71
+ [SwapType_1.SwapType.FROM_BTCLN_AUTO]: {
72
+ requiresInputWallet: false,
73
+ requiresOutputWallet: false,
74
+ supportsGasDrop: true
75
+ },
76
+ [SwapType_1.SwapType.TRUSTED_FROM_BTC]: {
77
+ requiresInputWallet: false,
78
+ requiresOutputWallet: false,
79
+ supportsGasDrop: false
80
+ },
81
+ [SwapType_1.SwapType.TRUSTED_FROM_BTCLN]: {
82
+ requiresInputWallet: false,
83
+ requiresOutputWallet: false,
84
+ supportsGasDrop: false
85
+ }
86
+ };
87
+ const storagePrefix = options?.storagePrefix ?? "atomiq-";
88
+ options ??= {};
89
+ options.bitcoinNetwork = options.bitcoinNetwork == null ? base_1.BitcoinNetwork.TESTNET : options.bitcoinNetwork;
90
+ const swapStorage = options.swapStorage ??= (name) => new IndexedDBUnifiedStorage_1.IndexedDBUnifiedStorage(name);
91
+ this.options = options;
92
+ this._bitcoinNetwork = options.bitcoinNetwork;
93
+ this.bitcoinNetwork = options.bitcoinNetwork === base_1.BitcoinNetwork.MAINNET ? utils_1.NETWORK :
94
+ (options.bitcoinNetwork === base_1.BitcoinNetwork.TESTNET || options.bitcoinNetwork === base_1.BitcoinNetwork.TESTNET4) ? utils_1.TEST_NETWORK : {
95
+ bech32: 'bcrt',
96
+ pubKeyHash: 111,
97
+ scriptHash: 196,
98
+ wif: 239
99
+ };
100
+ this.Utils = new SwapperUtils_1.SwapperUtils(this);
101
+ this.prices = pricing;
102
+ this.bitcoinRpc = bitcoinRpc;
103
+ this.mempoolApi = bitcoinRpc.api;
104
+ this.messenger = messenger;
105
+ this.tokens = {};
106
+ this.tokensByTicker = {};
107
+ for (let tokenData of tokens) {
108
+ for (let chainId in tokenData.chains) {
109
+ const chainData = tokenData.chains[chainId];
110
+ this.tokens[chainId] ??= {};
111
+ this.tokensByTicker[chainId] ??= {};
112
+ this.tokens[chainId][chainData.address] = this.tokensByTicker[chainId][tokenData.ticker] = {
113
+ chain: "SC",
114
+ chainId,
115
+ ticker: tokenData.ticker,
116
+ name: tokenData.name,
117
+ decimals: chainData.decimals,
118
+ displayDecimals: chainData.displayDecimals,
119
+ address: chainData.address
120
+ };
121
+ }
122
+ }
123
+ this.swapStateListener = (swap) => {
124
+ this.emit("swapState", swap);
125
+ };
126
+ this.chains = (0, Utils_1.objectMap)(chainsData, (chainData, key) => {
127
+ const { swapContract, chainEvents, btcRelay, chainInterface, spvVaultContract, spvVaultWithdrawalDataConstructor } = chainData;
128
+ const synchronizer = new MempoolBtcRelaySynchronizer_1.MempoolBtcRelaySynchronizer(btcRelay, bitcoinRpc);
129
+ const storageHandler = swapStorage(storagePrefix + chainData.chainId);
130
+ const unifiedSwapStorage = new UnifiedSwapStorage_1.UnifiedSwapStorage(storageHandler, this.options.noSwapCache);
131
+ const unifiedChainEvents = new UnifiedSwapEventListener_1.UnifiedSwapEventListener(unifiedSwapStorage, chainEvents);
132
+ const wrappers = {};
133
+ wrappers[SwapType_1.SwapType.TO_BTCLN] = new ToBTCLNWrapper_1.ToBTCLNWrapper(key, unifiedSwapStorage, unifiedChainEvents, chainInterface, swapContract, pricing, tokens, chainData.swapDataConstructor, {
134
+ getRequestTimeout: this.options.getRequestTimeout,
135
+ postRequestTimeout: this.options.postRequestTimeout,
136
+ });
137
+ wrappers[SwapType_1.SwapType.TO_BTC] = new ToBTCWrapper_1.ToBTCWrapper(key, unifiedSwapStorage, unifiedChainEvents, chainInterface, swapContract, pricing, tokens, chainData.swapDataConstructor, this.bitcoinRpc, {
138
+ getRequestTimeout: this.options.getRequestTimeout,
139
+ postRequestTimeout: this.options.postRequestTimeout,
140
+ bitcoinNetwork: this.bitcoinNetwork
141
+ });
142
+ wrappers[SwapType_1.SwapType.FROM_BTCLN] = new FromBTCLNWrapper_1.FromBTCLNWrapper(key, unifiedSwapStorage, unifiedChainEvents, chainInterface, swapContract, pricing, tokens, chainData.swapDataConstructor, bitcoinRpc, {
143
+ getRequestTimeout: this.options.getRequestTimeout,
144
+ postRequestTimeout: this.options.postRequestTimeout,
145
+ unsafeSkipLnNodeCheck: this._bitcoinNetwork === base_1.BitcoinNetwork.TESTNET4 || this._bitcoinNetwork === base_1.BitcoinNetwork.REGTEST
146
+ });
147
+ wrappers[SwapType_1.SwapType.FROM_BTC] = new FromBTCWrapper_1.FromBTCWrapper(key, unifiedSwapStorage, unifiedChainEvents, chainInterface, swapContract, pricing, tokens, chainData.swapDataConstructor, btcRelay, synchronizer, this.bitcoinRpc, {
148
+ getRequestTimeout: this.options.getRequestTimeout,
149
+ postRequestTimeout: this.options.postRequestTimeout,
150
+ bitcoinNetwork: this.bitcoinNetwork
151
+ });
152
+ wrappers[SwapType_1.SwapType.TRUSTED_FROM_BTCLN] = new LnForGasWrapper_1.LnForGasWrapper(key, unifiedSwapStorage, unifiedChainEvents, chainInterface, pricing, tokens, {
153
+ getRequestTimeout: this.options.getRequestTimeout,
154
+ postRequestTimeout: this.options.postRequestTimeout
155
+ });
156
+ wrappers[SwapType_1.SwapType.TRUSTED_FROM_BTC] = new OnchainForGasWrapper_1.OnchainForGasWrapper(key, unifiedSwapStorage, unifiedChainEvents, chainInterface, pricing, tokens, bitcoinRpc, {
157
+ getRequestTimeout: this.options.getRequestTimeout,
158
+ postRequestTimeout: this.options.postRequestTimeout,
159
+ bitcoinNetwork: this.bitcoinNetwork
160
+ });
161
+ if (spvVaultContract != null) {
162
+ wrappers[SwapType_1.SwapType.SPV_VAULT_FROM_BTC] = new SpvFromBTCWrapper_1.SpvFromBTCWrapper(key, unifiedSwapStorage, unifiedChainEvents, chainInterface, spvVaultContract, pricing, tokens, spvVaultWithdrawalDataConstructor, btcRelay, synchronizer, bitcoinRpc, {
163
+ getRequestTimeout: this.options.getRequestTimeout,
164
+ postRequestTimeout: this.options.postRequestTimeout,
165
+ bitcoinNetwork: this.bitcoinNetwork
166
+ });
167
+ }
168
+ if (swapContract.supportsInitWithoutClaimer) {
169
+ wrappers[SwapType_1.SwapType.FROM_BTCLN_AUTO] = new FromBTCLNAutoWrapper_1.FromBTCLNAutoWrapper(key, unifiedSwapStorage, unifiedChainEvents, chainInterface, swapContract, pricing, tokens, chainData.swapDataConstructor, bitcoinRpc, this.messenger, {
170
+ getRequestTimeout: this.options.getRequestTimeout,
171
+ postRequestTimeout: this.options.postRequestTimeout,
172
+ unsafeSkipLnNodeCheck: this._bitcoinNetwork === base_1.BitcoinNetwork.TESTNET4 || this._bitcoinNetwork === base_1.BitcoinNetwork.REGTEST
173
+ });
174
+ }
175
+ Object.keys(wrappers).forEach(key => wrappers[key].events.on("swapState", this.swapStateListener));
176
+ const reviver = (val) => {
177
+ const wrapper = wrappers[val.type];
178
+ if (wrapper == null)
179
+ return null;
180
+ return new wrapper.swapDeserializer(wrapper, val);
181
+ };
182
+ return {
183
+ chainEvents,
184
+ spvVaultContract,
185
+ swapContract,
186
+ chainInterface,
187
+ btcRelay,
188
+ synchronizer,
189
+ wrappers,
190
+ unifiedChainEvents,
191
+ unifiedSwapStorage,
192
+ reviver
193
+ };
194
+ });
195
+ const contracts = (0, Utils_1.objectMap)(chainsData, (data) => data.swapContract);
196
+ if (options.intermediaryUrl != null) {
197
+ this.intermediaryDiscovery = new IntermediaryDiscovery_1.IntermediaryDiscovery(contracts, options.registryUrl, Array.isArray(options.intermediaryUrl) ? options.intermediaryUrl : [options.intermediaryUrl], options.getRequestTimeout);
198
+ }
199
+ else {
200
+ this.intermediaryDiscovery = new IntermediaryDiscovery_1.IntermediaryDiscovery(contracts, options.registryUrl, undefined, options.getRequestTimeout);
201
+ }
202
+ this.intermediaryDiscovery.on("removed", (intermediaries) => {
203
+ this.emit("lpsRemoved", intermediaries);
204
+ });
205
+ this.intermediaryDiscovery.on("added", (intermediaries) => {
206
+ this.emit("lpsAdded", intermediaries);
207
+ });
208
+ }
209
+ async _init() {
210
+ this.logger.debug("init(): Initializing swapper, sdk-lib version 16.1.3");
211
+ const abortController = new AbortController();
212
+ const promises = [];
213
+ let automaticClockDriftCorrectionPromise = undefined;
214
+ if (this.options.automaticClockDriftCorrection) {
215
+ promises.push(automaticClockDriftCorrectionPromise = (0, RetryUtils_1.tryWithRetries)(AutomaticClockDriftCorrection_1.correctClock, undefined, undefined, abortController.signal).catch((err) => {
216
+ abortController.abort(err);
217
+ }));
218
+ }
219
+ this.logger.debug("init(): Initializing intermediary discovery");
220
+ if (!this.options.dontFetchLPs)
221
+ promises.push(this.intermediaryDiscovery.init(abortController.signal).catch(err => {
222
+ if (abortController.signal.aborted)
223
+ return;
224
+ this.logger.error("init(): Failed to fetch intermediaries/LPs: ", err);
225
+ }));
226
+ if (this.options.defaultTrustedIntermediaryUrl != null) {
227
+ promises.push(this.intermediaryDiscovery.getIntermediary(this.options.defaultTrustedIntermediaryUrl, abortController.signal)
228
+ .then(val => {
229
+ if (val == null)
230
+ throw new Error("Cannot get trusted LP");
231
+ this.defaultTrustedIntermediary = val;
232
+ })
233
+ .catch(err => {
234
+ if (abortController.signal.aborted)
235
+ return;
236
+ this.logger.error("init(): Failed to contact trusted LP url: ", err);
237
+ }));
238
+ }
239
+ if (automaticClockDriftCorrectionPromise != null) {
240
+ //We should await the promises here before checking the swaps
241
+ await automaticClockDriftCorrectionPromise;
242
+ }
243
+ const chainPromises = [];
244
+ for (let chainIdentifier in this.chains) {
245
+ chainPromises.push((async () => {
246
+ const { swapContract, unifiedChainEvents, unifiedSwapStorage, wrappers, reviver } = this.chains[chainIdentifier];
247
+ await swapContract.start();
248
+ this.logger.debug("init(): Intialized swap contract: " + chainIdentifier);
249
+ await unifiedSwapStorage.init();
250
+ if (unifiedSwapStorage.storage instanceof IndexedDBUnifiedStorage_1.IndexedDBUnifiedStorage) {
251
+ //Try to migrate the data here
252
+ const storagePrefix = chainIdentifier === "SOLANA" ?
253
+ "SOLv4-" + this._bitcoinNetwork + "-Swaps-" :
254
+ "atomiqsdk-" + this._bitcoinNetwork + chainIdentifier + "-Swaps-";
255
+ await unifiedSwapStorage.storage.tryMigrate([
256
+ [storagePrefix + "FromBTC", SwapType_1.SwapType.FROM_BTC],
257
+ [storagePrefix + "FromBTCLN", SwapType_1.SwapType.FROM_BTCLN],
258
+ [storagePrefix + "ToBTC", SwapType_1.SwapType.TO_BTC],
259
+ [storagePrefix + "ToBTCLN", SwapType_1.SwapType.TO_BTCLN]
260
+ ], (obj) => {
261
+ const swap = reviver(obj);
262
+ if (swap.randomNonce == null) {
263
+ const oldIdentifierHash = swap.getId();
264
+ swap.randomNonce = (0, Utils_1.randomBytes)(16).toString("hex");
265
+ const newIdentifierHash = swap.getId();
266
+ this.logger.info("init(): Found older swap version without randomNonce, replacing, old hash: " + oldIdentifierHash +
267
+ " new hash: " + newIdentifierHash);
268
+ }
269
+ return swap;
270
+ });
271
+ }
272
+ if (!this.options.noEvents)
273
+ await unifiedChainEvents.start();
274
+ this.logger.debug("init(): Intialized events: " + chainIdentifier);
275
+ for (let key in wrappers) {
276
+ // this.logger.debug("init(): Initializing "+SwapType[key]+": "+chainIdentifier);
277
+ await wrappers[key].init(this.options.noTimers, this.options.dontCheckPastSwaps);
278
+ }
279
+ })());
280
+ }
281
+ await Promise.all(chainPromises);
282
+ await Promise.all(promises);
283
+ this.logger.debug("init(): Initializing messenger");
284
+ await this.messenger.init();
285
+ }
286
+ /**
287
+ * Initializes the swap storage and loads existing swaps, needs to be called before any other action
288
+ */
289
+ async init() {
290
+ if (this.initialized)
291
+ return;
292
+ if (this.initPromise != null)
293
+ await this.initPromise;
294
+ try {
295
+ const promise = this._init();
296
+ this.initPromise = promise;
297
+ await promise;
298
+ delete this.initPromise;
299
+ this.initialized = true;
300
+ }
301
+ catch (e) {
302
+ delete this.initPromise;
303
+ throw e;
304
+ }
305
+ }
306
+ /**
307
+ * Stops listening for onchain events and closes this Swapper instance
308
+ */
309
+ async stop() {
310
+ if (this.initPromise)
311
+ await this.initPromise;
312
+ for (let chainIdentifier in this.chains) {
313
+ const { wrappers, unifiedChainEvents } = this.chains[chainIdentifier];
314
+ for (let key in wrappers) {
315
+ const wrapper = wrappers[key];
316
+ wrapper.events.removeListener("swapState", this.swapStateListener);
317
+ await wrapper.stop();
318
+ }
319
+ await unifiedChainEvents.stop();
320
+ await this.messenger.stop();
321
+ }
322
+ this.initialized = false;
323
+ }
324
+ /**
325
+ * Creates swap & handles intermediary, quote selection
326
+ *
327
+ * @param chainIdentifier
328
+ * @param create Callback to create the
329
+ * @param amountData Amount data as passed to the function
330
+ * @param swapType Swap type of the execution
331
+ * @param maxWaitTimeMS Maximum waiting time after the first intermediary returns the quote
332
+ * @private
333
+ * @throws {Error} when no intermediary was found
334
+ * @throws {Error} if the chain with the provided identifier cannot be found
335
+ */
336
+ async createSwap(chainIdentifier, create, amountData, swapType, maxWaitTimeMS = 2000) {
337
+ if (!this.initialized)
338
+ throw new Error("Swapper not initialized, init first with swapper.init()!");
339
+ if (this.chains[chainIdentifier] == null)
340
+ throw new Error("Invalid chain identifier! Unknown chain: " + chainIdentifier);
341
+ let candidates;
342
+ const inBtc = swapType === SwapType_1.SwapType.TO_BTCLN || swapType === SwapType_1.SwapType.TO_BTC ? !amountData.exactIn : amountData.exactIn;
343
+ if (!inBtc) {
344
+ //Get candidates not based on the amount
345
+ candidates = this.intermediaryDiscovery.getSwapCandidates(chainIdentifier, swapType, amountData.token);
346
+ }
347
+ else {
348
+ candidates = this.intermediaryDiscovery.getSwapCandidates(chainIdentifier, swapType, amountData.token, amountData.amount);
349
+ }
350
+ let swapLimitsChanged = false;
351
+ if (candidates.length === 0) {
352
+ this.logger.warn("createSwap(): No valid intermediary found, reloading intermediary database...");
353
+ await this.intermediaryDiscovery.reloadIntermediaries();
354
+ swapLimitsChanged = true;
355
+ if (!inBtc) {
356
+ //Get candidates not based on the amount
357
+ candidates = this.intermediaryDiscovery.getSwapCandidates(chainIdentifier, swapType, amountData.token);
358
+ }
359
+ else {
360
+ candidates = this.intermediaryDiscovery.getSwapCandidates(chainIdentifier, swapType, amountData.token, amountData.amount);
361
+ if (candidates.length === 0) {
362
+ const min = this.intermediaryDiscovery.getSwapMinimum(chainIdentifier, swapType, amountData.token);
363
+ const max = this.intermediaryDiscovery.getSwapMaximum(chainIdentifier, swapType, amountData.token);
364
+ if (min != null && max != null) {
365
+ if (amountData.amount < BigInt(min))
366
+ throw new RequestError_1.OutOfBoundsError("Amount too low!", 200, BigInt(min), BigInt(max));
367
+ if (amountData.amount > BigInt(max))
368
+ throw new RequestError_1.OutOfBoundsError("Amount too high!", 200, BigInt(min), BigInt(max));
369
+ }
370
+ }
371
+ }
372
+ if (candidates.length === 0)
373
+ throw new Error("No intermediary found!");
374
+ }
375
+ const abortController = new AbortController();
376
+ this.logger.debug("createSwap() Swap candidates: ", candidates.map(lp => lp.url).join());
377
+ const quotePromises = await create(candidates, abortController.signal, this.chains[chainIdentifier]);
378
+ const promiseAll = new Promise((resolve, reject) => {
379
+ let min;
380
+ let max;
381
+ let error;
382
+ let numResolved = 0;
383
+ let quotes = [];
384
+ let timeout;
385
+ quotePromises.forEach(data => {
386
+ data.quote.then(quote => {
387
+ if (numResolved === 0) {
388
+ timeout = setTimeout(() => {
389
+ abortController.abort(new Error("Timed out waiting for quote!"));
390
+ resolve(quotes);
391
+ }, maxWaitTimeMS);
392
+ }
393
+ numResolved++;
394
+ quotes.push({
395
+ quote,
396
+ intermediary: data.intermediary
397
+ });
398
+ if (numResolved === quotePromises.length) {
399
+ clearTimeout(timeout);
400
+ resolve(quotes);
401
+ return;
402
+ }
403
+ }).catch(e => {
404
+ numResolved++;
405
+ if (e instanceof IntermediaryError_1.IntermediaryError) {
406
+ //Blacklist that node
407
+ this.intermediaryDiscovery.removeIntermediary(data.intermediary);
408
+ swapLimitsChanged = true;
409
+ }
410
+ else if (e instanceof RequestError_1.OutOfBoundsError) {
411
+ if (min == null || max == null) {
412
+ min = e.min;
413
+ max = e.max;
414
+ }
415
+ else {
416
+ min = (0, Utils_1.bigIntMin)(min, e.min);
417
+ max = (0, Utils_1.bigIntMax)(max, e.max);
418
+ }
419
+ data.intermediary.swapBounds[swapType] ??= {};
420
+ data.intermediary.swapBounds[swapType][chainIdentifier] ??= {};
421
+ const tokenBoundsData = (data.intermediary.swapBounds[swapType][chainIdentifier][amountData.token] ??= { input: {}, output: {} });
422
+ if (amountData.exactIn) {
423
+ tokenBoundsData.input = { min: e.min, max: e.max };
424
+ }
425
+ else {
426
+ tokenBoundsData.output = { min: e.min, max: e.max };
427
+ }
428
+ swapLimitsChanged = true;
429
+ }
430
+ this.logger.warn("createSwap(): Intermediary " + data.intermediary.url + " error: ", e);
431
+ error = e;
432
+ if (numResolved === quotePromises.length) {
433
+ if (timeout != null)
434
+ clearTimeout(timeout);
435
+ if (quotes.length > 0) {
436
+ resolve(quotes);
437
+ return;
438
+ }
439
+ if (min != null && max != null) {
440
+ reject(new RequestError_1.OutOfBoundsError("Out of bounds", 400, min, max));
441
+ return;
442
+ }
443
+ reject(error);
444
+ }
445
+ });
446
+ });
447
+ });
448
+ try {
449
+ const quotes = await promiseAll;
450
+ //TODO: Intermediary's reputation is not taken into account!
451
+ quotes.sort((a, b) => {
452
+ if (amountData.exactIn) {
453
+ //Compare outputs
454
+ return (0, Utils_1.bigIntCompare)(b.quote.getOutput().rawAmount, a.quote.getOutput().rawAmount);
455
+ }
456
+ else {
457
+ //Compare inputs
458
+ return (0, Utils_1.bigIntCompare)(a.quote.getInput().rawAmount, b.quote.getInput().rawAmount);
459
+ }
460
+ });
461
+ this.logger.debug("createSwap(): Sorted quotes, best price to worst: ", quotes);
462
+ if (swapLimitsChanged)
463
+ this.emit("swapLimitsChanged");
464
+ const quote = quotes[0].quote;
465
+ if (this.options.saveUninitializedSwaps) {
466
+ quote._setInitiated();
467
+ await quote._save();
468
+ }
469
+ return quote;
470
+ }
471
+ catch (e) {
472
+ if (swapLimitsChanged)
473
+ this.emit("swapLimitsChanged");
474
+ throw e;
475
+ }
476
+ }
477
+ /**
478
+ * Creates To BTC swap
479
+ *
480
+ * @param chainIdentifier
481
+ * @param signer
482
+ * @param tokenAddress Token address to pay with
483
+ * @param address Recipient's bitcoin address
484
+ * @param amount Amount to send in satoshis (bitcoin's smallest denomination)
485
+ * @param exactIn Whether to use exact in instead of exact out
486
+ * @param additionalParams Additional parameters sent to the LP when creating the swap
487
+ * @param options
488
+ */
489
+ createToBTCSwap(chainIdentifier, signer, tokenAddress, address, amount, exactIn = false, additionalParams = this.options.defaultAdditionalParameters, options) {
490
+ if (this.chains[chainIdentifier] == null)
491
+ throw new Error("Invalid chain identifier! Unknown chain: " + chainIdentifier);
492
+ if (address.startsWith("bitcoin:")) {
493
+ address = address.substring(8).split("?")[0];
494
+ }
495
+ if (!this.Utils.isValidBitcoinAddress(address))
496
+ throw new Error("Invalid bitcoin address");
497
+ if (!this.chains[chainIdentifier].chainInterface.isValidAddress(signer, true))
498
+ throw new Error("Invalid " + chainIdentifier + " address");
499
+ signer = this.chains[chainIdentifier].chainInterface.normalizeAddress(signer);
500
+ options ??= {};
501
+ options.confirmationTarget ??= 3;
502
+ options.confirmations ??= 2;
503
+ const amountData = {
504
+ amount,
505
+ token: tokenAddress,
506
+ exactIn
507
+ };
508
+ return this.createSwap(chainIdentifier, (candidates, abortSignal, chain) => Promise.resolve(chain.wrappers[SwapType_1.SwapType.TO_BTC].create(signer, address, amountData, candidates, options, additionalParams, abortSignal)), amountData, SwapType_1.SwapType.TO_BTC);
509
+ }
510
+ /**
511
+ * Creates To BTCLN swap
512
+ *
513
+ * @param chainIdentifier
514
+ * @param signer
515
+ * @param tokenAddress Token address to pay with
516
+ * @param paymentRequest BOLT11 lightning network invoice to be paid (needs to have a fixed amount)
517
+ * @param additionalParams Additional parameters sent to the LP when creating the swap
518
+ * @param options
519
+ */
520
+ async createToBTCLNSwap(chainIdentifier, signer, tokenAddress, paymentRequest, additionalParams = this.options.defaultAdditionalParameters, options) {
521
+ if (this.chains[chainIdentifier] == null)
522
+ throw new Error("Invalid chain identifier! Unknown chain: " + chainIdentifier);
523
+ options ??= {};
524
+ if (paymentRequest.startsWith("lightning:"))
525
+ paymentRequest = paymentRequest.substring(10);
526
+ if (!this.Utils.isValidLightningInvoice(paymentRequest))
527
+ throw new Error("Invalid lightning network invoice");
528
+ if (!this.chains[chainIdentifier].chainInterface.isValidAddress(signer, true))
529
+ throw new Error("Invalid " + chainIdentifier + " address");
530
+ signer = this.chains[chainIdentifier].chainInterface.normalizeAddress(signer);
531
+ const parsedPR = (0, bolt11_1.decode)(paymentRequest);
532
+ if (parsedPR.millisatoshis == null)
533
+ throw new Error("Invalid lightning network invoice, no msat value field!");
534
+ const amountData = {
535
+ amount: (BigInt(parsedPR.millisatoshis) + 999n) / 1000n,
536
+ token: tokenAddress,
537
+ exactIn: false
538
+ };
539
+ options.expirySeconds ??= 5 * 24 * 3600;
540
+ return this.createSwap(chainIdentifier, (candidates, abortSignal, chain) => chain.wrappers[SwapType_1.SwapType.TO_BTCLN].create(signer, paymentRequest, amountData, candidates, options, additionalParams, abortSignal), amountData, SwapType_1.SwapType.TO_BTCLN);
541
+ }
542
+ /**
543
+ * Creates To BTCLN swap via LNURL-pay
544
+ *
545
+ * @param chainIdentifier
546
+ * @param signer
547
+ * @param tokenAddress Token address to pay with
548
+ * @param lnurlPay LNURL-pay link to use for the payment
549
+ * @param amount Amount to be paid in sats
550
+ * @param exactIn Whether to do an exact in swap instead of exact out
551
+ * @param additionalParams Additional parameters sent to the LP when creating the swap
552
+ * @param options
553
+ */
554
+ async createToBTCLNSwapViaLNURL(chainIdentifier, signer, tokenAddress, lnurlPay, amount, exactIn = false, additionalParams = this.options.defaultAdditionalParameters, options) {
555
+ if (this.chains[chainIdentifier] == null)
556
+ throw new Error("Invalid chain identifier! Unknown chain: " + chainIdentifier);
557
+ if (typeof (lnurlPay) === "string" && !this.Utils.isValidLNURL(lnurlPay))
558
+ throw new Error("Invalid LNURL-pay link");
559
+ if (!this.chains[chainIdentifier].chainInterface.isValidAddress(signer, true))
560
+ throw new Error("Invalid " + chainIdentifier + " address");
561
+ signer = this.chains[chainIdentifier].chainInterface.normalizeAddress(signer);
562
+ const amountData = {
563
+ amount,
564
+ token: tokenAddress,
565
+ exactIn
566
+ };
567
+ options ??= {};
568
+ options.expirySeconds ??= 5 * 24 * 3600;
569
+ return this.createSwap(chainIdentifier, (candidates, abortSignal, chain) => chain.wrappers[SwapType_1.SwapType.TO_BTCLN].createViaLNURL(signer, typeof (lnurlPay) === "string" ? (lnurlPay.startsWith("lightning:") ? lnurlPay.substring(10) : lnurlPay) : lnurlPay.params, amountData, candidates, options, additionalParams, abortSignal), amountData, SwapType_1.SwapType.TO_BTCLN);
570
+ }
571
+ /**
572
+ * Creates To BTCLN swap via InvoiceCreationService
573
+ *
574
+ * @param chainIdentifier
575
+ * @param signer
576
+ * @param tokenAddress Token address to pay with
577
+ * @param service Invoice create service object which facilitates the creation of fixed amount LN invoices
578
+ * @param amount Amount to be paid in sats
579
+ * @param exactIn Whether to do an exact in swap instead of exact out
580
+ * @param additionalParams Additional parameters sent to the LP when creating the swap
581
+ * @param options
582
+ */
583
+ async createToBTCLNSwapViaInvoiceCreateService(chainIdentifier, signer, tokenAddress, service, amount, exactIn = false, additionalParams = this.options.defaultAdditionalParameters, options) {
584
+ if (this.chains[chainIdentifier] == null)
585
+ throw new Error("Invalid chain identifier! Unknown chain: " + chainIdentifier);
586
+ if (!this.chains[chainIdentifier].chainInterface.isValidAddress(signer, true))
587
+ throw new Error("Invalid " + chainIdentifier + " address");
588
+ signer = this.chains[chainIdentifier].chainInterface.normalizeAddress(signer);
589
+ options ??= {};
590
+ const amountData = {
591
+ amount,
592
+ token: tokenAddress,
593
+ exactIn
594
+ };
595
+ options.expirySeconds ??= 5 * 24 * 3600;
596
+ return this.createSwap(chainIdentifier, (candidates, abortSignal, chain) => chain.wrappers[SwapType_1.SwapType.TO_BTCLN].createViaInvoiceCreateService(signer, Promise.resolve(service), amountData, candidates, options, additionalParams, abortSignal), amountData, SwapType_1.SwapType.TO_BTCLN);
597
+ }
598
+ /**
599
+ * Creates From BTC swap
600
+ *
601
+ * @param chainIdentifier
602
+ * @param signer
603
+ * @param tokenAddress Token address to receive
604
+ * @param amount Amount to receive, in satoshis (bitcoin's smallest denomination)
605
+ * @param exactOut Whether to use a exact out instead of exact in
606
+ * @param additionalParams Additional parameters sent to the LP when creating the swap
607
+ * @param options
608
+ */
609
+ async createFromBTCSwapNew(chainIdentifier, signer, tokenAddress, amount, exactOut = false, additionalParams = this.options.defaultAdditionalParameters, options) {
610
+ if (this.chains[chainIdentifier] == null)
611
+ throw new Error("Invalid chain identifier! Unknown chain: " + chainIdentifier);
612
+ if (!this.chains[chainIdentifier].chainInterface.isValidAddress(signer, true))
613
+ throw new Error("Invalid " + chainIdentifier + " address");
614
+ signer = this.chains[chainIdentifier].chainInterface.normalizeAddress(signer);
615
+ const amountData = {
616
+ amount,
617
+ token: tokenAddress,
618
+ exactIn: !exactOut
619
+ };
620
+ return this.createSwap(chainIdentifier, (candidates, abortSignal, chain) => Promise.resolve(chain.wrappers[SwapType_1.SwapType.SPV_VAULT_FROM_BTC].create(signer, amountData, candidates, options, additionalParams, abortSignal)), amountData, SwapType_1.SwapType.SPV_VAULT_FROM_BTC);
621
+ }
622
+ /**
623
+ * Creates From BTC swap
624
+ *
625
+ * @param chainIdentifier
626
+ * @param signer
627
+ * @param tokenAddress Token address to receive
628
+ * @param amount Amount to receive, in satoshis (bitcoin's smallest denomination)
629
+ * @param exactOut Whether to use a exact out instead of exact in
630
+ * @param additionalParams Additional parameters sent to the LP when creating the swap
631
+ * @param options
632
+ */
633
+ async createFromBTCSwap(chainIdentifier, signer, tokenAddress, amount, exactOut = false, additionalParams = this.options.defaultAdditionalParameters, options) {
634
+ if (this.chains[chainIdentifier] == null)
635
+ throw new Error("Invalid chain identifier! Unknown chain: " + chainIdentifier);
636
+ if (!this.chains[chainIdentifier].chainInterface.isValidAddress(signer, true))
637
+ throw new Error("Invalid " + chainIdentifier + " address");
638
+ signer = this.chains[chainIdentifier].chainInterface.normalizeAddress(signer);
639
+ const amountData = {
640
+ amount,
641
+ token: tokenAddress,
642
+ exactIn: !exactOut
643
+ };
644
+ return this.createSwap(chainIdentifier, (candidates, abortSignal, chain) => Promise.resolve(chain.wrappers[SwapType_1.SwapType.FROM_BTC].create(signer, amountData, candidates, options, additionalParams, abortSignal)), amountData, SwapType_1.SwapType.FROM_BTC);
645
+ }
646
+ /**
647
+ * Creates From BTCLN swap
648
+ *
649
+ * @param chainIdentifier
650
+ * @param signer
651
+ * @param tokenAddress Token address to receive
652
+ * @param amount Amount to receive, in satoshis (bitcoin's smallest denomination)
653
+ * @param exactOut Whether to use exact out instead of exact in
654
+ * @param additionalParams Additional parameters sent to the LP when creating the swap
655
+ * @param options
656
+ */
657
+ async createFromBTCLNSwap(chainIdentifier, signer, tokenAddress, amount, exactOut = false, additionalParams = this.options.defaultAdditionalParameters, options) {
658
+ if (this.chains[chainIdentifier] == null)
659
+ throw new Error("Invalid chain identifier! Unknown chain: " + chainIdentifier);
660
+ if (!this.chains[chainIdentifier].chainInterface.isValidAddress(signer, true))
661
+ throw new Error("Invalid " + chainIdentifier + " address");
662
+ signer = this.chains[chainIdentifier].chainInterface.normalizeAddress(signer);
663
+ const amountData = {
664
+ amount,
665
+ token: tokenAddress,
666
+ exactIn: !exactOut
667
+ };
668
+ return this.createSwap(chainIdentifier, (candidates, abortSignal, chain) => Promise.resolve(chain.wrappers[SwapType_1.SwapType.FROM_BTCLN].create(signer, amountData, candidates, options, additionalParams, abortSignal)), amountData, SwapType_1.SwapType.FROM_BTCLN);
669
+ }
670
+ /**
671
+ * Creates From BTCLN swap, withdrawing from LNURL-withdraw
672
+ *
673
+ * @param chainIdentifier
674
+ * @param signer
675
+ * @param tokenAddress Token address to receive
676
+ * @param lnurl LNURL-withdraw to pull the funds from
677
+ * @param amount Amount to receive, in satoshis (bitcoin's smallest denomination)
678
+ * @param exactOut Whether to use exact out instead of exact in
679
+ * @param additionalParams Additional parameters sent to the LP when creating the swap
680
+ */
681
+ async createFromBTCLNSwapViaLNURL(chainIdentifier, signer, tokenAddress, lnurl, amount, exactOut = false, additionalParams = this.options.defaultAdditionalParameters) {
682
+ if (this.chains[chainIdentifier] == null)
683
+ throw new Error("Invalid chain identifier! Unknown chain: " + chainIdentifier);
684
+ if (typeof (lnurl) === "string" && !this.Utils.isValidLNURL(lnurl))
685
+ throw new Error("Invalid LNURL-withdraw link");
686
+ if (!this.chains[chainIdentifier].chainInterface.isValidAddress(signer, true))
687
+ throw new Error("Invalid " + chainIdentifier + " address");
688
+ signer = this.chains[chainIdentifier].chainInterface.normalizeAddress(signer);
689
+ const amountData = {
690
+ amount,
691
+ token: tokenAddress,
692
+ exactIn: !exactOut
693
+ };
694
+ return this.createSwap(chainIdentifier, (candidates, abortSignal, chain) => chain.wrappers[SwapType_1.SwapType.FROM_BTCLN].createViaLNURL(signer, typeof (lnurl) === "string" ? (lnurl.startsWith("lightning:") ? lnurl.substring(10) : lnurl) : lnurl.params, amountData, candidates, additionalParams, abortSignal), amountData, SwapType_1.SwapType.FROM_BTCLN);
695
+ }
696
+ /**
697
+ * Creates From BTCLN swap using new protocol
698
+ *
699
+ * @param chainIdentifier
700
+ * @param signer
701
+ * @param tokenAddress Token address to receive
702
+ * @param amount Amount to receive, in satoshis (bitcoin's smallest denomination)
703
+ * @param exactOut Whether to use exact out instead of exact in
704
+ * @param additionalParams Additional parameters sent to the LP when creating the swap
705
+ * @param options
706
+ */
707
+ async createFromBTCLNSwapNew(chainIdentifier, signer, tokenAddress, amount, exactOut = false, additionalParams = this.options.defaultAdditionalParameters, options) {
708
+ if (this.chains[chainIdentifier] == null)
709
+ throw new Error("Invalid chain identifier! Unknown chain: " + chainIdentifier);
710
+ if (!this.chains[chainIdentifier].chainInterface.isValidAddress(signer, true))
711
+ throw new Error("Invalid " + chainIdentifier + " address");
712
+ signer = this.chains[chainIdentifier].chainInterface.normalizeAddress(signer);
713
+ const amountData = {
714
+ amount,
715
+ token: tokenAddress,
716
+ exactIn: !exactOut
717
+ };
718
+ return this.createSwap(chainIdentifier, (candidates, abortSignal, chain) => Promise.resolve(chain.wrappers[SwapType_1.SwapType.FROM_BTCLN_AUTO].create(signer, amountData, candidates, options, additionalParams, abortSignal)), amountData, SwapType_1.SwapType.FROM_BTCLN_AUTO);
719
+ }
720
+ /**
721
+ * Creates From BTCLN swap using new protocol, withdrawing from LNURL-withdraw
722
+ *
723
+ * @param chainIdentifier
724
+ * @param signer
725
+ * @param tokenAddress Token address to receive
726
+ * @param lnurl LNURL-withdraw to pull the funds from
727
+ * @param amount Amount to receive, in satoshis (bitcoin's smallest denomination)
728
+ * @param exactOut Whether to use exact out instead of exact in
729
+ * @param additionalParams Additional parameters sent to the LP when creating the swap
730
+ * @param options
731
+ */
732
+ async createFromBTCLNSwapNewViaLNURL(chainIdentifier, signer, tokenAddress, lnurl, amount, exactOut = false, additionalParams = this.options.defaultAdditionalParameters, options) {
733
+ if (this.chains[chainIdentifier] == null)
734
+ throw new Error("Invalid chain identifier! Unknown chain: " + chainIdentifier);
735
+ if (typeof (lnurl) === "string" && !this.Utils.isValidLNURL(lnurl))
736
+ throw new Error("Invalid LNURL-withdraw link");
737
+ if (!this.chains[chainIdentifier].chainInterface.isValidAddress(signer, true))
738
+ throw new Error("Invalid " + chainIdentifier + " address");
739
+ signer = this.chains[chainIdentifier].chainInterface.normalizeAddress(signer);
740
+ const amountData = {
741
+ amount,
742
+ token: tokenAddress,
743
+ exactIn: !exactOut
744
+ };
745
+ return this.createSwap(chainIdentifier, (candidates, abortSignal, chain) => chain.wrappers[SwapType_1.SwapType.FROM_BTCLN_AUTO].createViaLNURL(signer, typeof (lnurl) === "string" ? (lnurl.startsWith("lightning:") ? lnurl.substring(10) : lnurl) : lnurl.params, amountData, candidates, options, additionalParams, abortSignal), amountData, SwapType_1.SwapType.FROM_BTCLN_AUTO);
746
+ }
747
+ /**
748
+ * Creates trusted LN for Gas swap
749
+ *
750
+ * @param chainId
751
+ * @param signer
752
+ * @param amount Amount of native token to receive, in base units
753
+ * @param trustedIntermediaryOrUrl URL or Intermediary object of the trusted intermediary to use, otherwise uses default
754
+ * @throws {Error} If no trusted intermediary specified
755
+ */
756
+ createTrustedLNForGasSwap(chainId, signer, amount, trustedIntermediaryOrUrl) {
757
+ if (this.chains[chainId] == null)
758
+ throw new Error("Invalid chain identifier! Unknown chain: " + chainId);
759
+ if (!this.chains[chainId].chainInterface.isValidAddress(signer, true))
760
+ throw new Error("Invalid " + chainId + " address");
761
+ signer = this.chains[chainId].chainInterface.normalizeAddress(signer);
762
+ const useUrl = trustedIntermediaryOrUrl ?? this.defaultTrustedIntermediary ?? this.options.defaultTrustedIntermediaryUrl;
763
+ if (useUrl == null)
764
+ throw new Error("No trusted intermediary specified!");
765
+ return this.chains[chainId].wrappers[SwapType_1.SwapType.TRUSTED_FROM_BTCLN].create(signer, amount, useUrl);
766
+ }
767
+ /**
768
+ * Creates trusted BTC on-chain for Gas swap
769
+ *
770
+ * @param chainId
771
+ * @param signer
772
+ * @param amount Amount of native token to receive, in base units
773
+ * @param refundAddress Bitcoin refund address, in case the swap fails
774
+ * @param trustedIntermediaryOrUrl URL or Intermediary object of the trusted intermediary to use, otherwise uses default
775
+ * @throws {Error} If no trusted intermediary specified
776
+ */
777
+ createTrustedOnchainForGasSwap(chainId, signer, amount, refundAddress, trustedIntermediaryOrUrl) {
778
+ if (this.chains[chainId] == null)
779
+ throw new Error("Invalid chain identifier! Unknown chain: " + chainId);
780
+ if (!this.chains[chainId].chainInterface.isValidAddress(signer, true))
781
+ throw new Error("Invalid " + chainId + " address");
782
+ signer = this.chains[chainId].chainInterface.normalizeAddress(signer);
783
+ const useUrl = trustedIntermediaryOrUrl ?? this.defaultTrustedIntermediary ?? this.options.defaultTrustedIntermediaryUrl;
784
+ if (useUrl == null)
785
+ throw new Error("No trusted intermediary specified!");
786
+ return this.chains[chainId].wrappers[SwapType_1.SwapType.TRUSTED_FROM_BTC].create(signer, amount, useUrl, refundAddress);
787
+ }
788
+ /**
789
+ * Creates a swap from srcToken to dstToken, of a specific token amount, either specifying input amount (exactIn=true)
790
+ * or output amount (exactIn=false), NOTE: For regular -> BTC-LN (lightning) swaps the passed amount is ignored and
791
+ * invoice's pre-set amount is used instead.
792
+ * @deprecated Use swap() instead
793
+ *
794
+ * @param signer Smartchain (Solana, Starknet, etc.) address of the user
795
+ * @param srcToken Source token of the swap, user pays this token
796
+ * @param dstToken Destination token of the swap, user receives this token
797
+ * @param amount Amount of the swap
798
+ * @param exactIn Whether the amount specified is an input amount (exactIn=true) or an output amount (exactIn=false)
799
+ * @param addressLnurlLightningInvoice Bitcoin on-chain address, lightning invoice, LNURL-pay to pay or
800
+ * LNURL-withdrawal to withdraw money from
801
+ */
802
+ create(signer, srcToken, dstToken, amount, exactIn, addressLnurlLightningInvoice) {
803
+ if (srcToken.chain === "BTC") {
804
+ return this.swap(srcToken, dstToken, amount, exactIn, addressLnurlLightningInvoice, signer);
805
+ }
806
+ else {
807
+ return this.swap(srcToken, dstToken, amount, exactIn, signer, addressLnurlLightningInvoice);
808
+ }
809
+ }
810
+ /**
811
+ * Creates a swap from srcToken to dstToken, of a specific token amount, either specifying input amount (exactIn=true)
812
+ * or output amount (exactIn=false), NOTE: For regular SmartChain -> BTC-LN (lightning) swaps the passed amount is ignored and
813
+ * invoice's pre-set amount is used instead, use LNURL-pay for dynamic amounts
814
+ *
815
+ * @param _srcToken Source token of the swap, user pays this token
816
+ * @param _dstToken Destination token of the swap, user receives this token
817
+ * @param _amount Amount of the swap either in base units as {bigint} or in human readable format (with decimals) as {string}
818
+ * @param exactIn Whether the amount specified is an input amount (exactIn=true) or an output amount (exactIn=false)
819
+ * @param src Source wallet/lnurl-withdraw of the swap
820
+ * @param dst Destination smart chain address, bitcoin on-chain address, lightning invoice, LNURL-pay
821
+ * @param options Options for the swap
822
+ */
823
+ swap(_srcToken, _dstToken, _amount, exactIn, src, dst, options) {
824
+ const srcToken = typeof (_srcToken) === "string" ? this.getToken(_srcToken) : _srcToken;
825
+ const dstToken = typeof (_dstToken) === "string" ? this.getToken(_dstToken) : _dstToken;
826
+ const amount = _amount == null ? null : (typeof (_amount) === "bigint" ? _amount : (0, Utils_1.fromDecimal)(_amount, exactIn ? srcToken.decimals : dstToken.decimals));
827
+ if (srcToken.chain === "BTC") {
828
+ if (dstToken.chain === "SC") {
829
+ if (typeof (dst) !== "string")
830
+ throw new Error("Destination for BTC/BTC-LN -> smart chain swaps must be a smart chain address!");
831
+ if (amount == null)
832
+ throw new Error("Amount cannot be null for from btc swaps!");
833
+ if (srcToken.lightning) {
834
+ //FROM_BTCLN
835
+ if (src != null) {
836
+ if (typeof (src) !== "string" && !(0, LNURLWithdraw_1.isLNURLWithdraw)(src))
837
+ throw new Error("LNURL must be a string or LNURLWithdraw object!");
838
+ return this.supportsSwapType(dstToken.chainId, SwapType_1.SwapType.FROM_BTCLN_AUTO) ?
839
+ this.createFromBTCLNSwapNewViaLNURL(dstToken.chainId, dst, dstToken.address, src, amount, !exactIn, undefined, options) :
840
+ this.createFromBTCLNSwapViaLNURL(dstToken.chainId, dst, dstToken.address, src, amount, !exactIn);
841
+ }
842
+ else {
843
+ return this.supportsSwapType(dstToken.chainId, SwapType_1.SwapType.FROM_BTCLN_AUTO) ?
844
+ this.createFromBTCLNSwapNew(dstToken.chainId, dst, dstToken.address, amount, !exactIn, undefined, options) :
845
+ this.createFromBTCLNSwap(dstToken.chainId, dst, dstToken.address, amount, !exactIn, undefined, options);
846
+ }
847
+ }
848
+ else {
849
+ //FROM_BTC
850
+ if (this.supportsSwapType(dstToken.chainId, SwapType_1.SwapType.SPV_VAULT_FROM_BTC)) {
851
+ return this.createFromBTCSwapNew(dstToken.chainId, dst, dstToken.address, amount, !exactIn, undefined, options);
852
+ }
853
+ else {
854
+ return this.createFromBTCSwap(dstToken.chainId, dst, dstToken.address, amount, !exactIn, undefined, options);
855
+ }
856
+ }
857
+ }
858
+ }
859
+ else {
860
+ if (dstToken.chain === "BTC") {
861
+ if (typeof (src) !== "string")
862
+ throw new Error("Source address for BTC/BTC-LN -> smart chain swaps must be a smart chain address!");
863
+ if (dstToken.lightning) {
864
+ //TO_BTCLN
865
+ if (typeof (dst) !== "string" && !(0, LNURLPay_1.isLNURLPay)(dst))
866
+ throw new Error("Destination LNURL link/lightning invoice must be a string or LNURLPay object!");
867
+ if ((0, LNURLPay_1.isLNURLPay)(dst) || this.Utils.isValidLNURL(dst)) {
868
+ if (amount == null)
869
+ throw new Error("Amount cannot be null for to btcln swaps via LNURL-pay!");
870
+ return this.createToBTCLNSwapViaLNURL(srcToken.chainId, src, srcToken.address, dst, amount, !!exactIn, undefined, options);
871
+ }
872
+ else if ((0, ToBTCLNWrapper_1.isInvoiceCreateService)(dst)) {
873
+ if (amount == null)
874
+ throw new Error("Amount cannot be null for to btcln swaps via InvoiceCreateService!");
875
+ return this.createToBTCLNSwapViaInvoiceCreateService(srcToken.chainId, src, srcToken.address, dst, amount, !!exactIn, undefined, options);
876
+ }
877
+ else if (this.Utils.isLightningInvoice(dst)) {
878
+ if (!this.Utils.isValidLightningInvoice(dst))
879
+ throw new Error("Invalid lightning invoice specified, lightning invoice MUST contain pre-set amount!");
880
+ if (exactIn)
881
+ throw new Error("Only exact out swaps are possible with lightning invoices, use LNURL links for exact in lightning swaps!");
882
+ return this.createToBTCLNSwap(srcToken.chainId, src, srcToken.address, dst, undefined, options);
883
+ }
884
+ else {
885
+ throw new Error("Supplied parameter is not LNURL link nor lightning invoice (bolt11)!");
886
+ }
887
+ }
888
+ else {
889
+ //TO_BTC
890
+ if (typeof (dst) !== "string")
891
+ throw new Error("Destination bitcoin address must be a string!");
892
+ if (amount == null)
893
+ throw new Error("Amount cannot be null for to btc swaps!");
894
+ return this.createToBTCSwap(srcToken.chainId, src, srcToken.address, dst, amount, !!exactIn, undefined, options);
895
+ }
896
+ }
897
+ }
898
+ throw new Error("Unsupported swap type");
899
+ }
900
+ async getAllSwaps(chainId, signer) {
901
+ const queryParams = [];
902
+ if (signer != null)
903
+ queryParams.push({ key: "initiator", value: signer });
904
+ if (chainId == null) {
905
+ const res = await Promise.all(Object.keys(this.chains).map((chainId) => {
906
+ const { unifiedSwapStorage, reviver } = this.chains[chainId];
907
+ return unifiedSwapStorage.query([queryParams], reviver);
908
+ }));
909
+ return res.flat();
910
+ }
911
+ else {
912
+ const { unifiedSwapStorage, reviver } = this.chains[chainId];
913
+ return await unifiedSwapStorage.query([queryParams], reviver);
914
+ }
915
+ }
916
+ async getActionableSwaps(chainId, signer) {
917
+ if (chainId == null) {
918
+ const res = await Promise.all(Object.keys(this.chains).map((chainId) => {
919
+ const { unifiedSwapStorage, reviver, wrappers } = this.chains[chainId];
920
+ const queryParams = [];
921
+ for (let key in wrappers) {
922
+ const wrapper = wrappers[key];
923
+ const swapTypeQueryParams = [{ key: "type", value: wrapper.TYPE }];
924
+ if (signer != null)
925
+ swapTypeQueryParams.push({ key: "initiator", value: signer });
926
+ swapTypeQueryParams.push({ key: "state", value: wrapper.pendingSwapStates });
927
+ queryParams.push(swapTypeQueryParams);
928
+ }
929
+ return unifiedSwapStorage.query(queryParams, reviver);
930
+ }));
931
+ return res.flat().filter(swap => swap.requiresAction());
932
+ }
933
+ else {
934
+ const { unifiedSwapStorage, reviver, wrappers } = this.chains[chainId];
935
+ const queryParams = [];
936
+ for (let key in wrappers) {
937
+ const wrapper = wrappers[key];
938
+ const swapTypeQueryParams = [{ key: "type", value: wrapper.TYPE }];
939
+ if (signer != null)
940
+ swapTypeQueryParams.push({ key: "initiator", value: signer });
941
+ swapTypeQueryParams.push({ key: "state", value: wrapper.pendingSwapStates });
942
+ queryParams.push(swapTypeQueryParams);
943
+ }
944
+ return (await unifiedSwapStorage.query(queryParams, reviver)).filter(swap => swap.requiresAction());
945
+ }
946
+ }
947
+ async getRefundableSwaps(chainId, signer) {
948
+ if (chainId == null) {
949
+ const res = await Promise.all(Object.keys(this.chains).map((chainId) => {
950
+ const { unifiedSwapStorage, reviver, wrappers } = this.chains[chainId];
951
+ const queryParams = [];
952
+ for (let wrapper of [wrappers[SwapType_1.SwapType.TO_BTCLN], wrappers[SwapType_1.SwapType.TO_BTC]]) {
953
+ const swapTypeQueryParams = [{ key: "type", value: wrapper.TYPE }];
954
+ if (signer != null)
955
+ swapTypeQueryParams.push({ key: "initiator", value: signer });
956
+ swapTypeQueryParams.push({ key: "state", value: wrapper.refundableSwapStates });
957
+ queryParams.push(swapTypeQueryParams);
958
+ }
959
+ return unifiedSwapStorage.query(queryParams, reviver);
960
+ }));
961
+ return res.flat().filter(swap => swap.isRefundable());
962
+ }
963
+ else {
964
+ const { unifiedSwapStorage, reviver, wrappers } = this.chains[chainId];
965
+ const queryParams = [];
966
+ for (let wrapper of [wrappers[SwapType_1.SwapType.TO_BTCLN], wrappers[SwapType_1.SwapType.TO_BTC]]) {
967
+ const swapTypeQueryParams = [{ key: "type", value: wrapper.TYPE }];
968
+ if (signer != null)
969
+ swapTypeQueryParams.push({ key: "initiator", value: signer });
970
+ swapTypeQueryParams.push({ key: "state", value: wrapper.refundableSwapStates });
971
+ queryParams.push(swapTypeQueryParams);
972
+ }
973
+ const result = await unifiedSwapStorage.query(queryParams, reviver);
974
+ return result.filter(swap => swap.isRefundable());
975
+ }
976
+ }
977
+ async getClaimableSwaps(chainId, signer) {
978
+ if (chainId == null) {
979
+ const res = await Promise.all(Object.keys(this.chains).map((chainId) => {
980
+ const { unifiedSwapStorage, reviver, wrappers } = this.chains[chainId];
981
+ const queryParams = [];
982
+ for (let wrapper of [wrappers[SwapType_1.SwapType.FROM_BTC], wrappers[SwapType_1.SwapType.FROM_BTCLN], wrappers[SwapType_1.SwapType.SPV_VAULT_FROM_BTC], wrappers[SwapType_1.SwapType.FROM_BTCLN_AUTO]]) {
983
+ if (wrapper == null)
984
+ continue;
985
+ const swapTypeQueryParams = [{ key: "type", value: wrapper.TYPE }];
986
+ if (signer != null)
987
+ swapTypeQueryParams.push({ key: "initiator", value: signer });
988
+ swapTypeQueryParams.push({ key: "state", value: wrapper.claimableSwapStates });
989
+ queryParams.push(swapTypeQueryParams);
990
+ }
991
+ return unifiedSwapStorage.query(queryParams, reviver);
992
+ }));
993
+ return res.flat().filter(swap => swap.isClaimable());
994
+ }
995
+ else {
996
+ const { unifiedSwapStorage, reviver, wrappers } = this.chains[chainId];
997
+ const queryParams = [];
998
+ for (let wrapper of [wrappers[SwapType_1.SwapType.FROM_BTC], wrappers[SwapType_1.SwapType.FROM_BTCLN], wrappers[SwapType_1.SwapType.SPV_VAULT_FROM_BTC], wrappers[SwapType_1.SwapType.FROM_BTCLN_AUTO]]) {
999
+ if (wrapper == null)
1000
+ continue;
1001
+ const swapTypeQueryParams = [{ key: "type", value: wrapper.TYPE }];
1002
+ if (signer != null)
1003
+ swapTypeQueryParams.push({ key: "initiator", value: signer });
1004
+ swapTypeQueryParams.push({ key: "state", value: wrapper.claimableSwapStates });
1005
+ queryParams.push(swapTypeQueryParams);
1006
+ }
1007
+ const result = await unifiedSwapStorage.query(queryParams, reviver);
1008
+ return result.filter(swap => swap.isClaimable());
1009
+ }
1010
+ }
1011
+ async getSwapById(id, chainId, signer) {
1012
+ //Check in pending swaps first
1013
+ if (chainId != null) {
1014
+ for (let key in this.chains[chainId].wrappers) {
1015
+ const wrapper = this.chains[chainId].wrappers[key];
1016
+ const result = wrapper.pendingSwaps.get(id)?.deref();
1017
+ if (result != null) {
1018
+ if (signer != null) {
1019
+ if (result._getInitiator() === signer)
1020
+ return result;
1021
+ }
1022
+ else {
1023
+ return result;
1024
+ }
1025
+ }
1026
+ }
1027
+ }
1028
+ else {
1029
+ for (let chainId in this.chains) {
1030
+ for (let key in this.chains[chainId].wrappers) {
1031
+ const wrapper = this.chains[chainId].wrappers[key];
1032
+ const result = wrapper.pendingSwaps.get(id)?.deref();
1033
+ if (result != null) {
1034
+ if (signer != null) {
1035
+ if (result._getInitiator() === signer)
1036
+ return result;
1037
+ }
1038
+ else {
1039
+ return result;
1040
+ }
1041
+ }
1042
+ }
1043
+ }
1044
+ }
1045
+ const queryParams = [];
1046
+ if (signer != null)
1047
+ queryParams.push({ key: "initiator", value: signer });
1048
+ queryParams.push({ key: "id", value: id });
1049
+ if (chainId == null) {
1050
+ const res = await Promise.all(Object.keys(this.chains).map((chainId) => {
1051
+ const { unifiedSwapStorage, reviver } = this.chains[chainId];
1052
+ return unifiedSwapStorage.query([queryParams], reviver);
1053
+ }));
1054
+ return res.flat()[0];
1055
+ }
1056
+ else {
1057
+ const { unifiedSwapStorage, reviver } = this.chains[chainId];
1058
+ return (await unifiedSwapStorage.query([queryParams], reviver))[0];
1059
+ }
1060
+ }
1061
+ /**
1062
+ * Returns the swap with a proper return type, or undefined, if not found, or has wrong type
1063
+ *
1064
+ * @param id
1065
+ * @param chainId
1066
+ * @param swapType
1067
+ * @param signer
1068
+ */
1069
+ async getTypedSwapById(id, chainId, swapType, signer) {
1070
+ let _swapType = swapType;
1071
+ if (swapType === SwapType_1.SwapType.FROM_BTC && this.supportsSwapType(chainId, SwapType_1.SwapType.SPV_VAULT_FROM_BTC))
1072
+ _swapType = SwapType_1.SwapType.SPV_VAULT_FROM_BTC;
1073
+ if (swapType === SwapType_1.SwapType.FROM_BTCLN && this.supportsSwapType(chainId, SwapType_1.SwapType.FROM_BTCLN_AUTO))
1074
+ _swapType = SwapType_1.SwapType.FROM_BTCLN_AUTO;
1075
+ const wrapper = this.chains[chainId].wrappers[_swapType];
1076
+ if (wrapper == null)
1077
+ return;
1078
+ const result = wrapper.pendingSwaps.get(id)?.deref();
1079
+ if (result != null) {
1080
+ if (signer != null) {
1081
+ if (result._getInitiator() === signer)
1082
+ return result;
1083
+ }
1084
+ else {
1085
+ return result;
1086
+ }
1087
+ }
1088
+ const queryParams = [];
1089
+ if (signer != null)
1090
+ queryParams.push({ key: "initiator", value: signer });
1091
+ queryParams.push({ key: "id", value: id });
1092
+ const { unifiedSwapStorage, reviver } = this.chains[chainId];
1093
+ const swap = (await unifiedSwapStorage.query([queryParams], reviver))[0];
1094
+ if ((0, SwapUtils_1.isSwapType)(swap, swapType))
1095
+ return swap;
1096
+ }
1097
+ async syncSwapsForChain(chainId, signer) {
1098
+ const { unifiedSwapStorage, reviver, wrappers } = this.chains[chainId];
1099
+ const queryParams = [];
1100
+ for (let key in wrappers) {
1101
+ const wrapper = wrappers[key];
1102
+ const swapTypeQueryParams = [{ key: "type", value: wrapper.TYPE }];
1103
+ if (signer != null)
1104
+ swapTypeQueryParams.push({ key: "initiator", value: signer });
1105
+ swapTypeQueryParams.push({ key: "state", value: wrapper.pendingSwapStates });
1106
+ queryParams.push(swapTypeQueryParams);
1107
+ }
1108
+ this.logger.debug("_syncSwaps(): Querying swaps swaps for chain " + chainId + "!");
1109
+ const swaps = await unifiedSwapStorage.query(queryParams, reviver);
1110
+ this.logger.debug("_syncSwaps(): Syncing " + swaps.length + " swaps!");
1111
+ const changedSwaps = [];
1112
+ const removeSwaps = [];
1113
+ const assortedSwaps = {};
1114
+ swaps.forEach(swap => {
1115
+ (assortedSwaps[swap.getType()] ??= []).push(swap);
1116
+ });
1117
+ for (let key in assortedSwaps) {
1118
+ const swapType = key;
1119
+ const wrapperSwaps = assortedSwaps[swapType];
1120
+ const wrapper = wrappers[swapType];
1121
+ const result = await wrapper.checkPastSwaps(wrapperSwaps, true);
1122
+ changedSwaps.push(...result.changedSwaps);
1123
+ removeSwaps.push(...result.removeSwaps);
1124
+ }
1125
+ this.logger.debug("_syncSwaps(): Done syncing " + swaps.length + " swaps, saving " + changedSwaps.length + " changed swaps, removing " + removeSwaps.length + " swaps!");
1126
+ await unifiedSwapStorage.saveAll(changedSwaps);
1127
+ await unifiedSwapStorage.removeAll(removeSwaps);
1128
+ changedSwaps.forEach(swap => swap._emitEvent());
1129
+ removeSwaps.forEach(swap => swap._emitEvent());
1130
+ }
1131
+ /**
1132
+ * Synchronizes swaps from chain, this is usually ran when SDK is initialized, deletes expired quotes
1133
+ *
1134
+ * @param chainId
1135
+ * @param signer
1136
+ */
1137
+ async _syncSwaps(chainId, signer) {
1138
+ if (chainId == null) {
1139
+ await Promise.all(Object.keys(this.chains).map((chainId) => {
1140
+ return this.syncSwapsForChain(chainId, signer);
1141
+ }));
1142
+ }
1143
+ else {
1144
+ await this.syncSwapsForChain(chainId, signer);
1145
+ }
1146
+ }
1147
+ /**
1148
+ * Attempts to recover partial swap data from on-chain historical data
1149
+ *
1150
+ * @param chainId
1151
+ * @param signer
1152
+ * @param startBlockheight
1153
+ */
1154
+ async recoverSwaps(chainId, signer, startBlockheight) {
1155
+ const { swapContract, unifiedSwapStorage, reviver, wrappers } = this.chains[chainId];
1156
+ if (swapContract.getHistoricalSwaps == null)
1157
+ throw new Error(`Historical swap recovery is not supported for ${chainId}`);
1158
+ const { swaps } = await swapContract.getHistoricalSwaps(signer);
1159
+ const escrowHashes = Object.keys(swaps);
1160
+ this.logger.debug(`recoverSwaps(): Loaded on-chain data for ${escrowHashes.length} swaps`);
1161
+ this.logger.debug(`recoverSwaps(): Fetching if swap escrowHashes are known: ${escrowHashes.join(", ")}`);
1162
+ const knownSwapsArray = await unifiedSwapStorage.query([[{ key: "escrowHash", value: escrowHashes }]], reviver);
1163
+ const knownSwaps = {};
1164
+ knownSwapsArray.forEach(val => {
1165
+ const escrowHash = val._getEscrowHash();
1166
+ if (escrowHash != null)
1167
+ knownSwaps[escrowHash] = val;
1168
+ });
1169
+ this.logger.debug(`recoverSwaps(): Fetched known swaps escrowHashes: ${Object.keys(knownSwaps).join(", ")}`);
1170
+ const recoveredSwaps = [];
1171
+ for (let escrowHash in swaps) {
1172
+ const { init, state } = swaps[escrowHash];
1173
+ const knownSwap = knownSwaps[escrowHash];
1174
+ if (init == null) {
1175
+ if (knownSwap == null)
1176
+ this.logger.warn(`recoverSwaps(): Fetched ${escrowHash} swap state, but swap not found locally!`);
1177
+ //TODO: Update the existing swaps here
1178
+ this.logger.debug(`recoverSwaps(): Skipping ${escrowHash} swap: swap already known and in local storage!`);
1179
+ continue;
1180
+ }
1181
+ if (knownSwap != null) {
1182
+ //TODO: Update the existing swaps here
1183
+ this.logger.debug(`recoverSwaps(): Skipping ${escrowHash} swap: swap already known and in local storage!`);
1184
+ continue;
1185
+ }
1186
+ const data = init.data;
1187
+ //Classify swap
1188
+ let swap;
1189
+ let typeIdentified = false;
1190
+ if (data.getType() === base_1.ChainSwapType.HTLC) {
1191
+ if (data.isOfferer(signer)) {
1192
+ //To BTCLN
1193
+ typeIdentified = true;
1194
+ const lp = this.intermediaryDiscovery.intermediaries.find(val => val.supportsChain(chainId) && data.isClaimer(val.getAddress(chainId)));
1195
+ swap = await wrappers[SwapType_1.SwapType.TO_BTCLN].recoverFromSwapDataAndState(init, state, lp);
1196
+ }
1197
+ else if (data.isClaimer(signer)) {
1198
+ //From BTCLN
1199
+ typeIdentified = true;
1200
+ const lp = this.intermediaryDiscovery.intermediaries.find(val => val.supportsChain(chainId) && data.isOfferer(val.getAddress(chainId)));
1201
+ if (this.supportsSwapType(chainId, SwapType_1.SwapType.FROM_BTCLN_AUTO)) {
1202
+ swap = await wrappers[SwapType_1.SwapType.FROM_BTCLN_AUTO].recoverFromSwapDataAndState(init, state, lp);
1203
+ }
1204
+ else {
1205
+ swap = await wrappers[SwapType_1.SwapType.FROM_BTCLN].recoverFromSwapDataAndState(init, state, lp);
1206
+ }
1207
+ }
1208
+ }
1209
+ else if (data.getType() === base_1.ChainSwapType.CHAIN_NONCED) {
1210
+ //To BTC
1211
+ typeIdentified = true;
1212
+ const lp = this.intermediaryDiscovery.intermediaries.find(val => val.supportsChain(chainId) && data.isClaimer(val.getAddress(chainId)));
1213
+ swap = await wrappers[SwapType_1.SwapType.TO_BTC].recoverFromSwapDataAndState(init, state, lp);
1214
+ }
1215
+ else if (data.getType() === base_1.ChainSwapType.CHAIN) {
1216
+ //From BTC
1217
+ typeIdentified = true;
1218
+ const lp = this.intermediaryDiscovery.intermediaries.find(val => val.supportsChain(chainId) && data.isOfferer(val.getAddress(chainId)));
1219
+ swap = await wrappers[SwapType_1.SwapType.FROM_BTC].recoverFromSwapDataAndState(init, state, lp);
1220
+ }
1221
+ if (swap != null) {
1222
+ recoveredSwaps.push(swap);
1223
+ }
1224
+ else {
1225
+ if (typeIdentified)
1226
+ this.logger.debug(`recoverSwaps(): Swap data type correctly identified but swap returned is null for swap ${escrowHash}`);
1227
+ }
1228
+ }
1229
+ this.logger.debug(`recoverSwaps(): Successfully recovered ${recoveredSwaps.length} swaps!`);
1230
+ return recoveredSwaps;
1231
+ }
1232
+ getToken(tickerOrAddress) {
1233
+ //Btc tokens - BTC, BTCLN, BTC-LN
1234
+ if (tickerOrAddress === "BTC")
1235
+ return Token_1.BitcoinTokens.BTC;
1236
+ if (tickerOrAddress === "BTCLN" || tickerOrAddress === "BTC-LN")
1237
+ return Token_1.BitcoinTokens.BTCLN;
1238
+ //Check if the ticker is in format <chainId>-<ticker>, i.e. SOLANA-USDC, STARKNET-WBTC
1239
+ if (tickerOrAddress.includes("-")) {
1240
+ const [chainId, ticker] = tickerOrAddress.split("-");
1241
+ const token = this.tokensByTicker[chainId]?.[ticker];
1242
+ if (token == null)
1243
+ throw new UserError_1.UserError(`Not found ticker: ${ticker} for chainId: ${chainId}`);
1244
+ return token;
1245
+ }
1246
+ const possibleTokens = [];
1247
+ for (let chainId in this.chains) {
1248
+ const chain = this.chains[chainId];
1249
+ if (chain.chainInterface.isValidToken(tickerOrAddress)) {
1250
+ //Try to find in known token addresses
1251
+ const token = this.tokens[chainId]?.[tickerOrAddress];
1252
+ if (token != null)
1253
+ return token;
1254
+ }
1255
+ else {
1256
+ //Check in known tickers
1257
+ const token = this.tokensByTicker[chainId]?.[tickerOrAddress];
1258
+ if (token != null)
1259
+ possibleTokens.push(token);
1260
+ }
1261
+ }
1262
+ if (possibleTokens.length === 0)
1263
+ throw new UserError_1.UserError(`Specified token address or ticker ${tickerOrAddress} not found!`);
1264
+ //In case we've found the token in multiple chains
1265
+ if (possibleTokens.length > 1)
1266
+ throw new UserError_1.UserError(`A ticker ${tickerOrAddress} has been found in multiple chains, narrow it down by using <chainId>-${tickerOrAddress} notation`);
1267
+ return possibleTokens[0];
1268
+ }
1269
+ /**
1270
+ * Creates a child swapper instance with a given smart chain
1271
+ *
1272
+ * @param chainIdentifier
1273
+ */
1274
+ withChain(chainIdentifier) {
1275
+ if (this.chains[chainIdentifier] == null)
1276
+ throw new Error("Invalid chain identifier! Unknown chain: " + chainIdentifier);
1277
+ return new SwapperWithChain_1.SwapperWithChain(this, chainIdentifier);
1278
+ }
1279
+ /**
1280
+ * Returns supported smart chains
1281
+ */
1282
+ getSmartChains() {
1283
+ return Object.keys(this.chains);
1284
+ }
1285
+ /**
1286
+ * Returns whether the SDK supports a given swap type on a given chain based on currently known LPs
1287
+ *
1288
+ * @param chainId
1289
+ * @param swapType
1290
+ */
1291
+ supportsSwapType(chainId, swapType) {
1292
+ return (this.chains[chainId]?.wrappers[swapType] != null);
1293
+ }
1294
+ getSwapType(srcToken, dstToken) {
1295
+ if ((0, Token_1.isSCToken)(srcToken)) {
1296
+ if (!(0, Token_1.isBtcToken)(dstToken))
1297
+ throw new Error("Swap not supported");
1298
+ if (dstToken.lightning) {
1299
+ return SwapType_1.SwapType.TO_BTCLN;
1300
+ }
1301
+ else {
1302
+ return SwapType_1.SwapType.TO_BTC;
1303
+ }
1304
+ }
1305
+ else if ((0, Token_1.isBtcToken)(srcToken)) {
1306
+ if (!(0, Token_1.isSCToken)(dstToken))
1307
+ throw new Error("Swap not supported");
1308
+ if (srcToken.lightning) {
1309
+ if (this.supportsSwapType(dstToken.chainId, SwapType_1.SwapType.FROM_BTCLN_AUTO)) {
1310
+ return SwapType_1.SwapType.FROM_BTCLN_AUTO;
1311
+ }
1312
+ else {
1313
+ return SwapType_1.SwapType.FROM_BTCLN;
1314
+ }
1315
+ }
1316
+ else {
1317
+ if (this.supportsSwapType(dstToken.chainId, SwapType_1.SwapType.SPV_VAULT_FROM_BTC)) {
1318
+ return SwapType_1.SwapType.SPV_VAULT_FROM_BTC;
1319
+ }
1320
+ else {
1321
+ return SwapType_1.SwapType.FROM_BTC;
1322
+ }
1323
+ }
1324
+ }
1325
+ throw new Error("Swap not supported");
1326
+ }
1327
+ /**
1328
+ * Returns minimum/maximum limits for inputs and outputs for a swap between given tokens
1329
+ *
1330
+ * @param srcToken
1331
+ * @param dstToken
1332
+ */
1333
+ getSwapLimits(srcToken, dstToken) {
1334
+ const swapType = this.getSwapType(srcToken, dstToken);
1335
+ const scToken = (0, Token_1.isSCToken)(srcToken) ? srcToken : (0, Token_1.isSCToken)(dstToken) ? dstToken : null;
1336
+ if (scToken == null)
1337
+ throw new Error("At least one token needs to be a smart chain token!");
1338
+ const result = {
1339
+ input: {},
1340
+ output: {}
1341
+ };
1342
+ for (let lp of this.intermediaryDiscovery.intermediaries) {
1343
+ const lpMinMax = lp.getSwapLimits(swapType, scToken.chainId, scToken.address);
1344
+ if (lpMinMax == null)
1345
+ continue;
1346
+ result.input.min = result.input.min == null ? lpMinMax.input.min : (0, Utils_1.bigIntMin)(result.input.min, lpMinMax.input.min);
1347
+ result.input.max = result.input.max == null ? lpMinMax.input.max : (0, Utils_1.bigIntMax)(result.input.max, lpMinMax.input.max);
1348
+ result.output.min = result.output.min == null ? lpMinMax.output.min : (0, Utils_1.bigIntMin)(result.output.min, lpMinMax.output.min);
1349
+ result.output.max = result.output.max == null ? lpMinMax.output.max : (0, Utils_1.bigIntMax)(result.output.max, lpMinMax.output.max);
1350
+ }
1351
+ return {
1352
+ input: {
1353
+ min: (0, TokenAmount_1.toTokenAmount)(result.input.min ?? 1n, srcToken, this.prices),
1354
+ max: result.input.max == null ? undefined : (0, TokenAmount_1.toTokenAmount)(result.input.max, srcToken, this.prices),
1355
+ },
1356
+ output: {
1357
+ min: (0, TokenAmount_1.toTokenAmount)(result.output.min ?? 1n, dstToken, this.prices),
1358
+ max: result.output.max == null ? undefined : (0, TokenAmount_1.toTokenAmount)(result.output.max, dstToken, this.prices),
1359
+ }
1360
+ };
1361
+ }
1362
+ /**
1363
+ * Returns supported tokens for a given direction
1364
+ *
1365
+ * @param input Whether to return input tokens or output tokens
1366
+ */
1367
+ getSupportedTokens(input) {
1368
+ const tokens = {};
1369
+ let lightning = false;
1370
+ let btc = false;
1371
+ this.intermediaryDiscovery.intermediaries.forEach(lp => {
1372
+ for (let swapType of [SwapType_1.SwapType.TO_BTC, SwapType_1.SwapType.TO_BTCLN, SwapType_1.SwapType.FROM_BTC, SwapType_1.SwapType.FROM_BTCLN, SwapType_1.SwapType.SPV_VAULT_FROM_BTC, SwapType_1.SwapType.FROM_BTCLN_AUTO]) {
1373
+ if (lp.services[swapType]?.chainTokens == null)
1374
+ continue;
1375
+ for (let chainId of this.getSmartChains()) {
1376
+ if (this.supportsSwapType(chainId, SwapType_1.SwapType.SPV_VAULT_FROM_BTC) ? swapType === SwapType_1.SwapType.FROM_BTC : swapType === SwapType_1.SwapType.SPV_VAULT_FROM_BTC)
1377
+ continue;
1378
+ if (this.supportsSwapType(chainId, SwapType_1.SwapType.FROM_BTCLN_AUTO) ? swapType === SwapType_1.SwapType.FROM_BTCLN : swapType === SwapType_1.SwapType.FROM_BTCLN_AUTO)
1379
+ continue;
1380
+ const chainTokens = lp.services[swapType]?.chainTokens?.[chainId];
1381
+ if (chainTokens == null)
1382
+ continue;
1383
+ for (let tokenAddress of chainTokens) {
1384
+ if (input) {
1385
+ if (swapType === SwapType_1.SwapType.TO_BTC || swapType === SwapType_1.SwapType.TO_BTCLN) {
1386
+ tokens[chainId] ??= new Set();
1387
+ tokens[chainId].add(tokenAddress);
1388
+ }
1389
+ if (swapType === SwapType_1.SwapType.FROM_BTCLN || swapType === SwapType_1.SwapType.FROM_BTCLN_AUTO) {
1390
+ lightning = true;
1391
+ }
1392
+ if (swapType === SwapType_1.SwapType.FROM_BTC || swapType === SwapType_1.SwapType.SPV_VAULT_FROM_BTC) {
1393
+ btc = true;
1394
+ }
1395
+ }
1396
+ else {
1397
+ if (swapType === SwapType_1.SwapType.FROM_BTCLN || swapType === SwapType_1.SwapType.FROM_BTC || swapType === SwapType_1.SwapType.SPV_VAULT_FROM_BTC || swapType === SwapType_1.SwapType.FROM_BTCLN_AUTO) {
1398
+ tokens[chainId] ??= new Set();
1399
+ tokens[chainId].add(tokenAddress);
1400
+ }
1401
+ if (swapType === SwapType_1.SwapType.TO_BTCLN) {
1402
+ lightning = true;
1403
+ }
1404
+ if (swapType === SwapType_1.SwapType.TO_BTC) {
1405
+ btc = true;
1406
+ }
1407
+ }
1408
+ }
1409
+ }
1410
+ }
1411
+ });
1412
+ const output = [];
1413
+ if (lightning)
1414
+ output.push(Token_1.BitcoinTokens.BTCLN);
1415
+ if (btc)
1416
+ output.push(Token_1.BitcoinTokens.BTC);
1417
+ for (let chainId in tokens) {
1418
+ tokens[chainId].forEach(tokenAddress => {
1419
+ const token = this.tokens?.[chainId]?.[tokenAddress];
1420
+ if (token != null)
1421
+ output.push(token);
1422
+ });
1423
+ }
1424
+ return output;
1425
+ }
1426
+ /**
1427
+ * Returns a set of supported tokens by all the intermediaries offering a specific swap service
1428
+ *
1429
+ * @param _swapType Swap service type to check supported tokens for
1430
+ */
1431
+ getSupportedTokensForSwapType(_swapType) {
1432
+ const tokens = {};
1433
+ this.intermediaryDiscovery.intermediaries.forEach(lp => {
1434
+ for (let chainId of this.getSmartChains()) {
1435
+ let swapType = _swapType;
1436
+ if (swapType === SwapType_1.SwapType.FROM_BTC && this.supportsSwapType(chainId, SwapType_1.SwapType.SPV_VAULT_FROM_BTC))
1437
+ swapType = SwapType_1.SwapType.SPV_VAULT_FROM_BTC;
1438
+ if (swapType === SwapType_1.SwapType.FROM_BTCLN && this.supportsSwapType(chainId, SwapType_1.SwapType.FROM_BTCLN_AUTO))
1439
+ swapType = SwapType_1.SwapType.FROM_BTCLN_AUTO;
1440
+ if (lp.services[swapType]?.chainTokens == null)
1441
+ break;
1442
+ const chainTokens = lp.services[swapType]?.chainTokens?.[chainId];
1443
+ if (chainTokens == null)
1444
+ continue;
1445
+ for (let tokenAddress of chainTokens) {
1446
+ tokens[chainId] ??= new Set();
1447
+ tokens[chainId].add(tokenAddress);
1448
+ }
1449
+ }
1450
+ });
1451
+ const output = [];
1452
+ for (let chainId in tokens) {
1453
+ tokens[chainId].forEach(tokenAddress => {
1454
+ const token = this.tokens?.[chainId]?.[tokenAddress];
1455
+ if (token != null)
1456
+ output.push(token);
1457
+ });
1458
+ }
1459
+ return output;
1460
+ }
1461
+ /**
1462
+ * Returns the set of supported token addresses by all the intermediaries we know of offering a specific swapType service
1463
+ *
1464
+ * @param chainIdentifier
1465
+ * @param swapType Specific swap type for which to obtain supported tokens
1466
+ */
1467
+ getSupportedTokenAddresses(chainIdentifier, swapType) {
1468
+ const set = new Set();
1469
+ this.intermediaryDiscovery.intermediaries.forEach(lp => {
1470
+ const chainTokens = lp.services[swapType]?.chainTokens?.[chainIdentifier];
1471
+ if (chainTokens == null)
1472
+ return;
1473
+ chainTokens.forEach(token => set.add(token));
1474
+ });
1475
+ return set;
1476
+ }
1477
+ /**
1478
+ * Returns tokens that you can swap to (if input=true) from a given token,
1479
+ * or tokens that you can swap from (if input=false) to a given token
1480
+ */
1481
+ getSwapCounterTokens(token, input) {
1482
+ if ((0, Token_1.isSCToken)(token)) {
1483
+ const result = [];
1484
+ if (input) {
1485
+ //TO_BTC or TO_BTCLN
1486
+ if (this.getSupportedTokenAddresses(token.chainId, SwapType_1.SwapType.TO_BTCLN).has(token.address)) {
1487
+ result.push(Token_1.BitcoinTokens.BTCLN);
1488
+ }
1489
+ if (this.getSupportedTokenAddresses(token.chainId, SwapType_1.SwapType.TO_BTC).has(token.address)) {
1490
+ result.push(Token_1.BitcoinTokens.BTC);
1491
+ }
1492
+ }
1493
+ else {
1494
+ //FROM_BTC or FROM_BTCLN
1495
+ const fromLightningSwapType = this.supportsSwapType(token.chainId, SwapType_1.SwapType.FROM_BTCLN_AUTO) ? SwapType_1.SwapType.FROM_BTCLN_AUTO : SwapType_1.SwapType.FROM_BTCLN;
1496
+ if (this.getSupportedTokenAddresses(token.chainId, fromLightningSwapType).has(token.address)) {
1497
+ result.push(Token_1.BitcoinTokens.BTCLN);
1498
+ }
1499
+ const fromOnchainSwapType = this.supportsSwapType(token.chainId, SwapType_1.SwapType.SPV_VAULT_FROM_BTC) ? SwapType_1.SwapType.SPV_VAULT_FROM_BTC : SwapType_1.SwapType.FROM_BTC;
1500
+ if (this.getSupportedTokenAddresses(token.chainId, fromOnchainSwapType).has(token.address)) {
1501
+ result.push(Token_1.BitcoinTokens.BTC);
1502
+ }
1503
+ }
1504
+ return result;
1505
+ }
1506
+ else {
1507
+ if (input) {
1508
+ if (token.lightning) {
1509
+ return this.getSupportedTokensForSwapType(SwapType_1.SwapType.FROM_BTCLN);
1510
+ }
1511
+ else {
1512
+ return this.getSupportedTokensForSwapType(SwapType_1.SwapType.FROM_BTC);
1513
+ }
1514
+ }
1515
+ else {
1516
+ if (token.lightning) {
1517
+ return this.getSupportedTokensForSwapType(SwapType_1.SwapType.TO_BTCLN);
1518
+ }
1519
+ else {
1520
+ return this.getSupportedTokensForSwapType(SwapType_1.SwapType.TO_BTC);
1521
+ }
1522
+ }
1523
+ }
1524
+ }
1525
+ getSwapBounds(chainIdentifier) {
1526
+ if (chainIdentifier == null) {
1527
+ return this.intermediaryDiscovery.getMultichainSwapBounds();
1528
+ }
1529
+ else {
1530
+ return this.intermediaryDiscovery.getSwapBounds(chainIdentifier);
1531
+ }
1532
+ }
1533
+ /**
1534
+ * Returns maximum possible swap amount
1535
+ * @deprecated Use getSwapLimits() instead!
1536
+ *
1537
+ * @param chainIdentifier
1538
+ * @param type Type of the swap
1539
+ * @param token Token of the swap
1540
+ */
1541
+ getMaximum(chainIdentifier, type, token) {
1542
+ if (this.intermediaryDiscovery != null) {
1543
+ const max = this.intermediaryDiscovery.getSwapMaximum(chainIdentifier, type, token);
1544
+ if (max != null)
1545
+ return BigInt(max);
1546
+ }
1547
+ return 0n;
1548
+ }
1549
+ /**
1550
+ * Returns minimum possible swap amount
1551
+ * @deprecated Use getSwapLimits() instead!
1552
+ *
1553
+ * @param chainIdentifier
1554
+ * @param type Type of swap
1555
+ * @param token Token of the swap
1556
+ */
1557
+ getMinimum(chainIdentifier, type, token) {
1558
+ if (this.intermediaryDiscovery != null) {
1559
+ const min = this.intermediaryDiscovery.getSwapMinimum(chainIdentifier, type, token);
1560
+ if (min != null)
1561
+ return BigInt(min);
1562
+ }
1563
+ return 0n;
1564
+ }
1565
+ }
1566
+ exports.Swapper = Swapper;