@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,74 +1,36 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {PluginManager} from "../plugins/PluginManager";
|
|
8
|
-
import {
|
|
9
|
-
isQuoteSetFees,
|
|
10
|
-
isToBtcPluginQuote
|
|
11
|
-
} from "../plugins/IPlugin";
|
|
12
|
-
import {ToBtcLnRequestType} from "./tobtcln_abstract/ToBtcLnAbs";
|
|
13
|
-
import {ToBtcRequestType} from "./tobtc_abstract/ToBtcAbs";
|
|
14
|
-
import {Request} from "express";
|
|
1
|
+
import {AmountAssertions} from "./AmountAssertions";
|
|
2
|
+
import {ToBtcLnRequestType} from "../escrow/tobtcln_abstract/ToBtcLnAbs";
|
|
3
|
+
import {ToBtcRequestType} from "../escrow/tobtc_abstract/ToBtcAbs";
|
|
4
|
+
import {PluginManager} from "../../plugins/PluginManager";
|
|
5
|
+
import {isQuoteSetFees, isToBtcPluginQuote} from "../../plugins/IPlugin";
|
|
6
|
+
import {RequestData, SwapHandlerType} from "../SwapHandler";
|
|
15
7
|
|
|
16
|
-
export type ToBtcBaseConfig = SwapBaseConfig & {
|
|
17
|
-
gracePeriod: bigint,
|
|
18
|
-
refundAuthorizationTimeout: number
|
|
19
|
-
};
|
|
20
8
|
|
|
21
|
-
export
|
|
22
|
-
|
|
23
|
-
readonly pdaExistsForToken: {
|
|
24
|
-
[chainIdentifier: string]: {
|
|
25
|
-
[token: string]: boolean
|
|
26
|
-
}
|
|
27
|
-
} = {};
|
|
28
|
-
|
|
29
|
-
abstract config: ToBtcBaseConfig;
|
|
30
|
-
|
|
31
|
-
protected async checkVaultInitialized(chainIdentifier: string, token: string): Promise<void> {
|
|
32
|
-
if(!this.pdaExistsForToken[chainIdentifier] || !this.pdaExistsForToken[chainIdentifier][token]) {
|
|
33
|
-
this.logger.debug("checkVaultInitialized(): checking vault exists for chain: "+chainIdentifier+" token: "+token);
|
|
34
|
-
const {swapContract, signer} = this.getChain(chainIdentifier);
|
|
35
|
-
const reputation = await swapContract.getIntermediaryReputation(signer.getAddress(), token);
|
|
36
|
-
this.logger.debug("checkVaultInitialized(): vault state, chain: "+chainIdentifier+" token: "+token+" exists: "+(reputation!=null));
|
|
37
|
-
if(reputation!=null) {
|
|
38
|
-
if(this.pdaExistsForToken[chainIdentifier]==null) this.pdaExistsForToken[chainIdentifier] = {};
|
|
39
|
-
this.pdaExistsForToken[chainIdentifier][token] = true;
|
|
40
|
-
} else {
|
|
41
|
-
throw {
|
|
42
|
-
code: 20201,
|
|
43
|
-
msg: "Token not supported!"
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}
|
|
9
|
+
export class ToBtcAmountAssertions extends AmountAssertions {
|
|
48
10
|
|
|
49
11
|
/**
|
|
50
12
|
* Checks minimums/maximums, calculates the fee & total amount
|
|
51
13
|
*
|
|
14
|
+
* @param swapType
|
|
52
15
|
* @param request
|
|
53
16
|
* @param requestedAmount
|
|
54
|
-
* @param useToken
|
|
55
17
|
* @throws {DefinedRuntimeError} will throw an error if the amount is outside minimum/maximum bounds
|
|
56
18
|
*/
|
|
57
|
-
|
|
19
|
+
async preCheckToBtcAmounts(
|
|
20
|
+
swapType: SwapHandlerType.TO_BTCLN | SwapHandlerType.TO_BTC,
|
|
58
21
|
request: RequestData<ToBtcLnRequestType | ToBtcRequestType>,
|
|
59
|
-
requestedAmount: {input: boolean, amount: bigint}
|
|
60
|
-
useToken: string
|
|
22
|
+
requestedAmount: {input: boolean, amount: bigint, token: string}
|
|
61
23
|
): Promise<{baseFee: bigint, feePPM: bigint}> {
|
|
62
24
|
const res = await PluginManager.onHandlePreToBtcQuote(
|
|
25
|
+
swapType,
|
|
63
26
|
request,
|
|
64
27
|
requestedAmount,
|
|
65
28
|
request.chainIdentifier,
|
|
66
|
-
useToken,
|
|
67
29
|
{minInBtc: this.config.min, maxInBtc: this.config.max},
|
|
68
30
|
{baseFeeInBtc: this.config.baseFee, feePPM: this.config.feePPM},
|
|
69
31
|
);
|
|
70
32
|
if(res!=null) {
|
|
71
|
-
|
|
33
|
+
AmountAssertions.handlePluginErrorResponses(res);
|
|
72
34
|
if(isQuoteSetFees(res)) {
|
|
73
35
|
return {
|
|
74
36
|
baseFee: res.baseFee || this.config.baseFee,
|
|
@@ -88,24 +50,22 @@ export abstract class ToBtcBaseSwapHandler<V extends SwapHandlerSwap<SwapData, S
|
|
|
88
50
|
/**
|
|
89
51
|
* Checks minimums/maximums, calculates network fee (based on the callback passed), swap fee & total amount
|
|
90
52
|
*
|
|
53
|
+
* @param swapType
|
|
91
54
|
* @param request
|
|
92
55
|
* @param requestedAmount
|
|
93
56
|
* @param fees
|
|
94
|
-
* @param useToken
|
|
95
57
|
* @param getNetworkFee
|
|
96
58
|
* @param signal
|
|
97
|
-
* @param pricePrefetchPromise
|
|
98
59
|
* @throws {DefinedRuntimeError} will throw an error if the amount is outside minimum/maximum bounds,
|
|
99
60
|
* or if we don't have enough funds (getNetworkFee callback throws)
|
|
100
61
|
*/
|
|
101
|
-
|
|
62
|
+
async checkToBtcAmount<T extends {networkFee: bigint}>(
|
|
63
|
+
swapType: SwapHandlerType.TO_BTCLN | SwapHandlerType.TO_BTC,
|
|
102
64
|
request: RequestData<ToBtcLnRequestType | ToBtcRequestType>,
|
|
103
|
-
requestedAmount: {input: boolean, amount: bigint},
|
|
65
|
+
requestedAmount: {input: boolean, amount: bigint, token: string, pricePrefetch?: Promise<bigint>},
|
|
104
66
|
fees: {baseFee: bigint, feePPM: bigint},
|
|
105
|
-
useToken: string,
|
|
106
67
|
getNetworkFee: (amount: bigint) => Promise<T>,
|
|
107
|
-
signal: AbortSignal
|
|
108
|
-
pricePrefetchPromise?: Promise<bigint>
|
|
68
|
+
signal: AbortSignal
|
|
109
69
|
): Promise<{
|
|
110
70
|
amountBD: bigint,
|
|
111
71
|
networkFeeData: T,
|
|
@@ -118,17 +78,16 @@ export abstract class ToBtcBaseSwapHandler<V extends SwapHandlerSwap<SwapData, S
|
|
|
118
78
|
const chainIdentifier = request.chainIdentifier;
|
|
119
79
|
|
|
120
80
|
const res = await PluginManager.onHandlePostToBtcQuote<T>(
|
|
81
|
+
swapType,
|
|
121
82
|
request,
|
|
122
83
|
requestedAmount,
|
|
123
84
|
request.chainIdentifier,
|
|
124
|
-
useToken,
|
|
125
85
|
{minInBtc: this.config.min, maxInBtc: this.config.max},
|
|
126
|
-
{baseFeeInBtc: fees.baseFee, feePPM: fees.feePPM, networkFeeGetter: getNetworkFee}
|
|
127
|
-
pricePrefetchPromise
|
|
86
|
+
{baseFeeInBtc: fees.baseFee, feePPM: fees.feePPM, networkFeeGetter: getNetworkFee}
|
|
128
87
|
);
|
|
129
88
|
signal.throwIfAborted();
|
|
130
89
|
if(res!=null) {
|
|
131
|
-
|
|
90
|
+
AmountAssertions.handlePluginErrorResponses(res);
|
|
132
91
|
if(isQuoteSetFees(res)) {
|
|
133
92
|
if(res.baseFee!=null) fees.baseFee = res.baseFee;
|
|
134
93
|
if(res.feePPM!=null) fees.feePPM = res.feePPM;
|
|
@@ -161,7 +120,7 @@ export abstract class ToBtcBaseSwapHandler<V extends SwapHandlerSwap<SwapData, S
|
|
|
161
120
|
let amountBD: bigint;
|
|
162
121
|
let tooLow = false;
|
|
163
122
|
if(requestedAmount.input) {
|
|
164
|
-
amountBD = await this.swapPricing.getToBtcSwapAmount(requestedAmount.amount,
|
|
123
|
+
amountBD = await this.swapPricing.getToBtcSwapAmount(requestedAmount.amount, requestedAmount.token, chainIdentifier, null, requestedAmount.pricePrefetch);
|
|
165
124
|
signal.throwIfAborted();
|
|
166
125
|
|
|
167
126
|
//Decrease by base fee
|
|
@@ -178,7 +137,6 @@ export abstract class ToBtcBaseSwapHandler<V extends SwapHandlerSwap<SwapData, S
|
|
|
178
137
|
}
|
|
179
138
|
|
|
180
139
|
const resp = await getNetworkFee(amountBD);
|
|
181
|
-
this.logger.debug("checkToBtcAmount(): network fee calculated, amount: "+amountBD.toString(10)+" fee: "+resp.networkFee.toString(10));
|
|
182
140
|
signal.throwIfAborted();
|
|
183
141
|
|
|
184
142
|
if(requestedAmount.input) {
|
|
@@ -197,10 +155,10 @@ export abstract class ToBtcBaseSwapHandler<V extends SwapHandlerSwap<SwapData, S
|
|
|
197
155
|
adjustedMin = adjustedMin + fees.baseFee + resp.networkFee;
|
|
198
156
|
adjustedMax = adjustedMax + fees.baseFee + resp.networkFee;
|
|
199
157
|
const minIn = await this.swapPricing.getFromBtcSwapAmount(
|
|
200
|
-
adjustedMin,
|
|
158
|
+
adjustedMin, requestedAmount.token, chainIdentifier, null, requestedAmount.pricePrefetch
|
|
201
159
|
);
|
|
202
160
|
const maxIn = await this.swapPricing.getFromBtcSwapAmount(
|
|
203
|
-
adjustedMax,
|
|
161
|
+
adjustedMax, requestedAmount.token, chainIdentifier, null, requestedAmount.pricePrefetch
|
|
204
162
|
);
|
|
205
163
|
throw {
|
|
206
164
|
code: tooLow ? 20003 : 2004,
|
|
@@ -216,10 +174,10 @@ export abstract class ToBtcBaseSwapHandler<V extends SwapHandlerSwap<SwapData, S
|
|
|
216
174
|
const swapFee = fees.baseFee + (amountBD * fees.feePPM / 1000000n);
|
|
217
175
|
|
|
218
176
|
const networkFeeInToken = await this.swapPricing.getFromBtcSwapAmount(
|
|
219
|
-
resp.networkFee,
|
|
177
|
+
resp.networkFee, requestedAmount.token, chainIdentifier, true, requestedAmount.pricePrefetch
|
|
220
178
|
);
|
|
221
179
|
const swapFeeInToken = await this.swapPricing.getFromBtcSwapAmount(
|
|
222
|
-
swapFee,
|
|
180
|
+
swapFee, requestedAmount.token, chainIdentifier, true, requestedAmount.pricePrefetch
|
|
223
181
|
);
|
|
224
182
|
signal.throwIfAborted();
|
|
225
183
|
|
|
@@ -228,7 +186,7 @@ export abstract class ToBtcBaseSwapHandler<V extends SwapHandlerSwap<SwapData, S
|
|
|
228
186
|
total = requestedAmount.amount;
|
|
229
187
|
} else {
|
|
230
188
|
const amountInToken = await this.swapPricing.getFromBtcSwapAmount(
|
|
231
|
-
requestedAmount.amount,
|
|
189
|
+
requestedAmount.amount, requestedAmount.token, chainIdentifier, true, requestedAmount.pricePrefetch
|
|
232
190
|
);
|
|
233
191
|
signal.throwIfAborted();
|
|
234
192
|
total = amountInToken + swapFeeInToken + networkFeeInToken;
|
|
@@ -237,77 +195,4 @@ export abstract class ToBtcBaseSwapHandler<V extends SwapHandlerSwap<SwapData, S
|
|
|
237
195
|
return {amountBD, networkFeeData: resp, swapFee, swapFeeInToken, networkFee: resp.networkFee, networkFeeInToken, totalInToken: total};
|
|
238
196
|
}
|
|
239
197
|
|
|
240
|
-
/**
|
|
241
|
-
* Starts pre-fetches for swap pricing & signature data
|
|
242
|
-
*
|
|
243
|
-
* @param chainIdentifier
|
|
244
|
-
* @param token
|
|
245
|
-
* @param responseStream
|
|
246
|
-
* @param abortController
|
|
247
|
-
*/
|
|
248
|
-
protected getToBtcPrefetches(chainIdentifier: string, token: string, responseStream: ServerParamEncoder, abortController: AbortController): {
|
|
249
|
-
pricePrefetchPromise?: Promise<bigint>,
|
|
250
|
-
signDataPrefetchPromise?: Promise<any>
|
|
251
|
-
} {
|
|
252
|
-
//Fetch pricing & signature data in parallel
|
|
253
|
-
const pricePrefetchPromise: Promise<bigint> = this.swapPricing.preFetchPrice(token, chainIdentifier).catch(e => {
|
|
254
|
-
this.logger.error("getToBtcPrefetches(): pricePrefetch error", e);
|
|
255
|
-
abortController.abort(e);
|
|
256
|
-
return null;
|
|
257
|
-
});
|
|
258
|
-
|
|
259
|
-
return {
|
|
260
|
-
pricePrefetchPromise,
|
|
261
|
-
signDataPrefetchPromise: this.getSignDataPrefetch(chainIdentifier, abortController, responseStream)
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
/**
|
|
266
|
-
* Signs the created swap
|
|
267
|
-
*
|
|
268
|
-
* @param chainIdentifier
|
|
269
|
-
* @param swapObject
|
|
270
|
-
* @param req
|
|
271
|
-
* @param abortSignal
|
|
272
|
-
* @param signDataPrefetchPromise
|
|
273
|
-
*/
|
|
274
|
-
protected async getToBtcSignatureData(
|
|
275
|
-
chainIdentifier: string,
|
|
276
|
-
swapObject: SwapData,
|
|
277
|
-
req: Request & {paramReader: IParamReader},
|
|
278
|
-
abortSignal: AbortSignal,
|
|
279
|
-
signDataPrefetchPromise?: Promise<any>
|
|
280
|
-
): Promise<{
|
|
281
|
-
prefix: string,
|
|
282
|
-
timeout: string,
|
|
283
|
-
signature: string,
|
|
284
|
-
feeRate: string
|
|
285
|
-
}> {
|
|
286
|
-
const prefetchedSignData = signDataPrefetchPromise!=null ? await signDataPrefetchPromise : null;
|
|
287
|
-
if(prefetchedSignData!=null) this.logger.debug("getToBtcSignatureData(): pre-fetched signature data: ", prefetchedSignData);
|
|
288
|
-
abortSignal.throwIfAborted();
|
|
289
|
-
|
|
290
|
-
const feeRateObj = await req.paramReader.getParams({
|
|
291
|
-
feeRate: FieldTypeEnum.String
|
|
292
|
-
}).catch(() => null);
|
|
293
|
-
abortSignal.throwIfAborted();
|
|
294
|
-
|
|
295
|
-
const feeRate = feeRateObj?.feeRate!=null && typeof(feeRateObj.feeRate)==="string" ? feeRateObj.feeRate : null;
|
|
296
|
-
this.logger.debug("getToBtcSignatureData(): using fee rate from client: ", feeRate);
|
|
297
|
-
const {swapContract, signer} = this.getChain(chainIdentifier);
|
|
298
|
-
const sigData = await swapContract.getInitSignature(
|
|
299
|
-
signer,
|
|
300
|
-
swapObject,
|
|
301
|
-
this.getInitAuthorizationTimeout(chainIdentifier),
|
|
302
|
-
prefetchedSignData,
|
|
303
|
-
feeRate
|
|
304
|
-
);
|
|
305
|
-
abortSignal.throwIfAborted();
|
|
306
|
-
|
|
307
|
-
return {
|
|
308
|
-
...sigData,
|
|
309
|
-
feeRate
|
|
310
|
-
};
|
|
311
|
-
}
|
|
312
|
-
|
|
313
198
|
}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import {SwapBaseConfig, SwapHandler} from "../SwapHandler";
|
|
2
|
+
import {
|
|
3
|
+
ChainEvent, ChainSwapType, ClaimEvent, InitializeEvent, RefundEvent,
|
|
4
|
+
SwapData,
|
|
5
|
+
SwapEvent
|
|
6
|
+
} from "@atomiqlabs/base";
|
|
7
|
+
import {PluginManager} from "../../plugins/PluginManager";
|
|
8
|
+
import {EscrowHandlerSwap} from "./EscrowHandlerSwap";
|
|
9
|
+
import {ServerParamEncoder} from "../../utils/paramcoders/server/ServerParamEncoder";
|
|
10
|
+
import {SwapHandlerSwap} from "../SwapHandlerSwap";
|
|
11
|
+
|
|
12
|
+
export type ToBtcBaseConfig = SwapBaseConfig & {
|
|
13
|
+
gracePeriod: bigint,
|
|
14
|
+
refundAuthorizationTimeout: number
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export abstract class EscrowHandler<V extends EscrowHandlerSwap<SwapData, S>, S> extends SwapHandler<V, S> {
|
|
18
|
+
|
|
19
|
+
abstract readonly swapType: ChainSwapType;
|
|
20
|
+
|
|
21
|
+
readonly escrowHashMap: Map<string, V> = new Map();
|
|
22
|
+
|
|
23
|
+
protected swapLogger = {
|
|
24
|
+
debug: (swap: SwapHandlerSwap | SwapEvent<SwapData> | SwapData, msg: string, ...args: any) => this.logger.debug(this.getIdentifier(swap)+": "+msg, ...args),
|
|
25
|
+
info: (swap: SwapHandlerSwap | SwapEvent<SwapData> | SwapData, msg: string, ...args: any) => this.logger.info(this.getIdentifier(swap)+": "+msg, ...args),
|
|
26
|
+
warn: (swap: SwapHandlerSwap | SwapEvent<SwapData> | SwapData, msg: string, ...args: any) => this.logger.warn(this.getIdentifier(swap)+": "+msg, ...args),
|
|
27
|
+
error: (swap: SwapHandlerSwap | SwapEvent<SwapData> | SwapData, msg: string, ...args: any) => this.logger.error(this.getIdentifier(swap)+": "+msg, ...args)
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
protected abstract processInitializeEvent(chainIdentifier: string, swap: V, event: InitializeEvent<SwapData>): Promise<void>;
|
|
31
|
+
protected abstract processClaimEvent(chainIdentifier: string, swap: V, event: ClaimEvent<SwapData>): Promise<void>;
|
|
32
|
+
protected abstract processRefundEvent(chainIdentifier: string, swap: V, event: RefundEvent<SwapData>): Promise<void>;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Chain event processor
|
|
36
|
+
*
|
|
37
|
+
* @param chainIdentifier
|
|
38
|
+
* @param eventData
|
|
39
|
+
*/
|
|
40
|
+
protected async processEvent(chainIdentifier: string, eventData: ChainEvent<SwapData>[]): Promise<boolean> {
|
|
41
|
+
if(this.swapType==null) return true;
|
|
42
|
+
|
|
43
|
+
for(let event of eventData) {
|
|
44
|
+
if(event instanceof InitializeEvent) {
|
|
45
|
+
if(event.swapType!==this.swapType) continue;
|
|
46
|
+
const swap = this.getSwapByEscrowHash(chainIdentifier, event.escrowHash);
|
|
47
|
+
if(swap==null) continue;
|
|
48
|
+
|
|
49
|
+
swap.txIds.init = (event as any).meta?.txId;
|
|
50
|
+
if(swap.metadata!=null) swap.metadata.times.initTxReceived = Date.now();
|
|
51
|
+
|
|
52
|
+
await this.processInitializeEvent(chainIdentifier, swap, event);
|
|
53
|
+
} else if(event instanceof ClaimEvent) {
|
|
54
|
+
const swap = this.getSwapByEscrowHash(chainIdentifier, event.escrowHash);
|
|
55
|
+
if(swap==null) continue;
|
|
56
|
+
|
|
57
|
+
swap.txIds.claim = (event as any).meta?.txId;
|
|
58
|
+
if(swap.metadata!=null) swap.metadata.times.claimTxReceived = Date.now();
|
|
59
|
+
|
|
60
|
+
await this.processClaimEvent(chainIdentifier, swap, event);
|
|
61
|
+
} else if(event instanceof RefundEvent) {
|
|
62
|
+
const swap = this.getSwapByEscrowHash(chainIdentifier, event.escrowHash);
|
|
63
|
+
if(swap==null) continue;
|
|
64
|
+
|
|
65
|
+
swap.txIds.refund = (event as any).meta?.txId;
|
|
66
|
+
if(swap.metadata!=null) swap.metadata.times.refundTxReceived = Date.now();
|
|
67
|
+
|
|
68
|
+
await this.processRefundEvent(chainIdentifier, swap, event);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Initializes chain events subscription
|
|
77
|
+
*/
|
|
78
|
+
protected subscribeToEvents() {
|
|
79
|
+
for(let key in this.chains.chains) {
|
|
80
|
+
this.chains.chains[key].chainEvents.registerListener((events: ChainEvent<SwapData>[]) => this.processEvent(key, events));
|
|
81
|
+
}
|
|
82
|
+
this.logger.info("SC: Events: subscribed to smartchain events");
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
protected async loadData(ctor: new (data: any) => V) {
|
|
86
|
+
await super.loadData(ctor);
|
|
87
|
+
for(let {obj: swap, hash, sequence} of await this.storageManager.query([])) {
|
|
88
|
+
this.saveSwapToEscrowHashMap(swap);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
protected removeSwapData(hash: string, sequence: bigint): Promise<void>;
|
|
93
|
+
protected removeSwapData(swap: V, ultimateState?: S): Promise<void>;
|
|
94
|
+
protected async removeSwapData(hashOrSwap: string | V, sequenceOrUltimateState?: bigint | S) {
|
|
95
|
+
let swap: V;
|
|
96
|
+
if(typeof(hashOrSwap)==="string") {
|
|
97
|
+
if(typeof(sequenceOrUltimateState)!=="bigint") throw new Error("Sequence must be a BN instance!");
|
|
98
|
+
swap = await this.storageManager.getData(hashOrSwap, sequenceOrUltimateState);
|
|
99
|
+
} else {
|
|
100
|
+
swap = hashOrSwap;
|
|
101
|
+
if(sequenceOrUltimateState!=null && typeof(sequenceOrUltimateState)!=="bigint") await swap.setState(sequenceOrUltimateState);
|
|
102
|
+
}
|
|
103
|
+
if(swap!=null) await PluginManager.swapRemove(swap);
|
|
104
|
+
this.swapLogger.debug(swap, "removeSwapData(): removing swap final state: "+swap.state);
|
|
105
|
+
this.removeSwapFromEscrowHashMap(swap);
|
|
106
|
+
await this.storageManager.removeData(swap.getIdentifierHash(), swap.getSequence());
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
protected async saveSwapData(swap: V) {
|
|
110
|
+
this.saveSwapToEscrowHashMap(swap);
|
|
111
|
+
return super.saveSwapData(swap);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
protected saveSwapToEscrowHashMap(swap: V) {
|
|
115
|
+
if(swap.data!=null) this.escrowHashMap.set(swap.chainIdentifier+"_"+swap.getEscrowHash(), swap);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
protected removeSwapFromEscrowHashMap(swap: V) {
|
|
119
|
+
if(swap.data!=null) this.escrowHashMap.delete(swap.chainIdentifier+"_"+swap.getEscrowHash());
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
protected getSwapByEscrowHash(chainIdentifier: string, escrowHash: string) {
|
|
123
|
+
return this.escrowHashMap.get(chainIdentifier+"_"+escrowHash);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
protected getIdentifierFromEvent(event: SwapEvent<SwapData>): string {
|
|
127
|
+
if(event instanceof SwapEvent) {
|
|
128
|
+
const foundSwap = this.escrowHashMap.get(event.escrowHash);
|
|
129
|
+
if(foundSwap!=null) {
|
|
130
|
+
return foundSwap.getIdentifier();
|
|
131
|
+
}
|
|
132
|
+
return "UNKNOWN_"+event.escrowHash;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
protected getIdentifierFromSwapData(swapData: SwapData): string {
|
|
137
|
+
if(swapData.getSequence==null) return swapData.getClaimHash();
|
|
138
|
+
return swapData.getClaimHash()+"_"+swapData.getSequence().toString(16);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
protected getIdentifier(swap: SwapHandlerSwap | SwapEvent<SwapData> | SwapData) {
|
|
142
|
+
if(swap instanceof SwapHandlerSwap) {
|
|
143
|
+
return swap.getIdentifier();
|
|
144
|
+
}
|
|
145
|
+
if(swap instanceof ChainEvent) {
|
|
146
|
+
return this.getIdentifierFromEvent(swap);
|
|
147
|
+
}
|
|
148
|
+
return this.getIdentifierFromSwapData(swap);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Starts a pre-fetch for signature data
|
|
153
|
+
*
|
|
154
|
+
* @param chainIdentifier
|
|
155
|
+
* @param abortController
|
|
156
|
+
* @param responseStream
|
|
157
|
+
*/
|
|
158
|
+
protected getSignDataPrefetch(chainIdentifier: string, abortController: AbortController, responseStream?: ServerParamEncoder): Promise<any> {
|
|
159
|
+
const {swapContract} = this.getChain(chainIdentifier);
|
|
160
|
+
let signDataPrefetchPromise: Promise<any> = swapContract.preFetchBlockDataForSignatures!=null ? swapContract.preFetchBlockDataForSignatures().catch(e => {
|
|
161
|
+
this.logger.error("getSignDataPrefetch(): signDataPrefetch: ", e);
|
|
162
|
+
abortController.abort(e);
|
|
163
|
+
return null;
|
|
164
|
+
}) : null;
|
|
165
|
+
|
|
166
|
+
if(signDataPrefetchPromise!=null && responseStream!=null) {
|
|
167
|
+
signDataPrefetchPromise = signDataPrefetchPromise.then(val => val==null || abortController.signal.aborted ? null : responseStream.writeParams({
|
|
168
|
+
signDataPrefetch: val
|
|
169
|
+
}).then(() => val).catch(e => {
|
|
170
|
+
this.logger.error("getSignDataPrefetch(): signDataPreFetch: error when sending sign data to the client: ", e);
|
|
171
|
+
abortController.abort(e);
|
|
172
|
+
return null;
|
|
173
|
+
}));
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
return signDataPrefetchPromise;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import {Lockable, StorageObject, SwapData} from "@atomiqlabs/base";
|
|
2
|
+
import {SwapHandlerSwap} from "../SwapHandlerSwap";
|
|
3
|
+
|
|
4
|
+
function objectBigIntsToString(obj: Object) {
|
|
5
|
+
for(let key in obj) {
|
|
6
|
+
if(typeof obj[key] === "bigint") obj[key] = obj[key].toString(10);
|
|
7
|
+
if(typeof obj[key] === "object") objectBigIntsToString(obj[key]);
|
|
8
|
+
}
|
|
9
|
+
return obj;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export abstract class EscrowHandlerSwap<T extends SwapData = SwapData, S = any> extends SwapHandlerSwap<S> {
|
|
13
|
+
|
|
14
|
+
data: T;
|
|
15
|
+
|
|
16
|
+
txIds: {
|
|
17
|
+
init?: string,
|
|
18
|
+
claim?: string,
|
|
19
|
+
refund?: string
|
|
20
|
+
} = {};
|
|
21
|
+
|
|
22
|
+
prefix: string;
|
|
23
|
+
timeout: string;
|
|
24
|
+
signature: string;
|
|
25
|
+
feeRate: string;
|
|
26
|
+
|
|
27
|
+
protected constructor(chainIdentifier: string, swapFee: bigint, swapFeeInToken: bigint);
|
|
28
|
+
protected constructor(obj: any);
|
|
29
|
+
|
|
30
|
+
protected constructor(obj?: any | string, swapFee?: bigint, swapFeeInToken?: bigint) {
|
|
31
|
+
super(obj, swapFee, swapFeeInToken);
|
|
32
|
+
if(typeof(obj)==="string" && typeof(swapFee)==="bigint" && typeof(swapFeeInToken)==="bigint") {
|
|
33
|
+
return;
|
|
34
|
+
} else {
|
|
35
|
+
this.data = obj.data==null ? null : SwapData.deserialize(obj.data);
|
|
36
|
+
this.prefix = obj.prefix;
|
|
37
|
+
this.timeout = obj.timeout;
|
|
38
|
+
this.signature = obj.signature;
|
|
39
|
+
this.feeRate = obj.feeRate;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
serialize(): any {
|
|
44
|
+
return {
|
|
45
|
+
...super.serialize(),
|
|
46
|
+
data: this.data==null ? null : this.data.serialize(),
|
|
47
|
+
prefix: this.prefix,
|
|
48
|
+
timeout: this.timeout,
|
|
49
|
+
signature: this.signature,
|
|
50
|
+
feeRate: this.feeRate
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Returns the escrow hash - i.e. hash of the escrow data
|
|
56
|
+
*/
|
|
57
|
+
getEscrowHash(): string {
|
|
58
|
+
return this.data.getEscrowHash();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Returns the claim data hash - i.e. hash passed to the claim handler
|
|
63
|
+
*/
|
|
64
|
+
getClaimHash(): string {
|
|
65
|
+
return this.data.getClaimHash();
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Returns the identification hash of the swap, usually claim data hash, but can be overriden, e.g. for
|
|
70
|
+
* lightning swaps the identifier hash is used instead of claim data hash
|
|
71
|
+
*/
|
|
72
|
+
getIdentifierHash(): string {
|
|
73
|
+
return this.getClaimHash();
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
getSequence(): bigint | null {
|
|
77
|
+
return this.data?.getSequence==null ? null : this.data.getSequence();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Returns the smart chain token used for the swap
|
|
82
|
+
*/
|
|
83
|
+
getToken(): string {
|
|
84
|
+
return this.data?.getToken();
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import {deserializeBN, serializeBN} from "../../utils/Utils";
|
|
2
|
+
import {EscrowHandlerSwap} from "./EscrowHandlerSwap";
|
|
1
3
|
import {SwapData} from "@atomiqlabs/base";
|
|
2
|
-
import {SwapHandlerSwap} from "./SwapHandlerSwap";
|
|
3
|
-
import {deserializeBN, serializeBN} from "../utils/Utils";
|
|
4
4
|
|
|
5
|
-
export abstract class FromBtcBaseSwap<T extends SwapData, S = any> extends
|
|
5
|
+
export abstract class FromBtcBaseSwap<T extends SwapData = SwapData, S = any> extends EscrowHandlerSwap<T, S> {
|
|
6
6
|
|
|
7
7
|
amount: bigint;
|
|
8
8
|
|
|
@@ -18,16 +18,12 @@ export abstract class FromBtcBaseSwap<T extends SwapData, S = any> extends SwapH
|
|
|
18
18
|
}
|
|
19
19
|
};
|
|
20
20
|
|
|
21
|
-
getInputAmount(): bigint {
|
|
22
|
-
return this.getTotalInputAmount() - this.getSwapFee().inInputToken;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
21
|
getTotalInputAmount(): bigint {
|
|
26
22
|
return this.amount;
|
|
27
23
|
}
|
|
28
24
|
|
|
29
25
|
getOutputAmount(): bigint {
|
|
30
|
-
return this.data
|
|
26
|
+
return this.data?.getAmount();
|
|
31
27
|
}
|
|
32
28
|
|
|
33
29
|
getSwapFee(): { inInputToken: bigint; inOutputToken: bigint } {
|