@atomiqlabs/sdk 8.1.7 → 8.3.1

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