@atomiqlabs/lp-lib 14.0.0-dev.21 → 14.0.0-dev.24
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/LICENSE +201 -201
- package/dist/fees/IBtcFeeEstimator.d.ts +3 -3
- package/dist/fees/IBtcFeeEstimator.js +2 -2
- package/dist/index.d.ts +42 -42
- package/dist/index.js +58 -58
- package/dist/info/InfoHandler.d.ts +17 -17
- package/dist/info/InfoHandler.js +61 -61
- package/dist/plugins/IPlugin.d.ts +143 -143
- package/dist/plugins/IPlugin.js +34 -34
- package/dist/plugins/PluginManager.d.ts +112 -112
- package/dist/plugins/PluginManager.js +259 -259
- package/dist/prices/BinanceSwapPrice.d.ts +26 -26
- package/dist/prices/BinanceSwapPrice.js +92 -92
- package/dist/prices/CoinGeckoSwapPrice.d.ts +30 -30
- package/dist/prices/CoinGeckoSwapPrice.js +64 -64
- package/dist/prices/ISwapPrice.d.ts +43 -43
- package/dist/prices/ISwapPrice.js +55 -55
- package/dist/prices/OKXSwapPrice.d.ts +26 -26
- package/dist/prices/OKXSwapPrice.js +92 -92
- package/dist/storage/IIntermediaryStorage.d.ts +18 -18
- package/dist/storage/IIntermediaryStorage.js +2 -2
- package/dist/storagemanager/IntermediaryStorageManager.d.ts +19 -19
- package/dist/storagemanager/IntermediaryStorageManager.js +111 -111
- package/dist/storagemanager/StorageManager.d.ts +13 -13
- package/dist/storagemanager/StorageManager.js +64 -64
- package/dist/swaps/SwapHandler.d.ts +153 -153
- package/dist/swaps/SwapHandler.js +160 -160
- package/dist/swaps/SwapHandlerSwap.d.ts +79 -79
- package/dist/swaps/SwapHandlerSwap.js +78 -78
- package/dist/swaps/assertions/AmountAssertions.d.ts +28 -28
- package/dist/swaps/assertions/AmountAssertions.js +72 -72
- package/dist/swaps/assertions/FromBtcAmountAssertions.d.ts +76 -76
- package/dist/swaps/assertions/FromBtcAmountAssertions.js +180 -180
- package/dist/swaps/assertions/LightningAssertions.d.ts +44 -44
- package/dist/swaps/assertions/LightningAssertions.js +86 -86
- package/dist/swaps/assertions/ToBtcAmountAssertions.d.ts +53 -53
- package/dist/swaps/assertions/ToBtcAmountAssertions.js +150 -150
- package/dist/swaps/escrow/EscrowHandler.d.ts +51 -51
- package/dist/swaps/escrow/EscrowHandler.js +158 -158
- package/dist/swaps/escrow/EscrowHandlerSwap.d.ts +35 -35
- package/dist/swaps/escrow/EscrowHandlerSwap.js +69 -69
- package/dist/swaps/escrow/FromBtcBaseSwap.d.ts +14 -14
- package/dist/swaps/escrow/FromBtcBaseSwap.js +32 -32
- package/dist/swaps/escrow/FromBtcBaseSwapHandler.d.ts +102 -102
- package/dist/swaps/escrow/FromBtcBaseSwapHandler.js +210 -210
- package/dist/swaps/escrow/ToBtcBaseSwap.d.ts +36 -36
- package/dist/swaps/escrow/ToBtcBaseSwap.js +67 -67
- package/dist/swaps/escrow/ToBtcBaseSwapHandler.d.ts +53 -53
- package/dist/swaps/escrow/ToBtcBaseSwapHandler.js +81 -81
- package/dist/swaps/escrow/frombtc_abstract/FromBtcAbs.d.ts +83 -83
- package/dist/swaps/escrow/frombtc_abstract/FromBtcAbs.js +318 -318
- package/dist/swaps/escrow/frombtc_abstract/FromBtcSwapAbs.d.ts +21 -21
- package/dist/swaps/escrow/frombtc_abstract/FromBtcSwapAbs.js +50 -50
- package/dist/swaps/escrow/frombtcln_abstract/FromBtcLnAbs.d.ts +107 -107
- package/dist/swaps/escrow/frombtcln_abstract/FromBtcLnAbs.js +675 -675
- package/dist/swaps/escrow/frombtcln_abstract/FromBtcLnSwapAbs.d.ts +33 -33
- package/dist/swaps/escrow/frombtcln_abstract/FromBtcLnSwapAbs.js +91 -91
- package/dist/swaps/escrow/frombtcln_autoinit/FromBtcLnAuto.d.ts +111 -111
- package/dist/swaps/escrow/frombtcln_autoinit/FromBtcLnAuto.js +684 -684
- package/dist/swaps/escrow/frombtcln_autoinit/FromBtcLnAutoSwap.d.ts +55 -55
- package/dist/swaps/escrow/frombtcln_autoinit/FromBtcLnAutoSwap.js +120 -120
- package/dist/swaps/escrow/tobtc_abstract/ToBtcAbs.d.ts +171 -171
- package/dist/swaps/escrow/tobtc_abstract/ToBtcAbs.js +706 -706
- package/dist/swaps/escrow/tobtc_abstract/ToBtcSwapAbs.d.ts +26 -26
- package/dist/swaps/escrow/tobtc_abstract/ToBtcSwapAbs.js +62 -62
- package/dist/swaps/escrow/tobtcln_abstract/ToBtcLnAbs.d.ts +177 -177
- package/dist/swaps/escrow/tobtcln_abstract/ToBtcLnAbs.js +863 -863
- package/dist/swaps/escrow/tobtcln_abstract/ToBtcLnSwapAbs.d.ts +24 -24
- package/dist/swaps/escrow/tobtcln_abstract/ToBtcLnSwapAbs.js +58 -58
- package/dist/swaps/spv_vault_swap/SpvVault.d.ts +40 -41
- package/dist/swaps/spv_vault_swap/SpvVault.js +111 -111
- package/dist/swaps/spv_vault_swap/SpvVaultSwap.d.ts +67 -67
- package/dist/swaps/spv_vault_swap/SpvVaultSwap.js +158 -158
- package/dist/swaps/spv_vault_swap/SpvVaultSwapHandler.d.ts +68 -68
- package/dist/swaps/spv_vault_swap/SpvVaultSwapHandler.js +492 -492
- package/dist/swaps/spv_vault_swap/SpvVaults.d.ts +52 -52
- package/dist/swaps/spv_vault_swap/SpvVaults.js +394 -364
- package/dist/swaps/trusted/frombtc_trusted/FromBtcTrusted.d.ts +51 -51
- package/dist/swaps/trusted/frombtc_trusted/FromBtcTrusted.js +650 -650
- package/dist/swaps/trusted/frombtc_trusted/FromBtcTrustedSwap.d.ts +52 -52
- package/dist/swaps/trusted/frombtc_trusted/FromBtcTrustedSwap.js +118 -118
- package/dist/swaps/trusted/frombtcln_trusted/FromBtcLnTrusted.d.ts +76 -76
- package/dist/swaps/trusted/frombtcln_trusted/FromBtcLnTrusted.js +494 -494
- package/dist/swaps/trusted/frombtcln_trusted/FromBtcLnTrustedSwap.d.ts +34 -34
- package/dist/swaps/trusted/frombtcln_trusted/FromBtcLnTrustedSwap.js +81 -81
- package/dist/utils/BitcoinUtils.d.ts +2 -2
- package/dist/utils/BitcoinUtils.js +45 -45
- package/dist/utils/Utils.d.ts +29 -29
- package/dist/utils/Utils.js +89 -89
- package/dist/utils/paramcoders/IParamReader.d.ts +5 -5
- package/dist/utils/paramcoders/IParamReader.js +2 -2
- package/dist/utils/paramcoders/IParamWriter.d.ts +4 -4
- package/dist/utils/paramcoders/IParamWriter.js +2 -2
- package/dist/utils/paramcoders/LegacyParamEncoder.d.ts +10 -10
- package/dist/utils/paramcoders/LegacyParamEncoder.js +22 -22
- package/dist/utils/paramcoders/ParamDecoder.d.ts +25 -25
- package/dist/utils/paramcoders/ParamDecoder.js +222 -222
- package/dist/utils/paramcoders/ParamEncoder.d.ts +9 -9
- package/dist/utils/paramcoders/ParamEncoder.js +22 -22
- package/dist/utils/paramcoders/SchemaVerifier.d.ts +21 -21
- package/dist/utils/paramcoders/SchemaVerifier.js +84 -84
- package/dist/utils/paramcoders/server/ServerParamDecoder.d.ts +8 -8
- package/dist/utils/paramcoders/server/ServerParamDecoder.js +107 -107
- package/dist/utils/paramcoders/server/ServerParamEncoder.d.ts +11 -11
- package/dist/utils/paramcoders/server/ServerParamEncoder.js +65 -65
- package/dist/wallets/IBitcoinWallet.d.ts +67 -67
- package/dist/wallets/IBitcoinWallet.js +2 -2
- package/dist/wallets/ILightningWallet.d.ts +117 -117
- package/dist/wallets/ILightningWallet.js +37 -37
- package/dist/wallets/ISpvVaultSigner.d.ts +7 -7
- package/dist/wallets/ISpvVaultSigner.js +2 -2
- package/package.json +36 -36
- package/src/fees/IBtcFeeEstimator.ts +6 -6
- package/src/index.ts +53 -53
- package/src/info/InfoHandler.ts +106 -106
- package/src/plugins/IPlugin.ts +168 -168
- package/src/plugins/PluginManager.ts +336 -336
- package/src/prices/BinanceSwapPrice.ts +113 -113
- package/src/prices/CoinGeckoSwapPrice.ts +87 -87
- package/src/prices/ISwapPrice.ts +88 -88
- package/src/prices/OKXSwapPrice.ts +113 -113
- package/src/storage/IIntermediaryStorage.ts +19 -19
- package/src/storagemanager/IntermediaryStorageManager.ts +118 -118
- package/src/storagemanager/StorageManager.ts +78 -78
- package/src/swaps/SwapHandler.ts +277 -277
- package/src/swaps/SwapHandlerSwap.ts +141 -141
- package/src/swaps/assertions/AmountAssertions.ts +76 -76
- package/src/swaps/assertions/FromBtcAmountAssertions.ts +246 -246
- package/src/swaps/assertions/LightningAssertions.ts +103 -103
- package/src/swaps/assertions/ToBtcAmountAssertions.ts +203 -203
- package/src/swaps/escrow/EscrowHandler.ts +179 -179
- package/src/swaps/escrow/EscrowHandlerSwap.ts +86 -86
- package/src/swaps/escrow/FromBtcBaseSwap.ts +38 -38
- package/src/swaps/escrow/FromBtcBaseSwapHandler.ts +286 -286
- package/src/swaps/escrow/ToBtcBaseSwap.ts +85 -85
- package/src/swaps/escrow/ToBtcBaseSwapHandler.ts +129 -129
- package/src/swaps/escrow/frombtc_abstract/FromBtcAbs.ts +452 -452
- package/src/swaps/escrow/frombtc_abstract/FromBtcSwapAbs.ts +61 -61
- package/src/swaps/escrow/frombtcln_abstract/FromBtcLnAbs.ts +856 -856
- package/src/swaps/escrow/frombtcln_abstract/FromBtcLnSwapAbs.ts +141 -141
- package/src/swaps/escrow/frombtcln_autoinit/FromBtcLnAuto.ts +850 -850
- package/src/swaps/escrow/frombtcln_autoinit/FromBtcLnAutoSwap.ts +196 -196
- package/src/swaps/escrow/tobtc_abstract/ToBtcAbs.ts +879 -879
- package/src/swaps/escrow/tobtc_abstract/ToBtcSwapAbs.ts +102 -102
- package/src/swaps/escrow/tobtcln_abstract/ToBtcLnAbs.ts +1112 -1112
- package/src/swaps/escrow/tobtcln_abstract/ToBtcLnSwapAbs.ts +80 -80
- package/src/swaps/spv_vault_swap/SpvVault.ts +143 -143
- package/src/swaps/spv_vault_swap/SpvVaultSwap.ts +225 -225
- package/src/swaps/spv_vault_swap/SpvVaultSwapHandler.ts +628 -628
- package/src/swaps/spv_vault_swap/SpvVaults.ts +469 -435
- package/src/swaps/trusted/frombtc_trusted/FromBtcTrusted.ts +747 -747
- package/src/swaps/trusted/frombtc_trusted/FromBtcTrustedSwap.ts +185 -185
- package/src/swaps/trusted/frombtcln_trusted/FromBtcLnTrusted.ts +590 -590
- package/src/swaps/trusted/frombtcln_trusted/FromBtcLnTrustedSwap.ts +121 -121
- package/src/utils/BitcoinUtils.ts +42 -42
- package/src/utils/Utils.ts +104 -104
- package/src/utils/paramcoders/IParamReader.ts +7 -7
- package/src/utils/paramcoders/IParamWriter.ts +8 -8
- package/src/utils/paramcoders/LegacyParamEncoder.ts +27 -27
- package/src/utils/paramcoders/ParamDecoder.ts +218 -218
- package/src/utils/paramcoders/ParamEncoder.ts +29 -29
- package/src/utils/paramcoders/SchemaVerifier.ts +96 -96
- package/src/utils/paramcoders/server/ServerParamDecoder.ts +118 -118
- package/src/utils/paramcoders/server/ServerParamEncoder.ts +75 -75
- package/src/wallets/IBitcoinWallet.ts +68 -68
- package/src/wallets/ILightningWallet.ts +178 -178
- package/src/wallets/ISpvVaultSigner.ts +10 -10
|
@@ -1,287 +1,287 @@
|
|
|
1
|
-
import {SwapData} from "@atomiqlabs/base";
|
|
2
|
-
import {MultichainData, SwapBaseConfig} from "../SwapHandler";
|
|
3
|
-
import {IParamReader} from "../../utils/paramcoders/IParamReader";
|
|
4
|
-
import {FieldTypeEnum} from "../../utils/paramcoders/SchemaVerifier";
|
|
5
|
-
import {Request} from "express";
|
|
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";
|
|
11
|
-
|
|
12
|
-
const secondsInYear = BigInt(365*24*60*60);
|
|
13
|
-
|
|
14
|
-
export type FromBtcBaseConfig = SwapBaseConfig & {
|
|
15
|
-
securityDepositAPY: number
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
export abstract class FromBtcBaseSwapHandler<V extends FromBtcBaseSwap<SwapData, S>, S> extends EscrowHandler<V, S> {
|
|
19
|
-
|
|
20
|
-
abstract config: FromBtcBaseConfig;
|
|
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
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Starts a pre-fetch for swap price & security deposit price
|
|
37
|
-
*
|
|
38
|
-
* @param chainIdentifier
|
|
39
|
-
* @param useToken
|
|
40
|
-
* @param depositToken
|
|
41
|
-
* @param abortController
|
|
42
|
-
*/
|
|
43
|
-
protected getFromBtcPricePrefetches(chainIdentifier: string, useToken: string, depositToken: string, abortController: AbortController): {
|
|
44
|
-
pricePrefetchPromise: Promise<bigint>,
|
|
45
|
-
gasTokenPricePrefetchPromise: Promise<bigint>,
|
|
46
|
-
depositTokenPricePrefetchPromise: Promise<bigint>
|
|
47
|
-
} {
|
|
48
|
-
const pricePrefetchPromise: Promise<bigint> = this.swapPricing.preFetchPrice(useToken, chainIdentifier).catch(e => {
|
|
49
|
-
this.logger.error("getFromBtcPricePrefetches(): pricePrefetch error: ", e);
|
|
50
|
-
abortController.abort(e);
|
|
51
|
-
return null;
|
|
52
|
-
});
|
|
53
|
-
const {chainInterface} = this.getChain(chainIdentifier);
|
|
54
|
-
const gasTokenPricePrefetchPromise: Promise<bigint> = useToken.toString()===chainInterface.getNativeCurrencyAddress().toString() ?
|
|
55
|
-
pricePrefetchPromise :
|
|
56
|
-
this.swapPricing.preFetchPrice(chainInterface.getNativeCurrencyAddress(), chainIdentifier).catch(e => {
|
|
57
|
-
this.logger.error("getFromBtcPricePrefetches(): gasTokenPricePrefetchPromise error: ", e);
|
|
58
|
-
abortController.abort(e);
|
|
59
|
-
return null;
|
|
60
|
-
});
|
|
61
|
-
const depositTokenPricePrefetchPromise: Promise<bigint> = depositToken===chainInterface.getNativeCurrencyAddress() ?
|
|
62
|
-
gasTokenPricePrefetchPromise :
|
|
63
|
-
this.swapPricing.preFetchPrice(depositToken, chainIdentifier).catch(e => {
|
|
64
|
-
this.logger.error("getFromBtcPricePrefetches(): depositTokenPricePrefetchPromise error: ", e);
|
|
65
|
-
abortController.abort(e);
|
|
66
|
-
return null;
|
|
67
|
-
});
|
|
68
|
-
return {pricePrefetchPromise, gasTokenPricePrefetchPromise, depositTokenPricePrefetchPromise};
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Starts a pre-fetch for base security deposit (transaction fee for refunding transaction on our side)
|
|
73
|
-
*
|
|
74
|
-
* @param chainIdentifier
|
|
75
|
-
* @param dummySwapData
|
|
76
|
-
* @param depositToken
|
|
77
|
-
* @param gasTokenPricePrefetchPromise
|
|
78
|
-
* @param depositTokenPricePrefetchPromise
|
|
79
|
-
* @param abortController
|
|
80
|
-
*/
|
|
81
|
-
protected async getBaseSecurityDepositPrefetch(
|
|
82
|
-
chainIdentifier: string, dummySwapData: SwapData, depositToken: string,
|
|
83
|
-
gasTokenPricePrefetchPromise: Promise<bigint>, depositTokenPricePrefetchPromise: Promise<bigint>,
|
|
84
|
-
abortController: AbortController
|
|
85
|
-
): Promise<bigint> {
|
|
86
|
-
//Solana workaround
|
|
87
|
-
const {swapContract, chainInterface, signer} = this.getChain(chainIdentifier);
|
|
88
|
-
let feeResult: bigint;
|
|
89
|
-
const gasToken = chainInterface.getNativeCurrencyAddress();
|
|
90
|
-
if (swapContract.getRawRefundFee != null) {
|
|
91
|
-
try {
|
|
92
|
-
feeResult = await swapContract.getRawRefundFee(signer.getAddress(), dummySwapData);
|
|
93
|
-
} catch (e) {
|
|
94
|
-
this.logger.error("getBaseSecurityDepositPrefetch(): pre-fetch error: ", e);
|
|
95
|
-
abortController.abort(e);
|
|
96
|
-
return null;
|
|
97
|
-
}
|
|
98
|
-
} else {
|
|
99
|
-
try {
|
|
100
|
-
feeResult = await swapContract.getRefundFee(signer.getAddress(), dummySwapData);
|
|
101
|
-
} catch (e1) {
|
|
102
|
-
this.logger.error("getBaseSecurityDepositPrefetch(): pre-fetch error: ", e1);
|
|
103
|
-
abortController.abort(e1);
|
|
104
|
-
return null;
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
feeResult = feeResult * 2n;
|
|
108
|
-
if(gasToken===depositToken) return feeResult;
|
|
109
|
-
const btcValue = await this.swapPricing.getToBtcSwapAmount(feeResult, gasToken, chainIdentifier, true, gasTokenPricePrefetchPromise);
|
|
110
|
-
return await this.swapPricing.getFromBtcSwapAmount(btcValue, depositToken, chainIdentifier, true, depositTokenPricePrefetchPromise);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* Starts a pre-fetch for vault balance
|
|
115
|
-
*
|
|
116
|
-
* @param chainIdentifier
|
|
117
|
-
* @param useToken
|
|
118
|
-
* @param abortController
|
|
119
|
-
* @param inContract
|
|
120
|
-
*/
|
|
121
|
-
protected async getBalancePrefetch(chainIdentifier: string, useToken: string, abortController: AbortController, inContract: boolean = true): Promise<bigint> {
|
|
122
|
-
const {swapContract, signer} = this.getChain(chainIdentifier);
|
|
123
|
-
try {
|
|
124
|
-
return await swapContract.getBalance(signer.getAddress(), useToken, inContract);
|
|
125
|
-
} catch (e) {
|
|
126
|
-
this.logger.error("getBalancePrefetch(): balancePrefetch error: ", e);
|
|
127
|
-
abortController.abort(e);
|
|
128
|
-
return null;
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* Checks if we have enough balance of the token in the swap vault
|
|
134
|
-
*
|
|
135
|
-
* @param totalInToken
|
|
136
|
-
* @param balancePrefetch
|
|
137
|
-
* @param signal
|
|
138
|
-
* @throws {DefinedRuntimeError} will throw an error if there are not enough funds in the vault
|
|
139
|
-
*/
|
|
140
|
-
protected async checkBalance(totalInToken: bigint, balancePrefetch: Promise<bigint>, signal: AbortSignal | null): Promise<void> {
|
|
141
|
-
if(totalInToken===0n) return;
|
|
142
|
-
|
|
143
|
-
const balance = await balancePrefetch;
|
|
144
|
-
if(signal!=null) signal.throwIfAborted();
|
|
145
|
-
|
|
146
|
-
if(balance==null || balance < totalInToken) {
|
|
147
|
-
throw {
|
|
148
|
-
code: 20002,
|
|
149
|
-
msg: "Not enough liquidity"
|
|
150
|
-
};
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
/**
|
|
155
|
-
* Checks if the specified token is allowed as a deposit token
|
|
156
|
-
*
|
|
157
|
-
* @param chainIdentifier
|
|
158
|
-
* @param depositToken
|
|
159
|
-
* @throws {DefinedRuntimeError} will throw an error if there are not enough funds in the vault
|
|
160
|
-
*/
|
|
161
|
-
protected checkAllowedDepositToken(chainIdentifier: string, depositToken: string): void {
|
|
162
|
-
const {chainInterface, allowedDepositTokens} = this.getChain(chainIdentifier);
|
|
163
|
-
if(allowedDepositTokens==null) {
|
|
164
|
-
if(depositToken!==chainInterface.getNativeCurrencyAddress()) throw {
|
|
165
|
-
code: 20190,
|
|
166
|
-
msg: "Unsupported deposit token"
|
|
167
|
-
};
|
|
168
|
-
} else {
|
|
169
|
-
if(!allowedDepositTokens.includes(depositToken)) throw {
|
|
170
|
-
code: 20190,
|
|
171
|
-
msg: "Unsupported deposit token"
|
|
172
|
-
};
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
/**
|
|
177
|
-
* Signs the created swap
|
|
178
|
-
*
|
|
179
|
-
* @param chainIdentifier
|
|
180
|
-
* @param swapObject
|
|
181
|
-
* @param req
|
|
182
|
-
* @param abortSignal
|
|
183
|
-
* @param signDataPrefetchPromise
|
|
184
|
-
*/
|
|
185
|
-
protected async getFromBtcSignatureData(
|
|
186
|
-
chainIdentifier: string,
|
|
187
|
-
swapObject: SwapData,
|
|
188
|
-
req: Request & {paramReader: IParamReader},
|
|
189
|
-
abortSignal: AbortSignal,
|
|
190
|
-
signDataPrefetchPromise?: Promise<any>
|
|
191
|
-
): Promise<{
|
|
192
|
-
prefix: string,
|
|
193
|
-
timeout: string,
|
|
194
|
-
signature: string,
|
|
195
|
-
feeRate: string
|
|
196
|
-
}> {
|
|
197
|
-
const {swapContract, signer} = this.getChain(chainIdentifier);
|
|
198
|
-
|
|
199
|
-
const prefetchedSignData = signDataPrefetchPromise!=null ? await signDataPrefetchPromise : null;
|
|
200
|
-
if(prefetchedSignData!=null) this.logger.debug("getFromBtcSignatureData(): pre-fetched signature data: ", prefetchedSignData);
|
|
201
|
-
abortSignal.throwIfAborted();
|
|
202
|
-
|
|
203
|
-
const feeRateObj = await req.paramReader.getParams({
|
|
204
|
-
feeRate: FieldTypeEnum.String
|
|
205
|
-
}).catch(() => null);
|
|
206
|
-
abortSignal.throwIfAborted();
|
|
207
|
-
|
|
208
|
-
const feeRate = feeRateObj?.feeRate!=null && typeof(feeRateObj.feeRate)==="string" ? feeRateObj.feeRate : null;
|
|
209
|
-
this.logger.debug("getFromBtcSignatureData(): using fee rate from client: ", feeRate);
|
|
210
|
-
const sigData = await swapContract.getInitSignature(
|
|
211
|
-
signer,
|
|
212
|
-
swapObject,
|
|
213
|
-
this.getInitAuthorizationTimeout(chainIdentifier),
|
|
214
|
-
prefetchedSignData,
|
|
215
|
-
feeRate
|
|
216
|
-
);
|
|
217
|
-
abortSignal.throwIfAborted();
|
|
218
|
-
|
|
219
|
-
return {
|
|
220
|
-
...sigData,
|
|
221
|
-
feeRate
|
|
222
|
-
};
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
/**
|
|
226
|
-
* Calculates the required security deposit
|
|
227
|
-
*
|
|
228
|
-
* @param chainIdentifier
|
|
229
|
-
* @param amountBD
|
|
230
|
-
* @param swapFee
|
|
231
|
-
* @param expiryTimeout
|
|
232
|
-
* @param baseSecurityDepositPromise
|
|
233
|
-
* @param depositToken
|
|
234
|
-
* @param depositTokenPricePrefetchPromise
|
|
235
|
-
* @param securityDepositData
|
|
236
|
-
* @param signal
|
|
237
|
-
* @param metadata
|
|
238
|
-
*/
|
|
239
|
-
protected async getSecurityDeposit(
|
|
240
|
-
chainIdentifier: string,
|
|
241
|
-
amountBD: bigint,
|
|
242
|
-
swapFee: bigint,
|
|
243
|
-
expiryTimeout: bigint,
|
|
244
|
-
baseSecurityDepositPromise: Promise<bigint>,
|
|
245
|
-
depositToken: string,
|
|
246
|
-
depositTokenPricePrefetchPromise: Promise<bigint>,
|
|
247
|
-
securityDepositData: {
|
|
248
|
-
securityDepositApyPPM?: bigint,
|
|
249
|
-
securityDepositBaseMultiplierPPM?: bigint,
|
|
250
|
-
},
|
|
251
|
-
signal: AbortSignal,
|
|
252
|
-
metadata: any
|
|
253
|
-
): Promise<bigint> {
|
|
254
|
-
let baseSD: bigint = await baseSecurityDepositPromise;
|
|
255
|
-
if(securityDepositData.securityDepositBaseMultiplierPPM!=null)
|
|
256
|
-
baseSD = baseSD * securityDepositData.securityDepositBaseMultiplierPPM / 1_000_000n;
|
|
257
|
-
|
|
258
|
-
signal.throwIfAborted();
|
|
259
|
-
|
|
260
|
-
metadata.times.refundFeeFetched = Date.now();
|
|
261
|
-
|
|
262
|
-
const swapValueInDepositToken = await this.swapPricing.getFromBtcSwapAmount(
|
|
263
|
-
amountBD - swapFee,
|
|
264
|
-
depositToken,
|
|
265
|
-
chainIdentifier,
|
|
266
|
-
true,
|
|
267
|
-
depositTokenPricePrefetchPromise
|
|
268
|
-
);
|
|
269
|
-
|
|
270
|
-
signal.throwIfAborted();
|
|
271
|
-
|
|
272
|
-
const apyPPM = securityDepositData.securityDepositApyPPM ?? BigInt(Math.floor(this.config.securityDepositAPY*1000000));
|
|
273
|
-
const variableSD = swapValueInDepositToken * apyPPM * expiryTimeout / 1000000n / secondsInYear;
|
|
274
|
-
|
|
275
|
-
this.logger.debug(
|
|
276
|
-
"getSecurityDeposit(): base security deposit: "+baseSD.toString(10)+
|
|
277
|
-
" deposit token: "+depositToken+
|
|
278
|
-
" swap output in deposit token: "+swapValueInDepositToken.toString(10)+
|
|
279
|
-
" apy ppm: "+apyPPM.toString(10)+
|
|
280
|
-
" expiry timeout: "+expiryTimeout.toString(10)+
|
|
281
|
-
" variable security deposit: "+variableSD.toString(10)
|
|
282
|
-
);
|
|
283
|
-
|
|
284
|
-
return baseSD + variableSD;
|
|
285
|
-
}
|
|
286
|
-
|
|
1
|
+
import {SwapData} from "@atomiqlabs/base";
|
|
2
|
+
import {MultichainData, SwapBaseConfig} from "../SwapHandler";
|
|
3
|
+
import {IParamReader} from "../../utils/paramcoders/IParamReader";
|
|
4
|
+
import {FieldTypeEnum} from "../../utils/paramcoders/SchemaVerifier";
|
|
5
|
+
import {Request} from "express";
|
|
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";
|
|
11
|
+
|
|
12
|
+
const secondsInYear = BigInt(365*24*60*60);
|
|
13
|
+
|
|
14
|
+
export type FromBtcBaseConfig = SwapBaseConfig & {
|
|
15
|
+
securityDepositAPY: number
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export abstract class FromBtcBaseSwapHandler<V extends FromBtcBaseSwap<SwapData, S>, S> extends EscrowHandler<V, S> {
|
|
19
|
+
|
|
20
|
+
abstract config: FromBtcBaseConfig;
|
|
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
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Starts a pre-fetch for swap price & security deposit price
|
|
37
|
+
*
|
|
38
|
+
* @param chainIdentifier
|
|
39
|
+
* @param useToken
|
|
40
|
+
* @param depositToken
|
|
41
|
+
* @param abortController
|
|
42
|
+
*/
|
|
43
|
+
protected getFromBtcPricePrefetches(chainIdentifier: string, useToken: string, depositToken: string, abortController: AbortController): {
|
|
44
|
+
pricePrefetchPromise: Promise<bigint>,
|
|
45
|
+
gasTokenPricePrefetchPromise: Promise<bigint>,
|
|
46
|
+
depositTokenPricePrefetchPromise: Promise<bigint>
|
|
47
|
+
} {
|
|
48
|
+
const pricePrefetchPromise: Promise<bigint> = this.swapPricing.preFetchPrice(useToken, chainIdentifier).catch(e => {
|
|
49
|
+
this.logger.error("getFromBtcPricePrefetches(): pricePrefetch error: ", e);
|
|
50
|
+
abortController.abort(e);
|
|
51
|
+
return null;
|
|
52
|
+
});
|
|
53
|
+
const {chainInterface} = this.getChain(chainIdentifier);
|
|
54
|
+
const gasTokenPricePrefetchPromise: Promise<bigint> = useToken.toString()===chainInterface.getNativeCurrencyAddress().toString() ?
|
|
55
|
+
pricePrefetchPromise :
|
|
56
|
+
this.swapPricing.preFetchPrice(chainInterface.getNativeCurrencyAddress(), chainIdentifier).catch(e => {
|
|
57
|
+
this.logger.error("getFromBtcPricePrefetches(): gasTokenPricePrefetchPromise error: ", e);
|
|
58
|
+
abortController.abort(e);
|
|
59
|
+
return null;
|
|
60
|
+
});
|
|
61
|
+
const depositTokenPricePrefetchPromise: Promise<bigint> = depositToken===chainInterface.getNativeCurrencyAddress() ?
|
|
62
|
+
gasTokenPricePrefetchPromise :
|
|
63
|
+
this.swapPricing.preFetchPrice(depositToken, chainIdentifier).catch(e => {
|
|
64
|
+
this.logger.error("getFromBtcPricePrefetches(): depositTokenPricePrefetchPromise error: ", e);
|
|
65
|
+
abortController.abort(e);
|
|
66
|
+
return null;
|
|
67
|
+
});
|
|
68
|
+
return {pricePrefetchPromise, gasTokenPricePrefetchPromise, depositTokenPricePrefetchPromise};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Starts a pre-fetch for base security deposit (transaction fee for refunding transaction on our side)
|
|
73
|
+
*
|
|
74
|
+
* @param chainIdentifier
|
|
75
|
+
* @param dummySwapData
|
|
76
|
+
* @param depositToken
|
|
77
|
+
* @param gasTokenPricePrefetchPromise
|
|
78
|
+
* @param depositTokenPricePrefetchPromise
|
|
79
|
+
* @param abortController
|
|
80
|
+
*/
|
|
81
|
+
protected async getBaseSecurityDepositPrefetch(
|
|
82
|
+
chainIdentifier: string, dummySwapData: SwapData, depositToken: string,
|
|
83
|
+
gasTokenPricePrefetchPromise: Promise<bigint>, depositTokenPricePrefetchPromise: Promise<bigint>,
|
|
84
|
+
abortController: AbortController
|
|
85
|
+
): Promise<bigint> {
|
|
86
|
+
//Solana workaround
|
|
87
|
+
const {swapContract, chainInterface, signer} = this.getChain(chainIdentifier);
|
|
88
|
+
let feeResult: bigint;
|
|
89
|
+
const gasToken = chainInterface.getNativeCurrencyAddress();
|
|
90
|
+
if (swapContract.getRawRefundFee != null) {
|
|
91
|
+
try {
|
|
92
|
+
feeResult = await swapContract.getRawRefundFee(signer.getAddress(), dummySwapData);
|
|
93
|
+
} catch (e) {
|
|
94
|
+
this.logger.error("getBaseSecurityDepositPrefetch(): pre-fetch error: ", e);
|
|
95
|
+
abortController.abort(e);
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
} else {
|
|
99
|
+
try {
|
|
100
|
+
feeResult = await swapContract.getRefundFee(signer.getAddress(), dummySwapData);
|
|
101
|
+
} catch (e1) {
|
|
102
|
+
this.logger.error("getBaseSecurityDepositPrefetch(): pre-fetch error: ", e1);
|
|
103
|
+
abortController.abort(e1);
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
feeResult = feeResult * 2n;
|
|
108
|
+
if(gasToken===depositToken) return feeResult;
|
|
109
|
+
const btcValue = await this.swapPricing.getToBtcSwapAmount(feeResult, gasToken, chainIdentifier, true, gasTokenPricePrefetchPromise);
|
|
110
|
+
return await this.swapPricing.getFromBtcSwapAmount(btcValue, depositToken, chainIdentifier, true, depositTokenPricePrefetchPromise);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Starts a pre-fetch for vault balance
|
|
115
|
+
*
|
|
116
|
+
* @param chainIdentifier
|
|
117
|
+
* @param useToken
|
|
118
|
+
* @param abortController
|
|
119
|
+
* @param inContract
|
|
120
|
+
*/
|
|
121
|
+
protected async getBalancePrefetch(chainIdentifier: string, useToken: string, abortController: AbortController, inContract: boolean = true): Promise<bigint> {
|
|
122
|
+
const {swapContract, signer} = this.getChain(chainIdentifier);
|
|
123
|
+
try {
|
|
124
|
+
return await swapContract.getBalance(signer.getAddress(), useToken, inContract);
|
|
125
|
+
} catch (e) {
|
|
126
|
+
this.logger.error("getBalancePrefetch(): balancePrefetch error: ", e);
|
|
127
|
+
abortController.abort(e);
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Checks if we have enough balance of the token in the swap vault
|
|
134
|
+
*
|
|
135
|
+
* @param totalInToken
|
|
136
|
+
* @param balancePrefetch
|
|
137
|
+
* @param signal
|
|
138
|
+
* @throws {DefinedRuntimeError} will throw an error if there are not enough funds in the vault
|
|
139
|
+
*/
|
|
140
|
+
protected async checkBalance(totalInToken: bigint, balancePrefetch: Promise<bigint>, signal: AbortSignal | null): Promise<void> {
|
|
141
|
+
if(totalInToken===0n) return;
|
|
142
|
+
|
|
143
|
+
const balance = await balancePrefetch;
|
|
144
|
+
if(signal!=null) signal.throwIfAborted();
|
|
145
|
+
|
|
146
|
+
if(balance==null || balance < totalInToken) {
|
|
147
|
+
throw {
|
|
148
|
+
code: 20002,
|
|
149
|
+
msg: "Not enough liquidity"
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Checks if the specified token is allowed as a deposit token
|
|
156
|
+
*
|
|
157
|
+
* @param chainIdentifier
|
|
158
|
+
* @param depositToken
|
|
159
|
+
* @throws {DefinedRuntimeError} will throw an error if there are not enough funds in the vault
|
|
160
|
+
*/
|
|
161
|
+
protected checkAllowedDepositToken(chainIdentifier: string, depositToken: string): void {
|
|
162
|
+
const {chainInterface, allowedDepositTokens} = this.getChain(chainIdentifier);
|
|
163
|
+
if(allowedDepositTokens==null) {
|
|
164
|
+
if(depositToken!==chainInterface.getNativeCurrencyAddress()) throw {
|
|
165
|
+
code: 20190,
|
|
166
|
+
msg: "Unsupported deposit token"
|
|
167
|
+
};
|
|
168
|
+
} else {
|
|
169
|
+
if(!allowedDepositTokens.includes(depositToken)) throw {
|
|
170
|
+
code: 20190,
|
|
171
|
+
msg: "Unsupported deposit token"
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Signs the created swap
|
|
178
|
+
*
|
|
179
|
+
* @param chainIdentifier
|
|
180
|
+
* @param swapObject
|
|
181
|
+
* @param req
|
|
182
|
+
* @param abortSignal
|
|
183
|
+
* @param signDataPrefetchPromise
|
|
184
|
+
*/
|
|
185
|
+
protected async getFromBtcSignatureData(
|
|
186
|
+
chainIdentifier: string,
|
|
187
|
+
swapObject: SwapData,
|
|
188
|
+
req: Request & {paramReader: IParamReader},
|
|
189
|
+
abortSignal: AbortSignal,
|
|
190
|
+
signDataPrefetchPromise?: Promise<any>
|
|
191
|
+
): Promise<{
|
|
192
|
+
prefix: string,
|
|
193
|
+
timeout: string,
|
|
194
|
+
signature: string,
|
|
195
|
+
feeRate: string
|
|
196
|
+
}> {
|
|
197
|
+
const {swapContract, signer} = this.getChain(chainIdentifier);
|
|
198
|
+
|
|
199
|
+
const prefetchedSignData = signDataPrefetchPromise!=null ? await signDataPrefetchPromise : null;
|
|
200
|
+
if(prefetchedSignData!=null) this.logger.debug("getFromBtcSignatureData(): pre-fetched signature data: ", prefetchedSignData);
|
|
201
|
+
abortSignal.throwIfAborted();
|
|
202
|
+
|
|
203
|
+
const feeRateObj = await req.paramReader.getParams({
|
|
204
|
+
feeRate: FieldTypeEnum.String
|
|
205
|
+
}).catch(() => null);
|
|
206
|
+
abortSignal.throwIfAborted();
|
|
207
|
+
|
|
208
|
+
const feeRate = feeRateObj?.feeRate!=null && typeof(feeRateObj.feeRate)==="string" ? feeRateObj.feeRate : null;
|
|
209
|
+
this.logger.debug("getFromBtcSignatureData(): using fee rate from client: ", feeRate);
|
|
210
|
+
const sigData = await swapContract.getInitSignature(
|
|
211
|
+
signer,
|
|
212
|
+
swapObject,
|
|
213
|
+
this.getInitAuthorizationTimeout(chainIdentifier),
|
|
214
|
+
prefetchedSignData,
|
|
215
|
+
feeRate
|
|
216
|
+
);
|
|
217
|
+
abortSignal.throwIfAborted();
|
|
218
|
+
|
|
219
|
+
return {
|
|
220
|
+
...sigData,
|
|
221
|
+
feeRate
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Calculates the required security deposit
|
|
227
|
+
*
|
|
228
|
+
* @param chainIdentifier
|
|
229
|
+
* @param amountBD
|
|
230
|
+
* @param swapFee
|
|
231
|
+
* @param expiryTimeout
|
|
232
|
+
* @param baseSecurityDepositPromise
|
|
233
|
+
* @param depositToken
|
|
234
|
+
* @param depositTokenPricePrefetchPromise
|
|
235
|
+
* @param securityDepositData
|
|
236
|
+
* @param signal
|
|
237
|
+
* @param metadata
|
|
238
|
+
*/
|
|
239
|
+
protected async getSecurityDeposit(
|
|
240
|
+
chainIdentifier: string,
|
|
241
|
+
amountBD: bigint,
|
|
242
|
+
swapFee: bigint,
|
|
243
|
+
expiryTimeout: bigint,
|
|
244
|
+
baseSecurityDepositPromise: Promise<bigint>,
|
|
245
|
+
depositToken: string,
|
|
246
|
+
depositTokenPricePrefetchPromise: Promise<bigint>,
|
|
247
|
+
securityDepositData: {
|
|
248
|
+
securityDepositApyPPM?: bigint,
|
|
249
|
+
securityDepositBaseMultiplierPPM?: bigint,
|
|
250
|
+
},
|
|
251
|
+
signal: AbortSignal,
|
|
252
|
+
metadata: any
|
|
253
|
+
): Promise<bigint> {
|
|
254
|
+
let baseSD: bigint = await baseSecurityDepositPromise;
|
|
255
|
+
if(securityDepositData.securityDepositBaseMultiplierPPM!=null)
|
|
256
|
+
baseSD = baseSD * securityDepositData.securityDepositBaseMultiplierPPM / 1_000_000n;
|
|
257
|
+
|
|
258
|
+
signal.throwIfAborted();
|
|
259
|
+
|
|
260
|
+
metadata.times.refundFeeFetched = Date.now();
|
|
261
|
+
|
|
262
|
+
const swapValueInDepositToken = await this.swapPricing.getFromBtcSwapAmount(
|
|
263
|
+
amountBD - swapFee,
|
|
264
|
+
depositToken,
|
|
265
|
+
chainIdentifier,
|
|
266
|
+
true,
|
|
267
|
+
depositTokenPricePrefetchPromise
|
|
268
|
+
);
|
|
269
|
+
|
|
270
|
+
signal.throwIfAborted();
|
|
271
|
+
|
|
272
|
+
const apyPPM = securityDepositData.securityDepositApyPPM ?? BigInt(Math.floor(this.config.securityDepositAPY*1000000));
|
|
273
|
+
const variableSD = swapValueInDepositToken * apyPPM * expiryTimeout / 1000000n / secondsInYear;
|
|
274
|
+
|
|
275
|
+
this.logger.debug(
|
|
276
|
+
"getSecurityDeposit(): base security deposit: "+baseSD.toString(10)+
|
|
277
|
+
" deposit token: "+depositToken+
|
|
278
|
+
" swap output in deposit token: "+swapValueInDepositToken.toString(10)+
|
|
279
|
+
" apy ppm: "+apyPPM.toString(10)+
|
|
280
|
+
" expiry timeout: "+expiryTimeout.toString(10)+
|
|
281
|
+
" variable security deposit: "+variableSD.toString(10)
|
|
282
|
+
);
|
|
283
|
+
|
|
284
|
+
return baseSD + variableSD;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
287
|
}
|