@atomiqlabs/lp-lib 11.0.5 → 12.0.0-beta.0
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/info/InfoHandler.js +3 -12
- package/dist/plugins/IPlugin.d.ts +34 -35
- package/dist/plugins/IPlugin.js +7 -8
- package/dist/plugins/PluginManager.d.ts +29 -30
- package/dist/plugins/PluginManager.js +160 -188
- package/dist/prices/BinanceSwapPrice.d.ts +1 -2
- package/dist/prices/BinanceSwapPrice.js +56 -70
- package/dist/prices/CoinGeckoSwapPrice.d.ts +2 -3
- package/dist/prices/CoinGeckoSwapPrice.js +30 -42
- package/dist/prices/OKXSwapPrice.d.ts +1 -2
- package/dist/prices/OKXSwapPrice.js +56 -70
- package/dist/storage/IIntermediaryStorage.d.ts +8 -5
- package/dist/storagemanager/IntermediaryStorageManager.d.ts +8 -5
- package/dist/storagemanager/IntermediaryStorageManager.js +52 -61
- package/dist/storagemanager/StorageManager.js +42 -59
- package/dist/swaps/FromBtcBaseSwap.d.ts +7 -8
- package/dist/swaps/FromBtcBaseSwap.js +2 -3
- package/dist/swaps/FromBtcBaseSwapHandler.d.ts +44 -31
- package/dist/swaps/FromBtcBaseSwapHandler.js +217 -196
- package/dist/swaps/FromBtcLnBaseSwapHandler.d.ts +1 -2
- package/dist/swaps/FromBtcLnBaseSwapHandler.js +13 -24
- package/dist/swaps/ISwapPrice.d.ts +4 -5
- package/dist/swaps/ISwapPrice.js +8 -30
- package/dist/swaps/SwapHandler.d.ts +26 -15
- package/dist/swaps/SwapHandler.js +107 -66
- package/dist/swaps/SwapHandlerSwap.d.ts +22 -11
- package/dist/swaps/SwapHandlerSwap.js +32 -8
- package/dist/swaps/ToBtcBaseSwap.d.ts +16 -17
- package/dist/swaps/ToBtcBaseSwap.js +4 -4
- package/dist/swaps/ToBtcBaseSwapHandler.d.ts +17 -17
- package/dist/swaps/ToBtcBaseSwapHandler.js +140 -155
- package/dist/swaps/frombtc_abstract/FromBtcAbs.d.ts +8 -15
- package/dist/swaps/frombtc_abstract/FromBtcAbs.js +131 -196
- package/dist/swaps/frombtc_abstract/FromBtcSwapAbs.d.ts +3 -5
- package/dist/swaps/frombtc_abstract/FromBtcSwapAbs.js +4 -4
- package/dist/swaps/frombtc_trusted/FromBtcTrusted.d.ts +10 -8
- package/dist/swaps/frombtc_trusted/FromBtcTrusted.js +330 -362
- package/dist/swaps/frombtc_trusted/FromBtcTrustedSwap.d.ts +10 -10
- package/dist/swaps/frombtc_trusted/FromBtcTrustedSwap.js +7 -4
- package/dist/swaps/frombtcln_abstract/FromBtcLnAbs.d.ts +8 -8
- package/dist/swaps/frombtcln_abstract/FromBtcLnAbs.js +330 -400
- package/dist/swaps/frombtcln_abstract/FromBtcLnSwapAbs.d.ts +10 -4
- package/dist/swaps/frombtcln_abstract/FromBtcLnSwapAbs.js +36 -6
- package/dist/swaps/frombtcln_trusted/FromBtcLnTrusted.d.ts +8 -7
- package/dist/swaps/frombtcln_trusted/FromBtcLnTrusted.js +251 -273
- package/dist/swaps/frombtcln_trusted/FromBtcLnTrustedSwap.d.ts +5 -5
- package/dist/swaps/frombtcln_trusted/FromBtcLnTrustedSwap.js +7 -5
- package/dist/swaps/tobtc_abstract/ToBtcAbs.d.ts +13 -12
- package/dist/swaps/tobtc_abstract/ToBtcAbs.js +261 -323
- package/dist/swaps/tobtc_abstract/ToBtcSwapAbs.d.ts +4 -4
- package/dist/swaps/tobtc_abstract/ToBtcSwapAbs.js +7 -6
- package/dist/swaps/tobtcln_abstract/ToBtcLnAbs.d.ts +22 -21
- package/dist/swaps/tobtcln_abstract/ToBtcLnAbs.js +398 -453
- package/dist/swaps/tobtcln_abstract/ToBtcLnSwapAbs.d.ts +3 -2
- package/dist/swaps/tobtcln_abstract/ToBtcLnSwapAbs.js +10 -6
- package/dist/utils/Utils.d.ts +2 -3
- package/dist/utils/Utils.js +4 -14
- package/dist/utils/paramcoders/LegacyParamEncoder.js +3 -14
- package/dist/utils/paramcoders/ParamDecoder.js +53 -65
- package/dist/utils/paramcoders/SchemaVerifier.d.ts +4 -5
- package/dist/utils/paramcoders/SchemaVerifier.js +8 -9
- package/dist/utils/paramcoders/server/ServerParamDecoder.js +1 -1
- package/dist/utils/paramcoders/server/ServerParamEncoder.js +3 -14
- package/dist/wallets/IBitcoinWallet.d.ts +4 -5
- package/dist/wallets/ILightningWallet.d.ts +20 -21
- package/dist/wallets/ILightningWallet.js +1 -1
- package/package.json +4 -6
- package/src/plugins/IPlugin.ts +28 -29
- package/src/plugins/PluginManager.ts +21 -22
- package/src/prices/BinanceSwapPrice.ts +3 -4
- package/src/prices/CoinGeckoSwapPrice.ts +4 -5
- package/src/prices/OKXSwapPrice.ts +3 -4
- package/src/storage/IIntermediaryStorage.ts +4 -5
- package/src/storagemanager/IntermediaryStorageManager.ts +17 -9
- package/src/swaps/FromBtcBaseSwap.ts +9 -10
- package/src/swaps/FromBtcBaseSwapHandler.ts +133 -91
- package/src/swaps/FromBtcLnBaseSwapHandler.ts +2 -3
- package/src/swaps/ISwapPrice.ts +10 -20
- package/src/swaps/SwapHandler.ts +101 -35
- package/src/swaps/SwapHandlerSwap.ts +42 -17
- package/src/swaps/ToBtcBaseSwap.ts +20 -18
- package/src/swaps/ToBtcBaseSwapHandler.ts +33 -33
- package/src/swaps/frombtc_abstract/FromBtcAbs.ts +64 -97
- package/src/swaps/frombtc_abstract/FromBtcSwapAbs.ts +7 -8
- package/src/swaps/frombtc_trusted/FromBtcTrusted.ts +56 -55
- package/src/swaps/frombtc_trusted/FromBtcTrustedSwap.ts +28 -21
- package/src/swaps/frombtcln_abstract/FromBtcLnAbs.ts +81 -116
- package/src/swaps/frombtcln_abstract/FromBtcLnSwapAbs.ts +73 -9
- package/src/swaps/frombtcln_trusted/FromBtcLnTrusted.ts +39 -36
- package/src/swaps/frombtcln_trusted/FromBtcLnTrustedSwap.ts +26 -12
- package/src/swaps/tobtc_abstract/ToBtcAbs.ts +82 -98
- package/src/swaps/tobtc_abstract/ToBtcSwapAbs.ts +25 -20
- package/src/swaps/tobtcln_abstract/ToBtcLnAbs.ts +106 -118
- package/src/swaps/tobtcln_abstract/ToBtcLnSwapAbs.ts +17 -9
- package/src/utils/Utils.ts +3 -4
- package/src/utils/paramcoders/ParamDecoder.ts +5 -5
- package/src/utils/paramcoders/SchemaVerifier.ts +10 -11
- package/src/utils/paramcoders/server/ServerParamDecoder.ts +1 -1
- package/src/wallets/IBitcoinWallet.ts +4 -5
- package/src/wallets/ILightningWallet.ts +21 -22
package/src/swaps/SwapHandler.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {Express, Request} from "express";
|
|
2
2
|
import {ISwapPrice} from "./ISwapPrice";
|
|
3
3
|
import {
|
|
4
|
+
ChainSwapType,
|
|
4
5
|
ChainType,
|
|
5
6
|
ClaimEvent,
|
|
6
7
|
InitializeEvent, RefundEvent,
|
|
@@ -10,7 +11,6 @@ import {
|
|
|
10
11
|
import {SwapHandlerSwap} from "./SwapHandlerSwap";
|
|
11
12
|
import {PluginManager} from "../plugins/PluginManager";
|
|
12
13
|
import {IIntermediaryStorage} from "../storage/IIntermediaryStorage";
|
|
13
|
-
import * as BN from "bn.js";
|
|
14
14
|
import {ServerParamEncoder} from "../utils/paramcoders/server/ServerParamEncoder";
|
|
15
15
|
import {
|
|
16
16
|
isQuoteAmountTooHigh,
|
|
@@ -39,13 +39,16 @@ export type SwapHandlerInfoType = {
|
|
|
39
39
|
};
|
|
40
40
|
|
|
41
41
|
export type SwapBaseConfig = {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
42
|
+
initAuthorizationTimeout: number,
|
|
43
|
+
initAuthorizationTimeouts?: {
|
|
44
|
+
[chainId: string]: number
|
|
45
|
+
},
|
|
46
|
+
bitcoinBlocktime: bigint,
|
|
47
|
+
baseFee: bigint,
|
|
48
|
+
feePPM: bigint,
|
|
49
|
+
max: bigint,
|
|
50
|
+
min: bigint,
|
|
51
|
+
safetyFactor: bigint,
|
|
49
52
|
swapCheckInterval: number
|
|
50
53
|
};
|
|
51
54
|
|
|
@@ -61,6 +64,7 @@ export type ChainData<T extends ChainType = ChainType> = {
|
|
|
61
64
|
swapContract: T["Contract"],
|
|
62
65
|
chainEvents: T["Events"],
|
|
63
66
|
allowedTokens: string[],
|
|
67
|
+
allowedDepositTokens?: string[],
|
|
64
68
|
btcRelay?: T["BtcRelay"]
|
|
65
69
|
}
|
|
66
70
|
|
|
@@ -77,8 +81,10 @@ export type RequestData<T> = {
|
|
|
77
81
|
export abstract class SwapHandler<V extends SwapHandlerSwap<SwapData, S> = SwapHandlerSwap, S = any> {
|
|
78
82
|
|
|
79
83
|
abstract readonly type: SwapHandlerType;
|
|
84
|
+
abstract readonly swapType: ChainSwapType;
|
|
80
85
|
|
|
81
86
|
readonly storageManager: IIntermediaryStorage<V>;
|
|
87
|
+
readonly escrowHashMap: Map<string, V> = new Map();
|
|
82
88
|
readonly path: string;
|
|
83
89
|
|
|
84
90
|
readonly chains: MultichainData;
|
|
@@ -145,9 +151,9 @@ export abstract class SwapHandler<V extends SwapHandlerSwap<SwapData, S> = SwapH
|
|
|
145
151
|
await rerun();
|
|
146
152
|
}
|
|
147
153
|
|
|
148
|
-
protected abstract processInitializeEvent(chainIdentifier: string, event: InitializeEvent<SwapData>): Promise<void>;
|
|
149
|
-
protected abstract processClaimEvent(chainIdentifier: string, event: ClaimEvent<SwapData>): Promise<void>;
|
|
150
|
-
protected abstract processRefundEvent(chainIdentifier: string, event: RefundEvent<SwapData>): Promise<void>;
|
|
154
|
+
protected abstract processInitializeEvent?(chainIdentifier: string, swap: V, event: InitializeEvent<SwapData>): Promise<void>;
|
|
155
|
+
protected abstract processClaimEvent?(chainIdentifier: string, swap: V, event: ClaimEvent<SwapData>): Promise<void>;
|
|
156
|
+
protected abstract processRefundEvent?(chainIdentifier: string, swap: V, event: RefundEvent<SwapData>): Promise<void>;
|
|
151
157
|
|
|
152
158
|
/**
|
|
153
159
|
* Chain event processor
|
|
@@ -156,16 +162,34 @@ export abstract class SwapHandler<V extends SwapHandlerSwap<SwapData, S> = SwapH
|
|
|
156
162
|
* @param eventData
|
|
157
163
|
*/
|
|
158
164
|
protected async processEvent(chainIdentifier: string, eventData: SwapEvent<SwapData>[]): Promise<boolean> {
|
|
165
|
+
if(this.swapType==null) return true;
|
|
166
|
+
|
|
159
167
|
for(let event of eventData) {
|
|
160
168
|
if(event instanceof InitializeEvent) {
|
|
161
|
-
|
|
162
|
-
|
|
169
|
+
if(event.swapType!==this.swapType) continue;
|
|
170
|
+
const swap = this.getSwapByEscrowHash(chainIdentifier, event.escrowHash);
|
|
171
|
+
if(swap==null) continue;
|
|
172
|
+
|
|
173
|
+
swap.txIds.init = (event as any).meta?.txId;
|
|
174
|
+
if(swap.metadata!=null) swap.metadata.times.initTxReceived = Date.now();
|
|
175
|
+
|
|
176
|
+
await this.processInitializeEvent(chainIdentifier, swap, event);
|
|
163
177
|
} else if(event instanceof ClaimEvent) {
|
|
164
|
-
|
|
165
|
-
|
|
178
|
+
const swap = this.getSwapByEscrowHash(chainIdentifier, event.escrowHash);
|
|
179
|
+
if(swap==null) continue;
|
|
180
|
+
|
|
181
|
+
swap.txIds.claim = (event as any).meta?.txId;
|
|
182
|
+
if(swap.metadata!=null) swap.metadata.times.claimTxReceived = Date.now();
|
|
183
|
+
|
|
184
|
+
await this.processClaimEvent(chainIdentifier, swap, event);
|
|
166
185
|
} else if(event instanceof RefundEvent) {
|
|
167
|
-
|
|
168
|
-
|
|
186
|
+
const swap = this.getSwapByEscrowHash(chainIdentifier, event.escrowHash);
|
|
187
|
+
if(swap==null) continue;
|
|
188
|
+
|
|
189
|
+
swap.txIds.refund = (event as any).meta?.txId;
|
|
190
|
+
if(swap.metadata!=null) swap.metadata.times.refundTxReceived = Date.now();
|
|
191
|
+
|
|
192
|
+
await this.processRefundEvent(chainIdentifier, swap, event);
|
|
169
193
|
}
|
|
170
194
|
}
|
|
171
195
|
|
|
@@ -187,6 +211,22 @@ export abstract class SwapHandler<V extends SwapHandlerSwap<SwapData, S> = SwapH
|
|
|
187
211
|
*/
|
|
188
212
|
abstract init(): Promise<void>;
|
|
189
213
|
|
|
214
|
+
protected async loadData(ctor: new (data: any) => V) {
|
|
215
|
+
await this.storageManager.loadData(ctor);
|
|
216
|
+
//Check if all swaps contain a valid amount
|
|
217
|
+
for(let {obj: swap, hash, sequence} of await this.storageManager.query([])) {
|
|
218
|
+
if(hash!==swap.getIdentifierHash() || sequence !== (swap.getSequence() ?? 0n)) {
|
|
219
|
+
this.swapLogger.info(swap, "loadData(): Swap storage key or sequence mismatch, fixing,"+
|
|
220
|
+
" old hash: "+hash+" new hash: "+swap.getIdentifierHash()+
|
|
221
|
+
" old seq: "+sequence.toString(10)+" new seq: "+(swap.getSequence() ?? 0n).toString(10));
|
|
222
|
+
|
|
223
|
+
await this.storageManager.removeData(hash, sequence);
|
|
224
|
+
await this.storageManager.saveData(swap.getIdentifierHash(), swap.getSequence(), swap);
|
|
225
|
+
}
|
|
226
|
+
this.saveSwapToEscrowHashMap(swap);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
190
230
|
/**
|
|
191
231
|
* Sets up required listeners for the REST server
|
|
192
232
|
*
|
|
@@ -205,7 +245,7 @@ export abstract class SwapHandler<V extends SwapHandlerSwap<SwapData, S> = SwapH
|
|
|
205
245
|
* @param hash
|
|
206
246
|
* @param sequence
|
|
207
247
|
*/
|
|
208
|
-
protected removeSwapData(hash: string, sequence:
|
|
248
|
+
protected removeSwapData(hash: string, sequence: bigint): Promise<void>;
|
|
209
249
|
|
|
210
250
|
/**
|
|
211
251
|
* Remove swap data
|
|
@@ -215,18 +255,36 @@ export abstract class SwapHandler<V extends SwapHandlerSwap<SwapData, S> = SwapH
|
|
|
215
255
|
*/
|
|
216
256
|
protected removeSwapData(swap: V, ultimateState?: S): Promise<void>;
|
|
217
257
|
|
|
218
|
-
protected async removeSwapData(hashOrSwap: string | V, sequenceOrUltimateState?:
|
|
258
|
+
protected async removeSwapData(hashOrSwap: string | V, sequenceOrUltimateState?: bigint | S) {
|
|
219
259
|
let swap: V;
|
|
220
260
|
if(typeof(hashOrSwap)==="string") {
|
|
221
|
-
if(
|
|
261
|
+
if(typeof(sequenceOrUltimateState)!=="bigint") throw new Error("Sequence must be a BN instance!");
|
|
222
262
|
swap = await this.storageManager.getData(hashOrSwap, sequenceOrUltimateState);
|
|
223
263
|
} else {
|
|
224
264
|
swap = hashOrSwap;
|
|
225
|
-
if(sequenceOrUltimateState!=null &&
|
|
265
|
+
if(sequenceOrUltimateState!=null && typeof(sequenceOrUltimateState)!=="bigint") await swap.setState(sequenceOrUltimateState);
|
|
226
266
|
}
|
|
227
267
|
if(swap!=null) await PluginManager.swapRemove(swap);
|
|
228
268
|
this.swapLogger.debug(swap, "removeSwapData(): removing swap final state: "+swap.state);
|
|
229
|
-
|
|
269
|
+
this.removeSwapFromEscrowHashMap(swap);
|
|
270
|
+
await this.storageManager.removeData(swap.getIdentifierHash(), swap.getSequence());
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
protected async saveSwapData(swap: V) {
|
|
274
|
+
this.saveSwapToEscrowHashMap(swap);
|
|
275
|
+
await this.storageManager.saveData(swap.getIdentifierHash(), swap.getSequence(), swap);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
protected saveSwapToEscrowHashMap(swap: V) {
|
|
279
|
+
if(swap.data!=null) this.escrowHashMap.set(swap.chainIdentifier+"_"+swap.getEscrowHash(), swap);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
protected removeSwapFromEscrowHashMap(swap: V) {
|
|
283
|
+
if(swap.data!=null) this.escrowHashMap.delete(swap.chainIdentifier+"_"+swap.data.getEscrowHash());
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
protected getSwapByEscrowHash(chainIdentifier: string, escrowHash: string) {
|
|
287
|
+
return this.escrowHashMap.get(chainIdentifier+"_"+escrowHash);
|
|
230
288
|
}
|
|
231
289
|
|
|
232
290
|
/**
|
|
@@ -236,8 +294,8 @@ export abstract class SwapHandler<V extends SwapHandlerSwap<SwapData, S> = SwapH
|
|
|
236
294
|
* @protected
|
|
237
295
|
* @throws {DefinedRuntimeError} will throw an error if the amount is outside minimum/maximum bounds
|
|
238
296
|
*/
|
|
239
|
-
protected checkBtcAmountInBounds(amount:
|
|
240
|
-
if (amount
|
|
297
|
+
protected checkBtcAmountInBounds(amount: bigint): void {
|
|
298
|
+
if (amount < this.config.min) {
|
|
241
299
|
throw {
|
|
242
300
|
code: 20003,
|
|
243
301
|
msg: "Amount too low!",
|
|
@@ -248,7 +306,7 @@ export abstract class SwapHandler<V extends SwapHandlerSwap<SwapData, S> = SwapH
|
|
|
248
306
|
};
|
|
249
307
|
}
|
|
250
308
|
|
|
251
|
-
if(amount
|
|
309
|
+
if(amount > this.config.max) {
|
|
252
310
|
throw {
|
|
253
311
|
code: 20004,
|
|
254
312
|
msg: "Amount too high!",
|
|
@@ -297,6 +355,7 @@ export abstract class SwapHandler<V extends SwapHandlerSwap<SwapData, S> = SwapH
|
|
|
297
355
|
*/
|
|
298
356
|
protected getAbortController(responseStream: ServerParamEncoder): AbortController {
|
|
299
357
|
const abortController = new AbortController();
|
|
358
|
+
if(responseStream==null || responseStream.getAbortSignal==null) return abortController;
|
|
300
359
|
const responseStreamAbortController = responseStream.getAbortSignal();
|
|
301
360
|
responseStreamAbortController.addEventListener("abort", () => abortController.abort(responseStreamAbortController.reason));
|
|
302
361
|
return abortController;
|
|
@@ -331,13 +390,16 @@ export abstract class SwapHandler<V extends SwapHandlerSwap<SwapData, S> = SwapH
|
|
|
331
390
|
}
|
|
332
391
|
|
|
333
392
|
protected getIdentifierFromEvent(event: SwapEvent<SwapData>): string {
|
|
334
|
-
|
|
335
|
-
|
|
393
|
+
const foundSwap = this.escrowHashMap.get(event.escrowHash);
|
|
394
|
+
if(foundSwap!=null) {
|
|
395
|
+
return foundSwap.getIdentifier();
|
|
396
|
+
}
|
|
397
|
+
return "UNKNOWN_"+event.escrowHash;
|
|
336
398
|
}
|
|
337
399
|
|
|
338
400
|
protected getIdentifierFromSwapData(swapData: SwapData): string {
|
|
339
|
-
if(swapData.getSequence
|
|
340
|
-
return swapData.
|
|
401
|
+
if(swapData.getSequence==null) return swapData.getClaimHash();
|
|
402
|
+
return swapData.getClaimHash()+"_"+swapData.getSequence().toString(16);
|
|
341
403
|
}
|
|
342
404
|
|
|
343
405
|
protected getIdentifier(swap: SwapHandlerSwap | SwapEvent<SwapData> | SwapData) {
|
|
@@ -356,8 +418,8 @@ export abstract class SwapHandler<V extends SwapHandlerSwap<SwapData, S> = SwapH
|
|
|
356
418
|
* @param sequence
|
|
357
419
|
* @throws {DefinedRuntimeError} will throw an error if sequence number is out of bounds
|
|
358
420
|
*/
|
|
359
|
-
protected checkSequence(sequence:
|
|
360
|
-
if(sequence
|
|
421
|
+
protected checkSequence(sequence: bigint) {
|
|
422
|
+
if(sequence < 0n || sequence >= 2n ** 64n) {
|
|
361
423
|
throw {
|
|
362
424
|
code: 20060,
|
|
363
425
|
msg: "Invalid sequence"
|
|
@@ -384,14 +446,18 @@ export abstract class SwapHandler<V extends SwapHandlerSwap<SwapData, S> = SwapH
|
|
|
384
446
|
chainTokens[chainId] = Array.from<string>(this.allowedTokens[chainId]);
|
|
385
447
|
}
|
|
386
448
|
return {
|
|
387
|
-
swapFeePPM: this.config.feePPM
|
|
388
|
-
swapBaseFee: this.config.baseFee
|
|
389
|
-
min: this.config.min
|
|
390
|
-
max: this.config.max
|
|
449
|
+
swapFeePPM: Number(this.config.feePPM),
|
|
450
|
+
swapBaseFee: Number(this.config.baseFee),
|
|
451
|
+
min: Number(this.config.min),
|
|
452
|
+
max: Number(this.config.max),
|
|
391
453
|
data: this.getInfoData(),
|
|
392
454
|
tokens: Array.from<string>(this.allowedTokens[this.chains.default]),
|
|
393
455
|
chainTokens
|
|
394
456
|
};
|
|
395
457
|
}
|
|
396
458
|
|
|
459
|
+
protected getInitAuthorizationTimeout(chainIdentifier: string) {
|
|
460
|
+
return this.config.initAuthorizationTimeouts?.[chainIdentifier] ?? this.config.initAuthorizationTimeout;
|
|
461
|
+
}
|
|
462
|
+
|
|
397
463
|
}
|
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
import {Lockable, StorageObject, SwapData} from "@atomiqlabs/base";
|
|
2
2
|
import {SwapHandlerType} from "./SwapHandler";
|
|
3
3
|
import {PluginManager} from "../plugins/PluginManager";
|
|
4
|
-
import * as BN from "bn.js";
|
|
5
4
|
import {deserializeBN, serializeBN} from "../utils/Utils";
|
|
6
5
|
|
|
6
|
+
function objectBigIntsToString(obj: Object) {
|
|
7
|
+
for(let key in obj) {
|
|
8
|
+
if(typeof obj[key] === "bigint") obj[key] = obj[key].toString(10);
|
|
9
|
+
if(typeof obj[key] === "object") objectBigIntsToString(obj[key]);
|
|
10
|
+
}
|
|
11
|
+
return obj;
|
|
12
|
+
}
|
|
13
|
+
|
|
7
14
|
export abstract class SwapHandlerSwap<T extends SwapData = SwapData, S = any> extends Lockable implements StorageObject {
|
|
8
15
|
|
|
9
16
|
chainIdentifier: string;
|
|
@@ -21,20 +28,20 @@ export abstract class SwapHandlerSwap<T extends SwapData = SwapData, S = any> ex
|
|
|
21
28
|
claim?: string,
|
|
22
29
|
refund?: string
|
|
23
30
|
} = {};
|
|
24
|
-
readonly swapFee:
|
|
25
|
-
readonly swapFeeInToken:
|
|
31
|
+
readonly swapFee: bigint;
|
|
32
|
+
readonly swapFeeInToken: bigint;
|
|
26
33
|
|
|
27
34
|
prefix: string;
|
|
28
35
|
timeout: string;
|
|
29
36
|
signature: string;
|
|
30
37
|
feeRate: string;
|
|
31
38
|
|
|
32
|
-
protected constructor(chainIdentifier: string, swapFee:
|
|
39
|
+
protected constructor(chainIdentifier: string, swapFee: bigint, swapFeeInToken: bigint);
|
|
33
40
|
protected constructor(obj: any);
|
|
34
41
|
|
|
35
|
-
protected constructor(obj?: any | string, swapFee?:
|
|
42
|
+
protected constructor(obj?: any | string, swapFee?: bigint, swapFeeInToken?: bigint) {
|
|
36
43
|
super();
|
|
37
|
-
if(typeof(obj)==="string" &&
|
|
44
|
+
if(typeof(obj)==="string" && typeof(swapFee)==="bigint" && typeof(swapFeeInToken)==="bigint") {
|
|
38
45
|
this.chainIdentifier = obj;
|
|
39
46
|
this.swapFee = swapFee;
|
|
40
47
|
this.swapFeeInToken = swapFeeInToken;
|
|
@@ -59,7 +66,7 @@ export abstract class SwapHandlerSwap<T extends SwapData = SwapData, S = any> ex
|
|
|
59
66
|
state: this.state,
|
|
60
67
|
data: this.data==null ? null : this.data.serialize(),
|
|
61
68
|
chainIdentifier: this.chainIdentifier,
|
|
62
|
-
metadata: this.metadata,
|
|
69
|
+
metadata: objectBigIntsToString(this.metadata),
|
|
63
70
|
txIds: this.txIds,
|
|
64
71
|
swapFee: serializeBN(this.swapFee),
|
|
65
72
|
swapFeeInToken: serializeBN(this.swapFeeInToken),
|
|
@@ -81,12 +88,30 @@ export abstract class SwapHandlerSwap<T extends SwapData = SwapData, S = any> ex
|
|
|
81
88
|
return PluginManager.swapStateChange(this, oldState);
|
|
82
89
|
}
|
|
83
90
|
|
|
84
|
-
|
|
85
|
-
|
|
91
|
+
/**
|
|
92
|
+
* Returns the escrow hash - i.e. hash of the escrow data
|
|
93
|
+
*/
|
|
94
|
+
getEscrowHash(): string {
|
|
95
|
+
return this.data.getEscrowHash();
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Returns the claim data hash - i.e. hash passed to the claim handler
|
|
100
|
+
*/
|
|
101
|
+
getClaimHash(): string {
|
|
102
|
+
return this.data.getClaimHash();
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Returns the identification hash of the swap, usually claim data hash, but can be overriden, e.g. for
|
|
107
|
+
* lightning swaps the identifier hash is used instead of claim data hash
|
|
108
|
+
*/
|
|
109
|
+
getIdentifierHash(): string {
|
|
110
|
+
return this.getClaimHash();
|
|
86
111
|
}
|
|
87
112
|
|
|
88
|
-
getSequence():
|
|
89
|
-
return this.data.getSequence();
|
|
113
|
+
getSequence(): bigint | null {
|
|
114
|
+
return this.data?.getSequence==null ? null : this.data.getSequence();
|
|
90
115
|
}
|
|
91
116
|
|
|
92
117
|
/**
|
|
@@ -95,9 +120,9 @@ export abstract class SwapHandlerSwap<T extends SwapData = SwapData, S = any> ex
|
|
|
95
120
|
*/
|
|
96
121
|
getIdentifier(): string {
|
|
97
122
|
if(this.getSequence()!=null) {
|
|
98
|
-
return this.chainIdentifier+"_"+this.
|
|
123
|
+
return this.chainIdentifier+"_"+this.getIdentifierHash()+"_"+this.getSequence().toString(16);
|
|
99
124
|
}
|
|
100
|
-
return this.
|
|
125
|
+
return this.chainIdentifier+"_"+this.getIdentifierHash();
|
|
101
126
|
}
|
|
102
127
|
|
|
103
128
|
/**
|
|
@@ -125,22 +150,22 @@ export abstract class SwapHandlerSwap<T extends SwapData = SwapData, S = any> ex
|
|
|
125
150
|
/**
|
|
126
151
|
* Returns the input amount paid by the user (excluding fees)
|
|
127
152
|
*/
|
|
128
|
-
abstract getInputAmount():
|
|
153
|
+
abstract getInputAmount(): bigint;
|
|
129
154
|
|
|
130
155
|
/**
|
|
131
156
|
* Returns the total input amount paid by the user (including all fees)
|
|
132
157
|
*/
|
|
133
|
-
abstract getTotalInputAmount():
|
|
158
|
+
abstract getTotalInputAmount(): bigint;
|
|
134
159
|
|
|
135
160
|
/**
|
|
136
161
|
* Returns the actual output amount paid out to the user
|
|
137
162
|
*/
|
|
138
|
-
abstract getOutputAmount():
|
|
163
|
+
abstract getOutputAmount(): bigint;
|
|
139
164
|
|
|
140
165
|
/**
|
|
141
166
|
* Returns swap fee, denominated in input & output tokens (the fee is paid only once, it is just represented here in
|
|
142
167
|
* both denomination for ease of use)
|
|
143
168
|
*/
|
|
144
|
-
abstract getSwapFee(): {inInputToken:
|
|
169
|
+
abstract getSwapFee(): {inInputToken: bigint, inOutputToken: bigint};
|
|
145
170
|
|
|
146
171
|
}
|
|
@@ -1,23 +1,25 @@
|
|
|
1
1
|
import {SwapHandlerSwap} from "./SwapHandlerSwap";
|
|
2
2
|
import {SwapData} from "@atomiqlabs/base";
|
|
3
|
-
import * as BN from "bn.js";
|
|
4
3
|
import {deserializeBN, serializeBN} from "../utils/Utils";
|
|
5
4
|
|
|
6
5
|
|
|
7
6
|
export abstract class ToBtcBaseSwap<T extends SwapData = SwapData, S = any> extends SwapHandlerSwap<T, S> {
|
|
8
7
|
|
|
9
|
-
amount:
|
|
8
|
+
amount: bigint;
|
|
10
9
|
|
|
11
|
-
quotedNetworkFee:
|
|
12
|
-
readonly quotedNetworkFeeInToken:
|
|
13
|
-
realNetworkFee:
|
|
14
|
-
realNetworkFeeInToken:
|
|
10
|
+
quotedNetworkFee: bigint;
|
|
11
|
+
readonly quotedNetworkFeeInToken: bigint;
|
|
12
|
+
realNetworkFee: bigint;
|
|
13
|
+
realNetworkFeeInToken: bigint;
|
|
15
14
|
|
|
16
|
-
protected constructor(chainIdentifier: string, amount:
|
|
15
|
+
protected constructor(chainIdentifier: string, amount: bigint, swapFee: bigint, swapFeeInToken: bigint, quotedNetworkFee: bigint, quotedNetworkFeeInToken: bigint);
|
|
17
16
|
protected constructor(obj: any);
|
|
18
17
|
|
|
19
|
-
protected constructor(obj?: any | string, amount?:
|
|
20
|
-
if(
|
|
18
|
+
protected constructor(obj?: any | string, amount?: bigint, swapFee?: bigint, swapFeeInToken?: bigint, quotedNetworkFee?: bigint, quotedNetworkFeeInToken?: bigint) {
|
|
19
|
+
if(
|
|
20
|
+
typeof(obj)==="string" && typeof(amount)==="bigint" && typeof(swapFee)==="bigint" && typeof(swapFeeInToken)==="bigint" &&
|
|
21
|
+
typeof(quotedNetworkFee)==="bigint" && typeof(quotedNetworkFeeInToken)==="bigint"
|
|
22
|
+
) {
|
|
21
23
|
super(obj, swapFee, swapFeeInToken);
|
|
22
24
|
this.amount = amount;
|
|
23
25
|
this.quotedNetworkFee = quotedNetworkFee;
|
|
@@ -43,22 +45,22 @@ export abstract class ToBtcBaseSwap<T extends SwapData = SwapData, S = any> exte
|
|
|
43
45
|
return obj;
|
|
44
46
|
}
|
|
45
47
|
|
|
46
|
-
setRealNetworkFee(networkFeeInBtc:
|
|
48
|
+
setRealNetworkFee(networkFeeInBtc: bigint) {
|
|
47
49
|
this.realNetworkFee = networkFeeInBtc;
|
|
48
50
|
if(this.quotedNetworkFee!=null && this.quotedNetworkFeeInToken!=null) {
|
|
49
|
-
this.realNetworkFeeInToken = this.realNetworkFee
|
|
51
|
+
this.realNetworkFeeInToken = this.realNetworkFee * this.quotedNetworkFeeInToken / this.quotedNetworkFee;
|
|
50
52
|
}
|
|
51
53
|
}
|
|
52
54
|
|
|
53
|
-
getInputAmount():
|
|
54
|
-
return this.data.getAmount()
|
|
55
|
+
getInputAmount(): bigint {
|
|
56
|
+
return this.data.getAmount() - this.getSwapFee().inInputToken - this.getQuotedNetworkFee().inInputToken;
|
|
55
57
|
}
|
|
56
58
|
|
|
57
|
-
getTotalInputAmount():
|
|
59
|
+
getTotalInputAmount(): bigint {
|
|
58
60
|
return this.data.getAmount();
|
|
59
61
|
}
|
|
60
62
|
|
|
61
|
-
getSwapFee(): { inInputToken:
|
|
63
|
+
getSwapFee(): { inInputToken: bigint; inOutputToken: bigint } {
|
|
62
64
|
return {inInputToken: this.swapFeeInToken, inOutputToken: this.swapFee};
|
|
63
65
|
}
|
|
64
66
|
|
|
@@ -66,7 +68,7 @@ export abstract class ToBtcBaseSwap<T extends SwapData = SwapData, S = any> exte
|
|
|
66
68
|
* Returns quoted (expected) network fee, denominated in input & output tokens (the fee is paid only once, it is
|
|
67
69
|
* just represented here in both denomination for ease of use)
|
|
68
70
|
*/
|
|
69
|
-
getQuotedNetworkFee(): { inInputToken:
|
|
71
|
+
getQuotedNetworkFee(): { inInputToken: bigint; inOutputToken: bigint } {
|
|
70
72
|
return {inInputToken: this.quotedNetworkFeeInToken, inOutputToken: this.quotedNetworkFee};
|
|
71
73
|
}
|
|
72
74
|
|
|
@@ -74,11 +76,11 @@ export abstract class ToBtcBaseSwap<T extends SwapData = SwapData, S = any> exte
|
|
|
74
76
|
* Returns real network fee paid for the swap, denominated in input & output tokens (the fee is paid only once, it is
|
|
75
77
|
* just represented here in both denomination for ease of use)
|
|
76
78
|
*/
|
|
77
|
-
getRealNetworkFee(): { inInputToken:
|
|
79
|
+
getRealNetworkFee(): { inInputToken: bigint; inOutputToken: bigint } {
|
|
78
80
|
return {inInputToken: this.realNetworkFeeInToken, inOutputToken: this.realNetworkFee};
|
|
79
81
|
}
|
|
80
82
|
|
|
81
|
-
getOutputAmount():
|
|
83
|
+
getOutputAmount(): bigint {
|
|
82
84
|
return this.amount;
|
|
83
85
|
}
|
|
84
86
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import {RequestData, SwapBaseConfig, SwapHandler} from "./SwapHandler";
|
|
2
2
|
import {SwapHandlerSwap} from "./SwapHandlerSwap";
|
|
3
3
|
import {SwapData} from "@atomiqlabs/base";
|
|
4
|
-
import * as BN from "bn.js";
|
|
5
4
|
import {ServerParamEncoder} from "../utils/paramcoders/server/ServerParamEncoder";
|
|
6
5
|
import {IParamReader} from "../utils/paramcoders/IParamReader";
|
|
7
6
|
import {FieldTypeEnum} from "../utils/paramcoders/SchemaVerifier";
|
|
@@ -15,7 +14,8 @@ import {ToBtcRequestType} from "./tobtc_abstract/ToBtcAbs";
|
|
|
15
14
|
import {Request} from "express";
|
|
16
15
|
|
|
17
16
|
export type ToBtcBaseConfig = SwapBaseConfig & {
|
|
18
|
-
gracePeriod:
|
|
17
|
+
gracePeriod: bigint,
|
|
18
|
+
refundAuthorizationTimeout: number
|
|
19
19
|
};
|
|
20
20
|
|
|
21
21
|
export abstract class ToBtcBaseSwapHandler<V extends SwapHandlerSwap<SwapData, S>, S> extends SwapHandler<V, S> {
|
|
@@ -56,9 +56,9 @@ export abstract class ToBtcBaseSwapHandler<V extends SwapHandlerSwap<SwapData, S
|
|
|
56
56
|
*/
|
|
57
57
|
protected async preCheckAmounts(
|
|
58
58
|
request: RequestData<ToBtcLnRequestType | ToBtcRequestType>,
|
|
59
|
-
requestedAmount: {input: boolean, amount:
|
|
59
|
+
requestedAmount: {input: boolean, amount: bigint},
|
|
60
60
|
useToken: string
|
|
61
|
-
): Promise<{baseFee:
|
|
61
|
+
): Promise<{baseFee: bigint, feePPM: bigint}> {
|
|
62
62
|
const res = await PluginManager.onHandlePreToBtcQuote(
|
|
63
63
|
request,
|
|
64
64
|
requestedAmount,
|
|
@@ -98,22 +98,22 @@ export abstract class ToBtcBaseSwapHandler<V extends SwapHandlerSwap<SwapData, S
|
|
|
98
98
|
* @throws {DefinedRuntimeError} will throw an error if the amount is outside minimum/maximum bounds,
|
|
99
99
|
* or if we don't have enough funds (getNetworkFee callback throws)
|
|
100
100
|
*/
|
|
101
|
-
protected async checkToBtcAmount<T extends {networkFee:
|
|
101
|
+
protected async checkToBtcAmount<T extends {networkFee: bigint}>(
|
|
102
102
|
request: RequestData<ToBtcLnRequestType | ToBtcRequestType>,
|
|
103
|
-
requestedAmount: {input: boolean, amount:
|
|
104
|
-
fees: {baseFee:
|
|
103
|
+
requestedAmount: {input: boolean, amount: bigint},
|
|
104
|
+
fees: {baseFee: bigint, feePPM: bigint},
|
|
105
105
|
useToken: string,
|
|
106
|
-
getNetworkFee: (amount:
|
|
106
|
+
getNetworkFee: (amount: bigint) => Promise<T>,
|
|
107
107
|
signal: AbortSignal,
|
|
108
|
-
pricePrefetchPromise?: Promise<
|
|
108
|
+
pricePrefetchPromise?: Promise<bigint>
|
|
109
109
|
): Promise<{
|
|
110
|
-
amountBD:
|
|
110
|
+
amountBD: bigint,
|
|
111
111
|
networkFeeData: T,
|
|
112
|
-
swapFee:
|
|
113
|
-
swapFeeInToken:
|
|
114
|
-
networkFee:
|
|
115
|
-
networkFeeInToken:
|
|
116
|
-
totalInToken:
|
|
112
|
+
swapFee: bigint,
|
|
113
|
+
swapFeeInToken: bigint,
|
|
114
|
+
networkFee: bigint,
|
|
115
|
+
networkFeeInToken: bigint,
|
|
116
|
+
totalInToken: bigint
|
|
117
117
|
}> {
|
|
118
118
|
const chainIdentifier = request.chainIdentifier;
|
|
119
119
|
|
|
@@ -152,23 +152,23 @@ export abstract class ToBtcBaseSwapHandler<V extends SwapHandlerSwap<SwapData, S
|
|
|
152
152
|
networkFee: res.networkFee.inOutputTokens,
|
|
153
153
|
networkFeeInToken: res.networkFee.inInputTokens,
|
|
154
154
|
networkFeeData: res.networkFeeData,
|
|
155
|
-
totalInToken: res.amount.amount
|
|
155
|
+
totalInToken: res.amount.amount + res.swapFee.inInputTokens + res.networkFee.inInputTokens
|
|
156
156
|
}
|
|
157
157
|
}
|
|
158
158
|
}
|
|
159
159
|
}
|
|
160
160
|
|
|
161
|
-
let amountBD:
|
|
161
|
+
let amountBD: bigint;
|
|
162
162
|
let tooLow = false;
|
|
163
163
|
if(requestedAmount.input) {
|
|
164
164
|
amountBD = await this.swapPricing.getToBtcSwapAmount(requestedAmount.amount, useToken, chainIdentifier, null, pricePrefetchPromise);
|
|
165
165
|
signal.throwIfAborted();
|
|
166
166
|
|
|
167
167
|
//Decrease by base fee
|
|
168
|
-
amountBD = amountBD
|
|
168
|
+
amountBD = amountBD - fees.baseFee;
|
|
169
169
|
|
|
170
170
|
//If it's already smaller than minimum, set it to minimum so we can calculate the network fee
|
|
171
|
-
if(amountBD
|
|
171
|
+
if(amountBD < this.config.min) {
|
|
172
172
|
amountBD = this.config.min;
|
|
173
173
|
tooLow = true;
|
|
174
174
|
}
|
|
@@ -183,19 +183,19 @@ export abstract class ToBtcBaseSwapHandler<V extends SwapHandlerSwap<SwapData, S
|
|
|
183
183
|
|
|
184
184
|
if(requestedAmount.input) {
|
|
185
185
|
//Decrease by network fee
|
|
186
|
-
amountBD = amountBD
|
|
186
|
+
amountBD = amountBD - resp.networkFee;
|
|
187
187
|
|
|
188
188
|
//Decrease by percentage fee
|
|
189
|
-
amountBD = amountBD
|
|
189
|
+
amountBD = amountBD * 1000000n / (fees.feePPM + 1000000n);
|
|
190
190
|
|
|
191
|
-
const tooHigh = amountBD
|
|
192
|
-
tooLow ||= amountBD
|
|
191
|
+
const tooHigh = amountBD > (this.config.max * 105n / 100n);
|
|
192
|
+
tooLow ||= amountBD < (this.config.min * 95n / 100n);
|
|
193
193
|
if(tooLow || tooHigh) {
|
|
194
194
|
//Compute min/max
|
|
195
|
-
let adjustedMin = this.config.min
|
|
196
|
-
let adjustedMax = this.config.max
|
|
197
|
-
adjustedMin = adjustedMin
|
|
198
|
-
adjustedMax = adjustedMax
|
|
195
|
+
let adjustedMin = this.config.min * (fees.feePPM + 1000000n) / 1000000n;
|
|
196
|
+
let adjustedMax = this.config.max * (fees.feePPM + 1000000n) / 1000000n;
|
|
197
|
+
adjustedMin = adjustedMin + fees.baseFee + resp.networkFee;
|
|
198
|
+
adjustedMax = adjustedMax + fees.baseFee + resp.networkFee;
|
|
199
199
|
const minIn = await this.swapPricing.getFromBtcSwapAmount(
|
|
200
200
|
adjustedMin, useToken, chainIdentifier, null, pricePrefetchPromise
|
|
201
201
|
);
|
|
@@ -213,7 +213,7 @@ export abstract class ToBtcBaseSwapHandler<V extends SwapHandlerSwap<SwapData, S
|
|
|
213
213
|
}
|
|
214
214
|
}
|
|
215
215
|
|
|
216
|
-
const swapFee = fees.baseFee
|
|
216
|
+
const swapFee = fees.baseFee + (amountBD * fees.feePPM / 1000000n);
|
|
217
217
|
|
|
218
218
|
const networkFeeInToken = await this.swapPricing.getFromBtcSwapAmount(
|
|
219
219
|
resp.networkFee, useToken, chainIdentifier, true, pricePrefetchPromise
|
|
@@ -223,7 +223,7 @@ export abstract class ToBtcBaseSwapHandler<V extends SwapHandlerSwap<SwapData, S
|
|
|
223
223
|
);
|
|
224
224
|
signal.throwIfAborted();
|
|
225
225
|
|
|
226
|
-
let total:
|
|
226
|
+
let total: bigint;
|
|
227
227
|
if(requestedAmount.input) {
|
|
228
228
|
total = requestedAmount.amount;
|
|
229
229
|
} else {
|
|
@@ -231,7 +231,7 @@ export abstract class ToBtcBaseSwapHandler<V extends SwapHandlerSwap<SwapData, S
|
|
|
231
231
|
requestedAmount.amount, useToken, chainIdentifier, true, pricePrefetchPromise
|
|
232
232
|
);
|
|
233
233
|
signal.throwIfAborted();
|
|
234
|
-
total = amountInToken
|
|
234
|
+
total = amountInToken + swapFeeInToken + networkFeeInToken;
|
|
235
235
|
}
|
|
236
236
|
|
|
237
237
|
return {amountBD, networkFeeData: resp, swapFee, swapFeeInToken, networkFee: resp.networkFee, networkFeeInToken, totalInToken: total};
|
|
@@ -246,11 +246,11 @@ export abstract class ToBtcBaseSwapHandler<V extends SwapHandlerSwap<SwapData, S
|
|
|
246
246
|
* @param abortController
|
|
247
247
|
*/
|
|
248
248
|
protected getToBtcPrefetches(chainIdentifier: string, token: string, responseStream: ServerParamEncoder, abortController: AbortController): {
|
|
249
|
-
pricePrefetchPromise?: Promise<
|
|
249
|
+
pricePrefetchPromise?: Promise<bigint>,
|
|
250
250
|
signDataPrefetchPromise?: Promise<any>
|
|
251
251
|
} {
|
|
252
252
|
//Fetch pricing & signature data in parallel
|
|
253
|
-
const pricePrefetchPromise: Promise<
|
|
253
|
+
const pricePrefetchPromise: Promise<bigint> = this.swapPricing.preFetchPrice(token, chainIdentifier).catch(e => {
|
|
254
254
|
this.logger.error("getToBtcPrefetches(): pricePrefetch error", e);
|
|
255
255
|
abortController.abort(e);
|
|
256
256
|
return null;
|
|
@@ -298,7 +298,7 @@ export abstract class ToBtcBaseSwapHandler<V extends SwapHandlerSwap<SwapData, S
|
|
|
298
298
|
const sigData = await swapContract.getInitSignature(
|
|
299
299
|
signer,
|
|
300
300
|
swapObject,
|
|
301
|
-
this.
|
|
301
|
+
this.getInitAuthorizationTimeout(chainIdentifier),
|
|
302
302
|
prefetchedSignData,
|
|
303
303
|
feeRate
|
|
304
304
|
);
|