@atomiqlabs/sdk 8.1.8 → 8.3.5

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 (261) hide show
  1. package/dist/bitcoin/coinselect2/utils.d.ts +6 -0
  2. package/dist/bitcoin/wallet/BitcoinWallet.d.ts +41 -5
  3. package/dist/bitcoin/wallet/BitcoinWallet.js +36 -1
  4. package/dist/bitcoin/wallet/IBitcoinWallet.d.ts +52 -2
  5. package/dist/bitcoin/wallet/IBitcoinWallet.js +2 -1
  6. package/dist/bitcoin/wallet/SingleAddressBitcoinWallet.d.ts +42 -7
  7. package/dist/bitcoin/wallet/SingleAddressBitcoinWallet.js +36 -1
  8. package/dist/enums/FeeType.d.ts +8 -1
  9. package/dist/enums/FeeType.js +8 -1
  10. package/dist/enums/SwapAmountType.d.ts +7 -0
  11. package/dist/enums/SwapAmountType.js +7 -0
  12. package/dist/enums/SwapDirection.d.ts +7 -0
  13. package/dist/enums/SwapDirection.js +7 -0
  14. package/dist/enums/SwapType.d.ts +62 -1
  15. package/dist/enums/SwapType.js +62 -1
  16. package/dist/errors/IntermediaryError.d.ts +4 -0
  17. package/dist/errors/IntermediaryError.js +1 -0
  18. package/dist/errors/RequestError.d.ts +15 -1
  19. package/dist/errors/RequestError.js +8 -0
  20. package/dist/errors/UserError.d.ts +1 -0
  21. package/dist/errors/UserError.js +1 -0
  22. package/dist/index.d.ts +5 -5
  23. package/dist/index.js +7 -6
  24. package/dist/intermediaries/Intermediary.d.ts +61 -14
  25. package/dist/intermediaries/Intermediary.js +38 -11
  26. package/dist/intermediaries/IntermediaryDiscovery.d.ts +62 -29
  27. package/dist/intermediaries/IntermediaryDiscovery.js +39 -24
  28. package/dist/prices/RedundantSwapPrice.d.ts +26 -5
  29. package/dist/prices/RedundantSwapPrice.js +22 -2
  30. package/dist/prices/SingleSwapPrice.d.ts +10 -7
  31. package/dist/prices/SingleSwapPrice.js +11 -8
  32. package/dist/prices/SwapPriceWithChain.d.ts +56 -19
  33. package/dist/prices/SwapPriceWithChain.js +62 -25
  34. package/dist/prices/abstract/IPriceProvider.d.ts +4 -4
  35. package/dist/prices/abstract/IPriceProvider.js +1 -1
  36. package/dist/prices/abstract/ISwapPrice.d.ts +95 -46
  37. package/dist/prices/abstract/ISwapPrice.js +104 -56
  38. package/dist/prices/providers/BinancePriceProvider.d.ts +8 -1
  39. package/dist/prices/providers/BinancePriceProvider.js +8 -1
  40. package/dist/prices/providers/CoinGeckoPriceProvider.d.ts +7 -1
  41. package/dist/prices/providers/CoinGeckoPriceProvider.js +7 -1
  42. package/dist/prices/providers/CoinPaprikaPriceProvider.d.ts +7 -1
  43. package/dist/prices/providers/CoinPaprikaPriceProvider.js +7 -1
  44. package/dist/prices/providers/CustomPriceProvider.d.ts +12 -1
  45. package/dist/prices/providers/CustomPriceProvider.js +12 -1
  46. package/dist/prices/providers/KrakenPriceProvider.d.ts +10 -1
  47. package/dist/prices/providers/KrakenPriceProvider.js +10 -1
  48. package/dist/prices/providers/OKXPriceProvider.d.ts +7 -1
  49. package/dist/prices/providers/OKXPriceProvider.js +7 -1
  50. package/dist/prices/providers/abstract/ExchangePriceProvider.d.ts +3 -0
  51. package/dist/prices/providers/abstract/ExchangePriceProvider.js +3 -0
  52. package/dist/storage/IUnifiedStorage.d.ts +19 -7
  53. package/dist/storage/UnifiedSwapStorage.d.ts +33 -3
  54. package/dist/storage/UnifiedSwapStorage.js +29 -1
  55. package/dist/storage-browser/IndexedDBUnifiedStorage.d.ts +31 -7
  56. package/dist/storage-browser/IndexedDBUnifiedStorage.js +29 -6
  57. package/dist/storage-browser/LocalStorageManager.d.ts +25 -1
  58. package/dist/storage-browser/LocalStorageManager.js +25 -1
  59. package/dist/swapper/Swapper.d.ts +380 -226
  60. package/dist/swapper/Swapper.js +383 -349
  61. package/dist/swapper/SwapperFactory.d.ts +66 -18
  62. package/dist/swapper/SwapperFactory.js +24 -3
  63. package/dist/swapper/SwapperUtils.d.ts +75 -28
  64. package/dist/swapper/SwapperUtils.js +107 -60
  65. package/dist/swapper/SwapperWithChain.d.ts +286 -91
  66. package/dist/swapper/SwapperWithChain.js +218 -64
  67. package/dist/swapper/SwapperWithSigner.d.ts +229 -80
  68. package/dist/swapper/SwapperWithSigner.js +190 -44
  69. package/dist/swaps/IAddressSwap.d.ts +12 -3
  70. package/dist/swaps/IAddressSwap.js +3 -2
  71. package/dist/swaps/IBTCWalletSwap.d.ts +26 -8
  72. package/dist/swaps/IBTCWalletSwap.js +3 -2
  73. package/dist/swaps/IClaimableSwap.d.ts +38 -6
  74. package/dist/swaps/IClaimableSwap.js +3 -2
  75. package/dist/swaps/IClaimableSwapWrapper.d.ts +11 -1
  76. package/dist/swaps/IRefundableSwap.d.ts +31 -5
  77. package/dist/swaps/IRefundableSwap.js +3 -2
  78. package/dist/swaps/ISwap.d.ts +162 -24
  79. package/dist/swaps/ISwap.js +92 -35
  80. package/dist/swaps/ISwapWithGasDrop.d.ts +8 -2
  81. package/dist/swaps/ISwapWithGasDrop.js +2 -1
  82. package/dist/swaps/ISwapWrapper.d.ts +161 -52
  83. package/dist/swaps/ISwapWrapper.js +131 -73
  84. package/dist/swaps/escrow_swaps/IEscrowSelfInitSwap.d.ts +51 -6
  85. package/dist/swaps/escrow_swaps/IEscrowSelfInitSwap.js +22 -12
  86. package/dist/swaps/escrow_swaps/IEscrowSwap.d.ts +65 -12
  87. package/dist/swaps/escrow_swaps/IEscrowSwap.js +38 -19
  88. package/dist/swaps/escrow_swaps/IEscrowSwapWrapper.d.ts +39 -9
  89. package/dist/swaps/escrow_swaps/IEscrowSwapWrapper.js +30 -21
  90. package/dist/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.d.ts +31 -15
  91. package/dist/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.js +33 -18
  92. package/dist/swaps/escrow_swaps/frombtc/IFromBTCSelfInitSwap.d.ts +97 -28
  93. package/dist/swaps/escrow_swaps/frombtc/IFromBTCSelfInitSwap.js +91 -27
  94. package/dist/swaps/escrow_swaps/frombtc/IFromBTCWrapper.d.ts +22 -9
  95. package/dist/swaps/escrow_swaps/frombtc/IFromBTCWrapper.js +24 -11
  96. package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.d.ts +278 -60
  97. package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.js +519 -241
  98. package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.d.ts +77 -26
  99. package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.js +132 -50
  100. package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.d.ts +313 -52
  101. package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.js +544 -194
  102. package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.d.ts +87 -26
  103. package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.js +147 -58
  104. package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.d.ts +222 -55
  105. package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.js +462 -244
  106. package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.d.ts +77 -23
  107. package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.js +116 -46
  108. package/dist/swaps/escrow_swaps/tobtc/IToBTCSwap.d.ts +195 -58
  109. package/dist/swaps/escrow_swaps/tobtc/IToBTCSwap.js +324 -191
  110. package/dist/swaps/escrow_swaps/tobtc/IToBTCWrapper.d.ts +30 -5
  111. package/dist/swaps/escrow_swaps/tobtc/IToBTCWrapper.js +44 -19
  112. package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNSwap.d.ts +61 -20
  113. package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNSwap.js +75 -32
  114. package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.d.ts +76 -50
  115. package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.js +106 -101
  116. package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCSwap.d.ts +37 -14
  117. package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCSwap.js +66 -20
  118. package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.d.ts +46 -17
  119. package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.js +82 -27
  120. package/dist/swaps/spv_swaps/SpvFromBTCSwap.d.ts +350 -88
  121. package/dist/swaps/spv_swaps/SpvFromBTCSwap.js +482 -215
  122. package/dist/swaps/spv_swaps/SpvFromBTCWrapper.d.ts +76 -24
  123. package/dist/swaps/spv_swaps/SpvFromBTCWrapper.js +247 -124
  124. package/dist/swaps/trusted/ln/LnForGasSwap.d.ts +148 -20
  125. package/dist/swaps/trusted/ln/LnForGasSwap.js +175 -45
  126. package/dist/swaps/trusted/ln/LnForGasWrapper.d.ts +29 -10
  127. package/dist/swaps/trusted/ln/LnForGasWrapper.js +30 -11
  128. package/dist/swaps/trusted/onchain/OnchainForGasSwap.d.ts +202 -49
  129. package/dist/swaps/trusted/onchain/OnchainForGasSwap.js +232 -80
  130. package/dist/swaps/trusted/onchain/OnchainForGasWrapper.d.ts +34 -12
  131. package/dist/swaps/trusted/onchain/OnchainForGasWrapper.js +33 -14
  132. package/dist/types/AmountData.d.ts +2 -1
  133. package/dist/types/CustomPriceFunction.d.ts +8 -2
  134. package/dist/types/PriceInfoType.d.ts +4 -4
  135. package/dist/types/PriceInfoType.js +3 -3
  136. package/dist/types/SwapExecutionAction.d.ts +85 -4
  137. package/dist/types/SwapWithSigner.d.ts +5 -2
  138. package/dist/types/SwapWithSigner.js +5 -2
  139. package/dist/types/Token.d.ts +11 -5
  140. package/dist/types/Token.js +6 -3
  141. package/dist/types/TokenAmount.d.ts +3 -0
  142. package/dist/types/TokenAmount.js +2 -0
  143. package/dist/types/fees/Fee.d.ts +3 -2
  144. package/dist/types/fees/FeeBreakdown.d.ts +3 -2
  145. package/dist/types/fees/PercentagePPM.d.ts +4 -2
  146. package/dist/types/fees/PercentagePPM.js +2 -1
  147. package/dist/types/lnurl/LNURLPay.d.ts +20 -12
  148. package/dist/types/lnurl/LNURLPay.js +8 -4
  149. package/dist/types/lnurl/LNURLWithdraw.d.ts +17 -10
  150. package/dist/types/lnurl/LNURLWithdraw.js +8 -4
  151. package/dist/types/wallets/LightningInvoiceCreateService.d.ts +24 -0
  152. package/dist/types/wallets/LightningInvoiceCreateService.js +15 -0
  153. package/dist/types/wallets/MinimalBitcoinWalletInterface.d.ts +3 -1
  154. package/dist/types/wallets/MinimalLightningNetworkWalletInterface.d.ts +4 -2
  155. package/dist/utils/BitcoinUtils.d.ts +1 -0
  156. package/dist/utils/BitcoinUtils.js +5 -1
  157. package/dist/utils/SwapUtils.d.ts +58 -1
  158. package/dist/utils/SwapUtils.js +55 -1
  159. package/dist/utils/TokenUtils.d.ts +10 -2
  160. package/dist/utils/TokenUtils.js +12 -4
  161. package/package.json +3 -3
  162. package/src/bitcoin/coinselect2/utils.ts +6 -0
  163. package/src/bitcoin/wallet/BitcoinWallet.ts +41 -5
  164. package/src/bitcoin/wallet/IBitcoinWallet.ts +57 -2
  165. package/src/bitcoin/wallet/SingleAddressBitcoinWallet.ts +42 -6
  166. package/src/enums/FeeType.ts +8 -1
  167. package/src/enums/SwapAmountType.ts +7 -0
  168. package/src/enums/SwapDirection.ts +7 -0
  169. package/src/enums/SwapType.ts +62 -2
  170. package/src/errors/IntermediaryError.ts +4 -0
  171. package/src/errors/RequestError.ts +15 -1
  172. package/src/errors/UserError.ts +1 -0
  173. package/src/index.ts +12 -5
  174. package/src/intermediaries/Intermediary.ts +61 -14
  175. package/src/intermediaries/IntermediaryDiscovery.ts +69 -34
  176. package/src/prices/RedundantSwapPrice.ts +26 -6
  177. package/src/prices/SingleSwapPrice.ts +11 -8
  178. package/src/prices/SwapPriceWithChain.ts +63 -26
  179. package/src/prices/abstract/IPriceProvider.ts +4 -4
  180. package/src/prices/abstract/ISwapPrice.ts +115 -66
  181. package/src/prices/providers/BinancePriceProvider.ts +8 -1
  182. package/src/prices/providers/CoinGeckoPriceProvider.ts +7 -1
  183. package/src/prices/providers/CoinPaprikaPriceProvider.ts +7 -1
  184. package/src/prices/providers/CustomPriceProvider.ts +12 -1
  185. package/src/prices/providers/KrakenPriceProvider.ts +10 -1
  186. package/src/prices/providers/OKXPriceProvider.ts +7 -1
  187. package/src/prices/providers/abstract/ExchangePriceProvider.ts +3 -0
  188. package/src/storage/IUnifiedStorage.ts +19 -7
  189. package/src/storage/UnifiedSwapStorage.ts +33 -3
  190. package/src/storage-browser/IndexedDBUnifiedStorage.ts +31 -8
  191. package/src/storage-browser/LocalStorageManager.ts +25 -1
  192. package/src/swapper/Swapper.ts +599 -390
  193. package/src/swapper/SwapperFactory.ts +73 -24
  194. package/src/swapper/SwapperUtils.ts +107 -60
  195. package/src/swapper/SwapperWithChain.ts +320 -81
  196. package/src/swapper/SwapperWithSigner.ts +263 -56
  197. package/src/swaps/IAddressSwap.ts +13 -3
  198. package/src/swaps/IBTCWalletSwap.ts +26 -10
  199. package/src/swaps/IClaimableSwap.ts +41 -6
  200. package/src/swaps/IClaimableSwapWrapper.ts +11 -2
  201. package/src/swaps/IRefundableSwap.ts +34 -5
  202. package/src/swaps/ISwap.ts +224 -85
  203. package/src/swaps/ISwapWithGasDrop.ts +8 -2
  204. package/src/swaps/ISwapWrapper.ts +216 -98
  205. package/src/swaps/escrow_swaps/IEscrowSelfInitSwap.ts +64 -18
  206. package/src/swaps/escrow_swaps/IEscrowSwap.ts +83 -37
  207. package/src/swaps/escrow_swaps/IEscrowSwapWrapper.ts +61 -30
  208. package/src/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.ts +37 -19
  209. package/src/swaps/escrow_swaps/frombtc/IFromBTCSelfInitSwap.ts +123 -50
  210. package/src/swaps/escrow_swaps/frombtc/IFromBTCWrapper.ts +24 -11
  211. package/src/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.ts +562 -258
  212. package/src/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.ts +156 -62
  213. package/src/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.ts +592 -227
  214. package/src/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.ts +177 -74
  215. package/src/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.ts +483 -245
  216. package/src/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.ts +141 -59
  217. package/src/swaps/escrow_swaps/tobtc/IToBTCSwap.ts +350 -195
  218. package/src/swaps/escrow_swaps/tobtc/IToBTCWrapper.ts +48 -23
  219. package/src/swaps/escrow_swaps/tobtc/ln/ToBTCLNSwap.ts +87 -40
  220. package/src/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.ts +110 -110
  221. package/src/swaps/escrow_swaps/tobtc/onchain/ToBTCSwap.ts +89 -34
  222. package/src/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.ts +101 -31
  223. package/src/swaps/spv_swaps/SpvFromBTCSwap.ts +556 -259
  224. package/src/swaps/spv_swaps/SpvFromBTCWrapper.ts +292 -148
  225. package/src/swaps/trusted/ln/LnForGasSwap.ts +186 -47
  226. package/src/swaps/trusted/ln/LnForGasWrapper.ts +34 -15
  227. package/src/swaps/trusted/onchain/OnchainForGasSwap.ts +262 -88
  228. package/src/swaps/trusted/onchain/OnchainForGasWrapper.ts +41 -19
  229. package/src/types/AmountData.ts +2 -1
  230. package/src/types/CustomPriceFunction.ts +8 -2
  231. package/src/types/PriceInfoType.ts +4 -4
  232. package/src/types/SwapExecutionAction.ts +97 -5
  233. package/src/types/SwapWithSigner.ts +8 -4
  234. package/src/types/Token.ts +12 -5
  235. package/src/types/TokenAmount.ts +3 -0
  236. package/src/types/fees/Fee.ts +3 -2
  237. package/src/types/fees/FeeBreakdown.ts +3 -2
  238. package/src/types/fees/PercentagePPM.ts +4 -2
  239. package/src/types/lnurl/LNURLPay.ts +20 -12
  240. package/src/types/lnurl/LNURLWithdraw.ts +17 -10
  241. package/src/types/wallets/LightningInvoiceCreateService.ts +30 -0
  242. package/src/types/wallets/MinimalBitcoinWalletInterface.ts +3 -1
  243. package/src/types/wallets/MinimalLightningNetworkWalletInterface.ts +4 -2
  244. package/src/utils/BitcoinUtils.ts +5 -0
  245. package/src/utils/SwapUtils.ts +63 -1
  246. package/src/utils/TokenUtils.ts +12 -4
  247. package/dist/bitcoin/BitcoinRpcWithAddressIndex.d.ts +0 -68
  248. package/dist/bitcoin/BitcoinRpcWithAddressIndex.js +0 -2
  249. package/dist/bitcoin/LightningNetworkApi.d.ts +0 -12
  250. package/dist/bitcoin/LightningNetworkApi.js +0 -2
  251. package/dist/bitcoin/mempool/MempoolApi.d.ts +0 -350
  252. package/dist/bitcoin/mempool/MempoolApi.js +0 -311
  253. package/dist/bitcoin/mempool/MempoolBitcoinBlock.d.ts +0 -44
  254. package/dist/bitcoin/mempool/MempoolBitcoinBlock.js +0 -48
  255. package/dist/bitcoin/mempool/MempoolBitcoinRpc.d.ts +0 -119
  256. package/dist/bitcoin/mempool/MempoolBitcoinRpc.js +0 -361
  257. package/dist/bitcoin/mempool/synchronizer/MempoolBtcRelaySynchronizer.d.ts +0 -22
  258. package/dist/bitcoin/mempool/synchronizer/MempoolBtcRelaySynchronizer.js +0 -105
  259. package/dist/errors/PaymentAuthError.d.ts +0 -11
  260. package/dist/errors/PaymentAuthError.js +0 -23
  261. package/src/errors/PaymentAuthError.ts +0 -26
@@ -1,14 +1,16 @@
1
1
  import {ISwapWrapper, ISwapWrapperOptions, SwapTypeDefinition, WrapperCtorTokens} from "../ISwapWrapper";
2
2
  import {
3
- BitcoinRpcWithAddressIndex,
3
+ BitcoinRpcWithAddressIndex, BtcBlock,
4
4
  BtcRelay,
5
5
  ChainEvent,
6
6
  ChainType,
7
7
  RelaySynchronizer,
8
8
  SpvVaultClaimEvent,
9
- SpvVaultCloseEvent,
9
+ SpvVaultCloseEvent, SpvVaultData,
10
10
  SpvVaultFrontEvent,
11
11
  SpvVaultTokenBalance,
12
+ SpvWithdrawalClaimedState,
13
+ SpvWithdrawalFrontedState,
12
14
  SpvWithdrawalStateType
13
15
  } from "@atomiqlabs/base";
14
16
  import {SpvFromBTCSwap, SpvFromBTCSwapInit, SpvFromBTCSwapState} from "./SpvFromBTCSwap";
@@ -20,7 +22,7 @@ import {ISwapPrice} from "../../prices/abstract/ISwapPrice";
20
22
  import {EventEmitter} from "events";
21
23
  import {Intermediary} from "../../intermediaries/Intermediary";
22
24
  import {extendAbortController, randomBytes, throwIfUndefined} from "../../utils/Utils";
23
- import {toCoinselectAddressType, toOutputScript} from "../../utils/BitcoinUtils";
25
+ import {fromOutputScript, toCoinselectAddressType, toOutputScript} from "../../utils/BitcoinUtils";
24
26
  import {IntermediaryAPI, SpvFromBTCPrepareResponseType} from "../../intermediaries/apis/IntermediaryAPI";
25
27
  import {RequestError} from "../../errors/RequestError";
26
28
  import {IntermediaryError} from "../../errors/IntermediaryError";
@@ -51,20 +53,71 @@ export type SpvFromBTCWrapperOptions = ISwapWrapperOptions & {
51
53
 
52
54
  export type SpvFromBTCTypeDefinition<T extends ChainType> = SwapTypeDefinition<T, SpvFromBTCWrapper<T>, SpvFromBTCSwap<T>>;
53
55
 
56
+ /**
57
+ * New spv vault (UTXO-controlled vault) based swaps for Bitcoin -> Smart chain swaps not requiring
58
+ * any initiation on the destination chain, and with the added possibility for the user to receive
59
+ * a native token on the destination chain as part of the swap (a "gas drop" feature).
60
+ *
61
+ * @category Swaps/Bitcoin → Smart chain
62
+ */
54
63
  export class SpvFromBTCWrapper<
55
64
  T extends ChainType
56
65
  > extends ISwapWrapper<T, SpvFromBTCTypeDefinition<T>, SpvFromBTCWrapperOptions> implements IClaimableSwapWrapper<SpvFromBTCSwap<T>> {
66
+ public readonly TYPE: SwapType.SPV_VAULT_FROM_BTC = SwapType.SPV_VAULT_FROM_BTC;
67
+ /**
68
+ * @internal
69
+ */
70
+ readonly _claimableSwapStates = [SpvFromBTCSwapState.BTC_TX_CONFIRMED];
71
+ /**
72
+ * @internal
73
+ */
74
+ readonly _swapDeserializer = SpvFromBTCSwap;
57
75
 
58
- public readonly claimableSwapStates = [SpvFromBTCSwapState.BTC_TX_CONFIRMED];
59
- public readonly TYPE = SwapType.SPV_VAULT_FROM_BTC;
60
- public readonly swapDeserializer = SpvFromBTCSwap;
61
76
 
62
- readonly synchronizer: RelaySynchronizer<any, T["TX"], any>;
63
- readonly contract: T["SpvVaultContract"];
64
- readonly btcRelay: T["BtcRelay"];
65
- readonly btcRpc: BitcoinRpcWithAddressIndex<any>;
77
+ /**
78
+ * @internal
79
+ */
80
+ protected readonly btcRelay: T["BtcRelay"];
81
+ /**
82
+ * @internal
83
+ */
84
+ protected readonly tickSwapState: Array<SpvFromBTCSwap<T>["_state"]> = [
85
+ SpvFromBTCSwapState.CREATED,
86
+ SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED,
87
+ SpvFromBTCSwapState.SIGNED,
88
+ SpvFromBTCSwapState.POSTED,
89
+ SpvFromBTCSwapState.BROADCASTED
90
+ ];
66
91
 
67
- readonly spvWithdrawalDataDeserializer: new (data: any) => T["SpvVaultWithdrawalData"];
92
+
93
+ /**
94
+ * @internal
95
+ */
96
+ readonly _synchronizer: RelaySynchronizer<any, T["TX"], any>;
97
+ /**
98
+ * @internal
99
+ */
100
+ readonly _contract: T["SpvVaultContract"];
101
+ /**
102
+ * @internal
103
+ */
104
+ readonly _btcRpc: BitcoinRpcWithAddressIndex<BtcBlock>;
105
+ /**
106
+ * @internal
107
+ */
108
+ readonly _spvWithdrawalDataDeserializer: new (data: any) => T["SpvVaultWithdrawalData"];
109
+ /**
110
+ * @internal
111
+ */
112
+ readonly _pendingSwapStates: Array<SpvFromBTCSwap<T>["_state"]> = [
113
+ SpvFromBTCSwapState.CREATED,
114
+ SpvFromBTCSwapState.SIGNED,
115
+ SpvFromBTCSwapState.POSTED,
116
+ SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED,
117
+ SpvFromBTCSwapState.BROADCASTED,
118
+ SpvFromBTCSwapState.DECLINED,
119
+ SpvFromBTCSwapState.BTC_TX_CONFIRMED
120
+ ];
68
121
 
69
122
  /**
70
123
  * @param chainIdentifier
@@ -96,108 +149,90 @@ export class SpvFromBTCWrapper<
96
149
  options?: AllOptional<SpvFromBTCWrapperOptions>,
97
150
  events?: EventEmitter<{swapState: [ISwap]}>
98
151
  ) {
99
- if(options==null) options = {};
100
- options.bitcoinNetwork ??= TEST_NETWORK;
101
- options.maxConfirmations ??= 6;
102
- options.bitcoinBlocktime ??= 10*60;
103
- options.maxTransactionsDelta ??= 3;
104
- options.maxRawAmountAdjustmentDifferencePPM ??= 100;
105
- options.maxBtcFeeOffset ??= 5;
106
- options.maxBtcFeeMultiplier ??= 1.5;
107
152
  super(
108
153
  chainIdentifier, unifiedStorage, unifiedChainEvents, chain, prices, tokens,
109
154
  {
110
- bitcoinNetwork: options.bitcoinNetwork ?? TEST_NETWORK,
111
- maxConfirmations: options.maxConfirmations ?? 6,
112
- bitcoinBlocktime: options.bitcoinBlocktime ?? 10*60,
113
- maxTransactionsDelta: options.maxTransactionsDelta ?? 3,
114
- maxRawAmountAdjustmentDifferencePPM: options.maxRawAmountAdjustmentDifferencePPM ?? 100,
115
- maxBtcFeeOffset: options.maxBtcFeeOffset ?? 5,
116
- maxBtcFeeMultiplier: options.maxBtcFeeMultiplier ?? 1.5
155
+ bitcoinNetwork: options?.bitcoinNetwork ?? TEST_NETWORK,
156
+ maxConfirmations: options?.maxConfirmations ?? 6,
157
+ bitcoinBlocktime: options?.bitcoinBlocktime ?? 10*60,
158
+ maxTransactionsDelta: options?.maxTransactionsDelta ?? 3,
159
+ maxRawAmountAdjustmentDifferencePPM: options?.maxRawAmountAdjustmentDifferencePPM ?? 100,
160
+ maxBtcFeeOffset: options?.maxBtcFeeOffset ?? 10,
161
+ maxBtcFeeMultiplier: options?.maxBtcFeeMultiplier ?? 1.5
117
162
  },
118
163
  events
119
164
  );
120
- this.spvWithdrawalDataDeserializer = spvWithdrawalDataDeserializer;
121
- this.contract = contract;
165
+ this._spvWithdrawalDataDeserializer = spvWithdrawalDataDeserializer;
166
+ this._contract = contract;
122
167
  this.btcRelay = btcRelay;
123
- this.synchronizer = synchronizer;
124
- this.btcRpc = btcRpc;
168
+ this._synchronizer = synchronizer;
169
+ this._btcRpc = btcRpc;
125
170
  }
126
171
 
127
- readonly pendingSwapStates: Array<SpvFromBTCSwap<T>["state"]> = [
128
- SpvFromBTCSwapState.CREATED,
129
- SpvFromBTCSwapState.SIGNED,
130
- SpvFromBTCSwapState.POSTED,
131
- SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED,
132
- SpvFromBTCSwapState.BROADCASTED,
133
- SpvFromBTCSwapState.DECLINED,
134
- SpvFromBTCSwapState.BTC_TX_CONFIRMED
135
- ];
136
- readonly tickSwapState: Array<SpvFromBTCSwap<T>["state"]> = [
137
- SpvFromBTCSwapState.CREATED,
138
- SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED,
139
- SpvFromBTCSwapState.SIGNED,
140
- SpvFromBTCSwapState.POSTED,
141
- SpvFromBTCSwapState.BROADCASTED
142
- ];
143
-
144
- protected async processEventFront(event: SpvVaultFrontEvent, swap: SpvFromBTCSwap<T>): Promise<boolean> {
172
+ private async processEventFront(event: SpvVaultFrontEvent, swap: SpvFromBTCSwap<T>): Promise<boolean> {
145
173
  if(
146
- swap.state===SpvFromBTCSwapState.SIGNED || swap.state===SpvFromBTCSwapState.POSTED ||
147
- swap.state===SpvFromBTCSwapState.BROADCASTED || swap.state===SpvFromBTCSwapState.DECLINED ||
148
- swap.state===SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED || swap.state===SpvFromBTCSwapState.BTC_TX_CONFIRMED
174
+ swap._state===SpvFromBTCSwapState.SIGNED || swap._state===SpvFromBTCSwapState.POSTED ||
175
+ swap._state===SpvFromBTCSwapState.BROADCASTED || swap._state===SpvFromBTCSwapState.DECLINED ||
176
+ swap._state===SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED || swap._state===SpvFromBTCSwapState.BTC_TX_CONFIRMED
149
177
  ) {
178
+ swap._state = SpvFromBTCSwapState.FRONTED;
179
+ swap._frontTxId = event.meta?.txId;
150
180
  await swap._setBitcoinTxId(event.btcTxId).catch(e => {
151
181
  this.logger.warn("processEventFront(): Failed to set bitcoin txId: ", e);
152
182
  });
153
- swap.state = SpvFromBTCSwapState.FRONTED;
154
183
  return true;
155
184
  }
156
185
  return false;
157
186
  }
158
187
 
159
- protected async processEventClaim(event: SpvVaultClaimEvent, swap: SpvFromBTCSwap<T>): Promise<boolean> {
188
+ private async processEventClaim(event: SpvVaultClaimEvent, swap: SpvFromBTCSwap<T>): Promise<boolean> {
160
189
  if(
161
- swap.state===SpvFromBTCSwapState.SIGNED || swap.state===SpvFromBTCSwapState.POSTED ||
162
- swap.state===SpvFromBTCSwapState.BROADCASTED || swap.state===SpvFromBTCSwapState.DECLINED ||
163
- swap.state===SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED || swap.state===SpvFromBTCSwapState.BTC_TX_CONFIRMED
190
+ swap._state===SpvFromBTCSwapState.SIGNED || swap._state===SpvFromBTCSwapState.POSTED ||
191
+ swap._state===SpvFromBTCSwapState.BROADCASTED || swap._state===SpvFromBTCSwapState.DECLINED ||
192
+ swap._state===SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED || swap._state===SpvFromBTCSwapState.FRONTED ||
193
+ swap._state===SpvFromBTCSwapState.BTC_TX_CONFIRMED
164
194
  ) {
195
+ swap._state = SpvFromBTCSwapState.CLAIMED;
196
+ swap._claimTxId = event.meta?.txId;
165
197
  await swap._setBitcoinTxId(event.btcTxId).catch(e => {
166
198
  this.logger.warn("processEventClaim(): Failed to set bitcoin txId: ", e);
167
199
  });
168
- swap.state = SpvFromBTCSwapState.CLAIMED;
169
200
  return true;
170
201
  }
171
202
  return false;
172
203
  }
173
204
 
174
- protected processEventClose(event: SpvVaultCloseEvent, swap: SpvFromBTCSwap<T>): Promise<boolean> {
205
+ private processEventClose(event: SpvVaultCloseEvent, swap: SpvFromBTCSwap<T>): Promise<boolean> {
175
206
  if(
176
- swap.state===SpvFromBTCSwapState.SIGNED || swap.state===SpvFromBTCSwapState.POSTED ||
177
- swap.state===SpvFromBTCSwapState.BROADCASTED || swap.state===SpvFromBTCSwapState.DECLINED ||
178
- swap.state===SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED || swap.state===SpvFromBTCSwapState.BTC_TX_CONFIRMED
207
+ swap._state===SpvFromBTCSwapState.SIGNED || swap._state===SpvFromBTCSwapState.POSTED ||
208
+ swap._state===SpvFromBTCSwapState.BROADCASTED || swap._state===SpvFromBTCSwapState.DECLINED ||
209
+ swap._state===SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED || swap._state===SpvFromBTCSwapState.BTC_TX_CONFIRMED
179
210
  ) {
180
- swap.state = SpvFromBTCSwapState.CLOSED;
211
+ swap._state = SpvFromBTCSwapState.CLOSED;
181
212
  return Promise.resolve(true);
182
213
  }
183
214
  return Promise.resolve(false);
184
215
  }
185
216
 
217
+ /**
218
+ * @inheritDoc
219
+ * @internal
220
+ */
186
221
  protected async processEvent(event: ChainEvent<T["Data"]>, swap: SpvFromBTCSwap<T>): Promise<void> {
187
222
  if(swap==null) return;
188
223
 
189
224
  let swapChanged: boolean = false;
190
225
  if(event instanceof SpvVaultFrontEvent) {
191
226
  swapChanged = await this.processEventFront(event, swap);
192
- if(event.meta?.txId!=null && swap.frontTxId!==event.meta.txId) {
193
- swap.frontTxId = event.meta.txId;
227
+ if(event.meta?.txId!=null && swap._frontTxId!==event.meta.txId) {
228
+ swap._frontTxId = event.meta.txId;
194
229
  swapChanged ||= true;
195
230
  }
196
231
  }
197
232
  if(event instanceof SpvVaultClaimEvent) {
198
233
  swapChanged = await this.processEventClaim(event, swap);
199
- if(event.meta?.txId!=null && swap.claimTxId!==event.meta.txId) {
200
- swap.claimTxId = event.meta.txId;
234
+ if(event.meta?.txId!=null && swap._claimTxId!==event.meta.txId) {
235
+ swap._claimTxId = event.meta.txId;
201
236
  swapChanged ||= true;
202
237
  }
203
238
  }
@@ -220,7 +255,7 @@ export class SpvFromBTCWrapper<
220
255
  */
221
256
  private async preFetchFinalizedBlockHeight(abortController: AbortController): Promise<number | undefined> {
222
257
  try {
223
- const block = await this.chain.getFinalizedBlock();
258
+ const block = await this._chain.getFinalizedBlock();
224
259
  return block.height;
225
260
  } catch (e) {
226
261
  abortController.abort(e);
@@ -258,36 +293,36 @@ export class SpvFromBTCWrapper<
258
293
  ] = await Promise.all([
259
294
  this.btcRelay.getFeePerBlock(),
260
295
  this.btcRelay.getTipData(),
261
- this.btcRpc.getTipHeight(),
262
- this.contract.getClaimFee(this.chain.randomAddress()),
263
- nativeTokenPricePrefetch ?? (amountData.token===this.chain.getNativeCurrencyAddress() ?
296
+ this._btcRpc.getTipHeight(),
297
+ this._contract.getClaimFee(this._chain.randomAddress()),
298
+ nativeTokenPricePrefetch ?? (amountData.token===this._chain.getNativeCurrencyAddress() ?
264
299
  pricePrefetch :
265
- this.prices.preFetchPrice(this.chainIdentifier, this.chain.getNativeCurrencyAddress(), abortController.signal))
300
+ this._prices.preFetchPrice(this.chainIdentifier, this._chain.getNativeCurrencyAddress(), abortController.signal))
266
301
  ]);
267
302
 
268
303
  if(btcRelayData==null) throw new Error("Btc relay doesn't seem to be initialized!");
269
304
 
270
305
  const currentBtcRelayBlock = btcRelayData.blockheight;
271
- const blockDelta = Math.max(currentBtcBlock-currentBtcRelayBlock+this.options.maxConfirmations, 0);
306
+ const blockDelta = Math.max(currentBtcBlock-currentBtcRelayBlock+this._options.maxConfirmations, 0);
272
307
 
273
308
  const totalFeeInNativeToken = (
274
309
  (BigInt(blockDelta) * feePerBlock) +
275
- (claimFeeRate * BigInt(this.options.maxTransactionsDelta))
310
+ (claimFeeRate * BigInt(this._options.maxTransactionsDelta))
276
311
  ) * BigInt(Math.floor(options.feeSafetyFactor*1000000)) / 1_000_000n;
277
312
 
278
313
  let payoutAmount: bigint;
279
314
  if(amountData.exactIn) {
280
315
  //Convert input amount in BTC to
281
- const amountInNativeToken = await this.prices.getFromBtcSwapAmount(this.chainIdentifier, amountData.amount, this.chain.getNativeCurrencyAddress(), abortController.signal, nativeTokenPrice);
316
+ const amountInNativeToken = await this._prices.getFromBtcSwapAmount(this.chainIdentifier, amountData.amount, this._chain.getNativeCurrencyAddress(), abortController.signal, nativeTokenPrice);
282
317
  payoutAmount = amountInNativeToken - totalFeeInNativeToken;
283
318
  } else {
284
- if(amountData.token===this.chain.getNativeCurrencyAddress()) {
319
+ if(amountData.token===this._chain.getNativeCurrencyAddress()) {
285
320
  //Both amounts in same currency
286
321
  payoutAmount = amountData.amount;
287
322
  } else {
288
323
  //Need to convert both to native currency
289
- const btcAmount = await this.prices.getToBtcSwapAmount(this.chainIdentifier, amountData.amount, amountData.token, abortController.signal, await pricePrefetch);
290
- payoutAmount = await this.prices.getFromBtcSwapAmount(this.chainIdentifier, btcAmount, this.chain.getNativeCurrencyAddress(), abortController.signal, nativeTokenPrice);
324
+ const btcAmount = await this._prices.getToBtcSwapAmount(this.chainIdentifier, amountData.amount, amountData.token, abortController.signal, await pricePrefetch);
325
+ payoutAmount = await this._prices.getFromBtcSwapAmount(this.chainIdentifier, btcAmount, this._chain.getNativeCurrencyAddress(), abortController.signal, nativeTokenPrice);
291
326
  }
292
327
  }
293
328
 
@@ -330,7 +365,7 @@ export class SpvFromBTCWrapper<
330
365
  }> {
331
366
  const btcFeeRate = await throwIfUndefined(bitcoinFeeRatePromise, "Bitcoin fee rate promise failed!");
332
367
  abortSignal.throwIfAborted();
333
- if(btcFeeRate!=null && resp.btcFeeRate > btcFeeRate) throw new IntermediaryError("Bitcoin fee rate returned too high!");
368
+ if(btcFeeRate!=null && resp.btcFeeRate > btcFeeRate) throw new IntermediaryError(`Required bitcoin fee rate returned from the LP is too high! Maximum accepted: ${btcFeeRate} sats/vB, required by LP: ${resp.btcFeeRate} sats/vB`);
334
369
 
335
370
  //Vault related
336
371
  let vaultScript: Uint8Array;
@@ -338,9 +373,9 @@ export class SpvFromBTCWrapper<
338
373
  let btcAddressScript: Uint8Array;
339
374
  //Ensure valid btc addresses returned
340
375
  try {
341
- vaultScript = toOutputScript(this.options.bitcoinNetwork, resp.vaultBtcAddress);
376
+ vaultScript = toOutputScript(this._options.bitcoinNetwork, resp.vaultBtcAddress);
342
377
  vaultAddressType = toCoinselectAddressType(vaultScript);
343
- btcAddressScript = toOutputScript(this.options.bitcoinNetwork, resp.btcAddress);
378
+ btcAddressScript = toOutputScript(this._options.bitcoinNetwork, resp.btcAddress);
344
379
  } catch (e) {
345
380
  throw new IntermediaryError("Invalid btc address data returned", e);
346
381
  }
@@ -379,7 +414,7 @@ export class SpvFromBTCWrapper<
379
414
  //Fetch vault data
380
415
  let vault: T["SpvVaultData"] | null;
381
416
  try {
382
- vault = await this.contract.getVaultData(resp.address, resp.vaultId);
417
+ vault = await this._contract.getVaultData(resp.address, resp.vaultId);
383
418
  } catch (e) {
384
419
  this.logger.error("Error getting spv vault (owner: "+resp.address+" vaultId: "+resp.vaultId.toString(10)+"): ", e);
385
420
  throw new IntermediaryError("Spv swap vault not found", e);
@@ -389,7 +424,7 @@ export class SpvFromBTCWrapper<
389
424
  //Make sure vault is opened
390
425
  if(vault==null || !vault.isOpened()) throw new IntermediaryError("Returned spv swap vault is not opened!");
391
426
  //Make sure the vault doesn't require insane amount of confirmations
392
- if(vault.getConfirmations()>this.options.maxConfirmations) throw new IntermediaryError("SPV swap vault needs too many confirmations: "+vault.getConfirmations());
427
+ if(vault.getConfirmations()>this._options.maxConfirmations) throw new IntermediaryError("SPV swap vault needs too many confirmations: "+vault.getConfirmations());
393
428
  const tokenData = vault.getTokenData();
394
429
 
395
430
  //Amounts - make sure the amounts match
@@ -399,7 +434,7 @@ export class SpvFromBTCWrapper<
399
434
  //Check the difference between amount adjusted due to scaling to raw amount
400
435
  const adjustedAmount = amountData.amount / tokenData[0].multiplier * tokenData[0].multiplier;
401
436
  const adjustmentPPM = (amountData.amount - adjustedAmount)*1_000_000n / amountData.amount;
402
- if(adjustmentPPM > this.options.maxRawAmountAdjustmentDifferencePPM)
437
+ if(adjustmentPPM > this._options.maxRawAmountAdjustmentDifferencePPM)
403
438
  throw new IntermediaryError("Invalid amount0 multiplier used, rawAmount diff too high");
404
439
  if(resp.total !== adjustedAmount) throw new IntermediaryError("Invalid total returned");
405
440
  }
@@ -409,7 +444,7 @@ export class SpvFromBTCWrapper<
409
444
  //Check the difference between amount adjusted due to scaling to raw amount
410
445
  const adjustedGasAmount = options.gasAmount / tokenData[0].multiplier * tokenData[0].multiplier;
411
446
  const adjustmentPPM = (options.gasAmount - adjustedGasAmount)*1_000_000n / options.gasAmount;
412
- if(adjustmentPPM > this.options.maxRawAmountAdjustmentDifferencePPM)
447
+ if(adjustmentPPM > this._options.maxRawAmountAdjustmentDifferencePPM)
413
448
  throw new IntermediaryError("Invalid amount1 multiplier used, rawAmount diff too high");
414
449
  if(resp.totalGas !== adjustedGasAmount) throw new IntermediaryError("Invalid gas total returned");
415
450
  }
@@ -418,7 +453,7 @@ export class SpvFromBTCWrapper<
418
453
  })(),
419
454
  (async() => {
420
455
  //Require the vault UTXO to have at least 1 confirmation
421
- let btcTx = await this.btcRpc.getTransaction(txId);
456
+ let btcTx = await this._btcRpc.getTransaction(txId);
422
457
  if(btcTx==null) throw new IntermediaryError("Invalid UTXO, doesn't exist (txId)");
423
458
  abortController.signal.throwIfAborted();
424
459
  if(btcTx.confirmations==null || btcTx.confirmations<1) throw new IntermediaryError("SPV vault UTXO not confirmed");
@@ -429,7 +464,7 @@ export class SpvFromBTCWrapper<
429
464
  })(),
430
465
  (async() => {
431
466
  //Require vault UTXO is unspent
432
- if(await this.btcRpc.isSpent(utxo)) throw new IntermediaryError("Returned spv vault UTXO is already spent", null, true);
467
+ if(await this._btcRpc.isSpent(utxo)) throw new IntermediaryError("Returned spv vault UTXO is already spent", null, true);
433
468
  abortController.signal.throwIfAborted();
434
469
  })()
435
470
  ]).catch(e => {
@@ -445,17 +480,17 @@ export class SpvFromBTCWrapper<
445
480
  const [txId, voutStr] = utxo.split(":");
446
481
  //Such that 1st tx isn't fetched twice
447
482
  if(btcTx.txid!==txId) {
448
- const _btcTx = await this.btcRpc.getTransaction(txId);
483
+ const _btcTx = await this._btcRpc.getTransaction(txId);
449
484
  if(_btcTx==null) throw new IntermediaryError("Invalid ancestor transaction (not found)");
450
485
  btcTx = _btcTx;
451
486
  }
452
- const withdrawalData = await this.contract.getWithdrawalData(btcTx);
487
+ const withdrawalData = await this._contract.getWithdrawalData(btcTx);
453
488
  abortSignal.throwIfAborted();
454
489
  pendingWithdrawals.unshift(withdrawalData);
455
490
  utxo = pendingWithdrawals[0].getSpentVaultUtxo();
456
491
  this.logger.debug("verifyReturnedData(): Vault UTXO: "+vault.getUtxo()+" current utxo: "+utxo);
457
- if(pendingWithdrawals.length>=this.options.maxTransactionsDelta)
458
- throw new IntermediaryError("BTC <> SC state difference too deep, maximum: "+this.options.maxTransactionsDelta);
492
+ if(pendingWithdrawals.length>=this._options.maxTransactionsDelta)
493
+ throw new IntermediaryError("BTC <> SC state difference too deep, maximum: "+this._options.maxTransactionsDelta);
459
494
  }
460
495
 
461
496
  //Verify that the vault has enough balance after processing all pending withdrawals
@@ -476,7 +511,7 @@ export class SpvFromBTCWrapper<
476
511
  //Also verify that all the withdrawal txns are valid, this is an extra sanity check
477
512
  try {
478
513
  for(let withdrawal of pendingWithdrawals) {
479
- await this.contract.checkWithdrawalTx(withdrawal);
514
+ await this._contract.checkWithdrawalTx(withdrawal);
480
515
  }
481
516
  } catch (e) {
482
517
  this.logger.error("Error calculating spv vault balance (owner: "+resp.address+" vaultId: "+resp.vaultId.toString(10)+"): ", e);
@@ -491,17 +526,19 @@ export class SpvFromBTCWrapper<
491
526
  }
492
527
 
493
528
  /**
494
- * Returns a newly created swap, receiving 'amount' on chain
529
+ * Returns a newly created Bitcoin -> Smart chain swap using the SPV vault (UTXO-controlled vault) swap protocol,
530
+ * with the passed amount. Also allows specifying additional "gas drop" native token that the receipient receives
531
+ * on the destination chain in the `options` argument.
495
532
  *
496
- * @param signer Smartchain signer's address intiating the swap
497
- * @param amountData Amount of token & amount to swap
498
- * @param lps LPs (liquidity providers) to get the quotes from
499
- * @param options Quote options
500
- * @param additionalParams Additional parameters sent to the LP when creating the swap
501
- * @param abortSignal Abort signal for aborting the process
533
+ * @param recipient Recipient address on the destination smart chain
534
+ * @param amountData Amount, token and exact input/output data for to swap
535
+ * @param lps An array of intermediaries (LPs) to get the quotes from
536
+ * @param options Optional additional quote options
537
+ * @param additionalParams Optional additional parameters sent to the LP when creating the swap
538
+ * @param abortSignal Abort signal
502
539
  */
503
- create(
504
- signer: string,
540
+ public create(
541
+ recipient: string,
505
542
  amountData: AmountData,
506
543
  lps: Intermediary[],
507
544
  options?: SpvFromBTCOptions,
@@ -522,14 +559,14 @@ export class SpvFromBTCWrapper<
522
559
  const pricePrefetchPromise: Promise<bigint | undefined> = this.preFetchPrice(amountData, _abortController.signal);
523
560
  const usdPricePrefetchPromise: Promise<number | undefined> = this.preFetchUsdPrice(_abortController.signal);
524
561
  const finalizedBlockHeightPrefetchPromise: Promise<number | undefined> = this.preFetchFinalizedBlockHeight(_abortController);
525
- const nativeTokenAddress = this.chain.getNativeCurrencyAddress();
562
+ const nativeTokenAddress = this._chain.getNativeCurrencyAddress();
526
563
  const gasTokenPricePrefetchPromise: Promise<bigint | undefined> | undefined = _options.gasAmount===0n ?
527
564
  undefined :
528
565
  this.preFetchPrice({token: nativeTokenAddress}, _abortController.signal);
529
566
  const callerFeePrefetchPromise = this.preFetchCallerFeeShare(amountData, _options, pricePrefetchPromise, gasTokenPricePrefetchPromise, _abortController);
530
567
  const bitcoinFeeRatePromise: Promise<number | undefined> = _options.maxAllowedNetworkFeeRate!=Infinity ?
531
568
  Promise.resolve(_options.maxAllowedNetworkFeeRate) :
532
- this.btcRpc.getFeeRate().then(x => this.options.maxBtcFeeOffset + (x*this.options.maxBtcFeeMultiplier)).catch(e => {
569
+ this._btcRpc.getFeeRate().then(x => this._options.maxBtcFeeOffset + (x*this._options.maxBtcFeeMultiplier)).catch(e => {
533
570
  _abortController.abort(e);
534
571
  return undefined;
535
572
  });
@@ -547,7 +584,7 @@ export class SpvFromBTCWrapper<
547
584
  return await IntermediaryAPI.prepareSpvFromBTC(
548
585
  this.chainIdentifier, lp.url,
549
586
  {
550
- address: signer,
587
+ address: recipient,
551
588
  amount: amountData.amount,
552
589
  token: amountData.token.toString(),
553
590
  exactOut: !amountData.exactIn,
@@ -557,7 +594,7 @@ export class SpvFromBTCWrapper<
557
594
  frontingFeeRate: 0n,
558
595
  additionalParams
559
596
  },
560
- this.options.postRequestTimeout, abortController.signal, retryCount>0 ? false : undefined
597
+ this._options.postRequestTimeout, abortController.signal, retryCount>0 ? false : undefined
561
598
  );
562
599
  }, undefined, e => e instanceof RequestError, abortController.signal);
563
600
 
@@ -595,7 +632,7 @@ export class SpvFromBTCWrapper<
595
632
 
596
633
  quoteId: resp.quoteId,
597
634
 
598
- recipient: signer,
635
+ recipient,
599
636
 
600
637
  vaultOwner: resp.address,
601
638
  vaultId: resp.vaultId,
@@ -640,11 +677,117 @@ export class SpvFromBTCWrapper<
640
677
  });
641
678
  }
642
679
 
680
+ /**
681
+ * Recovers an SPV vault (UTXO-controlled vault) based swap from smart chain on-chain data
682
+ *
683
+ * @param state State of the spv vault withdrawal recovered from on-chain data
684
+ * @param vault SPV vault processing the swap
685
+ * @param lp Intermediary (LP) used as a counterparty for the swap
686
+ */
687
+ public async recoverFromState(state: SpvWithdrawalClaimedState | SpvWithdrawalFrontedState, vault?: SpvVaultData | null, lp?: Intermediary): Promise<SpvFromBTCSwap<T> | null> {
688
+ //Get the vault
689
+ vault ??= await this._contract.getVaultData(state.owner, state.vaultId);
690
+ if(vault==null) return null;
691
+ if(state.btcTxId==null) return null;
692
+ const btcTx = await this._btcRpc.getTransaction(state.btcTxId);
693
+ if(btcTx==null) return null;
694
+ const withdrawalData = await this._contract.getWithdrawalData(btcTx)
695
+ .catch(e => {
696
+ this.logger.warn(`Error parsing withdrawal data for tx ${btcTx.txid}: `, e);
697
+ return null;
698
+ });
699
+ if(withdrawalData==null) return null;
700
+
701
+ const vaultTokens = vault.getTokenData();
702
+ const withdrawalDataOutputs = withdrawalData.getTotalOutput();
703
+
704
+ const txBlock = await state.getTxBlock?.();
705
+
706
+ const swapInit: SpvFromBTCSwapInit = {
707
+ pricingInfo: {
708
+ isValid: true,
709
+ satsBaseFee: 0n,
710
+ swapPriceUSatPerToken: 100_000_000_000_000n,
711
+ realPriceUSatPerToken: 100_000_000_000_000n,
712
+ differencePPM: 0n,
713
+ feePPM: 0n,
714
+ },
715
+ url: lp?.url,
716
+ expiry: 0,
717
+ swapFee: 0n,
718
+ swapFeeBtc: 0n,
719
+ exactIn: true,
720
+
721
+ //Use bitcoin tx id as quote id, even though this is not strictly correct as this
722
+ // is an off-chain identifier presented by the LP that cannot be recovered from on-chain
723
+ // data
724
+ quoteId: btcTx.txid,
725
+
726
+ recipient: state.recipient,
727
+
728
+ vaultOwner: state.owner,
729
+ vaultId: state.vaultId,
730
+ vaultRequiredConfirmations: vault.getConfirmations(),
731
+ vaultTokenMultipliers: vault.getTokenData().map(val => val.multiplier),
732
+ vaultBtcAddress: fromOutputScript(this._options.bitcoinNetwork, withdrawalData.getNewVaultScript().toString("hex")),
733
+ vaultUtxo: withdrawalData.getSpentVaultUtxo(),
734
+ vaultUtxoValue: BigInt(withdrawalData.getNewVaultBtcAmount()),
735
+
736
+ btcDestinationAddress: fromOutputScript(this._options.bitcoinNetwork, btcTx.outs[2].scriptPubKey.hex),
737
+ btcAmount: BigInt(btcTx.outs[2].value),
738
+ btcAmountSwap: BigInt(btcTx.outs[2].value),
739
+ btcAmountGas: 0n,
740
+ minimumBtcFeeRate: 0,
741
+
742
+ outputTotalSwap: withdrawalDataOutputs[0] * vaultTokens[0].multiplier,
743
+ outputSwapToken: vaultTokens[0].token,
744
+ outputTotalGas: withdrawalDataOutputs[1] * vaultTokens[1].multiplier,
745
+ outputGasToken: vaultTokens[1].token,
746
+ gasSwapFeeBtc: 0n,
747
+ gasSwapFee: 0n,
748
+ gasPricingInfo: {
749
+ isValid: true,
750
+ satsBaseFee: 0n,
751
+ swapPriceUSatPerToken: 100_000_000_000_000n,
752
+ realPriceUSatPerToken: 100_000_000_000_000n,
753
+ differencePPM: 0n,
754
+ feePPM: 0n,
755
+ },
756
+
757
+ callerFeeShare: withdrawalData.callerFeeRate,
758
+ frontingFeeShare: withdrawalData.frontingFeeRate,
759
+ executionFeeShare: withdrawalData.executionFeeRate,
760
+
761
+ genesisSmartChainBlockHeight: txBlock?.blockHeight ?? 0
762
+ };
763
+ const quote = new SpvFromBTCSwap<T>(this, swapInit);
764
+ quote._data = withdrawalData;
765
+ if(txBlock!=null) {
766
+ quote.createdAt = txBlock.blockTime*1000;
767
+ } else if(btcTx.blockhash==null) {
768
+ quote.createdAt = Date.now();
769
+ } else {
770
+ const blockHeader = await this._btcRpc.getBlockHeader(btcTx.blockhash);
771
+ quote.createdAt = blockHeader==null ? Date.now() : blockHeader.getTimestamp()*1000;
772
+ }
773
+ quote._setInitiated();
774
+ if(btcTx.inputAddresses!=null) quote._senderAddress = btcTx.inputAddresses[1];
775
+ if(state.type===SpvWithdrawalStateType.FRONTED) {
776
+ quote._frontTxId = state.txId;
777
+ quote._state = SpvFromBTCSwapState.FRONTED;
778
+ } else {
779
+ quote._claimTxId = state.txId;
780
+ quote._state = SpvFromBTCSwapState.CLAIMED;
781
+ }
782
+ await quote._save();
783
+ return quote;
784
+ }
785
+
643
786
  /**
644
787
  * Returns a random dummy PSBT that can be used for fee estimation, the last output (the LP output) is omitted
645
788
  * to allow for coinselection algorithm to determine maximum sendable amount there
646
789
  *
647
- * @param includeGasToken Whether to return the PSBT also with the gas token amount (increases the vSize by 8)
790
+ * @param includeGasToken Whether to return the PSBT also with the gas token amount (increases the vSize by 8)
648
791
  */
649
792
  public getDummySwapPsbt(includeGasToken = false): Transaction {
650
793
  //Construct dummy swap psbt
@@ -670,8 +813,8 @@ export class SpvFromBTCWrapper<
670
813
  amount: 600n
671
814
  });
672
815
 
673
- const opReturnData = this.contract.toOpReturnData(
674
- this.chain.randomAddress(),
816
+ const opReturnData = this._contract.toOpReturnData(
817
+ this._chain.randomAddress(),
675
818
  includeGasToken ? [0xFFFFFFFFFFFFFFFFn, 0xFFFFFFFFFFFFFFFFn] : [0xFFFFFFFFFFFFFFFFn]
676
819
  );
677
820
 
@@ -686,6 +829,10 @@ export class SpvFromBTCWrapper<
686
829
  return psbt;
687
830
  }
688
831
 
832
+ /**
833
+ * @inheritDoc
834
+ * @internal
835
+ */
689
836
  protected async _checkPastSwaps(pastSwaps: SpvFromBTCSwap<T>[]): Promise<{
690
837
  changedSwaps: SpvFromBTCSwap<T>[];
691
838
  removeSwaps: SpvFromBTCSwap<T>[]
@@ -693,33 +840,33 @@ export class SpvFromBTCWrapper<
693
840
  const changedSwaps: Set<SpvFromBTCSwap<T>> = new Set();
694
841
  const removeSwaps: SpvFromBTCSwap<T>[] = [];
695
842
 
696
- const broadcastedOrConfirmedSwaps: (SpvFromBTCSwap<T> & {data: T["SpvVaultWithdrawalData"]})[] = [];
843
+ const broadcastedOrConfirmedSwaps: (SpvFromBTCSwap<T> & {_data: T["SpvVaultWithdrawalData"]})[] = [];
697
844
 
698
845
  for(let pastSwap of pastSwaps) {
699
846
  let changed: boolean = false;
700
847
 
701
848
  if(
702
- pastSwap.state===SpvFromBTCSwapState.SIGNED ||
703
- pastSwap.state===SpvFromBTCSwapState.POSTED ||
704
- pastSwap.state===SpvFromBTCSwapState.BROADCASTED ||
705
- pastSwap.state===SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED ||
706
- pastSwap.state===SpvFromBTCSwapState.DECLINED ||
707
- pastSwap.state===SpvFromBTCSwapState.BTC_TX_CONFIRMED
849
+ pastSwap._state===SpvFromBTCSwapState.SIGNED ||
850
+ pastSwap._state===SpvFromBTCSwapState.POSTED ||
851
+ pastSwap._state===SpvFromBTCSwapState.BROADCASTED ||
852
+ pastSwap._state===SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED ||
853
+ pastSwap._state===SpvFromBTCSwapState.DECLINED ||
854
+ pastSwap._state===SpvFromBTCSwapState.BTC_TX_CONFIRMED
708
855
  ) {
709
856
  //Check BTC transaction
710
857
  if(await pastSwap._syncStateFromBitcoin(false)) changed ||= true;
711
858
  }
712
859
 
713
860
  if(
714
- pastSwap.state===SpvFromBTCSwapState.CREATED ||
715
- pastSwap.state===SpvFromBTCSwapState.SIGNED ||
716
- pastSwap.state===SpvFromBTCSwapState.POSTED
861
+ pastSwap._state===SpvFromBTCSwapState.CREATED ||
862
+ pastSwap._state===SpvFromBTCSwapState.SIGNED ||
863
+ pastSwap._state===SpvFromBTCSwapState.POSTED
717
864
  ) {
718
- if(pastSwap.expiry<Date.now()) {
719
- if(pastSwap.state===SpvFromBTCSwapState.CREATED) {
720
- pastSwap.state = SpvFromBTCSwapState.QUOTE_EXPIRED;
865
+ if(await pastSwap._verifyQuoteDefinitelyExpired()) {
866
+ if(pastSwap._state===SpvFromBTCSwapState.CREATED) {
867
+ pastSwap._state = SpvFromBTCSwapState.QUOTE_EXPIRED;
721
868
  } else {
722
- pastSwap.state = SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED;
869
+ pastSwap._state = SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED;
723
870
  }
724
871
  changed ||= true;
725
872
  }
@@ -731,56 +878,53 @@ export class SpvFromBTCWrapper<
731
878
  }
732
879
  if(changed) changedSwaps.add(pastSwap);
733
880
 
734
- if(pastSwap.state===SpvFromBTCSwapState.BROADCASTED || pastSwap.state===SpvFromBTCSwapState.BTC_TX_CONFIRMED) {
735
- if(pastSwap.data!=null) broadcastedOrConfirmedSwaps.push(pastSwap as (SpvFromBTCSwap<T> & {data: T["SpvVaultWithdrawalData"]}));
881
+ if(pastSwap._state===SpvFromBTCSwapState.BROADCASTED || pastSwap._state===SpvFromBTCSwapState.BTC_TX_CONFIRMED) {
882
+ if(pastSwap._data!=null) broadcastedOrConfirmedSwaps.push(pastSwap as (SpvFromBTCSwap<T> & {_data: T["SpvVaultWithdrawalData"]}));
736
883
  }
737
884
  }
738
885
 
739
- const checkWithdrawalStateSwaps: (SpvFromBTCSwap<T> & {data: T["SpvVaultWithdrawalData"]})[] = [];
740
- const _fronts = await this.contract.getFronterAddresses(broadcastedOrConfirmedSwaps.map(val => ({
741
- owner: val.vaultOwner,
742
- vaultId: val.vaultId,
743
- withdrawal: val.data!
744
- })));
745
- const _vaultUtxos = await this.contract.getVaultLatestUtxos(broadcastedOrConfirmedSwaps.map(val => ({
746
- owner: val.vaultOwner,
747
- vaultId: val.vaultId
886
+ const checkWithdrawalStateSwaps: (SpvFromBTCSwap<T> & {_data: T["SpvVaultWithdrawalData"]})[] = [];
887
+ const _fronts = await this._contract.getFronterAddresses(broadcastedOrConfirmedSwaps.map(val => ({
888
+ ...val.getSpvVaultData(),
889
+ withdrawal: val._data!
748
890
  })));
891
+ const _vaultUtxos = await this._contract.getVaultLatestUtxos(broadcastedOrConfirmedSwaps.map(val => val.getSpvVaultData()));
749
892
  for(const pastSwap of broadcastedOrConfirmedSwaps) {
750
- const fronterAddress = _fronts[pastSwap.data.getTxId()];
751
- const latestVaultUtxo = _vaultUtxos[pastSwap.vaultOwner]?.[pastSwap.vaultId.toString(10)];
752
- if(fronterAddress===undefined) this.logger.warn(`_checkPastSwaps(): No fronter address returned for ${pastSwap.data.getTxId()}`);
753
- if(latestVaultUtxo===undefined) this.logger.warn(`_checkPastSwaps(): No last vault utxo returned for ${pastSwap.data.getTxId()}`);
893
+ const fronterAddress = _fronts[pastSwap._data.getTxId()];
894
+ const vault = pastSwap.getSpvVaultData();
895
+ const latestVaultUtxo = _vaultUtxos[vault.owner]?.[vault.vaultId.toString(10)];
896
+ if(fronterAddress===undefined) this.logger.warn(`_checkPastSwaps(): No fronter address returned for ${pastSwap._data.getTxId()}`);
897
+ if(latestVaultUtxo===undefined) this.logger.warn(`_checkPastSwaps(): No last vault utxo returned for ${pastSwap._data.getTxId()}`);
754
898
  if(await pastSwap._shouldCheckWithdrawalState(fronterAddress, latestVaultUtxo)) checkWithdrawalStateSwaps.push(pastSwap);
755
899
  }
756
900
 
757
- const withdrawalStates = await this.contract.getWithdrawalStates(
901
+ const withdrawalStates = await this._contract.getWithdrawalStates(
758
902
  checkWithdrawalStateSwaps.map(val => ({
759
- withdrawal: val.data,
760
- scStartBlockheight: val.genesisSmartChainBlockHeight
903
+ withdrawal: val._data,
904
+ scStartBlockheight: val._genesisSmartChainBlockHeight
761
905
  }))
762
906
  );
763
907
  for(const pastSwap of checkWithdrawalStateSwaps) {
764
- const status = withdrawalStates[pastSwap.data.getTxId()];
908
+ const status = withdrawalStates[pastSwap._data.getTxId()];
765
909
  if(status==null) {
766
- this.logger.warn(`_checkPastSwaps(): No withdrawal state returned for ${pastSwap.data.getTxId()}`);
910
+ this.logger.warn(`_checkPastSwaps(): No withdrawal state returned for ${pastSwap._data.getTxId()}`);
767
911
  continue;
768
912
  }
769
- this.logger.debug("syncStateFromChain(): status of "+pastSwap.data.btcTx.txid, status?.type);
913
+ this.logger.debug("syncStateFromChain(): status of "+pastSwap._data.btcTx.txid, status?.type);
770
914
  let changed = false;
771
915
  switch(status.type) {
772
916
  case SpvWithdrawalStateType.FRONTED:
773
- pastSwap.frontTxId = status.txId;
774
- pastSwap.state = SpvFromBTCSwapState.FRONTED;
917
+ pastSwap._frontTxId = status.txId;
918
+ pastSwap._state = SpvFromBTCSwapState.FRONTED;
775
919
  changed ||= true;
776
920
  break;
777
921
  case SpvWithdrawalStateType.CLAIMED:
778
- pastSwap.claimTxId = status.txId;
779
- pastSwap.state = SpvFromBTCSwapState.CLAIMED;
922
+ pastSwap._claimTxId = status.txId;
923
+ pastSwap._state = SpvFromBTCSwapState.CLAIMED;
780
924
  changed ||= true;
781
925
  break;
782
926
  case SpvWithdrawalStateType.CLOSED:
783
- pastSwap.state = SpvFromBTCSwapState.CLOSED;
927
+ pastSwap._state = SpvFromBTCSwapState.CLOSED;
784
928
  changed ||= true;
785
929
  break;
786
930
  }