@atomiqlabs/sdk 7.0.12 → 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} +37 -19
  120. package/dist/swapper/SwapperUtils.d.ts +153 -0
  121. package/dist/swapper/SwapperUtils.js +420 -0
  122. package/dist/swapper/SwapperWithChain.d.ts +214 -0
  123. package/dist/swapper/SwapperWithChain.js +315 -0
  124. package/dist/swapper/SwapperWithSigner.d.ts +178 -0
  125. package/dist/swapper/SwapperWithSigner.js +172 -0
  126. package/dist/swaps/IAddressSwap.d.ts +13 -0
  127. package/dist/swaps/IAddressSwap.js +13 -0
  128. package/dist/swaps/IBTCWalletSwap.d.ts +55 -0
  129. package/dist/swaps/IBTCWalletSwap.js +17 -0
  130. package/dist/swaps/IClaimableSwap.d.ts +17 -0
  131. package/dist/swaps/IClaimableSwap.js +14 -0
  132. package/dist/swaps/IClaimableSwapWrapper.d.ts +5 -0
  133. package/dist/swaps/IClaimableSwapWrapper.js +2 -0
  134. package/dist/swaps/IRefundableSwap.d.ts +17 -0
  135. package/dist/swaps/IRefundableSwap.js +13 -0
  136. package/dist/swaps/ISwap.d.ts +207 -0
  137. package/dist/swaps/ISwap.js +264 -0
  138. package/dist/swaps/ISwapWithGasDrop.d.ts +15 -0
  139. package/dist/swaps/ISwapWithGasDrop.js +11 -0
  140. package/dist/swaps/ISwapWrapper.d.ts +153 -0
  141. package/dist/swaps/ISwapWrapper.js +227 -0
  142. package/dist/swaps/escrow_swaps/IEscrowSelfInitSwap.d.ts +53 -0
  143. package/dist/swaps/escrow_swaps/IEscrowSelfInitSwap.js +116 -0
  144. package/dist/swaps/escrow_swaps/IEscrowSwap.d.ts +70 -0
  145. package/dist/swaps/escrow_swaps/IEscrowSwap.js +132 -0
  146. package/dist/swaps/escrow_swaps/IEscrowSwapWrapper.d.ts +85 -0
  147. package/dist/swaps/escrow_swaps/IEscrowSwapWrapper.js +122 -0
  148. package/dist/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.d.ts +86 -0
  149. package/dist/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.js +115 -0
  150. package/dist/swaps/escrow_swaps/frombtc/IFromBTCSelfInitSwap.d.ts +93 -0
  151. package/dist/swaps/escrow_swaps/frombtc/IFromBTCSelfInitSwap.js +121 -0
  152. package/dist/swaps/escrow_swaps/frombtc/IFromBTCWrapper.d.ts +45 -0
  153. package/dist/swaps/escrow_swaps/frombtc/IFromBTCWrapper.js +65 -0
  154. package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.d.ts +263 -0
  155. package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.js +933 -0
  156. package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.d.ts +110 -0
  157. package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.js +307 -0
  158. package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.d.ts +236 -0
  159. package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.js +898 -0
  160. package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.d.ts +125 -0
  161. package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.js +393 -0
  162. package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.d.ts +245 -0
  163. package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.js +841 -0
  164. package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.d.ts +120 -0
  165. package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.js +294 -0
  166. package/dist/swaps/escrow_swaps/tobtc/IToBTCSwap.d.ts +228 -0
  167. package/dist/swaps/escrow_swaps/tobtc/IToBTCSwap.js +721 -0
  168. package/dist/swaps/escrow_swaps/tobtc/IToBTCWrapper.d.ts +37 -0
  169. package/dist/swaps/escrow_swaps/tobtc/IToBTCWrapper.js +93 -0
  170. package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNSwap.d.ts +86 -0
  171. package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNSwap.js +213 -0
  172. package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.d.ts +170 -0
  173. package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.js +520 -0
  174. package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCSwap.d.ts +50 -0
  175. package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCSwap.js +109 -0
  176. package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.d.ts +93 -0
  177. package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.js +217 -0
  178. package/dist/swaps/spv_swaps/SpvFromBTCSwap.d.ts +315 -0
  179. package/dist/swaps/spv_swaps/SpvFromBTCSwap.js +1098 -0
  180. package/dist/swaps/spv_swaps/SpvFromBTCWrapper.d.ts +125 -0
  181. package/dist/swaps/spv_swaps/SpvFromBTCWrapper.js +631 -0
  182. package/dist/swaps/trusted/ln/LnForGasSwap.d.ts +107 -0
  183. package/dist/swaps/trusted/ln/LnForGasSwap.js +343 -0
  184. package/dist/swaps/trusted/ln/LnForGasWrapper.d.ts +21 -0
  185. package/dist/swaps/trusted/ln/LnForGasWrapper.js +62 -0
  186. package/dist/swaps/trusted/onchain/OnchainForGasSwap.d.ts +164 -0
  187. package/dist/swaps/trusted/onchain/OnchainForGasSwap.js +520 -0
  188. package/dist/swaps/trusted/onchain/OnchainForGasWrapper.d.ts +48 -0
  189. package/dist/swaps/trusted/onchain/OnchainForGasWrapper.js +74 -0
  190. package/dist/types/AmountData.d.ts +9 -0
  191. package/dist/types/AmountData.js +2 -0
  192. package/dist/types/CustomPriceFunction.d.ts +5 -0
  193. package/dist/types/CustomPriceFunction.js +2 -0
  194. package/dist/types/PriceInfoType.d.ts +28 -0
  195. package/dist/types/PriceInfoType.js +57 -0
  196. package/dist/types/SwapExecutionAction.d.ts +7 -0
  197. package/dist/types/SwapExecutionAction.js +2 -0
  198. package/dist/types/SwapWithSigner.d.ts +14 -0
  199. package/dist/types/SwapWithSigner.js +40 -0
  200. package/dist/types/Token.d.ts +53 -0
  201. package/dist/types/Token.js +58 -0
  202. package/dist/types/TokenAmount.d.ts +57 -0
  203. package/dist/types/TokenAmount.js +47 -0
  204. package/dist/types/fees/Fee.d.ts +49 -0
  205. package/dist/types/fees/Fee.js +2 -0
  206. package/dist/types/fees/FeeBreakdown.d.ts +10 -0
  207. package/dist/types/fees/FeeBreakdown.js +2 -0
  208. package/dist/types/fees/PercentagePPM.d.ts +15 -0
  209. package/dist/types/fees/PercentagePPM.js +17 -0
  210. package/dist/types/lnurl/LNURLPay.d.ts +54 -0
  211. package/dist/types/lnurl/LNURLPay.js +28 -0
  212. package/dist/types/lnurl/LNURLWithdraw.d.ts +42 -0
  213. package/dist/types/lnurl/LNURLWithdraw.js +24 -0
  214. package/dist/utils/AutomaticClockDriftCorrection.d.ts +1 -0
  215. package/dist/utils/AutomaticClockDriftCorrection.js +70 -0
  216. package/dist/utils/BitcoinUtils.d.ts +13 -0
  217. package/dist/utils/BitcoinUtils.js +98 -0
  218. package/dist/utils/BitcoinWalletUtils.d.ts +7 -0
  219. package/dist/utils/BitcoinWalletUtils.js +14 -0
  220. package/dist/utils/Logger.d.ts +7 -0
  221. package/dist/utils/Logger.js +12 -0
  222. package/dist/utils/RetryUtils.d.ts +21 -0
  223. package/dist/utils/RetryUtils.js +66 -0
  224. package/dist/utils/SwapUtils.d.ts +31 -0
  225. package/dist/utils/SwapUtils.js +18 -0
  226. package/dist/{Utils.d.ts → utils/TimeoutUtils.d.ts} +9 -3
  227. package/dist/utils/TimeoutUtils.js +55 -0
  228. package/dist/utils/TokenUtils.d.ts +11 -0
  229. package/dist/utils/TokenUtils.js +29 -0
  230. package/dist/utils/TypeUtils.d.ts +7 -0
  231. package/dist/utils/TypeUtils.js +2 -0
  232. package/dist/utils/Utils.d.ts +57 -0
  233. package/dist/utils/Utils.js +178 -0
  234. package/package.json +14 -6
  235. package/src/SmartChainAssets.ts +11 -3
  236. package/src/bitcoin/BitcoinRpcWithAddressIndex.ts +87 -0
  237. package/src/bitcoin/LightningNetworkApi.ts +16 -0
  238. package/src/bitcoin/coinselect2/accumulative.ts +68 -0
  239. package/src/bitcoin/coinselect2/blackjack.ts +49 -0
  240. package/src/bitcoin/coinselect2/index.ts +92 -0
  241. package/src/bitcoin/coinselect2/utils.ts +189 -0
  242. package/src/bitcoin/mempool/MempoolApi.ts +554 -0
  243. package/src/bitcoin/mempool/MempoolBitcoinBlock.ts +88 -0
  244. package/src/bitcoin/mempool/MempoolBitcoinRpc.ts +437 -0
  245. package/src/bitcoin/mempool/synchronizer/MempoolBtcRelaySynchronizer.ts +134 -0
  246. package/src/bitcoin/wallet/BitcoinWallet.ts +375 -0
  247. package/src/bitcoin/wallet/IBitcoinWallet.ts +44 -0
  248. package/src/bitcoin/wallet/MinimalBitcoinWalletInterface.ts +19 -0
  249. package/src/bitcoin/wallet/MinimalLightningNetworkWalletInterface.ts +7 -0
  250. package/src/bitcoin/wallet/SingleAddressBitcoinWallet.ts +108 -0
  251. package/src/enums/FeeType.ts +9 -0
  252. package/src/enums/SwapAmountType.ts +9 -0
  253. package/src/enums/SwapDirection.ts +9 -0
  254. package/src/enums/SwapType.ts +15 -0
  255. package/src/errors/IntermediaryError.ts +24 -0
  256. package/src/errors/PaymentAuthError.ts +26 -0
  257. package/src/errors/RequestError.ts +51 -0
  258. package/src/errors/UserError.ts +14 -0
  259. package/src/events/UnifiedSwapEventListener.ts +171 -0
  260. package/src/http/HttpUtils.ts +92 -0
  261. package/src/http/paramcoders/IParamReader.ts +10 -0
  262. package/src/http/paramcoders/ParamDecoder.ts +142 -0
  263. package/src/http/paramcoders/ParamEncoder.ts +37 -0
  264. package/src/http/paramcoders/SchemaVerifier.ts +153 -0
  265. package/src/http/paramcoders/client/ResponseParamDecoder.ts +58 -0
  266. package/src/http/paramcoders/client/StreamParamEncoder.ts +29 -0
  267. package/src/http/paramcoders/client/StreamingFetchPromise.ts +193 -0
  268. package/src/index.ts +102 -4
  269. package/src/intermediaries/Intermediary.ts +204 -0
  270. package/src/intermediaries/IntermediaryDiscovery.ts +485 -0
  271. package/src/intermediaries/apis/IntermediaryAPI.ts +940 -0
  272. package/src/intermediaries/apis/TrustedIntermediaryAPI.ts +257 -0
  273. package/src/lnurl/LNURL.ts +403 -0
  274. package/src/prices/RedundantSwapPrice.ts +245 -0
  275. package/src/prices/SingleSwapPrice.ts +47 -0
  276. package/src/prices/SwapPriceWithChain.ts +157 -0
  277. package/src/prices/abstract/ICachedSwapPrice.ts +86 -0
  278. package/src/prices/abstract/IPriceProvider.ts +128 -0
  279. package/src/prices/abstract/ISwapPrice.ts +328 -0
  280. package/src/prices/providers/BinancePriceProvider.ts +41 -0
  281. package/src/prices/providers/CoinGeckoPriceProvider.ts +40 -0
  282. package/src/prices/providers/CoinPaprikaPriceProvider.ts +44 -0
  283. package/src/prices/providers/CustomPriceProvider.ts +29 -0
  284. package/src/prices/providers/KrakenPriceProvider.ts +74 -0
  285. package/src/prices/providers/OKXPriceProvider.ts +53 -0
  286. package/src/prices/providers/abstract/ExchangePriceProvider.ts +29 -0
  287. package/src/prices/providers/abstract/HttpPriceProvider.ts +15 -0
  288. package/src/storage/IUnifiedStorage.ts +83 -0
  289. package/src/storage/UnifiedSwapStorage.ts +104 -0
  290. package/src/storage-browser/IndexedDBUnifiedStorage.ts +328 -0
  291. package/src/{storage → storage-browser}/LocalStorageManager.ts +2 -1
  292. package/src/swapper/Swapper.ts +2107 -0
  293. package/src/{SwapperFactory.ts → swapper/SwapperFactory.ts} +113 -72
  294. package/src/swapper/SwapperUtils.ts +510 -0
  295. package/src/swapper/SwapperWithChain.ts +464 -0
  296. package/src/swapper/SwapperWithSigner.ts +300 -0
  297. package/src/swaps/IAddressSwap.ts +20 -0
  298. package/src/swaps/IBTCWalletSwap.ts +77 -0
  299. package/src/swaps/IClaimableSwap.ts +30 -0
  300. package/src/swaps/IClaimableSwapWrapper.ts +9 -0
  301. package/src/swaps/IRefundableSwap.ts +29 -0
  302. package/src/swaps/ISwap.ts +490 -0
  303. package/src/swaps/ISwapWithGasDrop.ts +19 -0
  304. package/src/swaps/ISwapWrapper.ts +344 -0
  305. package/src/swaps/escrow_swaps/IEscrowSelfInitSwap.ts +168 -0
  306. package/src/swaps/escrow_swaps/IEscrowSwap.ts +197 -0
  307. package/src/swaps/escrow_swaps/IEscrowSwapWrapper.ts +210 -0
  308. package/src/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.ts +150 -0
  309. package/src/swaps/escrow_swaps/frombtc/IFromBTCSelfInitSwap.ts +219 -0
  310. package/src/swaps/escrow_swaps/frombtc/IFromBTCWrapper.ts +84 -0
  311. package/src/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.ts +1082 -0
  312. package/src/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.ts +429 -0
  313. package/src/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.ts +1078 -0
  314. package/src/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.ts +549 -0
  315. package/src/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.ts +974 -0
  316. package/src/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.ts +443 -0
  317. package/src/swaps/escrow_swaps/tobtc/IToBTCSwap.ts +860 -0
  318. package/src/swaps/escrow_swaps/tobtc/IToBTCWrapper.ts +104 -0
  319. package/src/swaps/escrow_swaps/tobtc/ln/ToBTCLNSwap.ts +256 -0
  320. package/src/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.ts +716 -0
  321. package/src/swaps/escrow_swaps/tobtc/onchain/ToBTCSwap.ts +151 -0
  322. package/src/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.ts +299 -0
  323. package/src/swaps/spv_swaps/SpvFromBTCSwap.ts +1394 -0
  324. package/src/swaps/spv_swaps/SpvFromBTCWrapper.ts +796 -0
  325. package/src/swaps/trusted/ln/LnForGasSwap.ts +402 -0
  326. package/src/swaps/trusted/ln/LnForGasWrapper.ts +70 -0
  327. package/src/swaps/trusted/onchain/OnchainForGasSwap.ts +633 -0
  328. package/src/swaps/trusted/onchain/OnchainForGasWrapper.ts +110 -0
  329. package/src/types/AmountData.ts +9 -0
  330. package/src/types/CustomPriceFunction.ts +5 -0
  331. package/src/types/PriceInfoType.ts +67 -0
  332. package/src/types/SwapExecutionAction.ts +8 -0
  333. package/src/types/SwapWithSigner.ts +57 -0
  334. package/src/types/Token.ts +90 -0
  335. package/src/types/TokenAmount.ts +110 -0
  336. package/src/types/fees/Fee.ts +55 -0
  337. package/src/types/fees/FeeBreakdown.ts +11 -0
  338. package/src/types/fees/PercentagePPM.ts +24 -0
  339. package/src/types/lnurl/LNURLPay.ts +72 -0
  340. package/src/types/lnurl/LNURLWithdraw.ts +55 -0
  341. package/src/utils/AutomaticClockDriftCorrection.ts +71 -0
  342. package/src/utils/BitcoinUtils.ts +86 -0
  343. package/src/utils/BitcoinWalletUtils.ts +16 -0
  344. package/src/utils/Logger.ts +15 -0
  345. package/src/utils/RetryUtils.ts +71 -0
  346. package/src/utils/SwapUtils.ts +38 -0
  347. package/src/utils/TimeoutUtils.ts +50 -0
  348. package/src/utils/TokenUtils.ts +25 -0
  349. package/src/utils/TypeUtils.ts +9 -0
  350. package/src/utils/Utils.ts +182 -0
  351. package/dist/SwapperFactory.d.ts +0 -52
  352. package/dist/Utils.js +0 -37
  353. package/dist/fs-storage/FileSystemStorageManager.d.ts +0 -15
  354. package/dist/fs-storage/FileSystemStorageManager.js +0 -60
  355. package/dist/fs-storage/index.d.ts +0 -1
  356. package/dist/fs-storage/index.js +0 -17
  357. package/src/SmartChainAssets.js +0 -75
  358. package/src/SwapperFactory.js +0 -120
  359. package/src/Utils.js +0 -37
  360. package/src/Utils.ts +0 -31
  361. package/src/fs-storage/FileSystemStorageManager.ts +0 -71
  362. package/src/fs-storage/index.ts +0 -1
  363. package/src/index.js +0 -21
  364. package/src/storage/LocalStorageManager.js +0 -72
@@ -0,0 +1,631 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SpvFromBTCWrapper = void 0;
4
+ const ISwapWrapper_1 = require("../ISwapWrapper");
5
+ const base_1 = require("@atomiqlabs/base");
6
+ const SpvFromBTCSwap_1 = require("./SpvFromBTCSwap");
7
+ const utils_1 = require("@scure/btc-signer/utils");
8
+ const SwapType_1 = require("../../enums/SwapType");
9
+ const Utils_1 = require("../../utils/Utils");
10
+ const BitcoinUtils_1 = require("../../utils/BitcoinUtils");
11
+ const IntermediaryAPI_1 = require("../../intermediaries/apis/IntermediaryAPI");
12
+ const RequestError_1 = require("../../errors/RequestError");
13
+ const IntermediaryError_1 = require("../../errors/IntermediaryError");
14
+ const btc_signer_1 = require("@scure/btc-signer");
15
+ const RetryUtils_1 = require("../../utils/RetryUtils");
16
+ class SpvFromBTCWrapper extends ISwapWrapper_1.ISwapWrapper {
17
+ /**
18
+ * @param chainIdentifier
19
+ * @param unifiedStorage Storage interface for the current environment
20
+ * @param unifiedChainEvents On-chain event listener
21
+ * @param chain
22
+ * @param contract Underlying contract handling the swaps
23
+ * @param prices Pricing to use
24
+ * @param tokens
25
+ * @param spvWithdrawalDataDeserializer Deserializer for SpvVaultWithdrawalData
26
+ * @param btcRelay
27
+ * @param synchronizer Btc relay synchronizer
28
+ * @param btcRpc Bitcoin RPC which also supports getting transactions by txoHash
29
+ * @param options
30
+ * @param events Instance to use for emitting events
31
+ */
32
+ constructor(chainIdentifier, unifiedStorage, unifiedChainEvents, chain, contract, prices, tokens, spvWithdrawalDataDeserializer, btcRelay, synchronizer, btcRpc, options, events) {
33
+ if (options == null)
34
+ options = {};
35
+ options.bitcoinNetwork ??= utils_1.TEST_NETWORK;
36
+ options.maxConfirmations ??= 6;
37
+ options.bitcoinBlocktime ??= 10 * 60;
38
+ options.maxTransactionsDelta ??= 3;
39
+ options.maxRawAmountAdjustmentDifferencePPM ??= 100;
40
+ options.maxBtcFeeOffset ??= 5;
41
+ options.maxBtcFeeMultiplier ??= 1.5;
42
+ super(chainIdentifier, unifiedStorage, unifiedChainEvents, chain, prices, tokens, {
43
+ bitcoinNetwork: options.bitcoinNetwork ?? utils_1.TEST_NETWORK,
44
+ maxConfirmations: options.maxConfirmations ?? 6,
45
+ bitcoinBlocktime: options.bitcoinBlocktime ?? 10 * 60,
46
+ maxTransactionsDelta: options.maxTransactionsDelta ?? 3,
47
+ maxRawAmountAdjustmentDifferencePPM: options.maxRawAmountAdjustmentDifferencePPM ?? 100,
48
+ maxBtcFeeOffset: options.maxBtcFeeOffset ?? 5,
49
+ maxBtcFeeMultiplier: options.maxBtcFeeMultiplier ?? 1.5
50
+ }, events);
51
+ this.claimableSwapStates = [SpvFromBTCSwap_1.SpvFromBTCSwapState.BTC_TX_CONFIRMED];
52
+ this.TYPE = SwapType_1.SwapType.SPV_VAULT_FROM_BTC;
53
+ this.swapDeserializer = SpvFromBTCSwap_1.SpvFromBTCSwap;
54
+ this.pendingSwapStates = [
55
+ SpvFromBTCSwap_1.SpvFromBTCSwapState.CREATED,
56
+ SpvFromBTCSwap_1.SpvFromBTCSwapState.SIGNED,
57
+ SpvFromBTCSwap_1.SpvFromBTCSwapState.POSTED,
58
+ SpvFromBTCSwap_1.SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED,
59
+ SpvFromBTCSwap_1.SpvFromBTCSwapState.BROADCASTED,
60
+ SpvFromBTCSwap_1.SpvFromBTCSwapState.DECLINED,
61
+ SpvFromBTCSwap_1.SpvFromBTCSwapState.BTC_TX_CONFIRMED
62
+ ];
63
+ this.tickSwapState = [
64
+ SpvFromBTCSwap_1.SpvFromBTCSwapState.CREATED,
65
+ SpvFromBTCSwap_1.SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED,
66
+ SpvFromBTCSwap_1.SpvFromBTCSwapState.SIGNED,
67
+ SpvFromBTCSwap_1.SpvFromBTCSwapState.POSTED,
68
+ SpvFromBTCSwap_1.SpvFromBTCSwapState.BROADCASTED
69
+ ];
70
+ this.spvWithdrawalDataDeserializer = spvWithdrawalDataDeserializer;
71
+ this.contract = contract;
72
+ this.btcRelay = btcRelay;
73
+ this.synchronizer = synchronizer;
74
+ this.btcRpc = btcRpc;
75
+ }
76
+ async processEventFront(event, swap) {
77
+ if (swap.state === SpvFromBTCSwap_1.SpvFromBTCSwapState.SIGNED || swap.state === SpvFromBTCSwap_1.SpvFromBTCSwapState.POSTED ||
78
+ swap.state === SpvFromBTCSwap_1.SpvFromBTCSwapState.BROADCASTED || swap.state === SpvFromBTCSwap_1.SpvFromBTCSwapState.DECLINED ||
79
+ swap.state === SpvFromBTCSwap_1.SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED || swap.state === SpvFromBTCSwap_1.SpvFromBTCSwapState.BTC_TX_CONFIRMED) {
80
+ await swap._setBitcoinTxId(event.btcTxId).catch(e => {
81
+ this.logger.warn("processEventFront(): Failed to set bitcoin txId: ", e);
82
+ });
83
+ swap.state = SpvFromBTCSwap_1.SpvFromBTCSwapState.FRONTED;
84
+ return true;
85
+ }
86
+ return false;
87
+ }
88
+ async processEventClaim(event, swap) {
89
+ if (swap.state === SpvFromBTCSwap_1.SpvFromBTCSwapState.SIGNED || swap.state === SpvFromBTCSwap_1.SpvFromBTCSwapState.POSTED ||
90
+ swap.state === SpvFromBTCSwap_1.SpvFromBTCSwapState.BROADCASTED || swap.state === SpvFromBTCSwap_1.SpvFromBTCSwapState.DECLINED ||
91
+ swap.state === SpvFromBTCSwap_1.SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED || swap.state === SpvFromBTCSwap_1.SpvFromBTCSwapState.BTC_TX_CONFIRMED) {
92
+ await swap._setBitcoinTxId(event.btcTxId).catch(e => {
93
+ this.logger.warn("processEventClaim(): Failed to set bitcoin txId: ", e);
94
+ });
95
+ swap.state = SpvFromBTCSwap_1.SpvFromBTCSwapState.CLAIMED;
96
+ return true;
97
+ }
98
+ return false;
99
+ }
100
+ processEventClose(event, swap) {
101
+ if (swap.state === SpvFromBTCSwap_1.SpvFromBTCSwapState.SIGNED || swap.state === SpvFromBTCSwap_1.SpvFromBTCSwapState.POSTED ||
102
+ swap.state === SpvFromBTCSwap_1.SpvFromBTCSwapState.BROADCASTED || swap.state === SpvFromBTCSwap_1.SpvFromBTCSwapState.DECLINED ||
103
+ swap.state === SpvFromBTCSwap_1.SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED || swap.state === SpvFromBTCSwap_1.SpvFromBTCSwapState.BTC_TX_CONFIRMED) {
104
+ swap.state = SpvFromBTCSwap_1.SpvFromBTCSwapState.CLOSED;
105
+ return Promise.resolve(true);
106
+ }
107
+ return Promise.resolve(false);
108
+ }
109
+ async processEvent(event, swap) {
110
+ if (swap == null)
111
+ return;
112
+ let swapChanged = false;
113
+ if (event instanceof base_1.SpvVaultFrontEvent) {
114
+ swapChanged = await this.processEventFront(event, swap);
115
+ if (event.meta?.txId != null && swap.frontTxId !== event.meta.txId) {
116
+ swap.frontTxId = event.meta.txId;
117
+ swapChanged ||= true;
118
+ }
119
+ }
120
+ if (event instanceof base_1.SpvVaultClaimEvent) {
121
+ swapChanged = await this.processEventClaim(event, swap);
122
+ if (event.meta?.txId != null && swap.claimTxId !== event.meta.txId) {
123
+ swap.claimTxId = event.meta.txId;
124
+ swapChanged ||= true;
125
+ }
126
+ }
127
+ if (event instanceof base_1.SpvVaultCloseEvent) {
128
+ swapChanged = await this.processEventClose(event, swap);
129
+ }
130
+ this.logger.info("processEvents(): " + event.constructor.name + " processed for " + swap.getId() + " swap: ", swap);
131
+ if (swapChanged) {
132
+ await swap._saveAndEmit();
133
+ }
134
+ }
135
+ /**
136
+ * Pre-fetches latest finalized block height of the smart chain
137
+ *
138
+ * @param abortController
139
+ * @private
140
+ */
141
+ async preFetchFinalizedBlockHeight(abortController) {
142
+ try {
143
+ const block = await this.chain.getFinalizedBlock();
144
+ return block.height;
145
+ }
146
+ catch (e) {
147
+ abortController.abort(e);
148
+ }
149
+ }
150
+ /**
151
+ * Pre-fetches caller (watchtower) bounty data for the swap. Doesn't throw, instead returns null and aborts the
152
+ * provided abortController
153
+ *
154
+ * @param amountData
155
+ * @param options Options as passed to the swap creation function
156
+ * @param pricePrefetch
157
+ * @param nativeTokenPricePrefetch
158
+ * @param abortController
159
+ * @private
160
+ */
161
+ async preFetchCallerFeeShare(amountData, options, pricePrefetch, nativeTokenPricePrefetch, abortController) {
162
+ if (options.unsafeZeroWatchtowerFee)
163
+ return 0n;
164
+ if (amountData.amount === 0n)
165
+ return 0n;
166
+ try {
167
+ const [feePerBlock, btcRelayData, currentBtcBlock, claimFeeRate, nativeTokenPrice] = await Promise.all([
168
+ this.btcRelay.getFeePerBlock(),
169
+ this.btcRelay.getTipData(),
170
+ this.btcRpc.getTipHeight(),
171
+ this.contract.getClaimFee(this.chain.randomAddress()),
172
+ nativeTokenPricePrefetch ?? (amountData.token === this.chain.getNativeCurrencyAddress() ?
173
+ pricePrefetch :
174
+ this.prices.preFetchPrice(this.chainIdentifier, this.chain.getNativeCurrencyAddress(), abortController.signal))
175
+ ]);
176
+ if (btcRelayData == null)
177
+ throw new Error("Btc relay doesn't seem to be initialized!");
178
+ const currentBtcRelayBlock = btcRelayData.blockheight;
179
+ const blockDelta = Math.max(currentBtcBlock - currentBtcRelayBlock + this.options.maxConfirmations, 0);
180
+ const totalFeeInNativeToken = ((BigInt(blockDelta) * feePerBlock) +
181
+ (claimFeeRate * BigInt(this.options.maxTransactionsDelta))) * BigInt(Math.floor(options.feeSafetyFactor * 1000000)) / 1000000n;
182
+ let payoutAmount;
183
+ if (amountData.exactIn) {
184
+ //Convert input amount in BTC to
185
+ const amountInNativeToken = await this.prices.getFromBtcSwapAmount(this.chainIdentifier, amountData.amount, this.chain.getNativeCurrencyAddress(), abortController.signal, nativeTokenPrice);
186
+ payoutAmount = amountInNativeToken - totalFeeInNativeToken;
187
+ }
188
+ else {
189
+ if (amountData.token === this.chain.getNativeCurrencyAddress()) {
190
+ //Both amounts in same currency
191
+ payoutAmount = amountData.amount;
192
+ }
193
+ else {
194
+ //Need to convert both to native currency
195
+ const btcAmount = await this.prices.getToBtcSwapAmount(this.chainIdentifier, amountData.amount, amountData.token, abortController.signal, await pricePrefetch);
196
+ payoutAmount = await this.prices.getFromBtcSwapAmount(this.chainIdentifier, btcAmount, this.chain.getNativeCurrencyAddress(), abortController.signal, nativeTokenPrice);
197
+ }
198
+ }
199
+ this.logger.debug("preFetchCallerFeeShare(): Caller fee in native token: " + totalFeeInNativeToken.toString(10) + " total payout in native token: " + payoutAmount.toString(10));
200
+ const callerFeeShare = ((totalFeeInNativeToken * 100000n) + payoutAmount - 1n) / payoutAmount; //Make sure to round up here
201
+ if (callerFeeShare < 0n)
202
+ return 0n;
203
+ if (callerFeeShare >= 2n ** 20n)
204
+ return 2n ** 20n - 1n;
205
+ return callerFeeShare;
206
+ }
207
+ catch (e) {
208
+ abortController.abort(e);
209
+ }
210
+ }
211
+ /**
212
+ * Verifies response returned from intermediary
213
+ *
214
+ * @param resp Response as returned by the intermediary
215
+ * @param amountData
216
+ * @param lp Intermediary
217
+ * @param options Options as passed to the swap creation function
218
+ * @param callerFeeShare
219
+ * @param bitcoinFeeRatePromise Maximum accepted fee rate from the LPs
220
+ * @param abortSignal
221
+ * @private
222
+ * @throws {IntermediaryError} in case the response is invalid
223
+ */
224
+ async verifyReturnedData(resp, amountData, lp, options, callerFeeShare, bitcoinFeeRatePromise, abortSignal) {
225
+ const btcFeeRate = await (0, Utils_1.throwIfUndefined)(bitcoinFeeRatePromise, "Bitcoin fee rate promise failed!");
226
+ abortSignal.throwIfAborted();
227
+ if (btcFeeRate != null && resp.btcFeeRate > btcFeeRate)
228
+ throw new IntermediaryError_1.IntermediaryError("Bitcoin fee rate returned too high!");
229
+ //Vault related
230
+ let vaultScript;
231
+ let vaultAddressType;
232
+ let btcAddressScript;
233
+ //Ensure valid btc addresses returned
234
+ try {
235
+ vaultScript = (0, BitcoinUtils_1.toOutputScript)(this.options.bitcoinNetwork, resp.vaultBtcAddress);
236
+ vaultAddressType = (0, BitcoinUtils_1.toCoinselectAddressType)(vaultScript);
237
+ btcAddressScript = (0, BitcoinUtils_1.toOutputScript)(this.options.bitcoinNetwork, resp.btcAddress);
238
+ }
239
+ catch (e) {
240
+ throw new IntermediaryError_1.IntermediaryError("Invalid btc address data returned", e);
241
+ }
242
+ const decodedUtxo = resp.btcUtxo.split(":");
243
+ if (resp.address !== lp.getAddress(this.chainIdentifier) || //Ensure the LP is indeed the vault owner
244
+ resp.vaultId < 0n || //Ensure vaultId is not negative
245
+ vaultScript == null || //Make sure vault script is parsable and of known type
246
+ btcAddressScript == null || //Make sure btc address script is parsable and of known type
247
+ vaultAddressType === "p2pkh" || vaultAddressType === "p2sh-p2wpkh" || //Constrain the vault script type to witness types
248
+ decodedUtxo.length !== 2 || decodedUtxo[0].length !== 64 || isNaN(parseInt(decodedUtxo[1])) || //Check valid UTXO
249
+ resp.btcFeeRate < 1 || resp.btcFeeRate > 10000 //Sanity check on the returned BTC fee rate
250
+ )
251
+ throw new IntermediaryError_1.IntermediaryError("Invalid vault data returned!");
252
+ //Amounts sanity
253
+ if (resp.btcAmountSwap + resp.btcAmountGas !== resp.btcAmount)
254
+ throw new Error("Btc amount mismatch");
255
+ if (resp.swapFeeBtc + resp.gasSwapFeeBtc !== resp.totalFeeBtc)
256
+ throw new Error("Btc fee mismatch");
257
+ //TODO: For now ensure fees are at 0
258
+ if (resp.callerFeeShare !== callerFeeShare ||
259
+ resp.frontingFeeShare !== 0n ||
260
+ resp.executionFeeShare !== 0n)
261
+ throw new IntermediaryError_1.IntermediaryError("Invalid caller/fronting/execution fee returned");
262
+ //Check expiry
263
+ const timeNowSeconds = Math.floor(Date.now() / 1000);
264
+ if (resp.expiry < timeNowSeconds)
265
+ throw new IntermediaryError_1.IntermediaryError(`Quote already expired, expiry: ${resp.expiry}, systemTime: ${timeNowSeconds}, clockAdjusted: ${Date._now != null}`);
266
+ let utxo = resp.btcUtxo.toLowerCase();
267
+ const [txId, voutStr] = utxo.split(":");
268
+ const abortController = (0, Utils_1.extendAbortController)(abortSignal);
269
+ let [vault, { vaultUtxoValue, btcTx }] = await Promise.all([
270
+ (async () => {
271
+ //Fetch vault data
272
+ let vault;
273
+ try {
274
+ vault = await this.contract.getVaultData(resp.address, resp.vaultId);
275
+ }
276
+ catch (e) {
277
+ this.logger.error("Error getting spv vault (owner: " + resp.address + " vaultId: " + resp.vaultId.toString(10) + "): ", e);
278
+ throw new IntermediaryError_1.IntermediaryError("Spv swap vault not found", e);
279
+ }
280
+ abortController.signal.throwIfAborted();
281
+ //Make sure vault is opened
282
+ if (vault == null || !vault.isOpened())
283
+ throw new IntermediaryError_1.IntermediaryError("Returned spv swap vault is not opened!");
284
+ //Make sure the vault doesn't require insane amount of confirmations
285
+ if (vault.getConfirmations() > this.options.maxConfirmations)
286
+ throw new IntermediaryError_1.IntermediaryError("SPV swap vault needs too many confirmations: " + vault.getConfirmations());
287
+ const tokenData = vault.getTokenData();
288
+ //Amounts - make sure the amounts match
289
+ if (amountData.exactIn) {
290
+ if (resp.btcAmount !== amountData.amount)
291
+ throw new IntermediaryError_1.IntermediaryError("Invalid amount returned");
292
+ }
293
+ else {
294
+ //Check the difference between amount adjusted due to scaling to raw amount
295
+ const adjustedAmount = amountData.amount / tokenData[0].multiplier * tokenData[0].multiplier;
296
+ const adjustmentPPM = (amountData.amount - adjustedAmount) * 1000000n / amountData.amount;
297
+ if (adjustmentPPM > this.options.maxRawAmountAdjustmentDifferencePPM)
298
+ throw new IntermediaryError_1.IntermediaryError("Invalid amount0 multiplier used, rawAmount diff too high");
299
+ if (resp.total !== adjustedAmount)
300
+ throw new IntermediaryError_1.IntermediaryError("Invalid total returned");
301
+ }
302
+ if (options.gasAmount == null || options.gasAmount === 0n) {
303
+ if (resp.totalGas !== 0n)
304
+ throw new IntermediaryError_1.IntermediaryError("Invalid gas total returned");
305
+ }
306
+ else {
307
+ //Check the difference between amount adjusted due to scaling to raw amount
308
+ const adjustedGasAmount = options.gasAmount / tokenData[0].multiplier * tokenData[0].multiplier;
309
+ const adjustmentPPM = (options.gasAmount - adjustedGasAmount) * 1000000n / options.gasAmount;
310
+ if (adjustmentPPM > this.options.maxRawAmountAdjustmentDifferencePPM)
311
+ throw new IntermediaryError_1.IntermediaryError("Invalid amount1 multiplier used, rawAmount diff too high");
312
+ if (resp.totalGas !== adjustedGasAmount)
313
+ throw new IntermediaryError_1.IntermediaryError("Invalid gas total returned");
314
+ }
315
+ return vault;
316
+ })(),
317
+ (async () => {
318
+ //Require the vault UTXO to have at least 1 confirmation
319
+ let btcTx = await this.btcRpc.getTransaction(txId);
320
+ if (btcTx == null)
321
+ throw new IntermediaryError_1.IntermediaryError("Invalid UTXO, doesn't exist (txId)");
322
+ abortController.signal.throwIfAborted();
323
+ if (btcTx.confirmations == null || btcTx.confirmations < 1)
324
+ throw new IntermediaryError_1.IntermediaryError("SPV vault UTXO not confirmed");
325
+ const vout = parseInt(voutStr);
326
+ if (btcTx.outs[vout] == null)
327
+ throw new IntermediaryError_1.IntermediaryError("Invalid UTXO, doesn't exist");
328
+ const vaultUtxoValue = btcTx.outs[vout].value;
329
+ return { btcTx, vaultUtxoValue };
330
+ })(),
331
+ (async () => {
332
+ //Require vault UTXO is unspent
333
+ if (await this.btcRpc.isSpent(utxo))
334
+ throw new IntermediaryError_1.IntermediaryError("Returned spv vault UTXO is already spent", null, true);
335
+ abortController.signal.throwIfAborted();
336
+ })()
337
+ ]).catch(e => {
338
+ abortController.abort(e);
339
+ throw e;
340
+ });
341
+ this.logger.debug("verifyReturnedData(): Vault UTXO: " + vault.getUtxo() + " current utxo: " + utxo);
342
+ //Trace returned utxo back to what's saved on-chain
343
+ let pendingWithdrawals = [];
344
+ while (vault.getUtxo() !== utxo) {
345
+ const [txId, voutStr] = utxo.split(":");
346
+ //Such that 1st tx isn't fetched twice
347
+ if (btcTx.txid !== txId) {
348
+ const _btcTx = await this.btcRpc.getTransaction(txId);
349
+ if (_btcTx == null)
350
+ throw new IntermediaryError_1.IntermediaryError("Invalid ancestor transaction (not found)");
351
+ btcTx = _btcTx;
352
+ }
353
+ const withdrawalData = await this.contract.getWithdrawalData(btcTx);
354
+ abortSignal.throwIfAborted();
355
+ pendingWithdrawals.unshift(withdrawalData);
356
+ utxo = pendingWithdrawals[0].getSpentVaultUtxo();
357
+ this.logger.debug("verifyReturnedData(): Vault UTXO: " + vault.getUtxo() + " current utxo: " + utxo);
358
+ if (pendingWithdrawals.length >= this.options.maxTransactionsDelta)
359
+ throw new IntermediaryError_1.IntermediaryError("BTC <> SC state difference too deep, maximum: " + this.options.maxTransactionsDelta);
360
+ }
361
+ //Verify that the vault has enough balance after processing all pending withdrawals
362
+ let vaultBalances;
363
+ try {
364
+ vaultBalances = vault.calculateStateAfter(pendingWithdrawals);
365
+ }
366
+ catch (e) {
367
+ this.logger.error("Error calculating spv vault balance (owner: " + resp.address + " vaultId: " + resp.vaultId.toString(10) + "): ", e);
368
+ throw new IntermediaryError_1.IntermediaryError("Spv swap vault balance prediction failed", e);
369
+ }
370
+ if (vaultBalances.balances[0].scaledAmount < resp.total)
371
+ throw new IntermediaryError_1.IntermediaryError("SPV swap vault, insufficient balance, required: " + resp.total.toString(10) +
372
+ " has: " + vaultBalances.balances[0].scaledAmount.toString(10));
373
+ if (vaultBalances.balances[1].scaledAmount < resp.totalGas)
374
+ throw new IntermediaryError_1.IntermediaryError("SPV swap vault, insufficient balance, required: " + resp.totalGas.toString(10) +
375
+ " has: " + vaultBalances.balances[1].scaledAmount.toString(10));
376
+ //Also verify that all the withdrawal txns are valid, this is an extra sanity check
377
+ try {
378
+ for (let withdrawal of pendingWithdrawals) {
379
+ await this.contract.checkWithdrawalTx(withdrawal);
380
+ }
381
+ }
382
+ catch (e) {
383
+ this.logger.error("Error calculating spv vault balance (owner: " + resp.address + " vaultId: " + resp.vaultId.toString(10) + "): ", e);
384
+ throw new IntermediaryError_1.IntermediaryError("Spv swap vault balance prediction failed", e);
385
+ }
386
+ abortSignal.throwIfAborted();
387
+ return {
388
+ vault,
389
+ vaultUtxoValue
390
+ };
391
+ }
392
+ /**
393
+ * Returns a newly created swap, receiving 'amount' on chain
394
+ *
395
+ * @param signer Smartchain signer's address intiating the swap
396
+ * @param amountData Amount of token & amount to swap
397
+ * @param lps LPs (liquidity providers) to get the quotes from
398
+ * @param options Quote options
399
+ * @param additionalParams Additional parameters sent to the LP when creating the swap
400
+ * @param abortSignal Abort signal for aborting the process
401
+ */
402
+ create(signer, amountData, lps, options, additionalParams, abortSignal) {
403
+ const _options = {
404
+ gasAmount: options?.gasAmount ?? 0n,
405
+ unsafeZeroWatchtowerFee: options?.unsafeZeroWatchtowerFee ?? false,
406
+ feeSafetyFactor: options?.feeSafetyFactor ?? 1.25,
407
+ maxAllowedNetworkFeeRate: options?.maxAllowedNetworkFeeRate ?? Infinity
408
+ };
409
+ const _abortController = (0, Utils_1.extendAbortController)(abortSignal);
410
+ const pricePrefetchPromise = this.preFetchPrice(amountData, _abortController.signal);
411
+ const usdPricePrefetchPromise = this.preFetchUsdPrice(_abortController.signal);
412
+ const finalizedBlockHeightPrefetchPromise = this.preFetchFinalizedBlockHeight(_abortController);
413
+ const nativeTokenAddress = this.chain.getNativeCurrencyAddress();
414
+ const gasTokenPricePrefetchPromise = _options.gasAmount === 0n ?
415
+ undefined :
416
+ this.preFetchPrice({ token: nativeTokenAddress }, _abortController.signal);
417
+ const callerFeePrefetchPromise = this.preFetchCallerFeeShare(amountData, _options, pricePrefetchPromise, gasTokenPricePrefetchPromise, _abortController);
418
+ const bitcoinFeeRatePromise = _options.maxAllowedNetworkFeeRate != Infinity ?
419
+ Promise.resolve(_options.maxAllowedNetworkFeeRate) :
420
+ this.btcRpc.getFeeRate().then(x => this.options.maxBtcFeeOffset + (x * this.options.maxBtcFeeMultiplier)).catch(e => {
421
+ _abortController.abort(e);
422
+ return undefined;
423
+ });
424
+ return lps.map(lp => {
425
+ return {
426
+ intermediary: lp,
427
+ quote: (0, RetryUtils_1.tryWithRetries)(async () => {
428
+ if (lp.services[SwapType_1.SwapType.SPV_VAULT_FROM_BTC] == null)
429
+ throw new Error("LP service for processing spv vault swaps not found!");
430
+ const abortController = (0, Utils_1.extendAbortController)(_abortController.signal);
431
+ try {
432
+ const resp = await (0, RetryUtils_1.tryWithRetries)(async (retryCount) => {
433
+ return await IntermediaryAPI_1.IntermediaryAPI.prepareSpvFromBTC(this.chainIdentifier, lp.url, {
434
+ address: signer,
435
+ amount: amountData.amount,
436
+ token: amountData.token.toString(),
437
+ exactOut: !amountData.exactIn,
438
+ gasToken: nativeTokenAddress,
439
+ gasAmount: _options.gasAmount,
440
+ callerFeeRate: (0, Utils_1.throwIfUndefined)(callerFeePrefetchPromise, "Caller fee prefetch failed!"),
441
+ frontingFeeRate: 0n,
442
+ additionalParams
443
+ }, this.options.postRequestTimeout, abortController.signal, retryCount > 0 ? false : undefined);
444
+ }, undefined, e => e instanceof RequestError_1.RequestError, abortController.signal);
445
+ this.logger.debug("create(" + lp.url + "): LP response: ", resp);
446
+ const callerFeeShare = (await callerFeePrefetchPromise);
447
+ const [pricingInfo, gasPricingInfo, { vault, vaultUtxoValue }] = await Promise.all([
448
+ this.verifyReturnedPrice(lp.services[SwapType_1.SwapType.SPV_VAULT_FROM_BTC], false, resp.btcAmountSwap, resp.total * (100000n + callerFeeShare) / 100000n, amountData.token, {}, pricePrefetchPromise, usdPricePrefetchPromise, abortController.signal),
449
+ _options.gasAmount === 0n ? Promise.resolve(undefined) : this.verifyReturnedPrice({ ...lp.services[SwapType_1.SwapType.SPV_VAULT_FROM_BTC], swapBaseFee: 0 }, //Base fee should be charged only on the amount, not on gas
450
+ false, resp.btcAmountGas, resp.totalGas * (100000n + callerFeeShare) / 100000n, nativeTokenAddress, {}, gasTokenPricePrefetchPromise, usdPricePrefetchPromise, abortController.signal),
451
+ this.verifyReturnedData(resp, amountData, lp, _options, callerFeeShare, bitcoinFeeRatePromise, abortController.signal)
452
+ ]);
453
+ const swapInit = {
454
+ pricingInfo,
455
+ url: lp.url,
456
+ expiry: resp.expiry * 1000,
457
+ swapFee: resp.swapFee,
458
+ swapFeeBtc: resp.swapFeeBtc,
459
+ exactIn: amountData.exactIn ?? true,
460
+ quoteId: resp.quoteId,
461
+ recipient: signer,
462
+ vaultOwner: resp.address,
463
+ vaultId: resp.vaultId,
464
+ vaultRequiredConfirmations: vault.getConfirmations(),
465
+ vaultTokenMultipliers: vault.getTokenData().map(val => val.multiplier),
466
+ vaultBtcAddress: resp.vaultBtcAddress,
467
+ vaultUtxo: resp.btcUtxo,
468
+ vaultUtxoValue: BigInt(vaultUtxoValue),
469
+ btcDestinationAddress: resp.btcAddress,
470
+ btcAmount: resp.btcAmount,
471
+ btcAmountSwap: resp.btcAmountSwap,
472
+ btcAmountGas: resp.btcAmountGas,
473
+ minimumBtcFeeRate: resp.btcFeeRate,
474
+ outputTotalSwap: resp.total,
475
+ outputSwapToken: amountData.token,
476
+ outputTotalGas: resp.totalGas,
477
+ outputGasToken: nativeTokenAddress,
478
+ gasSwapFeeBtc: resp.gasSwapFeeBtc,
479
+ gasSwapFee: resp.gasSwapFee,
480
+ gasPricingInfo,
481
+ callerFeeShare: resp.callerFeeShare,
482
+ frontingFeeShare: resp.frontingFeeShare,
483
+ executionFeeShare: resp.executionFeeShare,
484
+ genesisSmartChainBlockHeight: await (0, Utils_1.throwIfUndefined)(finalizedBlockHeightPrefetchPromise, "Finalize block height promise failed!")
485
+ };
486
+ const quote = new SpvFromBTCSwap_1.SpvFromBTCSwap(this, swapInit);
487
+ await quote._save();
488
+ return quote;
489
+ }
490
+ catch (e) {
491
+ abortController.abort(e);
492
+ throw e;
493
+ }
494
+ }, undefined, err => !(err instanceof IntermediaryError_1.IntermediaryError && err.recoverable), _abortController.signal)
495
+ };
496
+ });
497
+ }
498
+ /**
499
+ * Returns a random dummy PSBT that can be used for fee estimation, the last output (the LP output) is omitted
500
+ * to allow for coinselection algorithm to determine maximum sendable amount there
501
+ *
502
+ * @param includeGasToken Whether to return the PSBT also with the gas token amount (increases the vSize by 8)
503
+ */
504
+ getDummySwapPsbt(includeGasToken = false) {
505
+ //Construct dummy swap psbt
506
+ const psbt = new btc_signer_1.Transaction({
507
+ allowUnknownInputs: true,
508
+ allowLegacyWitnessUtxo: true,
509
+ allowUnknownOutputs: true
510
+ });
511
+ const randomVaultOutScript = btc_signer_1.OutScript.encode({ type: "tr", pubkey: Buffer.from("0101010101010101010101010101010101010101010101010101010101010101", "hex") });
512
+ psbt.addInput({
513
+ txid: (0, Utils_1.randomBytes)(32),
514
+ index: 0,
515
+ witnessUtxo: {
516
+ script: randomVaultOutScript,
517
+ amount: 600n
518
+ }
519
+ });
520
+ psbt.addOutput({
521
+ script: randomVaultOutScript,
522
+ amount: 600n
523
+ });
524
+ const opReturnData = this.contract.toOpReturnData(this.chain.randomAddress(), includeGasToken ? [0xffffffffffffffffn, 0xffffffffffffffffn] : [0xffffffffffffffffn]);
525
+ psbt.addOutput({
526
+ script: Buffer.concat([
527
+ opReturnData.length <= 75 ? Buffer.from([0x6a, opReturnData.length]) : Buffer.from([0x6a, 0x4c, opReturnData.length]),
528
+ opReturnData
529
+ ]),
530
+ amount: 0n
531
+ });
532
+ return psbt;
533
+ }
534
+ async _checkPastSwaps(pastSwaps) {
535
+ const changedSwaps = new Set();
536
+ const removeSwaps = [];
537
+ const broadcastedOrConfirmedSwaps = [];
538
+ for (let pastSwap of pastSwaps) {
539
+ let changed = false;
540
+ if (pastSwap.state === SpvFromBTCSwap_1.SpvFromBTCSwapState.SIGNED ||
541
+ pastSwap.state === SpvFromBTCSwap_1.SpvFromBTCSwapState.POSTED ||
542
+ pastSwap.state === SpvFromBTCSwap_1.SpvFromBTCSwapState.BROADCASTED ||
543
+ pastSwap.state === SpvFromBTCSwap_1.SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED ||
544
+ pastSwap.state === SpvFromBTCSwap_1.SpvFromBTCSwapState.DECLINED ||
545
+ pastSwap.state === SpvFromBTCSwap_1.SpvFromBTCSwapState.BTC_TX_CONFIRMED) {
546
+ //Check BTC transaction
547
+ if (await pastSwap._syncStateFromBitcoin(false))
548
+ changed ||= true;
549
+ }
550
+ if (pastSwap.state === SpvFromBTCSwap_1.SpvFromBTCSwapState.CREATED ||
551
+ pastSwap.state === SpvFromBTCSwap_1.SpvFromBTCSwapState.SIGNED ||
552
+ pastSwap.state === SpvFromBTCSwap_1.SpvFromBTCSwapState.POSTED) {
553
+ if (pastSwap.expiry < Date.now()) {
554
+ if (pastSwap.state === SpvFromBTCSwap_1.SpvFromBTCSwapState.CREATED) {
555
+ pastSwap.state = SpvFromBTCSwap_1.SpvFromBTCSwapState.QUOTE_EXPIRED;
556
+ }
557
+ else {
558
+ pastSwap.state = SpvFromBTCSwap_1.SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED;
559
+ }
560
+ changed ||= true;
561
+ }
562
+ }
563
+ if (pastSwap.isQuoteExpired()) {
564
+ removeSwaps.push(pastSwap);
565
+ continue;
566
+ }
567
+ if (changed)
568
+ changedSwaps.add(pastSwap);
569
+ if (pastSwap.state === SpvFromBTCSwap_1.SpvFromBTCSwapState.BROADCASTED || pastSwap.state === SpvFromBTCSwap_1.SpvFromBTCSwapState.BTC_TX_CONFIRMED) {
570
+ if (pastSwap.data != null)
571
+ broadcastedOrConfirmedSwaps.push(pastSwap);
572
+ }
573
+ }
574
+ const checkWithdrawalStateSwaps = [];
575
+ const _fronts = await this.contract.getFronterAddresses(broadcastedOrConfirmedSwaps.map(val => ({
576
+ owner: val.vaultOwner,
577
+ vaultId: val.vaultId,
578
+ withdrawal: val.data
579
+ })));
580
+ const _vaultUtxos = await this.contract.getVaultLatestUtxos(broadcastedOrConfirmedSwaps.map(val => ({
581
+ owner: val.vaultOwner,
582
+ vaultId: val.vaultId
583
+ })));
584
+ for (const pastSwap of broadcastedOrConfirmedSwaps) {
585
+ const fronterAddress = _fronts[pastSwap.data.getTxId()];
586
+ const latestVaultUtxo = _vaultUtxos[pastSwap.vaultOwner]?.[pastSwap.vaultId.toString(10)];
587
+ if (fronterAddress === undefined)
588
+ this.logger.warn(`_checkPastSwaps(): No fronter address returned for ${pastSwap.data.getTxId()}`);
589
+ if (latestVaultUtxo === undefined)
590
+ this.logger.warn(`_checkPastSwaps(): No last vault utxo returned for ${pastSwap.data.getTxId()}`);
591
+ if (await pastSwap._shouldCheckWithdrawalState(fronterAddress, latestVaultUtxo))
592
+ checkWithdrawalStateSwaps.push(pastSwap);
593
+ }
594
+ const withdrawalStates = await this.contract.getWithdrawalStates(checkWithdrawalStateSwaps.map(val => ({
595
+ withdrawal: val.data,
596
+ scStartBlockheight: val.genesisSmartChainBlockHeight
597
+ })));
598
+ for (const pastSwap of checkWithdrawalStateSwaps) {
599
+ const status = withdrawalStates[pastSwap.data.getTxId()];
600
+ if (status == null) {
601
+ this.logger.warn(`_checkPastSwaps(): No withdrawal state returned for ${pastSwap.data.getTxId()}`);
602
+ continue;
603
+ }
604
+ this.logger.debug("syncStateFromChain(): status of " + pastSwap.data.btcTx.txid, status?.type);
605
+ let changed = false;
606
+ switch (status.type) {
607
+ case base_1.SpvWithdrawalStateType.FRONTED:
608
+ pastSwap.frontTxId = status.txId;
609
+ pastSwap.state = SpvFromBTCSwap_1.SpvFromBTCSwapState.FRONTED;
610
+ changed ||= true;
611
+ break;
612
+ case base_1.SpvWithdrawalStateType.CLAIMED:
613
+ pastSwap.claimTxId = status.txId;
614
+ pastSwap.state = SpvFromBTCSwap_1.SpvFromBTCSwapState.CLAIMED;
615
+ changed ||= true;
616
+ break;
617
+ case base_1.SpvWithdrawalStateType.CLOSED:
618
+ pastSwap.state = SpvFromBTCSwap_1.SpvFromBTCSwapState.CLOSED;
619
+ changed ||= true;
620
+ break;
621
+ }
622
+ if (changed)
623
+ changedSwaps.add(pastSwap);
624
+ }
625
+ return {
626
+ changedSwaps: Array.from(changedSwaps),
627
+ removeSwaps
628
+ };
629
+ }
630
+ }
631
+ exports.SpvFromBTCWrapper = SpvFromBTCWrapper;