@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.
- package/dist/index.d.ts +18 -13
- package/dist/index.js +18 -13
- package/dist/plugins/IPlugin.d.ts +35 -12
- package/dist/plugins/PluginManager.d.ts +38 -15
- package/dist/plugins/PluginManager.js +33 -9
- package/dist/prices/BinanceSwapPrice.d.ts +1 -1
- package/dist/prices/BinanceSwapPrice.js +1 -1
- package/dist/prices/CoinGeckoSwapPrice.d.ts +1 -1
- package/dist/prices/CoinGeckoSwapPrice.js +1 -1
- package/dist/{swaps → prices}/ISwapPrice.js +4 -0
- package/dist/prices/OKXSwapPrice.d.ts +1 -1
- package/dist/prices/OKXSwapPrice.js +1 -1
- package/dist/swaps/SwapHandler.d.ts +20 -58
- package/dist/swaps/SwapHandler.js +17 -186
- package/dist/swaps/SwapHandlerSwap.d.ts +8 -23
- package/dist/swaps/SwapHandlerSwap.js +7 -39
- package/dist/swaps/assertions/AmountAssertions.d.ts +28 -0
- package/dist/swaps/assertions/AmountAssertions.js +72 -0
- package/dist/swaps/assertions/FromBtcAmountAssertions.d.ts +76 -0
- package/dist/swaps/assertions/FromBtcAmountAssertions.js +162 -0
- package/dist/swaps/assertions/LightningAssertions.d.ts +44 -0
- package/dist/swaps/assertions/LightningAssertions.js +86 -0
- package/dist/swaps/assertions/ToBtcAmountAssertions.d.ts +53 -0
- package/dist/swaps/{ToBtcBaseSwapHandler.js → assertions/ToBtcAmountAssertions.js} +20 -94
- package/dist/swaps/escrow/EscrowHandler.d.ts +51 -0
- package/dist/swaps/escrow/EscrowHandler.js +158 -0
- package/dist/swaps/escrow/EscrowHandlerSwap.d.ts +35 -0
- package/dist/swaps/escrow/EscrowHandlerSwap.js +69 -0
- package/dist/swaps/{FromBtcBaseSwap.d.ts → escrow/FromBtcBaseSwap.d.ts} +2 -3
- package/dist/swaps/{FromBtcBaseSwap.js → escrow/FromBtcBaseSwap.js} +4 -7
- package/dist/swaps/{FromBtcBaseSwapHandler.d.ts → escrow/FromBtcBaseSwapHandler.d.ts} +10 -49
- package/dist/swaps/{FromBtcBaseSwapHandler.js → escrow/FromBtcBaseSwapHandler.js} +16 -137
- package/dist/swaps/{ToBtcBaseSwap.d.ts → escrow/ToBtcBaseSwap.d.ts} +2 -2
- package/dist/swaps/{ToBtcBaseSwap.js → escrow/ToBtcBaseSwap.js} +4 -4
- package/dist/swaps/escrow/ToBtcBaseSwapHandler.d.ts +53 -0
- package/dist/swaps/escrow/ToBtcBaseSwapHandler.js +81 -0
- package/dist/swaps/{frombtc_abstract → escrow/frombtc_abstract}/FromBtcAbs.d.ts +4 -4
- package/dist/swaps/{frombtc_abstract → escrow/frombtc_abstract}/FromBtcAbs.js +15 -15
- package/dist/swaps/{frombtc_abstract → escrow/frombtc_abstract}/FromBtcSwapAbs.js +1 -1
- package/dist/swaps/{frombtcln_abstract → escrow/frombtcln_abstract}/FromBtcLnAbs.d.ts +9 -7
- package/dist/swaps/{frombtcln_abstract → escrow/frombtcln_abstract}/FromBtcLnAbs.js +22 -19
- package/dist/swaps/{frombtcln_abstract → escrow/frombtcln_abstract}/FromBtcLnSwapAbs.js +3 -3
- package/dist/swaps/{tobtc_abstract → escrow/tobtc_abstract}/ToBtcAbs.d.ts +4 -4
- package/dist/swaps/{tobtc_abstract → escrow/tobtc_abstract}/ToBtcAbs.js +14 -13
- package/dist/swaps/{tobtc_abstract → escrow/tobtc_abstract}/ToBtcSwapAbs.js +3 -3
- package/dist/swaps/{tobtcln_abstract → escrow/tobtcln_abstract}/ToBtcLnAbs.d.ts +6 -26
- package/dist/swaps/{tobtcln_abstract → escrow/tobtcln_abstract}/ToBtcLnAbs.js +20 -57
- package/dist/swaps/{tobtcln_abstract → escrow/tobtcln_abstract}/ToBtcLnSwapAbs.js +3 -3
- package/dist/swaps/spv_vault_swap/SpvVault.d.ts +41 -0
- package/dist/swaps/spv_vault_swap/SpvVault.js +111 -0
- package/dist/swaps/spv_vault_swap/SpvVaultSwap.d.ts +63 -0
- package/dist/swaps/spv_vault_swap/SpvVaultSwap.js +145 -0
- package/dist/swaps/spv_vault_swap/SpvVaultSwapHandler.d.ts +68 -0
- package/dist/swaps/spv_vault_swap/SpvVaultSwapHandler.js +469 -0
- package/dist/swaps/spv_vault_swap/SpvVaults.d.ts +57 -0
- package/dist/swaps/spv_vault_swap/SpvVaults.js +369 -0
- package/dist/swaps/{frombtc_trusted → trusted/frombtc_trusted}/FromBtcTrusted.d.ts +10 -13
- package/dist/swaps/{frombtc_trusted → trusted/frombtc_trusted}/FromBtcTrusted.js +25 -30
- package/dist/swaps/{frombtc_trusted → trusted/frombtc_trusted}/FromBtcTrustedSwap.d.ts +9 -4
- package/dist/swaps/{frombtc_trusted → trusted/frombtc_trusted}/FromBtcTrustedSwap.js +15 -7
- package/dist/swaps/{frombtcln_trusted → trusted/frombtcln_trusted}/FromBtcLnTrusted.d.ts +12 -14
- package/dist/swaps/{frombtcln_trusted → trusted/frombtcln_trusted}/FromBtcLnTrusted.js +33 -35
- package/dist/swaps/{frombtcln_trusted → trusted/frombtcln_trusted}/FromBtcLnTrustedSwap.d.ts +9 -4
- package/dist/swaps/{frombtcln_trusted → trusted/frombtcln_trusted}/FromBtcLnTrustedSwap.js +17 -7
- package/dist/utils/Utils.d.ts +13 -5
- package/dist/utils/Utils.js +23 -1
- package/dist/wallets/IBitcoinWallet.d.ts +6 -0
- package/dist/wallets/ISpvVaultSigner.d.ts +7 -0
- package/dist/wallets/ISpvVaultSigner.js +2 -0
- package/dist/wallets/ISpvVaultWallet.d.ts +42 -0
- package/dist/wallets/ISpvVaultWallet.js +2 -0
- package/package.json +2 -2
- package/src/index.ts +21 -15
- package/src/plugins/IPlugin.ts +27 -19
- package/src/plugins/PluginManager.ts +51 -26
- package/src/prices/BinanceSwapPrice.ts +1 -1
- package/src/prices/CoinGeckoSwapPrice.ts +1 -1
- package/src/{swaps → prices}/ISwapPrice.ts +4 -0
- package/src/prices/OKXSwapPrice.ts +1 -1
- package/src/swaps/SwapHandler.ts +22 -205
- package/src/swaps/SwapHandlerSwap.ts +10 -46
- package/src/swaps/assertions/AmountAssertions.ts +77 -0
- package/src/swaps/assertions/FromBtcAmountAssertions.ts +228 -0
- package/src/swaps/assertions/LightningAssertions.ts +103 -0
- package/src/swaps/{ToBtcBaseSwapHandler.ts → assertions/ToBtcAmountAssertions.ts} +27 -142
- package/src/swaps/escrow/EscrowHandler.ts +179 -0
- package/src/swaps/escrow/EscrowHandlerSwap.ts +87 -0
- package/src/swaps/{FromBtcBaseSwap.ts → escrow/FromBtcBaseSwap.ts} +4 -8
- package/src/swaps/{FromBtcBaseSwapHandler.ts → escrow/FromBtcBaseSwapHandler.ts} +30 -190
- package/src/swaps/{ToBtcBaseSwap.ts → escrow/ToBtcBaseSwap.ts} +4 -5
- package/src/swaps/escrow/ToBtcBaseSwapHandler.ts +130 -0
- package/src/swaps/{frombtc_abstract → escrow/frombtc_abstract}/FromBtcAbs.ts +20 -20
- package/src/swaps/{frombtc_abstract → escrow/frombtc_abstract}/FromBtcSwapAbs.ts +1 -1
- package/src/swaps/{frombtcln_abstract → escrow/frombtcln_abstract}/FromBtcLnAbs.ts +29 -25
- package/src/swaps/{frombtcln_abstract → escrow/frombtcln_abstract}/FromBtcLnSwapAbs.ts +2 -2
- package/src/swaps/{tobtc_abstract → escrow/tobtc_abstract}/ToBtcAbs.ts +19 -18
- package/src/swaps/{tobtc_abstract → escrow/tobtc_abstract}/ToBtcSwapAbs.ts +2 -2
- package/src/swaps/{tobtcln_abstract → escrow/tobtcln_abstract}/ToBtcLnAbs.ts +26 -66
- package/src/swaps/{tobtcln_abstract → escrow/tobtcln_abstract}/ToBtcLnSwapAbs.ts +2 -2
- package/src/swaps/spv_vault_swap/SpvVault.ts +143 -0
- package/src/swaps/spv_vault_swap/SpvVaultSwap.ts +207 -0
- package/src/swaps/spv_vault_swap/SpvVaultSwapHandler.ts +606 -0
- package/src/swaps/spv_vault_swap/SpvVaults.ts +441 -0
- package/src/swaps/{frombtc_trusted → trusted/frombtc_trusted}/FromBtcTrusted.ts +36 -51
- package/src/swaps/{frombtc_trusted → trusted/frombtc_trusted}/FromBtcTrustedSwap.ts +18 -8
- package/src/swaps/{frombtcln_trusted → trusted/frombtcln_trusted}/FromBtcLnTrusted.ts +43 -52
- package/src/swaps/{frombtcln_trusted → trusted/frombtcln_trusted}/FromBtcLnTrustedSwap.ts +20 -8
- package/src/utils/Utils.ts +27 -1
- package/src/wallets/IBitcoinWallet.ts +4 -0
- package/src/wallets/ISpvVaultSigner.ts +11 -0
- package/dist/swaps/FromBtcLnBaseSwapHandler.d.ts +0 -26
- package/dist/swaps/FromBtcLnBaseSwapHandler.js +0 -46
- package/dist/swaps/ToBtcBaseSwapHandler.d.ts +0 -95
- package/src/swaps/FromBtcLnBaseSwapHandler.ts +0 -63
- /package/dist/{swaps → prices}/ISwapPrice.d.ts +0 -0
- /package/dist/swaps/{frombtc_abstract → escrow/frombtc_abstract}/FromBtcSwapAbs.d.ts +0 -0
- /package/dist/swaps/{frombtcln_abstract → escrow/frombtcln_abstract}/FromBtcLnSwapAbs.d.ts +0 -0
- /package/dist/swaps/{tobtc_abstract → escrow/tobtc_abstract}/ToBtcSwapAbs.d.ts +0 -0
- /package/dist/swaps/{tobtcln_abstract → escrow/tobtcln_abstract}/ToBtcLnSwapAbs.d.ts +0 -0
|
@@ -1,17 +1,13 @@
|
|
|
1
|
-
import {SwapHandlerSwap} from "./SwapHandlerSwap";
|
|
2
1
|
import {SwapData} from "@atomiqlabs/base";
|
|
3
|
-
import {
|
|
4
|
-
import {IParamReader} from "
|
|
5
|
-
import {FieldTypeEnum} from "
|
|
6
|
-
import {FromBtcLnRequestType} from "./frombtcln_abstract/FromBtcLnAbs";
|
|
7
|
-
import {FromBtcRequestType} from "./frombtc_abstract/FromBtcAbs";
|
|
8
|
-
import {PluginManager} from "../plugins/PluginManager";
|
|
9
|
-
import {
|
|
10
|
-
isPluginQuote,
|
|
11
|
-
isQuoteSetFees
|
|
12
|
-
} from "../plugins/IPlugin";
|
|
2
|
+
import {MultichainData, SwapBaseConfig} from "../SwapHandler";
|
|
3
|
+
import {IParamReader} from "../../utils/paramcoders/IParamReader";
|
|
4
|
+
import {FieldTypeEnum} from "../../utils/paramcoders/SchemaVerifier";
|
|
13
5
|
import {Request} from "express";
|
|
14
|
-
import {
|
|
6
|
+
import {EscrowHandler} from "./EscrowHandler";
|
|
7
|
+
import {FromBtcBaseSwap} from "./FromBtcBaseSwap";
|
|
8
|
+
import {FromBtcAmountAssertions} from "../assertions/FromBtcAmountAssertions";
|
|
9
|
+
import {IIntermediaryStorage} from "../../storage/IIntermediaryStorage";
|
|
10
|
+
import {ISwapPrice} from "../../prices/ISwapPrice";
|
|
15
11
|
|
|
16
12
|
const secondsInYear = BigInt(365*24*60*60);
|
|
17
13
|
|
|
@@ -19,10 +15,23 @@ export type FromBtcBaseConfig = SwapBaseConfig & {
|
|
|
19
15
|
securityDepositAPY: number
|
|
20
16
|
};
|
|
21
17
|
|
|
22
|
-
export abstract class FromBtcBaseSwapHandler<V extends
|
|
18
|
+
export abstract class FromBtcBaseSwapHandler<V extends FromBtcBaseSwap<SwapData, S>, S> extends EscrowHandler<V, S> {
|
|
23
19
|
|
|
24
20
|
abstract config: FromBtcBaseConfig;
|
|
25
21
|
|
|
22
|
+
readonly AmountAssertions: FromBtcAmountAssertions;
|
|
23
|
+
|
|
24
|
+
constructor(
|
|
25
|
+
storageDirectory: IIntermediaryStorage<V>,
|
|
26
|
+
path: string,
|
|
27
|
+
chainsData: MultichainData,
|
|
28
|
+
swapPricing: ISwapPrice,
|
|
29
|
+
config: FromBtcBaseConfig
|
|
30
|
+
) {
|
|
31
|
+
super(storageDirectory, path, chainsData, swapPricing);
|
|
32
|
+
this.AmountAssertions = new FromBtcAmountAssertions(config, swapPricing);
|
|
33
|
+
}
|
|
34
|
+
|
|
26
35
|
/**
|
|
27
36
|
* Starts a pre-fetch for swap price & security deposit price
|
|
28
37
|
*
|
|
@@ -41,15 +50,15 @@ export abstract class FromBtcBaseSwapHandler<V extends SwapHandlerSwap<SwapData,
|
|
|
41
50
|
abortController.abort(e);
|
|
42
51
|
return null;
|
|
43
52
|
});
|
|
44
|
-
const {
|
|
45
|
-
const gasTokenPricePrefetchPromise: Promise<bigint> = useToken.toString()===
|
|
53
|
+
const {chainInterface} = this.getChain(chainIdentifier);
|
|
54
|
+
const gasTokenPricePrefetchPromise: Promise<bigint> = useToken.toString()===chainInterface.getNativeCurrencyAddress().toString() ?
|
|
46
55
|
pricePrefetchPromise :
|
|
47
|
-
this.swapPricing.preFetchPrice(
|
|
56
|
+
this.swapPricing.preFetchPrice(chainInterface.getNativeCurrencyAddress(), chainIdentifier).catch(e => {
|
|
48
57
|
this.logger.error("getFromBtcPricePrefetches(): gasTokenPricePrefetchPromise error: ", e);
|
|
49
58
|
abortController.abort(e);
|
|
50
59
|
return null;
|
|
51
60
|
});
|
|
52
|
-
const depositTokenPricePrefetchPromise: Promise<bigint> = depositToken===
|
|
61
|
+
const depositTokenPricePrefetchPromise: Promise<bigint> = depositToken===chainInterface.getNativeCurrencyAddress() ?
|
|
53
62
|
gasTokenPricePrefetchPromise :
|
|
54
63
|
this.swapPricing.preFetchPrice(depositToken, chainIdentifier).catch(e => {
|
|
55
64
|
this.logger.error("getFromBtcPricePrefetches(): depositTokenPricePrefetchPromise error: ", e);
|
|
@@ -75,9 +84,9 @@ export abstract class FromBtcBaseSwapHandler<V extends SwapHandlerSwap<SwapData,
|
|
|
75
84
|
abortController: AbortController
|
|
76
85
|
): Promise<bigint> {
|
|
77
86
|
//Solana workaround
|
|
78
|
-
const {swapContract} = this.getChain(chainIdentifier);
|
|
87
|
+
const {swapContract, chainInterface} = this.getChain(chainIdentifier);
|
|
79
88
|
let feeResult: bigint;
|
|
80
|
-
const gasToken =
|
|
89
|
+
const gasToken = chainInterface.getNativeCurrencyAddress();
|
|
81
90
|
if (swapContract.getRawRefundFee != null) {
|
|
82
91
|
try {
|
|
83
92
|
feeResult = await swapContract.getRawRefundFee(dummySwapData);
|
|
@@ -147,9 +156,9 @@ export abstract class FromBtcBaseSwapHandler<V extends SwapHandlerSwap<SwapData,
|
|
|
147
156
|
* @throws {DefinedRuntimeError} will throw an error if there are not enough funds in the vault
|
|
148
157
|
*/
|
|
149
158
|
protected checkAllowedDepositToken(chainIdentifier: string, depositToken: string): void {
|
|
150
|
-
const {
|
|
159
|
+
const {chainInterface, allowedDepositTokens} = this.getChain(chainIdentifier);
|
|
151
160
|
if(allowedDepositTokens==null) {
|
|
152
|
-
if(depositToken!==
|
|
161
|
+
if(depositToken!==chainInterface.getNativeCurrencyAddress()) throw {
|
|
153
162
|
code: 20190,
|
|
154
163
|
msg: "Unsupported deposit token"
|
|
155
164
|
};
|
|
@@ -161,175 +170,6 @@ export abstract class FromBtcBaseSwapHandler<V extends SwapHandlerSwap<SwapData,
|
|
|
161
170
|
}
|
|
162
171
|
}
|
|
163
172
|
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* Checks minimums/maximums, calculates the fee & total amount
|
|
167
|
-
*
|
|
168
|
-
* @param request
|
|
169
|
-
* @param requestedAmount
|
|
170
|
-
* @param useToken
|
|
171
|
-
* @throws {DefinedRuntimeError} will throw an error if the amount is outside minimum/maximum bounds
|
|
172
|
-
*/
|
|
173
|
-
protected async preCheckAmounts(
|
|
174
|
-
request: RequestData<FromBtcLnRequestType | FromBtcRequestType | FromBtcLnTrustedRequestType>,
|
|
175
|
-
requestedAmount: {input: boolean, amount: bigint},
|
|
176
|
-
useToken: string
|
|
177
|
-
): Promise<{
|
|
178
|
-
baseFee: bigint,
|
|
179
|
-
feePPM: bigint,
|
|
180
|
-
securityDepositApyPPM?: bigint,
|
|
181
|
-
securityDepositBaseMultiplierPPM?: bigint,
|
|
182
|
-
}> {
|
|
183
|
-
const res = await PluginManager.onHandlePreFromBtcQuote(
|
|
184
|
-
request,
|
|
185
|
-
requestedAmount,
|
|
186
|
-
request.chainIdentifier,
|
|
187
|
-
useToken,
|
|
188
|
-
{minInBtc: this.config.min, maxInBtc: this.config.max},
|
|
189
|
-
{baseFeeInBtc: this.config.baseFee, feePPM: this.config.feePPM},
|
|
190
|
-
);
|
|
191
|
-
if(res!=null) {
|
|
192
|
-
this.handlePluginErrorResponses(res);
|
|
193
|
-
if(isQuoteSetFees(res)) {
|
|
194
|
-
return {
|
|
195
|
-
baseFee: res.baseFee || this.config.baseFee,
|
|
196
|
-
feePPM: res.feePPM || this.config.feePPM,
|
|
197
|
-
securityDepositApyPPM: res.securityDepositApyPPM,
|
|
198
|
-
securityDepositBaseMultiplierPPM: res.securityDepositBaseMultiplierPPM
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
if(requestedAmount.input) this.checkBtcAmountInBounds(requestedAmount.amount);
|
|
203
|
-
return {
|
|
204
|
-
baseFee: this.config.baseFee,
|
|
205
|
-
feePPM: this.config.feePPM
|
|
206
|
-
};
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
/**
|
|
210
|
-
* Checks minimums/maximums, calculates the fee & total amount
|
|
211
|
-
*
|
|
212
|
-
* @param request
|
|
213
|
-
* @param requestedAmount
|
|
214
|
-
* @param fees
|
|
215
|
-
* @param useToken
|
|
216
|
-
* @param signal
|
|
217
|
-
* @param pricePrefetchPromise
|
|
218
|
-
* @throws {DefinedRuntimeError} will throw an error if the amount is outside minimum/maximum bounds
|
|
219
|
-
*/
|
|
220
|
-
protected async checkFromBtcAmount(
|
|
221
|
-
request: RequestData<FromBtcLnRequestType | FromBtcRequestType | FromBtcLnTrustedRequestType>,
|
|
222
|
-
requestedAmount: {input: boolean, amount: bigint},
|
|
223
|
-
fees: {baseFee: bigint, feePPM: bigint},
|
|
224
|
-
useToken: string,
|
|
225
|
-
signal: AbortSignal,
|
|
226
|
-
pricePrefetchPromise: Promise<bigint> = Promise.resolve(null)
|
|
227
|
-
): Promise<{
|
|
228
|
-
amountBD: bigint,
|
|
229
|
-
swapFee: bigint, //Swap fee in BTC
|
|
230
|
-
swapFeeInToken: bigint, //Swap fee in token on top of what should be paid out to the user
|
|
231
|
-
totalInToken: bigint, //Total to be paid out to the user
|
|
232
|
-
securityDepositApyPPM?: bigint,
|
|
233
|
-
securityDepositBaseMultiplierPPM?: bigint
|
|
234
|
-
}> {
|
|
235
|
-
const chainIdentifier = request.chainIdentifier;
|
|
236
|
-
|
|
237
|
-
let securityDepositApyPPM: bigint;
|
|
238
|
-
let securityDepositBaseMultiplierPPM: bigint;
|
|
239
|
-
|
|
240
|
-
const res = await PluginManager.onHandlePostFromBtcQuote(
|
|
241
|
-
request,
|
|
242
|
-
requestedAmount,
|
|
243
|
-
chainIdentifier,
|
|
244
|
-
useToken,
|
|
245
|
-
{minInBtc: this.config.min, maxInBtc: this.config.max},
|
|
246
|
-
{baseFeeInBtc: fees.baseFee, feePPM: fees.feePPM},
|
|
247
|
-
pricePrefetchPromise
|
|
248
|
-
);
|
|
249
|
-
signal.throwIfAborted();
|
|
250
|
-
if(res!=null) {
|
|
251
|
-
this.handlePluginErrorResponses(res);
|
|
252
|
-
if(isQuoteSetFees(res)) {
|
|
253
|
-
if(res.baseFee!=null) fees.baseFee = res.baseFee;
|
|
254
|
-
if(res.feePPM!=null) fees.feePPM = res.feePPM;
|
|
255
|
-
if(res.securityDepositApyPPM!=null) securityDepositApyPPM = res.securityDepositApyPPM;
|
|
256
|
-
if(res.securityDepositBaseMultiplierPPM!=null) securityDepositBaseMultiplierPPM = res.securityDepositBaseMultiplierPPM;
|
|
257
|
-
}
|
|
258
|
-
if(isPluginQuote(res)) {
|
|
259
|
-
if(!requestedAmount.input) {
|
|
260
|
-
return {
|
|
261
|
-
amountBD: res.amount.amount + res.swapFee.inInputTokens,
|
|
262
|
-
swapFee: res.swapFee.inInputTokens,
|
|
263
|
-
swapFeeInToken: res.swapFee.inOutputTokens,
|
|
264
|
-
totalInToken: requestedAmount.amount
|
|
265
|
-
}
|
|
266
|
-
} else {
|
|
267
|
-
return {
|
|
268
|
-
amountBD: requestedAmount.amount,
|
|
269
|
-
swapFee: res.swapFee.inInputTokens,
|
|
270
|
-
swapFeeInToken: res.swapFee.inOutputTokens,
|
|
271
|
-
totalInToken: res.amount.amount
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
let amountBD: bigint;
|
|
278
|
-
if(!requestedAmount.input) {
|
|
279
|
-
amountBD = await this.swapPricing.getToBtcSwapAmount(requestedAmount.amount, useToken, chainIdentifier, true, pricePrefetchPromise);
|
|
280
|
-
signal.throwIfAborted();
|
|
281
|
-
|
|
282
|
-
// amt = (amt+base_fee)/(1-fee)
|
|
283
|
-
amountBD = (amountBD + fees.baseFee) * 1000000n / (1000000n - fees.feePPM);
|
|
284
|
-
|
|
285
|
-
const tooLow = amountBD < (this.config.min * 95n / 100n);
|
|
286
|
-
const tooHigh = amountBD > (this.config.max * 105n / 100n);
|
|
287
|
-
if(tooLow || tooHigh) {
|
|
288
|
-
const adjustedMin = this.config.min * (1000000n - fees.feePPM) / (1000000n - fees.baseFee);
|
|
289
|
-
const adjustedMax = this.config.max * (1000000n - fees.feePPM) / (1000000n - fees.baseFee);
|
|
290
|
-
const minIn = await this.swapPricing.getFromBtcSwapAmount(
|
|
291
|
-
adjustedMin, useToken, chainIdentifier, null, pricePrefetchPromise
|
|
292
|
-
);
|
|
293
|
-
const maxIn = await this.swapPricing.getFromBtcSwapAmount(
|
|
294
|
-
adjustedMax, useToken, chainIdentifier, null, pricePrefetchPromise
|
|
295
|
-
);
|
|
296
|
-
throw {
|
|
297
|
-
code: tooLow ? 20003 : 20004,
|
|
298
|
-
msg: tooLow ? "Amount too low!" : "Amount too high!",
|
|
299
|
-
data: {
|
|
300
|
-
min: minIn.toString(10),
|
|
301
|
-
max: maxIn.toString(10)
|
|
302
|
-
}
|
|
303
|
-
};
|
|
304
|
-
}
|
|
305
|
-
} else {
|
|
306
|
-
amountBD = requestedAmount.amount;
|
|
307
|
-
this.checkBtcAmountInBounds(amountBD);
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
const swapFee = fees.baseFee + (amountBD * fees.feePPM / 1000000n);
|
|
311
|
-
const swapFeeInToken = await this.swapPricing.getFromBtcSwapAmount(swapFee, useToken, chainIdentifier, true, pricePrefetchPromise);
|
|
312
|
-
signal.throwIfAborted();
|
|
313
|
-
|
|
314
|
-
let totalInToken: bigint;
|
|
315
|
-
if(!requestedAmount.input) {
|
|
316
|
-
totalInToken = requestedAmount.amount;
|
|
317
|
-
} else {
|
|
318
|
-
const amountInToken = await this.swapPricing.getFromBtcSwapAmount(requestedAmount.amount, useToken, chainIdentifier, null, pricePrefetchPromise);
|
|
319
|
-
totalInToken = amountInToken - swapFeeInToken;
|
|
320
|
-
signal.throwIfAborted();
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
return {
|
|
324
|
-
amountBD,
|
|
325
|
-
swapFee,
|
|
326
|
-
swapFeeInToken,
|
|
327
|
-
totalInToken,
|
|
328
|
-
securityDepositApyPPM,
|
|
329
|
-
securityDepositBaseMultiplierPPM
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
|
|
333
173
|
/**
|
|
334
174
|
* Signs the created swap
|
|
335
175
|
*
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import {SwapHandlerSwap} from "./SwapHandlerSwap";
|
|
2
1
|
import {SwapData} from "@atomiqlabs/base";
|
|
3
|
-
import {deserializeBN, serializeBN} from "
|
|
2
|
+
import {deserializeBN, serializeBN} from "../../utils/Utils";
|
|
3
|
+
import {EscrowHandlerSwap} from "./EscrowHandlerSwap";
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
export abstract class ToBtcBaseSwap<T extends SwapData = SwapData, S = any> extends SwapHandlerSwap<T, S> {
|
|
5
|
+
export abstract class ToBtcBaseSwap<T extends SwapData = SwapData, S = any> extends EscrowHandlerSwap<T, S> {
|
|
7
6
|
|
|
8
7
|
amount: bigint;
|
|
9
8
|
|
|
@@ -53,7 +52,7 @@ export abstract class ToBtcBaseSwap<T extends SwapData = SwapData, S = any> exte
|
|
|
53
52
|
}
|
|
54
53
|
|
|
55
54
|
getInputAmount(): bigint {
|
|
56
|
-
return this.
|
|
55
|
+
return this.getTotalInputAmount() - this.getSwapFee().inInputToken - this.getQuotedNetworkFee().inInputToken;
|
|
57
56
|
}
|
|
58
57
|
|
|
59
58
|
getTotalInputAmount(): bigint {
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import {MultichainData, SwapBaseConfig} from "../SwapHandler";
|
|
2
|
+
import {SwapData} from "@atomiqlabs/base";
|
|
3
|
+
import {ServerParamEncoder} from "../../utils/paramcoders/server/ServerParamEncoder";
|
|
4
|
+
import {IParamReader} from "../../utils/paramcoders/IParamReader";
|
|
5
|
+
import {FieldTypeEnum} from "../../utils/paramcoders/SchemaVerifier";
|
|
6
|
+
import {Request} from "express";
|
|
7
|
+
import {ToBtcBaseSwap} from "./ToBtcBaseSwap";
|
|
8
|
+
import {EscrowHandler} from "./EscrowHandler";
|
|
9
|
+
import {ToBtcAmountAssertions} from "../assertions/ToBtcAmountAssertions";
|
|
10
|
+
import {IIntermediaryStorage} from "../../storage/IIntermediaryStorage";
|
|
11
|
+
import {ISwapPrice} from "../../prices/ISwapPrice";
|
|
12
|
+
|
|
13
|
+
export type ToBtcBaseConfig = SwapBaseConfig & {
|
|
14
|
+
gracePeriod: bigint,
|
|
15
|
+
refundAuthorizationTimeout: number
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export abstract class ToBtcBaseSwapHandler<V extends ToBtcBaseSwap<SwapData, S>, S> extends EscrowHandler<V, S> {
|
|
19
|
+
|
|
20
|
+
readonly AmountAssertions: ToBtcAmountAssertions;
|
|
21
|
+
|
|
22
|
+
readonly pdaExistsForToken: {
|
|
23
|
+
[chainIdentifier: string]: {
|
|
24
|
+
[token: string]: boolean
|
|
25
|
+
}
|
|
26
|
+
} = {};
|
|
27
|
+
|
|
28
|
+
constructor(
|
|
29
|
+
storageDirectory: IIntermediaryStorage<V>,
|
|
30
|
+
path: string,
|
|
31
|
+
chainsData: MultichainData,
|
|
32
|
+
swapPricing: ISwapPrice,
|
|
33
|
+
config: ToBtcBaseConfig
|
|
34
|
+
) {
|
|
35
|
+
super(storageDirectory, path, chainsData, swapPricing);
|
|
36
|
+
this.AmountAssertions = new ToBtcAmountAssertions(config, swapPricing);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
protected async checkVaultInitialized(chainIdentifier: string, token: string): Promise<void> {
|
|
40
|
+
if(!this.pdaExistsForToken[chainIdentifier] || !this.pdaExistsForToken[chainIdentifier][token]) {
|
|
41
|
+
this.logger.debug("checkVaultInitialized(): checking vault exists for chain: "+chainIdentifier+" token: "+token);
|
|
42
|
+
const {swapContract, signer} = this.getChain(chainIdentifier);
|
|
43
|
+
const reputation = await swapContract.getIntermediaryReputation(signer.getAddress(), token);
|
|
44
|
+
this.logger.debug("checkVaultInitialized(): vault state, chain: "+chainIdentifier+" token: "+token+" exists: "+(reputation!=null));
|
|
45
|
+
if(reputation!=null) {
|
|
46
|
+
if(this.pdaExistsForToken[chainIdentifier]==null) this.pdaExistsForToken[chainIdentifier] = {};
|
|
47
|
+
this.pdaExistsForToken[chainIdentifier][token] = true;
|
|
48
|
+
} else {
|
|
49
|
+
throw {
|
|
50
|
+
code: 20201,
|
|
51
|
+
msg: "Token not supported!"
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Starts pre-fetches for swap pricing & signature data
|
|
59
|
+
*
|
|
60
|
+
* @param chainIdentifier
|
|
61
|
+
* @param token
|
|
62
|
+
* @param responseStream
|
|
63
|
+
* @param abortController
|
|
64
|
+
*/
|
|
65
|
+
protected getToBtcPrefetches(chainIdentifier: string, token: string, responseStream: ServerParamEncoder, abortController: AbortController): {
|
|
66
|
+
pricePrefetchPromise?: Promise<bigint>,
|
|
67
|
+
signDataPrefetchPromise?: Promise<any>
|
|
68
|
+
} {
|
|
69
|
+
//Fetch pricing & signature data in parallel
|
|
70
|
+
const pricePrefetchPromise: Promise<bigint> = this.swapPricing.preFetchPrice(token, chainIdentifier).catch(e => {
|
|
71
|
+
this.logger.error("getToBtcPrefetches(): pricePrefetch error", e);
|
|
72
|
+
abortController.abort(e);
|
|
73
|
+
return null;
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
return {
|
|
77
|
+
pricePrefetchPromise,
|
|
78
|
+
signDataPrefetchPromise: this.getSignDataPrefetch(chainIdentifier, abortController, responseStream)
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Signs the created swap
|
|
84
|
+
*
|
|
85
|
+
* @param chainIdentifier
|
|
86
|
+
* @param swapObject
|
|
87
|
+
* @param req
|
|
88
|
+
* @param abortSignal
|
|
89
|
+
* @param signDataPrefetchPromise
|
|
90
|
+
*/
|
|
91
|
+
protected async getToBtcSignatureData(
|
|
92
|
+
chainIdentifier: string,
|
|
93
|
+
swapObject: SwapData,
|
|
94
|
+
req: Request & {paramReader: IParamReader},
|
|
95
|
+
abortSignal: AbortSignal,
|
|
96
|
+
signDataPrefetchPromise?: Promise<any>
|
|
97
|
+
): Promise<{
|
|
98
|
+
prefix: string,
|
|
99
|
+
timeout: string,
|
|
100
|
+
signature: string,
|
|
101
|
+
feeRate: string
|
|
102
|
+
}> {
|
|
103
|
+
const prefetchedSignData = signDataPrefetchPromise!=null ? await signDataPrefetchPromise : null;
|
|
104
|
+
if(prefetchedSignData!=null) this.logger.debug("getToBtcSignatureData(): pre-fetched signature data: ", prefetchedSignData);
|
|
105
|
+
abortSignal.throwIfAborted();
|
|
106
|
+
|
|
107
|
+
const feeRateObj = await req.paramReader.getParams({
|
|
108
|
+
feeRate: FieldTypeEnum.String
|
|
109
|
+
}).catch(() => null);
|
|
110
|
+
abortSignal.throwIfAborted();
|
|
111
|
+
|
|
112
|
+
const feeRate = feeRateObj?.feeRate!=null && typeof(feeRateObj.feeRate)==="string" ? feeRateObj.feeRate : null;
|
|
113
|
+
this.logger.debug("getToBtcSignatureData(): using fee rate from client: ", feeRate);
|
|
114
|
+
const {swapContract, signer} = this.getChain(chainIdentifier);
|
|
115
|
+
const sigData = await swapContract.getInitSignature(
|
|
116
|
+
signer,
|
|
117
|
+
swapObject,
|
|
118
|
+
this.getInitAuthorizationTimeout(chainIdentifier),
|
|
119
|
+
prefetchedSignData,
|
|
120
|
+
feeRate
|
|
121
|
+
);
|
|
122
|
+
abortSignal.throwIfAborted();
|
|
123
|
+
|
|
124
|
+
return {
|
|
125
|
+
...sigData,
|
|
126
|
+
feeRate
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {Express, Request, Response} from "express";
|
|
2
2
|
import {FromBtcSwapAbs, FromBtcSwapState} from "./FromBtcSwapAbs";
|
|
3
|
-
import {MultichainData, SwapHandlerType} from "
|
|
4
|
-
import {ISwapPrice} from "
|
|
3
|
+
import {MultichainData, SwapHandlerType} from "../../SwapHandler";
|
|
4
|
+
import {ISwapPrice} from "../../../prices/ISwapPrice";
|
|
5
5
|
import {
|
|
6
6
|
BigIntBufferUtils,
|
|
7
7
|
ChainSwapType,
|
|
@@ -11,15 +11,15 @@ import {
|
|
|
11
11
|
SwapData
|
|
12
12
|
} from "@atomiqlabs/base";
|
|
13
13
|
import {randomBytes} from "crypto";
|
|
14
|
-
import {expressHandlerWrapper} from "
|
|
15
|
-
import {PluginManager} from "
|
|
16
|
-
import {IIntermediaryStorage} from "
|
|
17
|
-
import {FieldTypeEnum} from "
|
|
18
|
-
import {serverParamDecoder} from "
|
|
19
|
-
import {IParamReader} from "
|
|
20
|
-
import {ServerParamEncoder} from "
|
|
14
|
+
import {expressHandlerWrapper, getAbortController} from "../../../utils/Utils";
|
|
15
|
+
import {PluginManager} from "../../../plugins/PluginManager";
|
|
16
|
+
import {IIntermediaryStorage} from "../../../storage/IIntermediaryStorage";
|
|
17
|
+
import {FieldTypeEnum} from "../../../utils/paramcoders/SchemaVerifier";
|
|
18
|
+
import {serverParamDecoder} from "../../../utils/paramcoders/server/ServerParamDecoder";
|
|
19
|
+
import {IParamReader} from "../../../utils/paramcoders/IParamReader";
|
|
20
|
+
import {ServerParamEncoder} from "../../../utils/paramcoders/server/ServerParamEncoder";
|
|
21
21
|
import {FromBtcBaseConfig, FromBtcBaseSwapHandler} from "../FromBtcBaseSwapHandler";
|
|
22
|
-
import {IBitcoinWallet} from "
|
|
22
|
+
import {IBitcoinWallet} from "../../../wallets/IBitcoinWallet";
|
|
23
23
|
|
|
24
24
|
export type FromBtcConfig = FromBtcBaseConfig & {
|
|
25
25
|
confirmations: number,
|
|
@@ -53,7 +53,7 @@ export class FromBtcAbs extends FromBtcBaseSwapHandler<FromBtcSwapAbs, FromBtcSw
|
|
|
53
53
|
swapPricing: ISwapPrice,
|
|
54
54
|
config: FromBtcConfig
|
|
55
55
|
) {
|
|
56
|
-
super(storageDirectory, path, chains, swapPricing);
|
|
56
|
+
super(storageDirectory, path, chains, swapPricing, config);
|
|
57
57
|
this.bitcoin = bitcoin;
|
|
58
58
|
this.config = {
|
|
59
59
|
...config,
|
|
@@ -97,8 +97,8 @@ export class FromBtcAbs extends FromBtcBaseSwapHandler<FromBtcSwapAbs, FromBtcSw
|
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
this.swapLogger.info(swap, "processPastSwap(state=CREATED): removing past swap due to authorization expiry, address: "+swap.address);
|
|
100
|
-
await this.bitcoin.addUnusedAddress(swap.address);
|
|
101
100
|
await this.removeSwapData(swap, FromBtcSwapState.CANCELED);
|
|
101
|
+
await this.bitcoin.addUnusedAddress(swap.address);
|
|
102
102
|
return false;
|
|
103
103
|
}
|
|
104
104
|
|
|
@@ -182,8 +182,8 @@ export class FromBtcAbs extends FromBtcBaseSwapHandler<FromBtcSwapAbs, FromBtcSw
|
|
|
182
182
|
savedSwap.txIds.refund = (event as any).meta?.txId;
|
|
183
183
|
|
|
184
184
|
this.swapLogger.info(event, "SC: RefundEvent: swap refunded, address: "+savedSwap.address);
|
|
185
|
-
await this.bitcoin.addUnusedAddress(savedSwap.address);
|
|
186
185
|
await this.removeSwapData(savedSwap, FromBtcSwapState.REFUNDED);
|
|
186
|
+
await this.bitcoin.addUnusedAddress(savedSwap.address);
|
|
187
187
|
}
|
|
188
188
|
|
|
189
189
|
/**
|
|
@@ -255,8 +255,8 @@ export class FromBtcAbs extends FromBtcBaseSwapHandler<FromBtcSwapAbs, FromBtcSw
|
|
|
255
255
|
} = {request: {}, times: {}};
|
|
256
256
|
|
|
257
257
|
const chainIdentifier = req.query.chain as string ?? this.chains.default;
|
|
258
|
-
const {swapContract, signer} = this.getChain(chainIdentifier);
|
|
259
|
-
const depositToken = req.query.depositToken as string ??
|
|
258
|
+
const {swapContract, signer, chainInterface} = this.getChain(chainIdentifier);
|
|
259
|
+
const depositToken = req.query.depositToken as string ?? chainInterface.getNativeCurrencyAddress();
|
|
260
260
|
this.checkAllowedDepositToken(chainIdentifier, depositToken);
|
|
261
261
|
|
|
262
262
|
metadata.times.requestReceived = Date.now();
|
|
@@ -279,7 +279,7 @@ export class FromBtcAbs extends FromBtcBaseSwapHandler<FromBtcSwapAbs, FromBtcSw
|
|
|
279
279
|
const parsedBody: FromBtcRequestType = await req.paramReader.getParams({
|
|
280
280
|
address: (val: string) => val!=null &&
|
|
281
281
|
typeof(val)==="string" &&
|
|
282
|
-
|
|
282
|
+
chainInterface.isValidAddress(val) ? val : null,
|
|
283
283
|
amount: FieldTypeEnum.BigInt,
|
|
284
284
|
token: (val: string) => val!=null &&
|
|
285
285
|
typeof(val)==="string" &&
|
|
@@ -293,7 +293,7 @@ export class FromBtcAbs extends FromBtcBaseSwapHandler<FromBtcSwapAbs, FromBtcSw
|
|
|
293
293
|
};
|
|
294
294
|
metadata.request = parsedBody;
|
|
295
295
|
|
|
296
|
-
const requestedAmount = {input: !parsedBody.exactOut, amount: parsedBody.amount};
|
|
296
|
+
const requestedAmount = {input: !parsedBody.exactOut, amount: parsedBody.amount, token: parsedBody.token};
|
|
297
297
|
const request = {
|
|
298
298
|
chainIdentifier,
|
|
299
299
|
raw: req,
|
|
@@ -304,12 +304,12 @@ export class FromBtcAbs extends FromBtcBaseSwapHandler<FromBtcSwapAbs, FromBtcSw
|
|
|
304
304
|
|
|
305
305
|
//Check request params
|
|
306
306
|
this.checkSequence(parsedBody.sequence);
|
|
307
|
-
const fees = await this.
|
|
307
|
+
const fees = await this.AmountAssertions.preCheckFromBtcAmounts(this.type, request, requestedAmount);
|
|
308
308
|
metadata.times.requestChecked = Date.now();
|
|
309
309
|
|
|
310
310
|
//Create abortController for parallel prefetches
|
|
311
311
|
const responseStream = res.responseStream;
|
|
312
|
-
const abortController =
|
|
312
|
+
const abortController = getAbortController(responseStream);
|
|
313
313
|
|
|
314
314
|
//Pre-fetch data
|
|
315
315
|
const {
|
|
@@ -336,7 +336,7 @@ export class FromBtcAbs extends FromBtcBaseSwapHandler<FromBtcSwapAbs, FromBtcSw
|
|
|
336
336
|
totalInToken,
|
|
337
337
|
securityDepositApyPPM,
|
|
338
338
|
securityDepositBaseMultiplierPPM
|
|
339
|
-
} = await this.checkFromBtcAmount(request, requestedAmount,
|
|
339
|
+
} = await this.AmountAssertions.checkFromBtcAmount(this.type, request, {...requestedAmount, pricePrefetch: pricePrefetchPromise}, fees, abortController.signal);
|
|
340
340
|
metadata.times.priceCalculated = Date.now();
|
|
341
341
|
|
|
342
342
|
if(securityDepositApyPPM!=null) fees.securityDepositApyPPM = securityDepositApyPPM;
|