@atomiqlabs/sdk 8.9.1 → 8.9.2

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 (366) hide show
  1. package/LICENSE +201 -201
  2. package/README.md +1760 -1760
  3. package/api/index.d.ts +1 -1
  4. package/api/index.js +3 -3
  5. package/dist/ApiList.d.ts +37 -37
  6. package/dist/ApiList.js +30 -30
  7. package/dist/SmartChainAssets.d.ts +181 -181
  8. package/dist/SmartChainAssets.js +181 -181
  9. package/dist/api/ApiEndpoints.d.ts +393 -393
  10. package/dist/api/ApiEndpoints.js +2 -2
  11. package/dist/api/ApiParser.d.ts +10 -10
  12. package/dist/api/ApiParser.js +134 -134
  13. package/dist/api/ApiTypes.d.ts +157 -157
  14. package/dist/api/ApiTypes.js +75 -75
  15. package/dist/api/SerializedAction.d.ts +40 -40
  16. package/dist/api/SerializedAction.js +59 -59
  17. package/dist/api/SwapperApi.d.ts +50 -50
  18. package/dist/api/SwapperApi.js +431 -431
  19. package/dist/api/index.d.ts +5 -5
  20. package/dist/api/index.js +24 -24
  21. package/dist/bitcoin/coinselect2/accumulative.d.ts +7 -7
  22. package/dist/bitcoin/coinselect2/accumulative.js +52 -52
  23. package/dist/bitcoin/coinselect2/blackjack.d.ts +7 -7
  24. package/dist/bitcoin/coinselect2/blackjack.js +38 -38
  25. package/dist/bitcoin/coinselect2/index.d.ts +20 -20
  26. package/dist/bitcoin/coinselect2/index.js +69 -69
  27. package/dist/bitcoin/coinselect2/utils.d.ts +82 -82
  28. package/dist/bitcoin/coinselect2/utils.js +158 -158
  29. package/dist/bitcoin/wallet/BitcoinWallet.d.ts +113 -113
  30. package/dist/bitcoin/wallet/BitcoinWallet.js +335 -335
  31. package/dist/bitcoin/wallet/IBitcoinWallet.d.ts +116 -116
  32. package/dist/bitcoin/wallet/IBitcoinWallet.js +21 -21
  33. package/dist/bitcoin/wallet/SingleAddressBitcoinWallet.d.ts +106 -106
  34. package/dist/bitcoin/wallet/SingleAddressBitcoinWallet.js +196 -196
  35. package/dist/enums/FeeType.d.ts +15 -15
  36. package/dist/enums/FeeType.js +19 -19
  37. package/dist/enums/SwapAmountType.d.ts +15 -15
  38. package/dist/enums/SwapAmountType.js +19 -19
  39. package/dist/enums/SwapDirection.d.ts +15 -15
  40. package/dist/enums/SwapDirection.js +19 -19
  41. package/dist/enums/SwapSide.d.ts +15 -15
  42. package/dist/enums/SwapSide.js +19 -19
  43. package/dist/enums/SwapType.d.ts +75 -75
  44. package/dist/enums/SwapType.js +79 -79
  45. package/dist/errors/IntermediaryError.d.ts +13 -13
  46. package/dist/errors/IntermediaryError.js +27 -27
  47. package/dist/errors/RequestError.d.ts +32 -32
  48. package/dist/errors/RequestError.js +54 -54
  49. package/dist/errors/UserError.d.ts +8 -8
  50. package/dist/errors/UserError.js +16 -16
  51. package/dist/events/UnifiedSwapEventListener.d.ts +24 -24
  52. package/dist/events/UnifiedSwapEventListener.js +138 -138
  53. package/dist/http/HttpUtils.d.ts +29 -29
  54. package/dist/http/HttpUtils.js +97 -97
  55. package/dist/http/paramcoders/IParamReader.d.ts +8 -8
  56. package/dist/http/paramcoders/IParamReader.js +2 -2
  57. package/dist/http/paramcoders/ParamDecoder.d.ts +44 -44
  58. package/dist/http/paramcoders/ParamDecoder.js +137 -137
  59. package/dist/http/paramcoders/ParamEncoder.d.ts +20 -20
  60. package/dist/http/paramcoders/ParamEncoder.js +36 -36
  61. package/dist/http/paramcoders/SchemaVerifier.d.ts +26 -26
  62. package/dist/http/paramcoders/SchemaVerifier.js +145 -145
  63. package/dist/http/paramcoders/client/ResponseParamDecoder.d.ts +11 -11
  64. package/dist/http/paramcoders/client/ResponseParamDecoder.js +57 -57
  65. package/dist/http/paramcoders/client/StreamParamEncoder.d.ts +13 -13
  66. package/dist/http/paramcoders/client/StreamParamEncoder.js +26 -26
  67. package/dist/http/paramcoders/client/StreamingFetchPromise.d.ts +17 -17
  68. package/dist/http/paramcoders/client/StreamingFetchPromise.js +175 -175
  69. package/dist/index.d.ts +86 -86
  70. package/dist/index.js +159 -159
  71. package/dist/intermediaries/Intermediary.d.ts +178 -178
  72. package/dist/intermediaries/Intermediary.js +166 -166
  73. package/dist/intermediaries/IntermediaryDiscovery.d.ts +216 -216
  74. package/dist/intermediaries/IntermediaryDiscovery.js +424 -424
  75. package/dist/intermediaries/apis/IntermediaryAPI.d.ts +607 -607
  76. package/dist/intermediaries/apis/IntermediaryAPI.js +764 -764
  77. package/dist/intermediaries/apis/TrustedIntermediaryAPI.d.ts +155 -155
  78. package/dist/intermediaries/apis/TrustedIntermediaryAPI.js +137 -137
  79. package/dist/intermediaries/auth/SignedKeyBasedAuth.d.ts +14 -14
  80. package/dist/intermediaries/auth/SignedKeyBasedAuth.js +68 -68
  81. package/dist/lnurl/LNURL.d.ts +102 -102
  82. package/dist/lnurl/LNURL.js +321 -321
  83. package/dist/prices/RedundantSwapPrice.d.ts +110 -110
  84. package/dist/prices/RedundantSwapPrice.js +222 -222
  85. package/dist/prices/SingleSwapPrice.d.ts +34 -34
  86. package/dist/prices/SingleSwapPrice.js +44 -44
  87. package/dist/prices/SwapPriceWithChain.d.ts +107 -107
  88. package/dist/prices/SwapPriceWithChain.js +128 -128
  89. package/dist/prices/abstract/ICachedSwapPrice.d.ts +28 -28
  90. package/dist/prices/abstract/ICachedSwapPrice.js +62 -62
  91. package/dist/prices/abstract/IPriceProvider.d.ts +81 -81
  92. package/dist/prices/abstract/IPriceProvider.js +74 -74
  93. package/dist/prices/abstract/ISwapPrice.d.ts +168 -168
  94. package/dist/prices/abstract/ISwapPrice.js +279 -279
  95. package/dist/prices/providers/BinancePriceProvider.d.ts +23 -23
  96. package/dist/prices/providers/BinancePriceProvider.js +30 -30
  97. package/dist/prices/providers/CoinGeckoPriceProvider.d.ts +23 -23
  98. package/dist/prices/providers/CoinGeckoPriceProvider.js +29 -29
  99. package/dist/prices/providers/CoinPaprikaPriceProvider.d.ts +25 -25
  100. package/dist/prices/providers/CoinPaprikaPriceProvider.js +29 -29
  101. package/dist/prices/providers/CustomPriceProvider.d.ts +24 -24
  102. package/dist/prices/providers/CustomPriceProvider.js +35 -35
  103. package/dist/prices/providers/KrakenPriceProvider.d.ts +38 -38
  104. package/dist/prices/providers/KrakenPriceProvider.js +45 -45
  105. package/dist/prices/providers/OKXPriceProvider.d.ts +34 -34
  106. package/dist/prices/providers/OKXPriceProvider.js +29 -29
  107. package/dist/prices/providers/abstract/ExchangePriceProvider.d.ts +17 -17
  108. package/dist/prices/providers/abstract/ExchangePriceProvider.js +21 -21
  109. package/dist/prices/providers/abstract/HttpPriceProvider.d.ts +7 -7
  110. package/dist/prices/providers/abstract/HttpPriceProvider.js +12 -12
  111. package/dist/storage/IUnifiedStorage.d.ts +127 -127
  112. package/dist/storage/IUnifiedStorage.js +2 -2
  113. package/dist/storage/UnifiedSwapStorage.d.ts +120 -120
  114. package/dist/storage/UnifiedSwapStorage.js +154 -154
  115. package/dist/storage-browser/IndexedDBUnifiedStorage.d.ts +63 -63
  116. package/dist/storage-browser/IndexedDBUnifiedStorage.js +298 -298
  117. package/dist/storage-browser/LocalStorageManager.d.ts +49 -49
  118. package/dist/storage-browser/LocalStorageManager.js +93 -93
  119. package/dist/swapper/Swapper.d.ts +765 -770
  120. package/dist/swapper/Swapper.js +1749 -1758
  121. package/dist/swapper/SwapperFactory.d.ts +135 -135
  122. package/dist/swapper/SwapperFactory.js +162 -162
  123. package/dist/swapper/SwapperUtils.d.ts +222 -222
  124. package/dist/swapper/SwapperUtils.js +519 -519
  125. package/dist/swapper/SwapperWithChain.d.ts +404 -404
  126. package/dist/swapper/SwapperWithChain.js +469 -469
  127. package/dist/swapper/SwapperWithSigner.d.ts +322 -322
  128. package/dist/swapper/SwapperWithSigner.js +318 -318
  129. package/dist/swaps/IAddressSwap.d.ts +22 -22
  130. package/dist/swaps/IAddressSwap.js +14 -14
  131. package/dist/swaps/IBTCWalletSwap.d.ts +73 -73
  132. package/dist/swaps/IBTCWalletSwap.js +18 -18
  133. package/dist/swaps/IClaimableSwap.d.ts +49 -49
  134. package/dist/swaps/IClaimableSwap.js +15 -15
  135. package/dist/swaps/IClaimableSwapWrapper.d.ts +15 -15
  136. package/dist/swaps/IClaimableSwapWrapper.js +2 -2
  137. package/dist/swaps/IRefundableSwap.d.ts +43 -43
  138. package/dist/swaps/IRefundableSwap.js +14 -14
  139. package/dist/swaps/ISwap.d.ts +453 -453
  140. package/dist/swaps/ISwap.js +371 -371
  141. package/dist/swaps/ISwapWithGasDrop.d.ts +21 -21
  142. package/dist/swaps/ISwapWithGasDrop.js +12 -12
  143. package/dist/swaps/ISwapWrapper.d.ts +295 -295
  144. package/dist/swaps/ISwapWrapper.js +373 -373
  145. package/dist/swaps/escrow_swaps/IEscrowSelfInitSwap.d.ts +98 -98
  146. package/dist/swaps/escrow_swaps/IEscrowSelfInitSwap.js +126 -126
  147. package/dist/swaps/escrow_swaps/IEscrowSwap.d.ts +139 -139
  148. package/dist/swaps/escrow_swaps/IEscrowSwap.js +172 -172
  149. package/dist/swaps/escrow_swaps/IEscrowSwapWrapper.d.ts +129 -129
  150. package/dist/swaps/escrow_swaps/IEscrowSwapWrapper.js +167 -167
  151. package/dist/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.d.ts +107 -107
  152. package/dist/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.js +130 -130
  153. package/dist/swaps/escrow_swaps/frombtc/IFromBTCSelfInitSwap.d.ts +162 -162
  154. package/dist/swaps/escrow_swaps/frombtc/IFromBTCSelfInitSwap.js +190 -190
  155. package/dist/swaps/escrow_swaps/frombtc/IFromBTCWrapper.d.ts +64 -64
  156. package/dist/swaps/escrow_swaps/frombtc/IFromBTCWrapper.js +82 -82
  157. package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.d.ts +547 -547
  158. package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.js +1419 -1419
  159. package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.d.ts +192 -192
  160. package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.js +432 -432
  161. package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.d.ts +650 -650
  162. package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.js +1577 -1577
  163. package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.d.ts +237 -237
  164. package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.js +525 -525
  165. package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.d.ts +491 -491
  166. package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.js +1463 -1463
  167. package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.d.ts +204 -204
  168. package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.js +406 -406
  169. package/dist/swaps/escrow_swaps/tobtc/IToBTCSwap.d.ts +446 -446
  170. package/dist/swaps/escrow_swaps/tobtc/IToBTCSwap.js +1097 -1097
  171. package/dist/swaps/escrow_swaps/tobtc/IToBTCWrapper.d.ts +68 -68
  172. package/dist/swaps/escrow_swaps/tobtc/IToBTCWrapper.js +117 -117
  173. package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNSwap.d.ts +127 -127
  174. package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNSwap.js +256 -256
  175. package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.d.ts +252 -252
  176. package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.js +535 -535
  177. package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCSwap.d.ts +73 -73
  178. package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCSwap.js +155 -155
  179. package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.d.ts +134 -134
  180. package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.js +286 -286
  181. package/dist/swaps/spv_swaps/SpvFromBTCSwap.d.ts +694 -694
  182. package/dist/swaps/spv_swaps/SpvFromBTCSwap.js +1687 -1687
  183. package/dist/swaps/spv_swaps/SpvFromBTCWrapper.d.ts +259 -259
  184. package/dist/swaps/spv_swaps/SpvFromBTCWrapper.js +947 -947
  185. package/dist/swaps/trusted/ln/LnForGasSwap.d.ts +302 -302
  186. package/dist/swaps/trusted/ln/LnForGasSwap.js +625 -625
  187. package/dist/swaps/trusted/ln/LnForGasWrapper.d.ts +40 -40
  188. package/dist/swaps/trusted/ln/LnForGasWrapper.js +82 -82
  189. package/dist/swaps/trusted/onchain/OnchainForGasSwap.d.ts +343 -343
  190. package/dist/swaps/trusted/onchain/OnchainForGasSwap.js +698 -698
  191. package/dist/swaps/trusted/onchain/OnchainForGasWrapper.d.ts +71 -71
  192. package/dist/swaps/trusted/onchain/OnchainForGasWrapper.js +93 -93
  193. package/dist/types/AmountData.d.ts +10 -10
  194. package/dist/types/AmountData.js +2 -2
  195. package/dist/types/CustomPriceFunction.d.ts +11 -11
  196. package/dist/types/CustomPriceFunction.js +2 -2
  197. package/dist/types/PriceInfoType.d.ts +28 -28
  198. package/dist/types/PriceInfoType.js +57 -57
  199. package/dist/types/SwapExecutionAction.d.ts +195 -195
  200. package/dist/types/SwapExecutionAction.js +106 -106
  201. package/dist/types/SwapExecutionStep.d.ts +144 -144
  202. package/dist/types/SwapExecutionStep.js +87 -87
  203. package/dist/types/SwapStateInfo.d.ts +5 -5
  204. package/dist/types/SwapStateInfo.js +2 -2
  205. package/dist/types/SwapWithSigner.d.ts +17 -17
  206. package/dist/types/SwapWithSigner.js +43 -43
  207. package/dist/types/Token.d.ts +99 -99
  208. package/dist/types/Token.js +76 -76
  209. package/dist/types/TokenAmount.d.ts +75 -75
  210. package/dist/types/TokenAmount.js +85 -85
  211. package/dist/types/fees/Fee.d.ts +50 -50
  212. package/dist/types/fees/Fee.js +2 -2
  213. package/dist/types/fees/FeeBreakdown.d.ts +11 -11
  214. package/dist/types/fees/FeeBreakdown.js +2 -2
  215. package/dist/types/fees/PercentagePPM.d.ts +17 -17
  216. package/dist/types/fees/PercentagePPM.js +18 -18
  217. package/dist/types/lnurl/LNURLPay.d.ts +61 -61
  218. package/dist/types/lnurl/LNURLPay.js +31 -31
  219. package/dist/types/lnurl/LNURLWithdraw.d.ts +48 -48
  220. package/dist/types/lnurl/LNURLWithdraw.js +27 -27
  221. package/dist/types/wallets/LightningInvoiceCreateService.d.ts +24 -24
  222. package/dist/types/wallets/LightningInvoiceCreateService.js +15 -15
  223. package/dist/types/wallets/MinimalBitcoinWalletInterface.d.ts +23 -23
  224. package/dist/types/wallets/MinimalBitcoinWalletInterface.js +2 -2
  225. package/dist/types/wallets/MinimalLightningNetworkWalletInterface.d.ts +9 -9
  226. package/dist/types/wallets/MinimalLightningNetworkWalletInterface.js +2 -2
  227. package/dist/utils/AutomaticClockDriftCorrection.d.ts +1 -1
  228. package/dist/utils/AutomaticClockDriftCorrection.js +70 -70
  229. package/dist/utils/BitcoinUtils.d.ts +18 -18
  230. package/dist/utils/BitcoinUtils.js +174 -174
  231. package/dist/utils/BitcoinWalletUtils.d.ts +7 -7
  232. package/dist/utils/BitcoinWalletUtils.js +14 -14
  233. package/dist/utils/Logger.d.ts +7 -7
  234. package/dist/utils/Logger.js +12 -12
  235. package/dist/utils/RetryUtils.d.ts +22 -22
  236. package/dist/utils/RetryUtils.js +67 -67
  237. package/dist/utils/SwapUtils.d.ts +88 -88
  238. package/dist/utils/SwapUtils.js +72 -72
  239. package/dist/utils/TimeoutUtils.d.ts +17 -17
  240. package/dist/utils/TimeoutUtils.js +55 -55
  241. package/dist/utils/TokenUtils.d.ts +19 -19
  242. package/dist/utils/TokenUtils.js +37 -37
  243. package/dist/utils/TypeUtils.d.ts +7 -7
  244. package/dist/utils/TypeUtils.js +2 -2
  245. package/dist/utils/Utils.d.ts +69 -69
  246. package/dist/utils/Utils.js +214 -214
  247. package/package.json +46 -46
  248. package/src/SmartChainAssets.ts +186 -186
  249. package/src/api/ApiEndpoints.ts +427 -427
  250. package/src/api/ApiParser.ts +138 -138
  251. package/src/api/ApiTypes.ts +229 -229
  252. package/src/api/SerializedAction.ts +97 -97
  253. package/src/api/SwapperApi.ts +545 -545
  254. package/src/api/index.ts +5 -5
  255. package/src/bitcoin/coinselect2/accumulative.ts +69 -69
  256. package/src/bitcoin/coinselect2/blackjack.ts +50 -50
  257. package/src/bitcoin/coinselect2/index.ts +93 -93
  258. package/src/bitcoin/coinselect2/utils.ts +236 -236
  259. package/src/bitcoin/wallet/BitcoinWallet.ts +439 -439
  260. package/src/bitcoin/wallet/IBitcoinWallet.ts +140 -140
  261. package/src/bitcoin/wallet/SingleAddressBitcoinWallet.ts +225 -225
  262. package/src/enums/FeeType.ts +15 -15
  263. package/src/enums/SwapAmountType.ts +16 -16
  264. package/src/enums/SwapDirection.ts +15 -15
  265. package/src/enums/SwapSide.ts +16 -16
  266. package/src/enums/SwapType.ts +75 -75
  267. package/src/errors/IntermediaryError.ts +28 -28
  268. package/src/errors/RequestError.ts +64 -64
  269. package/src/errors/UserError.ts +15 -15
  270. package/src/events/UnifiedSwapEventListener.ts +181 -181
  271. package/src/http/HttpUtils.ts +97 -97
  272. package/src/http/paramcoders/IParamReader.ts +9 -9
  273. package/src/http/paramcoders/ParamDecoder.ts +145 -145
  274. package/src/http/paramcoders/ParamEncoder.ts +40 -40
  275. package/src/http/paramcoders/SchemaVerifier.ts +153 -153
  276. package/src/http/paramcoders/client/ResponseParamDecoder.ts +57 -57
  277. package/src/http/paramcoders/client/StreamParamEncoder.ts +28 -28
  278. package/src/http/paramcoders/client/StreamingFetchPromise.ts +194 -194
  279. package/src/index.ts +141 -141
  280. package/src/intermediaries/Intermediary.ts +280 -280
  281. package/src/intermediaries/IntermediaryDiscovery.ts +548 -548
  282. package/src/intermediaries/apis/IntermediaryAPI.ts +1247 -1247
  283. package/src/intermediaries/auth/SignedKeyBasedAuth.ts +69 -69
  284. package/src/lnurl/LNURL.ts +402 -402
  285. package/src/prices/RedundantSwapPrice.ts +264 -264
  286. package/src/prices/SingleSwapPrice.ts +50 -50
  287. package/src/prices/SwapPriceWithChain.ts +194 -194
  288. package/src/prices/abstract/ICachedSwapPrice.ts +85 -85
  289. package/src/prices/abstract/IPriceProvider.ts +127 -127
  290. package/src/prices/abstract/ISwapPrice.ts +390 -390
  291. package/src/prices/providers/BinancePriceProvider.ts +48 -48
  292. package/src/prices/providers/CoinGeckoPriceProvider.ts +46 -46
  293. package/src/prices/providers/CoinPaprikaPriceProvider.ts +49 -49
  294. package/src/prices/providers/CustomPriceProvider.ts +40 -40
  295. package/src/prices/providers/KrakenPriceProvider.ts +83 -83
  296. package/src/prices/providers/OKXPriceProvider.ts +59 -59
  297. package/src/prices/providers/abstract/ExchangePriceProvider.ts +31 -31
  298. package/src/prices/providers/abstract/HttpPriceProvider.ts +14 -14
  299. package/src/storage/IUnifiedStorage.ts +136 -136
  300. package/src/storage/UnifiedSwapStorage.ts +175 -175
  301. package/src/storage-browser/IndexedDBUnifiedStorage.ts +350 -350
  302. package/src/storage-browser/LocalStorageManager.ts +106 -106
  303. package/src/swapper/Swapper.ts +2557 -2570
  304. package/src/swapper/SwapperFactory.ts +307 -307
  305. package/src/swapper/SwapperUtils.ts +610 -610
  306. package/src/swapper/SwapperWithChain.ts +707 -707
  307. package/src/swapper/SwapperWithSigner.ts +511 -511
  308. package/src/swaps/IAddressSwap.ts +30 -30
  309. package/src/swaps/IBTCWalletSwap.ts +92 -92
  310. package/src/swaps/IClaimableSwap.ts +65 -65
  311. package/src/swaps/IClaimableSwapWrapper.ts +17 -17
  312. package/src/swaps/IRefundableSwap.ts +58 -58
  313. package/src/swaps/ISwap.ts +775 -775
  314. package/src/swaps/ISwapWithGasDrop.ts +25 -25
  315. package/src/swaps/ISwapWrapper.ts +564 -564
  316. package/src/swaps/escrow_swaps/IEscrowSelfInitSwap.ts +217 -217
  317. package/src/swaps/escrow_swaps/IEscrowSwap.ts +271 -271
  318. package/src/swaps/escrow_swaps/IEscrowSwapWrapper.ts +284 -284
  319. package/src/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.ts +172 -172
  320. package/src/swaps/escrow_swaps/frombtc/IFromBTCSelfInitSwap.ts +300 -300
  321. package/src/swaps/escrow_swaps/frombtc/IFromBTCWrapper.ts +107 -107
  322. package/src/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.ts +1670 -1671
  323. package/src/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.ts +603 -603
  324. package/src/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.ts +1883 -1883
  325. package/src/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.ts +752 -752
  326. package/src/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.ts +1753 -1753
  327. package/src/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.ts +612 -612
  328. package/src/swaps/escrow_swaps/tobtc/IToBTCSwap.ts +1327 -1327
  329. package/src/swaps/escrow_swaps/tobtc/IToBTCWrapper.ts +138 -138
  330. package/src/swaps/escrow_swaps/tobtc/ln/ToBTCLNSwap.ts +304 -304
  331. package/src/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.ts +787 -787
  332. package/src/swaps/escrow_swaps/tobtc/onchain/ToBTCSwap.ts +206 -206
  333. package/src/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.ts +403 -403
  334. package/src/swaps/spv_swaps/SpvFromBTCSwap.ts +2148 -2148
  335. package/src/swaps/spv_swaps/SpvFromBTCWrapper.ts +1238 -1238
  336. package/src/swaps/trusted/ln/LnForGasSwap.ts +753 -753
  337. package/src/swaps/trusted/ln/LnForGasWrapper.ts +90 -90
  338. package/src/swaps/trusted/onchain/OnchainForGasSwap.ts +843 -843
  339. package/src/swaps/trusted/onchain/OnchainForGasWrapper.ts +133 -133
  340. package/src/types/AmountData.ts +9 -9
  341. package/src/types/CustomPriceFunction.ts +11 -11
  342. package/src/types/PriceInfoType.ts +66 -66
  343. package/src/types/SwapExecutionAction.ts +323 -323
  344. package/src/types/SwapExecutionStep.ts +224 -224
  345. package/src/types/SwapStateInfo.ts +6 -6
  346. package/src/types/SwapWithSigner.ts +61 -61
  347. package/src/types/Token.ts +163 -163
  348. package/src/types/TokenAmount.ts +167 -167
  349. package/src/types/fees/Fee.ts +56 -56
  350. package/src/types/fees/FeeBreakdown.ts +11 -11
  351. package/src/types/fees/PercentagePPM.ts +26 -26
  352. package/src/types/lnurl/LNURLPay.ts +79 -79
  353. package/src/types/lnurl/LNURLWithdraw.ts +61 -61
  354. package/src/types/wallets/LightningInvoiceCreateService.ts +30 -30
  355. package/src/types/wallets/MinimalBitcoinWalletInterface.ts +21 -21
  356. package/src/types/wallets/MinimalLightningNetworkWalletInterface.ts +9 -9
  357. package/src/utils/AutomaticClockDriftCorrection.ts +71 -71
  358. package/src/utils/BitcoinUtils.ts +164 -164
  359. package/src/utils/BitcoinWalletUtils.ts +15 -15
  360. package/src/utils/Logger.ts +14 -14
  361. package/src/utils/RetryUtils.ts +78 -78
  362. package/src/utils/SwapUtils.ts +99 -99
  363. package/src/utils/TimeoutUtils.ts +49 -49
  364. package/src/utils/TokenUtils.ts +33 -33
  365. package/src/utils/TypeUtils.ts +8 -8
  366. package/src/utils/Utils.ts +221 -221
@@ -1,775 +1,775 @@
1
- import {SwapType} from "../enums/SwapType";
2
- import {EventEmitter} from "events";
3
- import {ISwapWrapper, SwapTypeDefinition} from "./ISwapWrapper";
4
- import {ChainType} from "@atomiqlabs/base";
5
- import {randomBytes, toBigInt} from "../utils/Utils";
6
- import {SwapDirection} from "../enums/SwapDirection";
7
- import {Fee} from "../types/fees/Fee";
8
- import {FeeBreakdown} from "../types/fees/FeeBreakdown";
9
- import {PercentagePPM, ppmToPercentage} from "../types/fees/PercentagePPM";
10
- import {TokenAmount} from "../types/TokenAmount";
11
- import {isSCToken, Token} from "../types/Token";
12
- import {SwapExecutionAction} from "../types/SwapExecutionAction";
13
- import {LoggerType} from "../utils/Logger";
14
- import {isPriceInfoType, PriceInfoType} from "../types/PriceInfoType";
15
- import {SwapStateInfo} from "../types/SwapStateInfo";
16
- import {SwapExecutionStep} from "../types/SwapExecutionStep";
17
-
18
- /**
19
- * Initialization data for creating a swap
20
- *
21
- * @category Swaps/Base
22
- */
23
- export type ISwapInit = {
24
- pricingInfo: PriceInfoType,
25
- url?: string,
26
- expiry: number,
27
- swapFee: bigint,
28
- swapFeeBtc: bigint,
29
- exactIn: boolean,
30
- contractVersion: string
31
- };
32
-
33
- /**
34
- * Type guard to check if an object is an ISwapInit
35
- *
36
- * @category Swaps/Base
37
- */
38
- export function isISwapInit(obj: any): obj is ISwapInit {
39
- return typeof obj === 'object' &&
40
- obj != null &&
41
- isPriceInfoType(obj.pricingInfo) &&
42
- (obj.url==null || typeof obj.url === 'string') &&
43
- typeof obj.expiry === 'number' &&
44
- typeof(obj.swapFee) === "bigint" &&
45
- typeof(obj.swapFeeBtc) === "bigint" &&
46
- (typeof obj.exactIn === 'boolean');
47
- }
48
-
49
- /**
50
- * Base abstract class for all swap types
51
- *
52
- * @category Swaps/Base
53
- */
54
- export abstract class ISwap<
55
- T extends ChainType = ChainType,
56
- D extends SwapTypeDefinition<T, ISwapWrapper<T, D>, ISwap<T, D, S>> = SwapTypeDefinition<T, ISwapWrapper<T, any>, ISwap<T, any, any>>,
57
- S extends number = number
58
- > {
59
- /**
60
- * Swap type
61
- */
62
- protected readonly abstract TYPE: SwapType;
63
-
64
- /**
65
- * Description for the states
66
- * @internal
67
- */
68
- protected readonly abstract swapStateDescription: Record<S, string>;
69
- /**
70
- * Name of the states
71
- * @internal
72
- */
73
- protected readonly abstract swapStateName: (state: number) => string;
74
- /**
75
- * Swap logger
76
- * @internal
77
- */
78
- protected readonly abstract logger: LoggerType;
79
- /**
80
- * Current newest defined version of the swap
81
- * @internal
82
- */
83
- protected readonly currentVersion: number = 1;
84
- /**
85
- * Wrapper instance holding this swap
86
- * @internal
87
- */
88
- protected readonly wrapper: D["Wrapper"];
89
-
90
-
91
- /**
92
- * The current version of the swap
93
- * @internal
94
- */
95
- protected version: number;
96
- /**
97
- * Whether a swap was initialized, a swap is considered initialize on first interaction with it, i.e.
98
- * calling commit() on a Smart chain -> Bitcoin swaps, calling waitForPayment() or similar on the other
99
- * direction. Not initiated swaps are not saved to the persistent storage by default (see
100
- * {@link SwapperOptions.saveUninitializedSwaps})
101
- * @internal
102
- */
103
- protected initiated: boolean = false;
104
- /**
105
- * Expiration of the swap quote
106
- * @internal
107
- */
108
- protected expiry: number;
109
- /**
110
- * Pricing information of the swap
111
- * @internal
112
- */
113
- protected pricingInfo?: PriceInfoType;
114
- /**
115
- * Swap fee in the non-bitcoin token
116
- * @internal
117
- */
118
- protected swapFee: bigint;
119
- /**
120
- * Swap fee in bitcoin satoshis
121
- * @internal
122
- */
123
- protected swapFeeBtc: bigint;
124
-
125
-
126
- /**
127
- * Swap state
128
- * @internal
129
- */
130
- _state: S = 0 as S;
131
- /**
132
- * Random nonce to differentiate the swap from others with the same identifier hash (i.e. when quoting the same swap
133
- * from multiple LPs)
134
- * @internal
135
- */
136
- _randomNonce: string;
137
- /**
138
- * Whether the swap is saved in the persistent storage or not.
139
- *
140
- * @remarks This field itself is not persisted but is instead derived during runtime
141
- *
142
- * @internal
143
- */
144
- _persisted: boolean = false;
145
- /**
146
- * @internal
147
- */
148
- _contractVersion?: string;
149
- /**
150
- * Storage specific metadata that can be used for e.g. optimistic concurrency
151
- *
152
- * @internal
153
- */
154
- _meta?: any;
155
-
156
-
157
- /**
158
- * Event emitter emitting `"swapState"` event when swap's state changes
159
- */
160
- readonly events: EventEmitter<{swapState: [D["Swap"]]}> = new EventEmitter();
161
- /**
162
- * URL of the intermediary (LP) used for this swap, already has the swap service specific path appended
163
- */
164
- readonly url?: string;
165
- /**
166
- * Smart chain identifier string corresponding to this swap
167
- */
168
- readonly chainIdentifier: T["ChainId"];
169
- /**
170
- * Whether a swap is an exact input swap
171
- */
172
- readonly exactIn: boolean;
173
- /**
174
- * A UNIX milliseconds timestamps of when this swap was created
175
- */
176
- createdAt: number;
177
-
178
- protected constructor(wrapper: D["Wrapper"], obj: any);
179
- protected constructor(wrapper: D["Wrapper"], swapInit: ISwapInit);
180
- protected constructor(
181
- wrapper: D["Wrapper"],
182
- swapInitOrObj: ISwapInit | any,
183
- ) {
184
- this.chainIdentifier = wrapper.chainIdentifier;
185
- this.wrapper = wrapper;
186
- if(isISwapInit(swapInitOrObj)) {
187
- this.pricingInfo = swapInitOrObj.pricingInfo;
188
- this.url = swapInitOrObj.url;
189
- this.expiry = swapInitOrObj.expiry;
190
- this.swapFee = swapInitOrObj.swapFee;
191
- this.swapFeeBtc = swapInitOrObj.swapFeeBtc;
192
- this.exactIn = swapInitOrObj.exactIn;
193
- this.version = this.currentVersion;
194
- this.createdAt = Date.now();
195
- this._randomNonce = randomBytes(16).toString("hex");
196
- this._contractVersion = swapInitOrObj.contractVersion;
197
- } else {
198
- this.expiry = swapInitOrObj.expiry;
199
- this.url = swapInitOrObj.url;
200
-
201
- this._state = swapInitOrObj.state;
202
-
203
- if(
204
- swapInitOrObj._isValid!=null && swapInitOrObj._differencePPM!=null && swapInitOrObj._satsBaseFee!=null &&
205
- swapInitOrObj._feePPM!=null && swapInitOrObj._swapPriceUSatPerToken!=null
206
- ) {
207
- this.pricingInfo = {
208
- isValid: swapInitOrObj._isValid,
209
- differencePPM: BigInt(swapInitOrObj._differencePPM),
210
- satsBaseFee: BigInt(swapInitOrObj._satsBaseFee),
211
- feePPM: BigInt(swapInitOrObj._feePPM),
212
- realPriceUSatPerToken: toBigInt(swapInitOrObj._realPriceUSatPerToken),
213
- realPriceUsdPerBitcoin: swapInitOrObj._realPriceUsdPerBitcoin,
214
- swapPriceUSatPerToken: BigInt(swapInitOrObj._swapPriceUSatPerToken),
215
- };
216
- }
217
-
218
- this.swapFee = toBigInt(swapInitOrObj.swapFee);
219
- this.swapFeeBtc = toBigInt(swapInitOrObj.swapFeeBtc);
220
-
221
- this.version = swapInitOrObj.version;
222
- this.initiated = swapInitOrObj.initiated;
223
- this.exactIn = swapInitOrObj.exactIn;
224
- this.createdAt = swapInitOrObj.createdAt ?? swapInitOrObj.expiry;
225
-
226
- this._randomNonce = swapInitOrObj.randomNonce;
227
- this._contractVersion = swapInitOrObj.contractVersion;
228
- this._meta = swapInitOrObj._meta;
229
- }
230
- if(this.version!==this.currentVersion) {
231
- this.upgradeVersion();
232
- }
233
- if(this.initiated==null) this.initiated = true;
234
- }
235
-
236
- /**
237
- * Called when swap is deserialized to potentially update the version of the data for the swap
238
- *
239
- * @internal
240
- */
241
- protected abstract upgradeVersion(): void;
242
-
243
- /**
244
- * Waits till the swap reaches a specific state
245
- *
246
- * @param targetState The state to wait for
247
- * @param type Whether to wait for the state exactly or also to a state with a higher number
248
- * @param abortSignal Abort signal
249
- * @internal
250
- */
251
- protected waitTillState(targetState: S, type: "eq" | "gte" | "neq" = "eq", abortSignal?: AbortSignal): Promise<void> {
252
- //TODO: This doesn't hold strong reference to the swap, hence if no other strong reference to the
253
- // swap exists, it will just never resolve!
254
- return new Promise((resolve, reject) => {
255
- let listener: () => void;
256
- listener = () => {
257
- if(type==="eq" ? this._state===targetState : type==="gte" ? this._state>=targetState : this._state!=targetState) {
258
- resolve();
259
- this.events.removeListener("swapState", listener);
260
- }
261
- };
262
- this.events.on("swapState", listener);
263
- if(abortSignal!=null) abortSignal.addEventListener("abort", () => {
264
- this.events.removeListener("swapState", listener);
265
- reject(abortSignal.reason);
266
- });
267
- });
268
- }
269
-
270
- /**
271
- * Executes the swap with the provided wallet, the exact arguments for this functions differ for various swap
272
- * types. Check the `execute()` function signature in the respective swap class to see the required arguments.
273
- *
274
- * @param args Execution arguments, usually contains a source wallet object, callbacks and options, for exact
275
- * syntax check the respective swap class.
276
- *
277
- * @returns Whether a swap was successfully executed or not, if it wasn't the user can refund or claim manually
278
- */
279
- public abstract execute(...args: any[]): Promise<boolean>;
280
-
281
- //////////////////////////////
282
- //// Pricing
283
-
284
- /**
285
- * This attempts to populate missing fields in the pricing info based on the swap amounts
286
- *
287
- * @internal
288
- */
289
- protected tryRecomputeSwapPrice(): void {
290
- if(this.pricingInfo==null) return;
291
- if(this.pricingInfo.swapPriceUSatPerToken==null) {
292
- const priceUsdPerBtc = this.pricingInfo.realPriceUsdPerBitcoin;
293
- const input = this.getInput();
294
- const output = this.getOutput();
295
- if(input.isUnknown || output.isUnknown) return;
296
- if(isSCToken(input.token) && this.getDirection()===SwapDirection.TO_BTC) {
297
- this.pricingInfo = this.wrapper._prices.recomputePriceInfoSend(
298
- this.chainIdentifier,
299
- output.rawAmount!,
300
- this.pricingInfo.satsBaseFee,
301
- this.pricingInfo.feePPM,
302
- input.rawAmount!,
303
- input.token.address
304
- );
305
- this.pricingInfo.realPriceUsdPerBitcoin = priceUsdPerBtc;
306
- } else if(isSCToken(output.token) && this.getDirection()===SwapDirection.FROM_BTC) {
307
- this.pricingInfo = this.wrapper._prices.recomputePriceInfoReceive(
308
- this.chainIdentifier,
309
- input.rawAmount!,
310
- this.pricingInfo.satsBaseFee,
311
- this.pricingInfo.feePPM,
312
- output.rawAmount!,
313
- output.token.address
314
- );
315
- this.pricingInfo.realPriceUsdPerBitcoin = priceUsdPerBtc;
316
- }
317
- }
318
- }
319
-
320
- /**
321
- * Returns the specific state along with the human-readable description of that state
322
- *
323
- * @internal
324
- */
325
- protected _getStateInfo(state: S): SwapStateInfo<S> {
326
- return {
327
- state: state,
328
- name: this.swapStateName(state),
329
- description: this.swapStateDescription[state]
330
- };
331
- }
332
-
333
- /**
334
- * Re-fetches & revalidates the price data based on the current market prices
335
- */
336
- public async refreshPriceData(): Promise<void> {
337
- if(this.pricingInfo==null) return;
338
- const priceUsdPerBtc = this.pricingInfo.realPriceUsdPerBitcoin;
339
- const output = this.getOutput();
340
- if(output.isUnknown) return;
341
-
342
- if(isSCToken(this.getInputToken()) && this.getDirection()===SwapDirection.TO_BTC) {
343
- const input = this.getInputWithoutFee();
344
- if(input.isUnknown) return;
345
-
346
- this.pricingInfo = await this.wrapper._prices.isValidAmountSend(
347
- this.chainIdentifier,
348
- output.rawAmount!,
349
- this.pricingInfo.satsBaseFee,
350
- this.pricingInfo.feePPM,
351
- input.rawAmount! + this.swapFee,
352
- input.token.address,
353
- undefined,
354
- undefined,
355
- this.swapFeeBtc
356
- );
357
- this.pricingInfo.realPriceUsdPerBitcoin = priceUsdPerBtc;
358
- } else if(isSCToken(output.token) && this.getDirection()===SwapDirection.FROM_BTC) {
359
- const input = this.getInput();
360
- if(input.isUnknown) return;
361
-
362
- this.pricingInfo = await this.wrapper._prices.isValidAmountReceive(
363
- this.chainIdentifier,
364
- input.rawAmount!,
365
- this.pricingInfo.satsBaseFee,
366
- this.pricingInfo.feePPM,
367
- output.rawAmount!,
368
- output.token.address,
369
- undefined,
370
- undefined,
371
- this.swapFeeBtc
372
- );
373
- this.pricingInfo.realPriceUsdPerBitcoin = priceUsdPerBtc;
374
- }
375
- }
376
-
377
- /**
378
- * Checks if the pricing for the swap is valid, according to max allowed price difference set in the ISwapPrice
379
- */
380
- public hasValidPrice(): boolean {
381
- if(this.pricingInfo==null) throw new Error("Pricing info not found, cannot check price validity!");
382
- return this.pricingInfo.isValid;
383
- }
384
-
385
- /**
386
- * Returns pricing info about the swap
387
- */
388
- public getPriceInfo(): {
389
- marketPrice?: number,
390
- swapPrice: number,
391
- difference: PercentagePPM
392
- } {
393
- if(this.pricingInfo==null) throw new Error("Pricing info not provided and not known!");
394
-
395
- const swapPrice = this.getDirection()===SwapDirection.TO_BTC ?
396
- 100_000_000_000_000/Number(this.pricingInfo.swapPriceUSatPerToken) :
397
- Number(this.pricingInfo.swapPriceUSatPerToken)/100_000_000_000_000;
398
-
399
- let marketPrice: number | undefined;
400
- if(this.pricingInfo.realPriceUSatPerToken!=null)
401
- marketPrice = this.getDirection()===SwapDirection.TO_BTC ?
402
- 100_000_000_000_000/Number(this.pricingInfo.realPriceUSatPerToken) :
403
- Number(this.pricingInfo.realPriceUSatPerToken)/100_000_000_000_000;
404
-
405
- return {
406
- marketPrice,
407
- swapPrice,
408
- difference: ppmToPercentage(this.pricingInfo.differencePPM)
409
- }
410
- }
411
-
412
-
413
- //////////////////////////////
414
- //// Getters & utils
415
-
416
- /**
417
- * Asserts a given signer is the initiator of this swap
418
- *
419
- * @param signer Signer to check with this swap's initiator
420
- * @throws {Error} When signer's address doesn't match with the swap's initiator one
421
- * @internal
422
- */
423
- protected checkSigner(signer: T["Signer"] | string): void {
424
- if((typeof(signer)==="string" ? signer : signer.getAddress())!==this._getInitiator()) throw new Error("Invalid signer provided!");
425
- }
426
-
427
- /**
428
- * Await and prepares a list of passed transactions
429
- *
430
- * @param txsPromise
431
- * @internal
432
- */
433
- protected async prepareTransactions(txsPromise: Promise<T["TX"][]>): Promise<T["TX"][]> {
434
- const txs = await txsPromise;
435
- if(this.wrapper._chain.prepareTxs==null) return txs;
436
- return await this.wrapper._chain.prepareTxs(txs);
437
- }
438
-
439
- /**
440
- * Returns an escrow hash of the swap
441
- *
442
- * @internal
443
- */
444
- abstract _getEscrowHash(): string | null;
445
-
446
- /**
447
- * Checks if the swap's quote is expired for good (i.e. the swap strictly cannot be initiated anymore)
448
- * @internal
449
- */
450
- abstract _verifyQuoteDefinitelyExpired(): Promise<boolean>;
451
-
452
- /**
453
- * Checks if the swap's quote is still valid
454
- * @internal
455
- */
456
- abstract _verifyQuoteValid(): Promise<boolean>;
457
-
458
- /**
459
- * Returns the intiator address of the swap - address that created this swap
460
- * @internal
461
- */
462
- abstract _getInitiator(): string;
463
-
464
- /**
465
- * Sets this swap as initiated
466
- * @internal
467
- */
468
- _setInitiated(): void {
469
- this.initiated = true;
470
- }
471
-
472
- /**
473
- * Returns source address of the swap
474
- */
475
- public abstract getInputAddress(): string | null;
476
-
477
- /**
478
- * Returns destination address of the swap
479
- */
480
- public abstract getOutputAddress(): string | null;
481
-
482
- /**
483
- * Returns swap input transaction ID on the source chain
484
- */
485
- public abstract getInputTxId(): string | null;
486
-
487
- /**
488
- * Returns swap output transaction ID on the destination chain
489
- */
490
- public abstract getOutputTxId(): string | null;
491
-
492
- /**
493
- * Returns the ID of the swap, as used in the storage
494
- */
495
- public abstract getId(): string;
496
-
497
- /**
498
- * Checks whether there is some action required from the user for this swap - can mean either refundable or claimable
499
- */
500
- public abstract requiresAction(): boolean;
501
-
502
- /**
503
- * Returns whether the swap is finished and in its terminal state (this can mean successful, refunded or failed)
504
- */
505
- public abstract isFinished(): boolean;
506
-
507
- /**
508
- * Checks whether the swap's quote has definitely expired and cannot be committed anymore, we can remove such swap
509
- */
510
- public abstract isQuoteExpired(): boolean;
511
-
512
- /**
513
- * Checks whether the swap's quote is soft expired (this means there is not enough time buffer for it to commit,
514
- * but it still can happen)
515
- */
516
- public abstract isQuoteSoftExpired(): boolean;
517
-
518
- /**
519
- * Returns whether the swap finished successful
520
- */
521
- public abstract isSuccessful(): boolean;
522
-
523
- /**
524
- * Returns whether the swap failed (e.g. was refunded)
525
- */
526
- public abstract isFailed(): boolean;
527
-
528
- /**
529
- * Returns whether the swap is currently being processed
530
- */
531
- public abstract isInProgress(): boolean;
532
-
533
- /**
534
- * Whether a swap was initialized, a swap is considered initialized on first interaction with it, i.e.
535
- * calling commit() on a Smart chain -> Bitcoin swaps, calling waitForPayment() or similar on the other
536
- * direction. Not initiated swaps are not saved to the persistent storage by default (see
537
- * {@link SwapperOptions.saveUninitializedSwaps})
538
- */
539
- public isInitiated(): boolean {
540
- return this.initiated;
541
- }
542
-
543
- /**
544
- * Returns quote expiry in UNIX millis
545
- */
546
- public getQuoteExpiry(): number {
547
- return this.expiry;
548
- }
549
-
550
- /**
551
- * Returns the type of the swap
552
- */
553
- public getType(): SwapType {
554
- return this.TYPE;
555
- }
556
-
557
- /**
558
- * Returns the direction of the swap
559
- */
560
- public getDirection(): SwapDirection {
561
- return this.TYPE===SwapType.TO_BTC || this.TYPE===SwapType.TO_BTCLN ? SwapDirection.TO_BTC : SwapDirection.FROM_BTC;
562
- }
563
-
564
- /**
565
- * Returns the current state of the swap
566
- */
567
- public getState(): S {
568
- return this._state;
569
- }
570
-
571
- /**
572
- * Returns the current state of the swap along with the human-readable description of the state
573
- */
574
- public getStateInfo(): SwapStateInfo<S> {
575
- return this._getStateInfo(this._state);
576
- }
577
-
578
- /**
579
- * Returns a current state-dependent action for the user to execute, or `undefined` if there is no more action
580
- * required for this swap - this means that the swap is probably finished (either expired, failed or settled).
581
- *
582
- * @param options Optional options argument for the additional action context (i.e. passing bitcoin wallet info to
583
- * get funded PSBTs or passing the externally-generated swap secret), see the actual type in the respective swap
584
- * classes
585
- */
586
- public abstract getExecutionAction(options?: any): Promise<SwapExecutionAction | undefined>;
587
-
588
- /**
589
- * Returns a list of execution steps the user has to go through for a given swap, to see the possible execution
590
- * steps check out {@link SwapExecutionStep}.
591
- *
592
- * @param options Optional options argument for the additional steps context (i.e. automatic settlement timeout),
593
- * see the actual type in the respective swap classes
594
- */
595
- public abstract getExecutionSteps(options?: any): Promise<SwapExecutionStep[]>;
596
-
597
- /**
598
- * Returns the current action and the full execution steps for a given swap. Prefer this to calling
599
- * {@link getExecutionSteps} and {@link getExecutionAction} separately - if called sequentially they might
600
- * return the respective steps/actions in different states if you hit the state transition boundary.
601
- *
602
- * @param options Optional options argument for the additional execution status context, see the actual type in
603
- * the respective swap classes
604
- */
605
- public abstract getExecutionStatus(options?: { skipBuildingAction?: boolean } & any): Promise<{
606
- steps: SwapExecutionStep[],
607
- currentAction: SwapExecutionAction | undefined,
608
- stateInfo: SwapStateInfo<S>
609
- }>;
610
-
611
- /**
612
- * Submits signed transactions obtained from the execution action back to the swap.
613
- *
614
- * @remarks This endpoint will also wait till the submitted transactions are confirmed (on a smart-chain side)
615
- * and till the swap state change is observed from the authoritative chain/intermediary state.
616
- *
617
- * If invalid transactions are submitted, i.e. sending a simple noop or transfer transaction instead of the
618
- * expected tx, this call may wait indefinitely unless aborted via the AbortSignal.
619
- *
620
- * @param txs Signed transactions
621
- * @param abortSignal Abort signal
622
- * @param requiredStates Optional list of states that the swap has to be in for the transactions to be
623
- * submitted, else throws
624
- * @param idempotent Whether the tx submission should be handled idempotently, meaning if any of the supplied
625
- * transactions are already processed as e.g. init, claim, refund or execution transactions the function just
626
- * returns these transaction IDs without actually submitting them
627
- *
628
- * @internal
629
- */
630
- abstract _submitExecutionTransactions(txs: (T["SignedTXType"] | string | any)[], abortSignal?: AbortSignal, requiredStates?: S[], idempotent?: boolean): Promise<string[]>;
631
-
632
- //////////////////////////////
633
- //// Amounts & fees
634
-
635
- /**
636
- * Returns output amount of the swap, user receives this much
637
- */
638
- public abstract getOutput(): TokenAmount;
639
-
640
- /**
641
- * Returns the output token of the swap
642
- */
643
- public abstract getOutputToken(): Token<T["ChainId"]>;
644
-
645
- /**
646
- * Returns input amount of the swap, user needs to pay this much
647
- */
648
- public abstract getInput(): TokenAmount;
649
-
650
- /**
651
- * Returns the input token of the swap
652
- */
653
- public abstract getInputToken(): Token<T["ChainId"]>;
654
-
655
- /**
656
- * Returns input amount of the swap without the fees (swap fee, network fee)
657
- */
658
- public abstract getInputWithoutFee(): TokenAmount;
659
-
660
- /**
661
- * Returns total fee for the swap, the fee is represented in source currency & destination currency, but is
662
- * paid only once
663
- */
664
- public abstract getFee(): Fee;
665
-
666
- /**
667
- * Returns the breakdown of all the fees paid
668
- */
669
- public abstract getFeeBreakdown(): FeeBreakdown<T["ChainId"]>;
670
-
671
-
672
- //////////////////////////////
673
- //// Storage
674
-
675
- /**
676
- * Saves the swap data to the underlying storage, or removes it if it is in a quote expired state
677
- *
678
- * @internal
679
- */
680
- _save(): Promise<void> {
681
- if(this.isQuoteExpired()) {
682
- return this.wrapper._removeSwapData(this);
683
- } else {
684
- return this.wrapper._saveSwapData(this);
685
- }
686
- }
687
-
688
- /**
689
- * Saves the swap data and also emits a swap state change
690
- *
691
- * @param state Optional state to set before the swap is saved an event emitted
692
- *
693
- * @internal
694
- */
695
- async _saveAndEmit(state?: S): Promise<void> {
696
- if(state!=null) this._state = state;
697
- await this._save();
698
- this._emitEvent();
699
- }
700
-
701
- /**
702
- * Serializes the swap to a JSON stringifiable representation (i.e. no bigints, buffers etc.)
703
- */
704
- public serialize(): any {
705
- if(this.pricingInfo==null) return {};
706
- return {
707
- id: this.getId(),
708
- type: this.getType(),
709
- escrowHash: this._getEscrowHash(),
710
- initiator: this._getInitiator(),
711
-
712
- _isValid: this.pricingInfo.isValid,
713
- _differencePPM: this.pricingInfo.differencePPM==null ? null :this.pricingInfo.differencePPM.toString(10),
714
- _satsBaseFee: this.pricingInfo.satsBaseFee==null ? null :this.pricingInfo.satsBaseFee.toString(10),
715
- _feePPM: this.pricingInfo.feePPM==null ? null :this.pricingInfo.feePPM.toString(10),
716
- _realPriceUSatPerToken: this.pricingInfo.realPriceUSatPerToken==null ? null :this.pricingInfo.realPriceUSatPerToken.toString(10),
717
- _realPriceUsdPerBitcoin: this.pricingInfo.realPriceUsdPerBitcoin,
718
- _swapPriceUSatPerToken: this.pricingInfo.swapPriceUSatPerToken==null ? null :this.pricingInfo.swapPriceUSatPerToken.toString(10),
719
- state: this._state,
720
- url: this.url,
721
- swapFee: this.swapFee==null ? null : this.swapFee.toString(10),
722
- swapFeeBtc: this.swapFeeBtc==null ? null : this.swapFeeBtc.toString(10),
723
- expiry: this.expiry,
724
- version: this.version,
725
- initiated: this.initiated,
726
- exactIn: this.exactIn,
727
- createdAt: this.createdAt,
728
- randomNonce: this._randomNonce,
729
- contractVersion: this._contractVersion,
730
-
731
- _meta: this._meta
732
- }
733
- }
734
-
735
-
736
- //////////////////////////////
737
- //// Events
738
-
739
- /**
740
- * Emits a `swapState` event with the current swap
741
- *
742
- * @internal
743
- */
744
- _emitEvent() {
745
- this.wrapper.events.emit("swapState", this);
746
- this.events.emit("swapState", this);
747
- }
748
-
749
-
750
- //////////////////////////////
751
- //// Swap ticks & sync
752
-
753
- /**
754
- * Synchronizes swap state from chain and/or LP node, usually ran on startup
755
- *
756
- * @param save whether to save the new swap state or not
757
- *
758
- * @returns {boolean} true if the swap changed, false if the swap hasn't changed
759
- *
760
- * @internal
761
- */
762
- abstract _sync(save?: boolean): Promise<boolean>;
763
-
764
- /**
765
- * Runs quick checks on the swap, such as checking the expiry, usually ran periodically every few seconds
766
- *
767
- * @param save whether to save the new swap state or not
768
- *
769
- * @returns {boolean} true if the swap changed, false if the swap hasn't changed
770
- *
771
- * @internal
772
- */
773
- abstract _tick(save?: boolean): Promise<boolean>;
774
-
775
- }
1
+ import {SwapType} from "../enums/SwapType";
2
+ import {EventEmitter} from "events";
3
+ import {ISwapWrapper, SwapTypeDefinition} from "./ISwapWrapper";
4
+ import {ChainType} from "@atomiqlabs/base";
5
+ import {randomBytes, toBigInt} from "../utils/Utils";
6
+ import {SwapDirection} from "../enums/SwapDirection";
7
+ import {Fee} from "../types/fees/Fee";
8
+ import {FeeBreakdown} from "../types/fees/FeeBreakdown";
9
+ import {PercentagePPM, ppmToPercentage} from "../types/fees/PercentagePPM";
10
+ import {TokenAmount} from "../types/TokenAmount";
11
+ import {isSCToken, Token} from "../types/Token";
12
+ import {SwapExecutionAction} from "../types/SwapExecutionAction";
13
+ import {LoggerType} from "../utils/Logger";
14
+ import {isPriceInfoType, PriceInfoType} from "../types/PriceInfoType";
15
+ import {SwapStateInfo} from "../types/SwapStateInfo";
16
+ import {SwapExecutionStep} from "../types/SwapExecutionStep";
17
+
18
+ /**
19
+ * Initialization data for creating a swap
20
+ *
21
+ * @category Swaps/Base
22
+ */
23
+ export type ISwapInit = {
24
+ pricingInfo: PriceInfoType,
25
+ url?: string,
26
+ expiry: number,
27
+ swapFee: bigint,
28
+ swapFeeBtc: bigint,
29
+ exactIn: boolean,
30
+ contractVersion: string
31
+ };
32
+
33
+ /**
34
+ * Type guard to check if an object is an ISwapInit
35
+ *
36
+ * @category Swaps/Base
37
+ */
38
+ export function isISwapInit(obj: any): obj is ISwapInit {
39
+ return typeof obj === 'object' &&
40
+ obj != null &&
41
+ isPriceInfoType(obj.pricingInfo) &&
42
+ (obj.url==null || typeof obj.url === 'string') &&
43
+ typeof obj.expiry === 'number' &&
44
+ typeof(obj.swapFee) === "bigint" &&
45
+ typeof(obj.swapFeeBtc) === "bigint" &&
46
+ (typeof obj.exactIn === 'boolean');
47
+ }
48
+
49
+ /**
50
+ * Base abstract class for all swap types
51
+ *
52
+ * @category Swaps/Base
53
+ */
54
+ export abstract class ISwap<
55
+ T extends ChainType = ChainType,
56
+ D extends SwapTypeDefinition<T, ISwapWrapper<T, D>, ISwap<T, D, S>> = SwapTypeDefinition<T, ISwapWrapper<T, any>, ISwap<T, any, any>>,
57
+ S extends number = number
58
+ > {
59
+ /**
60
+ * Swap type
61
+ */
62
+ protected readonly abstract TYPE: SwapType;
63
+
64
+ /**
65
+ * Description for the states
66
+ * @internal
67
+ */
68
+ protected readonly abstract swapStateDescription: Record<S, string>;
69
+ /**
70
+ * Name of the states
71
+ * @internal
72
+ */
73
+ protected readonly abstract swapStateName: (state: number) => string;
74
+ /**
75
+ * Swap logger
76
+ * @internal
77
+ */
78
+ protected readonly abstract logger: LoggerType;
79
+ /**
80
+ * Current newest defined version of the swap
81
+ * @internal
82
+ */
83
+ protected readonly currentVersion: number = 1;
84
+ /**
85
+ * Wrapper instance holding this swap
86
+ * @internal
87
+ */
88
+ protected readonly wrapper: D["Wrapper"];
89
+
90
+
91
+ /**
92
+ * The current version of the swap
93
+ * @internal
94
+ */
95
+ protected version: number;
96
+ /**
97
+ * Whether a swap was initialized, a swap is considered initialize on first interaction with it, i.e.
98
+ * calling commit() on a Smart chain -> Bitcoin swaps, calling waitForPayment() or similar on the other
99
+ * direction. Not initiated swaps are not saved to the persistent storage by default (see
100
+ * {@link SwapperOptions.saveUninitializedSwaps})
101
+ * @internal
102
+ */
103
+ protected initiated: boolean = false;
104
+ /**
105
+ * Expiration of the swap quote
106
+ * @internal
107
+ */
108
+ protected expiry: number;
109
+ /**
110
+ * Pricing information of the swap
111
+ * @internal
112
+ */
113
+ protected pricingInfo?: PriceInfoType;
114
+ /**
115
+ * Swap fee in the non-bitcoin token
116
+ * @internal
117
+ */
118
+ protected swapFee: bigint;
119
+ /**
120
+ * Swap fee in bitcoin satoshis
121
+ * @internal
122
+ */
123
+ protected swapFeeBtc: bigint;
124
+
125
+
126
+ /**
127
+ * Swap state
128
+ * @internal
129
+ */
130
+ _state: S = 0 as S;
131
+ /**
132
+ * Random nonce to differentiate the swap from others with the same identifier hash (i.e. when quoting the same swap
133
+ * from multiple LPs)
134
+ * @internal
135
+ */
136
+ _randomNonce: string;
137
+ /**
138
+ * Whether the swap is saved in the persistent storage or not.
139
+ *
140
+ * @remarks This field itself is not persisted but is instead derived during runtime
141
+ *
142
+ * @internal
143
+ */
144
+ _persisted: boolean = false;
145
+ /**
146
+ * @internal
147
+ */
148
+ _contractVersion?: string;
149
+ /**
150
+ * Storage specific metadata that can be used for e.g. optimistic concurrency
151
+ *
152
+ * @internal
153
+ */
154
+ _meta?: any;
155
+
156
+
157
+ /**
158
+ * Event emitter emitting `"swapState"` event when swap's state changes
159
+ */
160
+ readonly events: EventEmitter<{swapState: [D["Swap"]]}> = new EventEmitter();
161
+ /**
162
+ * URL of the intermediary (LP) used for this swap, already has the swap service specific path appended
163
+ */
164
+ readonly url?: string;
165
+ /**
166
+ * Smart chain identifier string corresponding to this swap
167
+ */
168
+ readonly chainIdentifier: T["ChainId"];
169
+ /**
170
+ * Whether a swap is an exact input swap
171
+ */
172
+ readonly exactIn: boolean;
173
+ /**
174
+ * A UNIX milliseconds timestamps of when this swap was created
175
+ */
176
+ createdAt: number;
177
+
178
+ protected constructor(wrapper: D["Wrapper"], obj: any);
179
+ protected constructor(wrapper: D["Wrapper"], swapInit: ISwapInit);
180
+ protected constructor(
181
+ wrapper: D["Wrapper"],
182
+ swapInitOrObj: ISwapInit | any,
183
+ ) {
184
+ this.chainIdentifier = wrapper.chainIdentifier;
185
+ this.wrapper = wrapper;
186
+ if(isISwapInit(swapInitOrObj)) {
187
+ this.pricingInfo = swapInitOrObj.pricingInfo;
188
+ this.url = swapInitOrObj.url;
189
+ this.expiry = swapInitOrObj.expiry;
190
+ this.swapFee = swapInitOrObj.swapFee;
191
+ this.swapFeeBtc = swapInitOrObj.swapFeeBtc;
192
+ this.exactIn = swapInitOrObj.exactIn;
193
+ this.version = this.currentVersion;
194
+ this.createdAt = Date.now();
195
+ this._randomNonce = randomBytes(16).toString("hex");
196
+ this._contractVersion = swapInitOrObj.contractVersion;
197
+ } else {
198
+ this.expiry = swapInitOrObj.expiry;
199
+ this.url = swapInitOrObj.url;
200
+
201
+ this._state = swapInitOrObj.state;
202
+
203
+ if(
204
+ swapInitOrObj._isValid!=null && swapInitOrObj._differencePPM!=null && swapInitOrObj._satsBaseFee!=null &&
205
+ swapInitOrObj._feePPM!=null && swapInitOrObj._swapPriceUSatPerToken!=null
206
+ ) {
207
+ this.pricingInfo = {
208
+ isValid: swapInitOrObj._isValid,
209
+ differencePPM: BigInt(swapInitOrObj._differencePPM),
210
+ satsBaseFee: BigInt(swapInitOrObj._satsBaseFee),
211
+ feePPM: BigInt(swapInitOrObj._feePPM),
212
+ realPriceUSatPerToken: toBigInt(swapInitOrObj._realPriceUSatPerToken),
213
+ realPriceUsdPerBitcoin: swapInitOrObj._realPriceUsdPerBitcoin,
214
+ swapPriceUSatPerToken: BigInt(swapInitOrObj._swapPriceUSatPerToken),
215
+ };
216
+ }
217
+
218
+ this.swapFee = toBigInt(swapInitOrObj.swapFee);
219
+ this.swapFeeBtc = toBigInt(swapInitOrObj.swapFeeBtc);
220
+
221
+ this.version = swapInitOrObj.version;
222
+ this.initiated = swapInitOrObj.initiated;
223
+ this.exactIn = swapInitOrObj.exactIn;
224
+ this.createdAt = swapInitOrObj.createdAt ?? swapInitOrObj.expiry;
225
+
226
+ this._randomNonce = swapInitOrObj.randomNonce;
227
+ this._contractVersion = swapInitOrObj.contractVersion;
228
+ this._meta = swapInitOrObj._meta;
229
+ }
230
+ if(this.version!==this.currentVersion) {
231
+ this.upgradeVersion();
232
+ }
233
+ if(this.initiated==null) this.initiated = true;
234
+ }
235
+
236
+ /**
237
+ * Called when swap is deserialized to potentially update the version of the data for the swap
238
+ *
239
+ * @internal
240
+ */
241
+ protected abstract upgradeVersion(): void;
242
+
243
+ /**
244
+ * Waits till the swap reaches a specific state
245
+ *
246
+ * @param targetState The state to wait for
247
+ * @param type Whether to wait for the state exactly or also to a state with a higher number
248
+ * @param abortSignal Abort signal
249
+ * @internal
250
+ */
251
+ protected waitTillState(targetState: S, type: "eq" | "gte" | "neq" = "eq", abortSignal?: AbortSignal): Promise<void> {
252
+ //TODO: This doesn't hold strong reference to the swap, hence if no other strong reference to the
253
+ // swap exists, it will just never resolve!
254
+ return new Promise((resolve, reject) => {
255
+ let listener: () => void;
256
+ listener = () => {
257
+ if(type==="eq" ? this._state===targetState : type==="gte" ? this._state>=targetState : this._state!=targetState) {
258
+ resolve();
259
+ this.events.removeListener("swapState", listener);
260
+ }
261
+ };
262
+ this.events.on("swapState", listener);
263
+ if(abortSignal!=null) abortSignal.addEventListener("abort", () => {
264
+ this.events.removeListener("swapState", listener);
265
+ reject(abortSignal.reason);
266
+ });
267
+ });
268
+ }
269
+
270
+ /**
271
+ * Executes the swap with the provided wallet, the exact arguments for this functions differ for various swap
272
+ * types. Check the `execute()` function signature in the respective swap class to see the required arguments.
273
+ *
274
+ * @param args Execution arguments, usually contains a source wallet object, callbacks and options, for exact
275
+ * syntax check the respective swap class.
276
+ *
277
+ * @returns Whether a swap was successfully executed or not, if it wasn't the user can refund or claim manually
278
+ */
279
+ public abstract execute(...args: any[]): Promise<boolean>;
280
+
281
+ //////////////////////////////
282
+ //// Pricing
283
+
284
+ /**
285
+ * This attempts to populate missing fields in the pricing info based on the swap amounts
286
+ *
287
+ * @internal
288
+ */
289
+ protected tryRecomputeSwapPrice(): void {
290
+ if(this.pricingInfo==null) return;
291
+ if(this.pricingInfo.swapPriceUSatPerToken==null) {
292
+ const priceUsdPerBtc = this.pricingInfo.realPriceUsdPerBitcoin;
293
+ const input = this.getInput();
294
+ const output = this.getOutput();
295
+ if(input.isUnknown || output.isUnknown) return;
296
+ if(isSCToken(input.token) && this.getDirection()===SwapDirection.TO_BTC) {
297
+ this.pricingInfo = this.wrapper._prices.recomputePriceInfoSend(
298
+ this.chainIdentifier,
299
+ output.rawAmount!,
300
+ this.pricingInfo.satsBaseFee,
301
+ this.pricingInfo.feePPM,
302
+ input.rawAmount!,
303
+ input.token.address
304
+ );
305
+ this.pricingInfo.realPriceUsdPerBitcoin = priceUsdPerBtc;
306
+ } else if(isSCToken(output.token) && this.getDirection()===SwapDirection.FROM_BTC) {
307
+ this.pricingInfo = this.wrapper._prices.recomputePriceInfoReceive(
308
+ this.chainIdentifier,
309
+ input.rawAmount!,
310
+ this.pricingInfo.satsBaseFee,
311
+ this.pricingInfo.feePPM,
312
+ output.rawAmount!,
313
+ output.token.address
314
+ );
315
+ this.pricingInfo.realPriceUsdPerBitcoin = priceUsdPerBtc;
316
+ }
317
+ }
318
+ }
319
+
320
+ /**
321
+ * Returns the specific state along with the human-readable description of that state
322
+ *
323
+ * @internal
324
+ */
325
+ protected _getStateInfo(state: S): SwapStateInfo<S> {
326
+ return {
327
+ state: state,
328
+ name: this.swapStateName(state),
329
+ description: this.swapStateDescription[state]
330
+ };
331
+ }
332
+
333
+ /**
334
+ * Re-fetches & revalidates the price data based on the current market prices
335
+ */
336
+ public async refreshPriceData(): Promise<void> {
337
+ if(this.pricingInfo==null) return;
338
+ const priceUsdPerBtc = this.pricingInfo.realPriceUsdPerBitcoin;
339
+ const output = this.getOutput();
340
+ if(output.isUnknown) return;
341
+
342
+ if(isSCToken(this.getInputToken()) && this.getDirection()===SwapDirection.TO_BTC) {
343
+ const input = this.getInputWithoutFee();
344
+ if(input.isUnknown) return;
345
+
346
+ this.pricingInfo = await this.wrapper._prices.isValidAmountSend(
347
+ this.chainIdentifier,
348
+ output.rawAmount!,
349
+ this.pricingInfo.satsBaseFee,
350
+ this.pricingInfo.feePPM,
351
+ input.rawAmount! + this.swapFee,
352
+ input.token.address,
353
+ undefined,
354
+ undefined,
355
+ this.swapFeeBtc
356
+ );
357
+ this.pricingInfo.realPriceUsdPerBitcoin = priceUsdPerBtc;
358
+ } else if(isSCToken(output.token) && this.getDirection()===SwapDirection.FROM_BTC) {
359
+ const input = this.getInput();
360
+ if(input.isUnknown) return;
361
+
362
+ this.pricingInfo = await this.wrapper._prices.isValidAmountReceive(
363
+ this.chainIdentifier,
364
+ input.rawAmount!,
365
+ this.pricingInfo.satsBaseFee,
366
+ this.pricingInfo.feePPM,
367
+ output.rawAmount!,
368
+ output.token.address,
369
+ undefined,
370
+ undefined,
371
+ this.swapFeeBtc
372
+ );
373
+ this.pricingInfo.realPriceUsdPerBitcoin = priceUsdPerBtc;
374
+ }
375
+ }
376
+
377
+ /**
378
+ * Checks if the pricing for the swap is valid, according to max allowed price difference set in the ISwapPrice
379
+ */
380
+ public hasValidPrice(): boolean {
381
+ if(this.pricingInfo==null) throw new Error("Pricing info not found, cannot check price validity!");
382
+ return this.pricingInfo.isValid;
383
+ }
384
+
385
+ /**
386
+ * Returns pricing info about the swap
387
+ */
388
+ public getPriceInfo(): {
389
+ marketPrice?: number,
390
+ swapPrice: number,
391
+ difference: PercentagePPM
392
+ } {
393
+ if(this.pricingInfo==null) throw new Error("Pricing info not provided and not known!");
394
+
395
+ const swapPrice = this.getDirection()===SwapDirection.TO_BTC ?
396
+ 100_000_000_000_000/Number(this.pricingInfo.swapPriceUSatPerToken) :
397
+ Number(this.pricingInfo.swapPriceUSatPerToken)/100_000_000_000_000;
398
+
399
+ let marketPrice: number | undefined;
400
+ if(this.pricingInfo.realPriceUSatPerToken!=null)
401
+ marketPrice = this.getDirection()===SwapDirection.TO_BTC ?
402
+ 100_000_000_000_000/Number(this.pricingInfo.realPriceUSatPerToken) :
403
+ Number(this.pricingInfo.realPriceUSatPerToken)/100_000_000_000_000;
404
+
405
+ return {
406
+ marketPrice,
407
+ swapPrice,
408
+ difference: ppmToPercentage(this.pricingInfo.differencePPM)
409
+ }
410
+ }
411
+
412
+
413
+ //////////////////////////////
414
+ //// Getters & utils
415
+
416
+ /**
417
+ * Asserts a given signer is the initiator of this swap
418
+ *
419
+ * @param signer Signer to check with this swap's initiator
420
+ * @throws {Error} When signer's address doesn't match with the swap's initiator one
421
+ * @internal
422
+ */
423
+ protected checkSigner(signer: T["Signer"] | string): void {
424
+ if((typeof(signer)==="string" ? signer : signer.getAddress())!==this._getInitiator()) throw new Error("Invalid signer provided!");
425
+ }
426
+
427
+ /**
428
+ * Await and prepares a list of passed transactions
429
+ *
430
+ * @param txsPromise
431
+ * @internal
432
+ */
433
+ protected async prepareTransactions(txsPromise: Promise<T["TX"][]>): Promise<T["TX"][]> {
434
+ const txs = await txsPromise;
435
+ if(this.wrapper._chain.prepareTxs==null) return txs;
436
+ return await this.wrapper._chain.prepareTxs(txs);
437
+ }
438
+
439
+ /**
440
+ * Returns an escrow hash of the swap
441
+ *
442
+ * @internal
443
+ */
444
+ abstract _getEscrowHash(): string | null;
445
+
446
+ /**
447
+ * Checks if the swap's quote is expired for good (i.e. the swap strictly cannot be initiated anymore)
448
+ * @internal
449
+ */
450
+ abstract _verifyQuoteDefinitelyExpired(): Promise<boolean>;
451
+
452
+ /**
453
+ * Checks if the swap's quote is still valid
454
+ * @internal
455
+ */
456
+ abstract _verifyQuoteValid(): Promise<boolean>;
457
+
458
+ /**
459
+ * Returns the intiator address of the swap - address that created this swap
460
+ * @internal
461
+ */
462
+ abstract _getInitiator(): string;
463
+
464
+ /**
465
+ * Sets this swap as initiated
466
+ * @internal
467
+ */
468
+ _setInitiated(): void {
469
+ this.initiated = true;
470
+ }
471
+
472
+ /**
473
+ * Returns source address of the swap
474
+ */
475
+ public abstract getInputAddress(): string | null;
476
+
477
+ /**
478
+ * Returns destination address of the swap
479
+ */
480
+ public abstract getOutputAddress(): string | null;
481
+
482
+ /**
483
+ * Returns swap input transaction ID on the source chain
484
+ */
485
+ public abstract getInputTxId(): string | null;
486
+
487
+ /**
488
+ * Returns swap output transaction ID on the destination chain
489
+ */
490
+ public abstract getOutputTxId(): string | null;
491
+
492
+ /**
493
+ * Returns the ID of the swap, as used in the storage
494
+ */
495
+ public abstract getId(): string;
496
+
497
+ /**
498
+ * Checks whether there is some action required from the user for this swap - can mean either refundable or claimable
499
+ */
500
+ public abstract requiresAction(): boolean;
501
+
502
+ /**
503
+ * Returns whether the swap is finished and in its terminal state (this can mean successful, refunded or failed)
504
+ */
505
+ public abstract isFinished(): boolean;
506
+
507
+ /**
508
+ * Checks whether the swap's quote has definitely expired and cannot be committed anymore, we can remove such swap
509
+ */
510
+ public abstract isQuoteExpired(): boolean;
511
+
512
+ /**
513
+ * Checks whether the swap's quote is soft expired (this means there is not enough time buffer for it to commit,
514
+ * but it still can happen)
515
+ */
516
+ public abstract isQuoteSoftExpired(): boolean;
517
+
518
+ /**
519
+ * Returns whether the swap finished successful
520
+ */
521
+ public abstract isSuccessful(): boolean;
522
+
523
+ /**
524
+ * Returns whether the swap failed (e.g. was refunded)
525
+ */
526
+ public abstract isFailed(): boolean;
527
+
528
+ /**
529
+ * Returns whether the swap is currently being processed
530
+ */
531
+ public abstract isInProgress(): boolean;
532
+
533
+ /**
534
+ * Whether a swap was initialized, a swap is considered initialized on first interaction with it, i.e.
535
+ * calling commit() on a Smart chain -> Bitcoin swaps, calling waitForPayment() or similar on the other
536
+ * direction. Not initiated swaps are not saved to the persistent storage by default (see
537
+ * {@link SwapperOptions.saveUninitializedSwaps})
538
+ */
539
+ public isInitiated(): boolean {
540
+ return this.initiated;
541
+ }
542
+
543
+ /**
544
+ * Returns quote expiry in UNIX millis
545
+ */
546
+ public getQuoteExpiry(): number {
547
+ return this.expiry;
548
+ }
549
+
550
+ /**
551
+ * Returns the type of the swap
552
+ */
553
+ public getType(): SwapType {
554
+ return this.TYPE;
555
+ }
556
+
557
+ /**
558
+ * Returns the direction of the swap
559
+ */
560
+ public getDirection(): SwapDirection {
561
+ return this.TYPE===SwapType.TO_BTC || this.TYPE===SwapType.TO_BTCLN ? SwapDirection.TO_BTC : SwapDirection.FROM_BTC;
562
+ }
563
+
564
+ /**
565
+ * Returns the current state of the swap
566
+ */
567
+ public getState(): S {
568
+ return this._state;
569
+ }
570
+
571
+ /**
572
+ * Returns the current state of the swap along with the human-readable description of the state
573
+ */
574
+ public getStateInfo(): SwapStateInfo<S> {
575
+ return this._getStateInfo(this._state);
576
+ }
577
+
578
+ /**
579
+ * Returns a current state-dependent action for the user to execute, or `undefined` if there is no more action
580
+ * required for this swap - this means that the swap is probably finished (either expired, failed or settled).
581
+ *
582
+ * @param options Optional options argument for the additional action context (i.e. passing bitcoin wallet info to
583
+ * get funded PSBTs or passing the externally-generated swap secret), see the actual type in the respective swap
584
+ * classes
585
+ */
586
+ public abstract getExecutionAction(options?: any): Promise<SwapExecutionAction | undefined>;
587
+
588
+ /**
589
+ * Returns a list of execution steps the user has to go through for a given swap, to see the possible execution
590
+ * steps check out {@link SwapExecutionStep}.
591
+ *
592
+ * @param options Optional options argument for the additional steps context (i.e. automatic settlement timeout),
593
+ * see the actual type in the respective swap classes
594
+ */
595
+ public abstract getExecutionSteps(options?: any): Promise<SwapExecutionStep[]>;
596
+
597
+ /**
598
+ * Returns the current action and the full execution steps for a given swap. Prefer this to calling
599
+ * {@link getExecutionSteps} and {@link getExecutionAction} separately - if called sequentially they might
600
+ * return the respective steps/actions in different states if you hit the state transition boundary.
601
+ *
602
+ * @param options Optional options argument for the additional execution status context, see the actual type in
603
+ * the respective swap classes
604
+ */
605
+ public abstract getExecutionStatus(options?: { skipBuildingAction?: boolean } & any): Promise<{
606
+ steps: SwapExecutionStep[],
607
+ currentAction: SwapExecutionAction | undefined,
608
+ stateInfo: SwapStateInfo<S>
609
+ }>;
610
+
611
+ /**
612
+ * Submits signed transactions obtained from the execution action back to the swap.
613
+ *
614
+ * @remarks This endpoint will also wait till the submitted transactions are confirmed (on a smart-chain side)
615
+ * and till the swap state change is observed from the authoritative chain/intermediary state.
616
+ *
617
+ * If invalid transactions are submitted, i.e. sending a simple noop or transfer transaction instead of the
618
+ * expected tx, this call may wait indefinitely unless aborted via the AbortSignal.
619
+ *
620
+ * @param txs Signed transactions
621
+ * @param abortSignal Abort signal
622
+ * @param requiredStates Optional list of states that the swap has to be in for the transactions to be
623
+ * submitted, else throws
624
+ * @param idempotent Whether the tx submission should be handled idempotently, meaning if any of the supplied
625
+ * transactions are already processed as e.g. init, claim, refund or execution transactions the function just
626
+ * returns these transaction IDs without actually submitting them
627
+ *
628
+ * @internal
629
+ */
630
+ abstract _submitExecutionTransactions(txs: (T["SignedTXType"] | string | any)[], abortSignal?: AbortSignal, requiredStates?: S[], idempotent?: boolean): Promise<string[]>;
631
+
632
+ //////////////////////////////
633
+ //// Amounts & fees
634
+
635
+ /**
636
+ * Returns output amount of the swap, user receives this much
637
+ */
638
+ public abstract getOutput(): TokenAmount;
639
+
640
+ /**
641
+ * Returns the output token of the swap
642
+ */
643
+ public abstract getOutputToken(): Token<T["ChainId"]>;
644
+
645
+ /**
646
+ * Returns input amount of the swap, user needs to pay this much
647
+ */
648
+ public abstract getInput(): TokenAmount;
649
+
650
+ /**
651
+ * Returns the input token of the swap
652
+ */
653
+ public abstract getInputToken(): Token<T["ChainId"]>;
654
+
655
+ /**
656
+ * Returns input amount of the swap without the fees (swap fee, network fee)
657
+ */
658
+ public abstract getInputWithoutFee(): TokenAmount;
659
+
660
+ /**
661
+ * Returns total fee for the swap, the fee is represented in source currency & destination currency, but is
662
+ * paid only once
663
+ */
664
+ public abstract getFee(): Fee;
665
+
666
+ /**
667
+ * Returns the breakdown of all the fees paid
668
+ */
669
+ public abstract getFeeBreakdown(): FeeBreakdown<T["ChainId"]>;
670
+
671
+
672
+ //////////////////////////////
673
+ //// Storage
674
+
675
+ /**
676
+ * Saves the swap data to the underlying storage, or removes it if it is in a quote expired state
677
+ *
678
+ * @internal
679
+ */
680
+ _save(): Promise<void> {
681
+ if(this.isQuoteExpired()) {
682
+ return this.wrapper._removeSwapData(this);
683
+ } else {
684
+ return this.wrapper._saveSwapData(this);
685
+ }
686
+ }
687
+
688
+ /**
689
+ * Saves the swap data and also emits a swap state change
690
+ *
691
+ * @param state Optional state to set before the swap is saved an event emitted
692
+ *
693
+ * @internal
694
+ */
695
+ async _saveAndEmit(state?: S): Promise<void> {
696
+ if(state!=null) this._state = state;
697
+ await this._save();
698
+ this._emitEvent();
699
+ }
700
+
701
+ /**
702
+ * Serializes the swap to a JSON stringifiable representation (i.e. no bigints, buffers etc.)
703
+ */
704
+ public serialize(): any {
705
+ if(this.pricingInfo==null) return {};
706
+ return {
707
+ id: this.getId(),
708
+ type: this.getType(),
709
+ escrowHash: this._getEscrowHash(),
710
+ initiator: this._getInitiator(),
711
+
712
+ _isValid: this.pricingInfo.isValid,
713
+ _differencePPM: this.pricingInfo.differencePPM==null ? null :this.pricingInfo.differencePPM.toString(10),
714
+ _satsBaseFee: this.pricingInfo.satsBaseFee==null ? null :this.pricingInfo.satsBaseFee.toString(10),
715
+ _feePPM: this.pricingInfo.feePPM==null ? null :this.pricingInfo.feePPM.toString(10),
716
+ _realPriceUSatPerToken: this.pricingInfo.realPriceUSatPerToken==null ? null :this.pricingInfo.realPriceUSatPerToken.toString(10),
717
+ _realPriceUsdPerBitcoin: this.pricingInfo.realPriceUsdPerBitcoin,
718
+ _swapPriceUSatPerToken: this.pricingInfo.swapPriceUSatPerToken==null ? null :this.pricingInfo.swapPriceUSatPerToken.toString(10),
719
+ state: this._state,
720
+ url: this.url,
721
+ swapFee: this.swapFee==null ? null : this.swapFee.toString(10),
722
+ swapFeeBtc: this.swapFeeBtc==null ? null : this.swapFeeBtc.toString(10),
723
+ expiry: this.expiry,
724
+ version: this.version,
725
+ initiated: this.initiated,
726
+ exactIn: this.exactIn,
727
+ createdAt: this.createdAt,
728
+ randomNonce: this._randomNonce,
729
+ contractVersion: this._contractVersion,
730
+
731
+ _meta: this._meta
732
+ }
733
+ }
734
+
735
+
736
+ //////////////////////////////
737
+ //// Events
738
+
739
+ /**
740
+ * Emits a `swapState` event with the current swap
741
+ *
742
+ * @internal
743
+ */
744
+ _emitEvent() {
745
+ this.wrapper.events.emit("swapState", this);
746
+ this.events.emit("swapState", this);
747
+ }
748
+
749
+
750
+ //////////////////////////////
751
+ //// Swap ticks & sync
752
+
753
+ /**
754
+ * Synchronizes swap state from chain and/or LP node, usually ran on startup
755
+ *
756
+ * @param save whether to save the new swap state or not
757
+ *
758
+ * @returns {boolean} true if the swap changed, false if the swap hasn't changed
759
+ *
760
+ * @internal
761
+ */
762
+ abstract _sync(save?: boolean): Promise<boolean>;
763
+
764
+ /**
765
+ * Runs quick checks on the swap, such as checking the expiry, usually ran periodically every few seconds
766
+ *
767
+ * @param save whether to save the new swap state or not
768
+ *
769
+ * @returns {boolean} true if the swap changed, false if the swap hasn't changed
770
+ *
771
+ * @internal
772
+ */
773
+ abstract _tick(save?: boolean): Promise<boolean>;
774
+
775
+ }