@atomiqlabs/lp-lib 12.1.0 → 13.0.0-beta.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 (119) hide show
  1. package/dist/index.d.ts +18 -13
  2. package/dist/index.js +18 -13
  3. package/dist/plugins/IPlugin.d.ts +35 -12
  4. package/dist/plugins/PluginManager.d.ts +38 -15
  5. package/dist/plugins/PluginManager.js +33 -9
  6. package/dist/prices/BinanceSwapPrice.d.ts +1 -1
  7. package/dist/prices/BinanceSwapPrice.js +1 -1
  8. package/dist/prices/CoinGeckoSwapPrice.d.ts +1 -1
  9. package/dist/prices/CoinGeckoSwapPrice.js +1 -1
  10. package/dist/{swaps → prices}/ISwapPrice.js +4 -0
  11. package/dist/prices/OKXSwapPrice.d.ts +1 -1
  12. package/dist/prices/OKXSwapPrice.js +1 -1
  13. package/dist/swaps/SwapHandler.d.ts +20 -58
  14. package/dist/swaps/SwapHandler.js +17 -186
  15. package/dist/swaps/SwapHandlerSwap.d.ts +8 -23
  16. package/dist/swaps/SwapHandlerSwap.js +7 -39
  17. package/dist/swaps/assertions/AmountAssertions.d.ts +28 -0
  18. package/dist/swaps/assertions/AmountAssertions.js +72 -0
  19. package/dist/swaps/assertions/FromBtcAmountAssertions.d.ts +76 -0
  20. package/dist/swaps/assertions/FromBtcAmountAssertions.js +162 -0
  21. package/dist/swaps/assertions/LightningAssertions.d.ts +44 -0
  22. package/dist/swaps/assertions/LightningAssertions.js +86 -0
  23. package/dist/swaps/assertions/ToBtcAmountAssertions.d.ts +53 -0
  24. package/dist/swaps/{ToBtcBaseSwapHandler.js → assertions/ToBtcAmountAssertions.js} +20 -94
  25. package/dist/swaps/escrow/EscrowHandler.d.ts +51 -0
  26. package/dist/swaps/escrow/EscrowHandler.js +158 -0
  27. package/dist/swaps/escrow/EscrowHandlerSwap.d.ts +35 -0
  28. package/dist/swaps/escrow/EscrowHandlerSwap.js +69 -0
  29. package/dist/swaps/{FromBtcBaseSwap.d.ts → escrow/FromBtcBaseSwap.d.ts} +2 -3
  30. package/dist/swaps/{FromBtcBaseSwap.js → escrow/FromBtcBaseSwap.js} +4 -7
  31. package/dist/swaps/{FromBtcBaseSwapHandler.d.ts → escrow/FromBtcBaseSwapHandler.d.ts} +10 -49
  32. package/dist/swaps/{FromBtcBaseSwapHandler.js → escrow/FromBtcBaseSwapHandler.js} +16 -137
  33. package/dist/swaps/{ToBtcBaseSwap.d.ts → escrow/ToBtcBaseSwap.d.ts} +2 -2
  34. package/dist/swaps/{ToBtcBaseSwap.js → escrow/ToBtcBaseSwap.js} +4 -4
  35. package/dist/swaps/escrow/ToBtcBaseSwapHandler.d.ts +53 -0
  36. package/dist/swaps/escrow/ToBtcBaseSwapHandler.js +81 -0
  37. package/dist/swaps/{frombtc_abstract → escrow/frombtc_abstract}/FromBtcAbs.d.ts +4 -4
  38. package/dist/swaps/{frombtc_abstract → escrow/frombtc_abstract}/FromBtcAbs.js +15 -15
  39. package/dist/swaps/{frombtc_abstract → escrow/frombtc_abstract}/FromBtcSwapAbs.js +1 -1
  40. package/dist/swaps/{frombtcln_abstract → escrow/frombtcln_abstract}/FromBtcLnAbs.d.ts +9 -7
  41. package/dist/swaps/{frombtcln_abstract → escrow/frombtcln_abstract}/FromBtcLnAbs.js +22 -19
  42. package/dist/swaps/{frombtcln_abstract → escrow/frombtcln_abstract}/FromBtcLnSwapAbs.js +3 -3
  43. package/dist/swaps/{tobtc_abstract → escrow/tobtc_abstract}/ToBtcAbs.d.ts +4 -4
  44. package/dist/swaps/{tobtc_abstract → escrow/tobtc_abstract}/ToBtcAbs.js +14 -13
  45. package/dist/swaps/{tobtc_abstract → escrow/tobtc_abstract}/ToBtcSwapAbs.js +3 -3
  46. package/dist/swaps/{tobtcln_abstract → escrow/tobtcln_abstract}/ToBtcLnAbs.d.ts +6 -26
  47. package/dist/swaps/{tobtcln_abstract → escrow/tobtcln_abstract}/ToBtcLnAbs.js +20 -57
  48. package/dist/swaps/{tobtcln_abstract → escrow/tobtcln_abstract}/ToBtcLnSwapAbs.js +3 -3
  49. package/dist/swaps/spv_vault_swap/SpvVault.d.ts +41 -0
  50. package/dist/swaps/spv_vault_swap/SpvVault.js +111 -0
  51. package/dist/swaps/spv_vault_swap/SpvVaultSwap.d.ts +63 -0
  52. package/dist/swaps/spv_vault_swap/SpvVaultSwap.js +145 -0
  53. package/dist/swaps/spv_vault_swap/SpvVaultSwapHandler.d.ts +68 -0
  54. package/dist/swaps/spv_vault_swap/SpvVaultSwapHandler.js +469 -0
  55. package/dist/swaps/spv_vault_swap/SpvVaults.d.ts +57 -0
  56. package/dist/swaps/spv_vault_swap/SpvVaults.js +369 -0
  57. package/dist/swaps/{frombtc_trusted → trusted/frombtc_trusted}/FromBtcTrusted.d.ts +10 -13
  58. package/dist/swaps/{frombtc_trusted → trusted/frombtc_trusted}/FromBtcTrusted.js +25 -30
  59. package/dist/swaps/{frombtc_trusted → trusted/frombtc_trusted}/FromBtcTrustedSwap.d.ts +9 -4
  60. package/dist/swaps/{frombtc_trusted → trusted/frombtc_trusted}/FromBtcTrustedSwap.js +15 -7
  61. package/dist/swaps/{frombtcln_trusted → trusted/frombtcln_trusted}/FromBtcLnTrusted.d.ts +12 -14
  62. package/dist/swaps/{frombtcln_trusted → trusted/frombtcln_trusted}/FromBtcLnTrusted.js +33 -35
  63. package/dist/swaps/{frombtcln_trusted → trusted/frombtcln_trusted}/FromBtcLnTrustedSwap.d.ts +9 -4
  64. package/dist/swaps/{frombtcln_trusted → trusted/frombtcln_trusted}/FromBtcLnTrustedSwap.js +17 -7
  65. package/dist/utils/Utils.d.ts +13 -5
  66. package/dist/utils/Utils.js +23 -1
  67. package/dist/wallets/IBitcoinWallet.d.ts +6 -0
  68. package/dist/wallets/ISpvVaultSigner.d.ts +7 -0
  69. package/dist/wallets/ISpvVaultSigner.js +2 -0
  70. package/dist/wallets/ISpvVaultWallet.d.ts +42 -0
  71. package/dist/wallets/ISpvVaultWallet.js +2 -0
  72. package/package.json +2 -2
  73. package/src/index.ts +21 -15
  74. package/src/plugins/IPlugin.ts +27 -19
  75. package/src/plugins/PluginManager.ts +51 -26
  76. package/src/prices/BinanceSwapPrice.ts +1 -1
  77. package/src/prices/CoinGeckoSwapPrice.ts +1 -1
  78. package/src/{swaps → prices}/ISwapPrice.ts +4 -0
  79. package/src/prices/OKXSwapPrice.ts +1 -1
  80. package/src/swaps/SwapHandler.ts +22 -205
  81. package/src/swaps/SwapHandlerSwap.ts +10 -46
  82. package/src/swaps/assertions/AmountAssertions.ts +77 -0
  83. package/src/swaps/assertions/FromBtcAmountAssertions.ts +228 -0
  84. package/src/swaps/assertions/LightningAssertions.ts +103 -0
  85. package/src/swaps/{ToBtcBaseSwapHandler.ts → assertions/ToBtcAmountAssertions.ts} +27 -142
  86. package/src/swaps/escrow/EscrowHandler.ts +179 -0
  87. package/src/swaps/escrow/EscrowHandlerSwap.ts +87 -0
  88. package/src/swaps/{FromBtcBaseSwap.ts → escrow/FromBtcBaseSwap.ts} +4 -8
  89. package/src/swaps/{FromBtcBaseSwapHandler.ts → escrow/FromBtcBaseSwapHandler.ts} +30 -190
  90. package/src/swaps/{ToBtcBaseSwap.ts → escrow/ToBtcBaseSwap.ts} +4 -5
  91. package/src/swaps/escrow/ToBtcBaseSwapHandler.ts +130 -0
  92. package/src/swaps/{frombtc_abstract → escrow/frombtc_abstract}/FromBtcAbs.ts +20 -20
  93. package/src/swaps/{frombtc_abstract → escrow/frombtc_abstract}/FromBtcSwapAbs.ts +1 -1
  94. package/src/swaps/{frombtcln_abstract → escrow/frombtcln_abstract}/FromBtcLnAbs.ts +29 -25
  95. package/src/swaps/{frombtcln_abstract → escrow/frombtcln_abstract}/FromBtcLnSwapAbs.ts +2 -2
  96. package/src/swaps/{tobtc_abstract → escrow/tobtc_abstract}/ToBtcAbs.ts +19 -18
  97. package/src/swaps/{tobtc_abstract → escrow/tobtc_abstract}/ToBtcSwapAbs.ts +2 -2
  98. package/src/swaps/{tobtcln_abstract → escrow/tobtcln_abstract}/ToBtcLnAbs.ts +26 -66
  99. package/src/swaps/{tobtcln_abstract → escrow/tobtcln_abstract}/ToBtcLnSwapAbs.ts +2 -2
  100. package/src/swaps/spv_vault_swap/SpvVault.ts +143 -0
  101. package/src/swaps/spv_vault_swap/SpvVaultSwap.ts +207 -0
  102. package/src/swaps/spv_vault_swap/SpvVaultSwapHandler.ts +606 -0
  103. package/src/swaps/spv_vault_swap/SpvVaults.ts +441 -0
  104. package/src/swaps/{frombtc_trusted → trusted/frombtc_trusted}/FromBtcTrusted.ts +36 -51
  105. package/src/swaps/{frombtc_trusted → trusted/frombtc_trusted}/FromBtcTrustedSwap.ts +18 -8
  106. package/src/swaps/{frombtcln_trusted → trusted/frombtcln_trusted}/FromBtcLnTrusted.ts +43 -52
  107. package/src/swaps/{frombtcln_trusted → trusted/frombtcln_trusted}/FromBtcLnTrustedSwap.ts +20 -8
  108. package/src/utils/Utils.ts +27 -1
  109. package/src/wallets/IBitcoinWallet.ts +4 -0
  110. package/src/wallets/ISpvVaultSigner.ts +11 -0
  111. package/dist/swaps/FromBtcLnBaseSwapHandler.d.ts +0 -26
  112. package/dist/swaps/FromBtcLnBaseSwapHandler.js +0 -46
  113. package/dist/swaps/ToBtcBaseSwapHandler.d.ts +0 -95
  114. package/src/swaps/FromBtcLnBaseSwapHandler.ts +0 -63
  115. /package/dist/{swaps → prices}/ISwapPrice.d.ts +0 -0
  116. /package/dist/swaps/{frombtc_abstract → escrow/frombtc_abstract}/FromBtcSwapAbs.d.ts +0 -0
  117. /package/dist/swaps/{frombtcln_abstract → escrow/frombtcln_abstract}/FromBtcLnSwapAbs.d.ts +0 -0
  118. /package/dist/swaps/{tobtc_abstract → escrow/tobtc_abstract}/ToBtcSwapAbs.d.ts +0 -0
  119. /package/dist/swaps/{tobtcln_abstract → escrow/tobtcln_abstract}/ToBtcLnSwapAbs.d.ts +0 -0
@@ -0,0 +1,162 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FromBtcAmountAssertions = void 0;
4
+ const PluginManager_1 = require("../../plugins/PluginManager");
5
+ const IPlugin_1 = require("../../plugins/IPlugin");
6
+ const AmountAssertions_1 = require("./AmountAssertions");
7
+ class FromBtcAmountAssertions extends AmountAssertions_1.AmountAssertions {
8
+ constructor(config, swapPricing) {
9
+ super(config, swapPricing);
10
+ this.config = config;
11
+ }
12
+ /**
13
+ * Checks minimums/maximums, calculates the fee & total amount
14
+ *
15
+ * @param swapType
16
+ * @param request
17
+ * @param requestedAmount
18
+ * @param gasAmount
19
+ * @throws {DefinedRuntimeError} will throw an error if the amount is outside minimum/maximum bounds
20
+ */
21
+ async preCheckFromBtcAmounts(swapType, request, requestedAmount, gasAmount) {
22
+ const res = await PluginManager_1.PluginManager.onHandlePreFromBtcQuote(swapType, request, requestedAmount, request.chainIdentifier, { minInBtc: this.config.min, maxInBtc: this.config.max }, { baseFeeInBtc: this.config.baseFee, feePPM: this.config.feePPM }, gasAmount);
23
+ if (res != null) {
24
+ AmountAssertions_1.AmountAssertions.handlePluginErrorResponses(res);
25
+ if ((0, IPlugin_1.isQuoteSetFees)(res)) {
26
+ return {
27
+ baseFee: res.baseFee || this.config.baseFee,
28
+ feePPM: res.feePPM || this.config.feePPM,
29
+ securityDepositApyPPM: res.securityDepositApyPPM,
30
+ securityDepositBaseMultiplierPPM: res.securityDepositBaseMultiplierPPM
31
+ };
32
+ }
33
+ }
34
+ if (requestedAmount.input)
35
+ this.checkBtcAmountInBounds(requestedAmount.amount);
36
+ if (gasAmount != null && gasAmount.amount !== 0n) {
37
+ if (gasAmount.amount > (this.config.gasTokenMax?.[request.chainIdentifier] ?? 0n)) {
38
+ throw {
39
+ code: 20504,
40
+ msg: "Gas token amount too high!",
41
+ data: {
42
+ max: (this.config.gasTokenMax?.[request.chainIdentifier] ?? 0n).toString(10)
43
+ }
44
+ };
45
+ }
46
+ }
47
+ return {
48
+ baseFee: this.config.baseFee,
49
+ feePPM: this.config.feePPM
50
+ };
51
+ }
52
+ /**
53
+ * Checks minimums/maximums, calculates the fee & total amount
54
+ *
55
+ * @param swapType
56
+ * @param request
57
+ * @param requestedAmount
58
+ * @param fees
59
+ * @param signal
60
+ * @param gasTokenAmount
61
+ * @throws {DefinedRuntimeError} will throw an error if the amount is outside minimum/maximum bounds
62
+ */
63
+ async checkFromBtcAmount(swapType, request, requestedAmount, fees, signal, gasTokenAmount) {
64
+ const chainIdentifier = request.chainIdentifier;
65
+ let securityDepositApyPPM;
66
+ let securityDepositBaseMultiplierPPM;
67
+ const res = await PluginManager_1.PluginManager.onHandlePostFromBtcQuote(swapType, request, requestedAmount, chainIdentifier, { minInBtc: this.config.min, maxInBtc: this.config.max }, { baseFeeInBtc: fees.baseFee, feePPM: fees.feePPM }, gasTokenAmount);
68
+ signal.throwIfAborted();
69
+ if (res != null) {
70
+ AmountAssertions_1.AmountAssertions.handlePluginErrorResponses(res);
71
+ if ((0, IPlugin_1.isQuoteSetFees)(res)) {
72
+ if (res.baseFee != null)
73
+ fees.baseFee = res.baseFee;
74
+ if (res.feePPM != null)
75
+ fees.feePPM = res.feePPM;
76
+ if (res.securityDepositApyPPM != null)
77
+ securityDepositApyPPM = res.securityDepositApyPPM;
78
+ if (res.securityDepositBaseMultiplierPPM != null)
79
+ securityDepositBaseMultiplierPPM = res.securityDepositBaseMultiplierPPM;
80
+ }
81
+ if ((0, IPlugin_1.isPluginQuote)(res)) {
82
+ if (!requestedAmount.input) {
83
+ return {
84
+ amountBD: res.amount.amount + res.swapFee.inInputTokens,
85
+ swapFee: res.swapFee.inInputTokens,
86
+ swapFeeInToken: res.swapFee.inOutputTokens,
87
+ totalInToken: requestedAmount.amount
88
+ };
89
+ }
90
+ else {
91
+ return {
92
+ amountBD: requestedAmount.amount,
93
+ swapFee: res.swapFee.inInputTokens,
94
+ swapFeeInToken: res.swapFee.inOutputTokens,
95
+ totalInToken: res.amount.amount
96
+ };
97
+ }
98
+ }
99
+ }
100
+ let amountBDgas = 0n;
101
+ if (gasTokenAmount != null) {
102
+ amountBDgas = await this.swapPricing.getToBtcSwapAmount(gasTokenAmount.amount, gasTokenAmount.token, chainIdentifier, true, gasTokenAmount.pricePrefetch);
103
+ }
104
+ let amountBD;
105
+ if (!requestedAmount.input) {
106
+ amountBD = await this.swapPricing.getToBtcSwapAmount(requestedAmount.amount, requestedAmount.token, chainIdentifier, true, requestedAmount.pricePrefetch);
107
+ signal.throwIfAborted();
108
+ // amt = (amt+base_fee)/(1-fee)
109
+ amountBD = (amountBD + fees.baseFee) * 1000000n / (1000000n - fees.feePPM);
110
+ amountBDgas = amountBDgas * 1000000n / (1000000n - fees.feePPM);
111
+ const tooLow = amountBD < (this.config.min * 95n / 100n);
112
+ const tooHigh = amountBD > (this.config.max * 105n / 100n);
113
+ if (tooLow || tooHigh) {
114
+ const adjustedMin = this.config.min * (1000000n - fees.feePPM) / (1000000n - fees.baseFee);
115
+ const adjustedMax = this.config.max * (1000000n - fees.feePPM) / (1000000n - fees.baseFee);
116
+ const minIn = await this.swapPricing.getFromBtcSwapAmount(adjustedMin, requestedAmount.token, chainIdentifier, null, requestedAmount.pricePrefetch);
117
+ const maxIn = await this.swapPricing.getFromBtcSwapAmount(adjustedMax, requestedAmount.token, chainIdentifier, null, requestedAmount.pricePrefetch);
118
+ throw {
119
+ code: tooLow ? 20003 : 20004,
120
+ msg: tooLow ? "Amount too low!" : "Amount too high!",
121
+ data: {
122
+ min: minIn.toString(10),
123
+ max: maxIn.toString(10)
124
+ }
125
+ };
126
+ }
127
+ }
128
+ else {
129
+ amountBD = requestedAmount.amount - amountBDgas;
130
+ this.checkBtcAmountInBounds(amountBD);
131
+ }
132
+ const swapFee = fees.baseFee + (amountBD * fees.feePPM / 1000000n);
133
+ const swapFeeInToken = await this.swapPricing.getFromBtcSwapAmount(swapFee, requestedAmount.token, chainIdentifier, true, requestedAmount.pricePrefetch);
134
+ signal.throwIfAborted();
135
+ const gasSwapFee = ((amountBDgas * fees.feePPM) + 999999n) / 1000000n;
136
+ const gasSwapFeeInToken = gasTokenAmount == null ?
137
+ 0n :
138
+ await this.swapPricing.getFromBtcSwapAmount(gasSwapFee, gasTokenAmount.token, chainIdentifier, true, gasTokenAmount.pricePrefetch);
139
+ signal.throwIfAborted();
140
+ let totalInToken;
141
+ if (!requestedAmount.input) {
142
+ totalInToken = requestedAmount.amount;
143
+ }
144
+ else {
145
+ totalInToken = await this.swapPricing.getFromBtcSwapAmount(amountBD - swapFee - gasSwapFee, requestedAmount.token, chainIdentifier, null, requestedAmount.pricePrefetch);
146
+ signal.throwIfAborted();
147
+ }
148
+ return {
149
+ amountBD,
150
+ swapFee,
151
+ swapFeeInToken,
152
+ totalInToken,
153
+ amountBDgas,
154
+ gasSwapFee,
155
+ gasSwapFeeInToken,
156
+ totalInGasToken: gasTokenAmount?.amount,
157
+ securityDepositApyPPM,
158
+ securityDepositBaseMultiplierPPM
159
+ };
160
+ }
161
+ }
162
+ exports.FromBtcAmountAssertions = FromBtcAmountAssertions;
@@ -0,0 +1,44 @@
1
+ import { ILightningWallet, LightningNetworkChannel } from "../../wallets/ILightningWallet";
2
+ import { LoggerType } from "../../utils/Utils";
3
+ export declare class LightningAssertions {
4
+ protected readonly LIGHTNING_LIQUIDITY_CACHE_TIMEOUT: number;
5
+ lightningLiquidityCache: {
6
+ liquidity: bigint;
7
+ timestamp: number;
8
+ };
9
+ readonly lightning: ILightningWallet;
10
+ readonly logger: LoggerType;
11
+ constructor(logger: LoggerType, lightning: ILightningWallet);
12
+ /**
13
+ * Checks if the prior payment with the same paymentHash exists
14
+ *
15
+ * @param paymentHash
16
+ * @param abortSignal
17
+ * @throws {DefinedRuntimeError} will throw an error if payment already exists
18
+ */
19
+ checkPriorPayment(paymentHash: string, abortSignal: AbortSignal): Promise<void>;
20
+ /**
21
+ * Checks if the underlying LND backend has enough liquidity in channels to honor the swap
22
+ *
23
+ * @param amount
24
+ * @param abortSignal
25
+ * @param useCached Whether to use cached liquidity values
26
+ * @throws {DefinedRuntimeError} will throw an error if there isn't enough liquidity
27
+ */
28
+ checkLiquidity(amount: bigint, abortSignal: AbortSignal, useCached?: boolean): Promise<void>;
29
+ /**
30
+ * Checks if we have enough inbound liquidity to be able to receive an LN payment (without MPP)
31
+ *
32
+ * @param amountBD
33
+ * @param channelsPrefetch
34
+ * @param signal
35
+ * @throws {DefinedRuntimeError} will throw an error if there isn't enough inbound liquidity to receive the LN payment
36
+ */
37
+ checkInboundLiquidity(amountBD: bigint, channelsPrefetch: Promise<LightningNetworkChannel[]>, signal: AbortSignal): Promise<void>;
38
+ /**
39
+ * Starts LN channels pre-fetch
40
+ *
41
+ * @param abortController
42
+ */
43
+ getChannelsPrefetch(abortController: AbortController): Promise<LightningNetworkChannel[]>;
44
+ }
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LightningAssertions = void 0;
4
+ class LightningAssertions {
5
+ constructor(logger, lightning) {
6
+ this.LIGHTNING_LIQUIDITY_CACHE_TIMEOUT = 5 * 1000;
7
+ this.logger = logger;
8
+ this.lightning = lightning;
9
+ }
10
+ /**
11
+ * Checks if the prior payment with the same paymentHash exists
12
+ *
13
+ * @param paymentHash
14
+ * @param abortSignal
15
+ * @throws {DefinedRuntimeError} will throw an error if payment already exists
16
+ */
17
+ async checkPriorPayment(paymentHash, abortSignal) {
18
+ const payment = await this.lightning.getPayment(paymentHash);
19
+ if (payment != null)
20
+ throw {
21
+ code: 20010,
22
+ msg: "Already processed"
23
+ };
24
+ abortSignal.throwIfAborted();
25
+ }
26
+ /**
27
+ * Checks if the underlying LND backend has enough liquidity in channels to honor the swap
28
+ *
29
+ * @param amount
30
+ * @param abortSignal
31
+ * @param useCached Whether to use cached liquidity values
32
+ * @throws {DefinedRuntimeError} will throw an error if there isn't enough liquidity
33
+ */
34
+ async checkLiquidity(amount, abortSignal, useCached = false) {
35
+ if (!useCached || this.lightningLiquidityCache == null || this.lightningLiquidityCache.timestamp < Date.now() - this.LIGHTNING_LIQUIDITY_CACHE_TIMEOUT) {
36
+ const channelBalances = await this.lightning.getLightningBalance();
37
+ this.lightningLiquidityCache = {
38
+ liquidity: channelBalances.localBalance,
39
+ timestamp: Date.now()
40
+ };
41
+ }
42
+ if (amount > this.lightningLiquidityCache.liquidity) {
43
+ throw {
44
+ code: 20002,
45
+ msg: "Not enough liquidity"
46
+ };
47
+ }
48
+ abortSignal.throwIfAborted();
49
+ }
50
+ /**
51
+ * Checks if we have enough inbound liquidity to be able to receive an LN payment (without MPP)
52
+ *
53
+ * @param amountBD
54
+ * @param channelsPrefetch
55
+ * @param signal
56
+ * @throws {DefinedRuntimeError} will throw an error if there isn't enough inbound liquidity to receive the LN payment
57
+ */
58
+ async checkInboundLiquidity(amountBD, channelsPrefetch, signal) {
59
+ const channelsResponse = await channelsPrefetch;
60
+ signal.throwIfAborted();
61
+ let hasEnoughInboundLiquidity = false;
62
+ channelsResponse.forEach(channel => {
63
+ if (channel.remoteBalance >= amountBD)
64
+ hasEnoughInboundLiquidity = true;
65
+ });
66
+ if (!hasEnoughInboundLiquidity) {
67
+ throw {
68
+ code: 20050,
69
+ msg: "Not enough LN inbound liquidity"
70
+ };
71
+ }
72
+ }
73
+ /**
74
+ * Starts LN channels pre-fetch
75
+ *
76
+ * @param abortController
77
+ */
78
+ getChannelsPrefetch(abortController) {
79
+ return this.lightning.getChannels(true).catch(e => {
80
+ this.logger.error("getChannelsPrefetch(): error", e);
81
+ abortController.abort(e);
82
+ return null;
83
+ });
84
+ }
85
+ }
86
+ exports.LightningAssertions = LightningAssertions;
@@ -0,0 +1,53 @@
1
+ import { AmountAssertions } from "./AmountAssertions";
2
+ import { ToBtcLnRequestType } from "../escrow/tobtcln_abstract/ToBtcLnAbs";
3
+ import { ToBtcRequestType } from "../escrow/tobtc_abstract/ToBtcAbs";
4
+ import { RequestData, SwapHandlerType } from "../SwapHandler";
5
+ export declare class ToBtcAmountAssertions extends AmountAssertions {
6
+ /**
7
+ * Checks minimums/maximums, calculates the fee & total amount
8
+ *
9
+ * @param swapType
10
+ * @param request
11
+ * @param requestedAmount
12
+ * @throws {DefinedRuntimeError} will throw an error if the amount is outside minimum/maximum bounds
13
+ */
14
+ preCheckToBtcAmounts(swapType: SwapHandlerType.TO_BTCLN | SwapHandlerType.TO_BTC, request: RequestData<ToBtcLnRequestType | ToBtcRequestType>, requestedAmount: {
15
+ input: boolean;
16
+ amount: bigint;
17
+ token: string;
18
+ }): Promise<{
19
+ baseFee: bigint;
20
+ feePPM: bigint;
21
+ }>;
22
+ /**
23
+ * Checks minimums/maximums, calculates network fee (based on the callback passed), swap fee & total amount
24
+ *
25
+ * @param swapType
26
+ * @param request
27
+ * @param requestedAmount
28
+ * @param fees
29
+ * @param getNetworkFee
30
+ * @param signal
31
+ * @throws {DefinedRuntimeError} will throw an error if the amount is outside minimum/maximum bounds,
32
+ * or if we don't have enough funds (getNetworkFee callback throws)
33
+ */
34
+ checkToBtcAmount<T extends {
35
+ networkFee: bigint;
36
+ }>(swapType: SwapHandlerType.TO_BTCLN | SwapHandlerType.TO_BTC, request: RequestData<ToBtcLnRequestType | ToBtcRequestType>, requestedAmount: {
37
+ input: boolean;
38
+ amount: bigint;
39
+ token: string;
40
+ pricePrefetch?: Promise<bigint>;
41
+ }, fees: {
42
+ baseFee: bigint;
43
+ feePPM: bigint;
44
+ }, getNetworkFee: (amount: bigint) => Promise<T>, signal: AbortSignal): Promise<{
45
+ amountBD: bigint;
46
+ networkFeeData: T;
47
+ swapFee: bigint;
48
+ swapFeeInToken: bigint;
49
+ networkFee: bigint;
50
+ networkFeeInToken: bigint;
51
+ totalInToken: bigint;
52
+ }>;
53
+ }
@@ -1,46 +1,22 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ToBtcBaseSwapHandler = void 0;
4
- const SwapHandler_1 = require("./SwapHandler");
5
- const SchemaVerifier_1 = require("../utils/paramcoders/SchemaVerifier");
6
- const PluginManager_1 = require("../plugins/PluginManager");
7
- const IPlugin_1 = require("../plugins/IPlugin");
8
- class ToBtcBaseSwapHandler extends SwapHandler_1.SwapHandler {
9
- constructor() {
10
- super(...arguments);
11
- this.pdaExistsForToken = {};
12
- }
13
- async checkVaultInitialized(chainIdentifier, token) {
14
- if (!this.pdaExistsForToken[chainIdentifier] || !this.pdaExistsForToken[chainIdentifier][token]) {
15
- this.logger.debug("checkVaultInitialized(): checking vault exists for chain: " + chainIdentifier + " token: " + token);
16
- const { swapContract, signer } = this.getChain(chainIdentifier);
17
- const reputation = await swapContract.getIntermediaryReputation(signer.getAddress(), token);
18
- this.logger.debug("checkVaultInitialized(): vault state, chain: " + chainIdentifier + " token: " + token + " exists: " + (reputation != null));
19
- if (reputation != null) {
20
- if (this.pdaExistsForToken[chainIdentifier] == null)
21
- this.pdaExistsForToken[chainIdentifier] = {};
22
- this.pdaExistsForToken[chainIdentifier][token] = true;
23
- }
24
- else {
25
- throw {
26
- code: 20201,
27
- msg: "Token not supported!"
28
- };
29
- }
30
- }
31
- }
3
+ exports.ToBtcAmountAssertions = void 0;
4
+ const AmountAssertions_1 = require("./AmountAssertions");
5
+ const PluginManager_1 = require("../../plugins/PluginManager");
6
+ const IPlugin_1 = require("../../plugins/IPlugin");
7
+ class ToBtcAmountAssertions extends AmountAssertions_1.AmountAssertions {
32
8
  /**
33
9
  * Checks minimums/maximums, calculates the fee & total amount
34
10
  *
11
+ * @param swapType
35
12
  * @param request
36
13
  * @param requestedAmount
37
- * @param useToken
38
14
  * @throws {DefinedRuntimeError} will throw an error if the amount is outside minimum/maximum bounds
39
15
  */
40
- async preCheckAmounts(request, requestedAmount, useToken) {
41
- const res = await PluginManager_1.PluginManager.onHandlePreToBtcQuote(request, requestedAmount, request.chainIdentifier, useToken, { minInBtc: this.config.min, maxInBtc: this.config.max }, { baseFeeInBtc: this.config.baseFee, feePPM: this.config.feePPM });
16
+ async preCheckToBtcAmounts(swapType, request, requestedAmount) {
17
+ const res = await PluginManager_1.PluginManager.onHandlePreToBtcQuote(swapType, request, requestedAmount, request.chainIdentifier, { minInBtc: this.config.min, maxInBtc: this.config.max }, { baseFeeInBtc: this.config.baseFee, feePPM: this.config.feePPM });
42
18
  if (res != null) {
43
- this.handlePluginErrorResponses(res);
19
+ AmountAssertions_1.AmountAssertions.handlePluginErrorResponses(res);
44
20
  if ((0, IPlugin_1.isQuoteSetFees)(res)) {
45
21
  return {
46
22
  baseFee: res.baseFee || this.config.baseFee,
@@ -59,22 +35,21 @@ class ToBtcBaseSwapHandler extends SwapHandler_1.SwapHandler {
59
35
  /**
60
36
  * Checks minimums/maximums, calculates network fee (based on the callback passed), swap fee & total amount
61
37
  *
38
+ * @param swapType
62
39
  * @param request
63
40
  * @param requestedAmount
64
41
  * @param fees
65
- * @param useToken
66
42
  * @param getNetworkFee
67
43
  * @param signal
68
- * @param pricePrefetchPromise
69
44
  * @throws {DefinedRuntimeError} will throw an error if the amount is outside minimum/maximum bounds,
70
45
  * or if we don't have enough funds (getNetworkFee callback throws)
71
46
  */
72
- async checkToBtcAmount(request, requestedAmount, fees, useToken, getNetworkFee, signal, pricePrefetchPromise) {
47
+ async checkToBtcAmount(swapType, request, requestedAmount, fees, getNetworkFee, signal) {
73
48
  const chainIdentifier = request.chainIdentifier;
74
- const res = await PluginManager_1.PluginManager.onHandlePostToBtcQuote(request, requestedAmount, request.chainIdentifier, useToken, { minInBtc: this.config.min, maxInBtc: this.config.max }, { baseFeeInBtc: fees.baseFee, feePPM: fees.feePPM, networkFeeGetter: getNetworkFee }, pricePrefetchPromise);
49
+ const res = await PluginManager_1.PluginManager.onHandlePostToBtcQuote(swapType, request, requestedAmount, request.chainIdentifier, { minInBtc: this.config.min, maxInBtc: this.config.max }, { baseFeeInBtc: fees.baseFee, feePPM: fees.feePPM, networkFeeGetter: getNetworkFee });
75
50
  signal.throwIfAborted();
76
51
  if (res != null) {
77
- this.handlePluginErrorResponses(res);
52
+ AmountAssertions_1.AmountAssertions.handlePluginErrorResponses(res);
78
53
  if ((0, IPlugin_1.isQuoteSetFees)(res)) {
79
54
  if (res.baseFee != null)
80
55
  fees.baseFee = res.baseFee;
@@ -109,7 +84,7 @@ class ToBtcBaseSwapHandler extends SwapHandler_1.SwapHandler {
109
84
  let amountBD;
110
85
  let tooLow = false;
111
86
  if (requestedAmount.input) {
112
- amountBD = await this.swapPricing.getToBtcSwapAmount(requestedAmount.amount, useToken, chainIdentifier, null, pricePrefetchPromise);
87
+ amountBD = await this.swapPricing.getToBtcSwapAmount(requestedAmount.amount, requestedAmount.token, chainIdentifier, null, requestedAmount.pricePrefetch);
113
88
  signal.throwIfAborted();
114
89
  //Decrease by base fee
115
90
  amountBD = amountBD - fees.baseFee;
@@ -124,7 +99,6 @@ class ToBtcBaseSwapHandler extends SwapHandler_1.SwapHandler {
124
99
  this.checkBtcAmountInBounds(amountBD);
125
100
  }
126
101
  const resp = await getNetworkFee(amountBD);
127
- this.logger.debug("checkToBtcAmount(): network fee calculated, amount: " + amountBD.toString(10) + " fee: " + resp.networkFee.toString(10));
128
102
  signal.throwIfAborted();
129
103
  if (requestedAmount.input) {
130
104
  //Decrease by network fee
@@ -139,8 +113,8 @@ class ToBtcBaseSwapHandler extends SwapHandler_1.SwapHandler {
139
113
  let adjustedMax = this.config.max * (fees.feePPM + 1000000n) / 1000000n;
140
114
  adjustedMin = adjustedMin + fees.baseFee + resp.networkFee;
141
115
  adjustedMax = adjustedMax + fees.baseFee + resp.networkFee;
142
- const minIn = await this.swapPricing.getFromBtcSwapAmount(adjustedMin, useToken, chainIdentifier, null, pricePrefetchPromise);
143
- const maxIn = await this.swapPricing.getFromBtcSwapAmount(adjustedMax, useToken, chainIdentifier, null, pricePrefetchPromise);
116
+ const minIn = await this.swapPricing.getFromBtcSwapAmount(adjustedMin, requestedAmount.token, chainIdentifier, null, requestedAmount.pricePrefetch);
117
+ const maxIn = await this.swapPricing.getFromBtcSwapAmount(adjustedMax, requestedAmount.token, chainIdentifier, null, requestedAmount.pricePrefetch);
144
118
  throw {
145
119
  code: tooLow ? 20003 : 2004,
146
120
  msg: tooLow ? "Amount too low!" : "Amount too high!",
@@ -152,67 +126,19 @@ class ToBtcBaseSwapHandler extends SwapHandler_1.SwapHandler {
152
126
  }
153
127
  }
154
128
  const swapFee = fees.baseFee + (amountBD * fees.feePPM / 1000000n);
155
- const networkFeeInToken = await this.swapPricing.getFromBtcSwapAmount(resp.networkFee, useToken, chainIdentifier, true, pricePrefetchPromise);
156
- const swapFeeInToken = await this.swapPricing.getFromBtcSwapAmount(swapFee, useToken, chainIdentifier, true, pricePrefetchPromise);
129
+ const networkFeeInToken = await this.swapPricing.getFromBtcSwapAmount(resp.networkFee, requestedAmount.token, chainIdentifier, true, requestedAmount.pricePrefetch);
130
+ const swapFeeInToken = await this.swapPricing.getFromBtcSwapAmount(swapFee, requestedAmount.token, chainIdentifier, true, requestedAmount.pricePrefetch);
157
131
  signal.throwIfAborted();
158
132
  let total;
159
133
  if (requestedAmount.input) {
160
134
  total = requestedAmount.amount;
161
135
  }
162
136
  else {
163
- const amountInToken = await this.swapPricing.getFromBtcSwapAmount(requestedAmount.amount, useToken, chainIdentifier, true, pricePrefetchPromise);
137
+ const amountInToken = await this.swapPricing.getFromBtcSwapAmount(requestedAmount.amount, requestedAmount.token, chainIdentifier, true, requestedAmount.pricePrefetch);
164
138
  signal.throwIfAborted();
165
139
  total = amountInToken + swapFeeInToken + networkFeeInToken;
166
140
  }
167
141
  return { amountBD, networkFeeData: resp, swapFee, swapFeeInToken, networkFee: resp.networkFee, networkFeeInToken, totalInToken: total };
168
142
  }
169
- /**
170
- * Starts pre-fetches for swap pricing & signature data
171
- *
172
- * @param chainIdentifier
173
- * @param token
174
- * @param responseStream
175
- * @param abortController
176
- */
177
- getToBtcPrefetches(chainIdentifier, token, responseStream, abortController) {
178
- //Fetch pricing & signature data in parallel
179
- const pricePrefetchPromise = this.swapPricing.preFetchPrice(token, chainIdentifier).catch(e => {
180
- this.logger.error("getToBtcPrefetches(): pricePrefetch error", e);
181
- abortController.abort(e);
182
- return null;
183
- });
184
- return {
185
- pricePrefetchPromise,
186
- signDataPrefetchPromise: this.getSignDataPrefetch(chainIdentifier, abortController, responseStream)
187
- };
188
- }
189
- /**
190
- * Signs the created swap
191
- *
192
- * @param chainIdentifier
193
- * @param swapObject
194
- * @param req
195
- * @param abortSignal
196
- * @param signDataPrefetchPromise
197
- */
198
- async getToBtcSignatureData(chainIdentifier, swapObject, req, abortSignal, signDataPrefetchPromise) {
199
- const prefetchedSignData = signDataPrefetchPromise != null ? await signDataPrefetchPromise : null;
200
- if (prefetchedSignData != null)
201
- this.logger.debug("getToBtcSignatureData(): pre-fetched signature data: ", prefetchedSignData);
202
- abortSignal.throwIfAborted();
203
- const feeRateObj = await req.paramReader.getParams({
204
- feeRate: SchemaVerifier_1.FieldTypeEnum.String
205
- }).catch(() => null);
206
- abortSignal.throwIfAborted();
207
- const feeRate = feeRateObj?.feeRate != null && typeof (feeRateObj.feeRate) === "string" ? feeRateObj.feeRate : null;
208
- this.logger.debug("getToBtcSignatureData(): using fee rate from client: ", feeRate);
209
- const { swapContract, signer } = this.getChain(chainIdentifier);
210
- const sigData = await swapContract.getInitSignature(signer, swapObject, this.getInitAuthorizationTimeout(chainIdentifier), prefetchedSignData, feeRate);
211
- abortSignal.throwIfAborted();
212
- return {
213
- ...sigData,
214
- feeRate
215
- };
216
- }
217
143
  }
218
- exports.ToBtcBaseSwapHandler = ToBtcBaseSwapHandler;
144
+ exports.ToBtcAmountAssertions = ToBtcAmountAssertions;
@@ -0,0 +1,51 @@
1
+ import { SwapBaseConfig, SwapHandler } from "../SwapHandler";
2
+ import { ChainEvent, ChainSwapType, ClaimEvent, InitializeEvent, RefundEvent, SwapData, SwapEvent } from "@atomiqlabs/base";
3
+ import { EscrowHandlerSwap } from "./EscrowHandlerSwap";
4
+ import { ServerParamEncoder } from "../../utils/paramcoders/server/ServerParamEncoder";
5
+ import { SwapHandlerSwap } from "../SwapHandlerSwap";
6
+ export type ToBtcBaseConfig = SwapBaseConfig & {
7
+ gracePeriod: bigint;
8
+ refundAuthorizationTimeout: number;
9
+ };
10
+ export declare abstract class EscrowHandler<V extends EscrowHandlerSwap<SwapData, S>, S> extends SwapHandler<V, S> {
11
+ abstract readonly swapType: ChainSwapType;
12
+ readonly escrowHashMap: Map<string, V>;
13
+ protected swapLogger: {
14
+ debug: (swap: SwapHandlerSwap | SwapEvent<SwapData> | SwapData, msg: string, ...args: any) => void;
15
+ info: (swap: SwapHandlerSwap | SwapEvent<SwapData> | SwapData, msg: string, ...args: any) => void;
16
+ warn: (swap: SwapHandlerSwap | SwapEvent<SwapData> | SwapData, msg: string, ...args: any) => void;
17
+ error: (swap: SwapHandlerSwap | SwapEvent<SwapData> | SwapData, msg: string, ...args: any) => void;
18
+ };
19
+ protected abstract processInitializeEvent(chainIdentifier: string, swap: V, event: InitializeEvent<SwapData>): Promise<void>;
20
+ protected abstract processClaimEvent(chainIdentifier: string, swap: V, event: ClaimEvent<SwapData>): Promise<void>;
21
+ protected abstract processRefundEvent(chainIdentifier: string, swap: V, event: RefundEvent<SwapData>): Promise<void>;
22
+ /**
23
+ * Chain event processor
24
+ *
25
+ * @param chainIdentifier
26
+ * @param eventData
27
+ */
28
+ protected processEvent(chainIdentifier: string, eventData: ChainEvent<SwapData>[]): Promise<boolean>;
29
+ /**
30
+ * Initializes chain events subscription
31
+ */
32
+ protected subscribeToEvents(): void;
33
+ protected loadData(ctor: new (data: any) => V): Promise<void>;
34
+ protected removeSwapData(hash: string, sequence: bigint): Promise<void>;
35
+ protected removeSwapData(swap: V, ultimateState?: S): Promise<void>;
36
+ protected saveSwapData(swap: V): Promise<void>;
37
+ protected saveSwapToEscrowHashMap(swap: V): void;
38
+ protected removeSwapFromEscrowHashMap(swap: V): void;
39
+ protected getSwapByEscrowHash(chainIdentifier: string, escrowHash: string): V;
40
+ protected getIdentifierFromEvent(event: SwapEvent<SwapData>): string;
41
+ protected getIdentifierFromSwapData(swapData: SwapData): string;
42
+ protected getIdentifier(swap: SwapHandlerSwap | SwapEvent<SwapData> | SwapData): string;
43
+ /**
44
+ * Starts a pre-fetch for signature data
45
+ *
46
+ * @param chainIdentifier
47
+ * @param abortController
48
+ * @param responseStream
49
+ */
50
+ protected getSignDataPrefetch(chainIdentifier: string, abortController: AbortController, responseStream?: ServerParamEncoder): Promise<any>;
51
+ }