@atomiqlabs/lp-lib 10.3.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. package/LICENSE +201 -0
  2. package/dist/fees/IBtcFeeEstimator.d.ts +3 -0
  3. package/dist/fees/IBtcFeeEstimator.js +2 -0
  4. package/dist/fees/OneDollarFeeEstimator.d.ts +16 -0
  5. package/dist/fees/OneDollarFeeEstimator.js +71 -0
  6. package/dist/index.d.ts +33 -0
  7. package/dist/index.js +52 -0
  8. package/dist/info/InfoHandler.d.ts +17 -0
  9. package/dist/info/InfoHandler.js +70 -0
  10. package/dist/plugins/IPlugin.d.ts +118 -0
  11. package/dist/plugins/IPlugin.js +33 -0
  12. package/dist/plugins/PluginManager.d.ts +89 -0
  13. package/dist/plugins/PluginManager.js +263 -0
  14. package/dist/prices/BinanceSwapPrice.d.ts +27 -0
  15. package/dist/prices/BinanceSwapPrice.js +106 -0
  16. package/dist/prices/CoinGeckoSwapPrice.d.ts +31 -0
  17. package/dist/prices/CoinGeckoSwapPrice.js +76 -0
  18. package/dist/storage/IIntermediaryStorage.d.ts +15 -0
  19. package/dist/storage/IIntermediaryStorage.js +2 -0
  20. package/dist/storagemanager/IntermediaryStorageManager.d.ts +15 -0
  21. package/dist/storagemanager/IntermediaryStorageManager.js +113 -0
  22. package/dist/storagemanager/StorageManager.d.ts +12 -0
  23. package/dist/storagemanager/StorageManager.js +74 -0
  24. package/dist/swaps/FromBtcBaseSwap.d.ts +12 -0
  25. package/dist/swaps/FromBtcBaseSwap.js +16 -0
  26. package/dist/swaps/FromBtcBaseSwapHandler.d.ts +118 -0
  27. package/dist/swaps/FromBtcBaseSwapHandler.js +294 -0
  28. package/dist/swaps/FromBtcLnBaseSwapHandler.d.ts +25 -0
  29. package/dist/swaps/FromBtcLnBaseSwapHandler.js +55 -0
  30. package/dist/swaps/ISwapPrice.d.ts +44 -0
  31. package/dist/swaps/ISwapPrice.js +73 -0
  32. package/dist/swaps/SwapHandler.d.ts +186 -0
  33. package/dist/swaps/SwapHandler.js +292 -0
  34. package/dist/swaps/SwapHandlerSwap.d.ts +75 -0
  35. package/dist/swaps/SwapHandlerSwap.js +72 -0
  36. package/dist/swaps/ToBtcBaseSwap.d.ts +35 -0
  37. package/dist/swaps/ToBtcBaseSwap.js +61 -0
  38. package/dist/swaps/ToBtcBaseSwapHandler.d.ts +94 -0
  39. package/dist/swaps/ToBtcBaseSwapHandler.js +233 -0
  40. package/dist/swaps/frombtc_abstract/FromBtcAbs.d.ts +92 -0
  41. package/dist/swaps/frombtc_abstract/FromBtcAbs.js +386 -0
  42. package/dist/swaps/frombtc_abstract/FromBtcSwapAbs.d.ts +26 -0
  43. package/dist/swaps/frombtc_abstract/FromBtcSwapAbs.js +63 -0
  44. package/dist/swaps/frombtc_trusted/FromBtcTrusted.d.ts +55 -0
  45. package/dist/swaps/frombtc_trusted/FromBtcTrusted.js +586 -0
  46. package/dist/swaps/frombtc_trusted/FromBtcTrustedSwap.d.ts +43 -0
  47. package/dist/swaps/frombtc_trusted/FromBtcTrustedSwap.js +99 -0
  48. package/dist/swaps/frombtcln_abstract/FromBtcLnAbs.d.ts +105 -0
  49. package/dist/swaps/frombtcln_abstract/FromBtcLnAbs.js +731 -0
  50. package/dist/swaps/frombtcln_abstract/FromBtcLnSwapAbs.d.ts +29 -0
  51. package/dist/swaps/frombtcln_abstract/FromBtcLnSwapAbs.js +64 -0
  52. package/dist/swaps/frombtcln_trusted/FromBtcLnTrusted.d.ts +79 -0
  53. package/dist/swaps/frombtcln_trusted/FromBtcLnTrusted.js +514 -0
  54. package/dist/swaps/frombtcln_trusted/FromBtcLnTrustedSwap.d.ts +28 -0
  55. package/dist/swaps/frombtcln_trusted/FromBtcLnTrustedSwap.js +66 -0
  56. package/dist/swaps/tobtc_abstract/ToBtcAbs.d.ts +290 -0
  57. package/dist/swaps/tobtc_abstract/ToBtcAbs.js +1056 -0
  58. package/dist/swaps/tobtc_abstract/ToBtcSwapAbs.d.ts +29 -0
  59. package/dist/swaps/tobtc_abstract/ToBtcSwapAbs.js +70 -0
  60. package/dist/swaps/tobtcln_abstract/ToBtcLnAbs.d.ts +246 -0
  61. package/dist/swaps/tobtcln_abstract/ToBtcLnAbs.js +1169 -0
  62. package/dist/swaps/tobtcln_abstract/ToBtcLnSwapAbs.d.ts +27 -0
  63. package/dist/swaps/tobtcln_abstract/ToBtcLnSwapAbs.js +65 -0
  64. package/dist/utils/Utils.d.ts +32 -0
  65. package/dist/utils/Utils.js +109 -0
  66. package/dist/utils/coinselect2/accumulative.d.ts +6 -0
  67. package/dist/utils/coinselect2/accumulative.js +44 -0
  68. package/dist/utils/coinselect2/blackjack.d.ts +6 -0
  69. package/dist/utils/coinselect2/blackjack.js +41 -0
  70. package/dist/utils/coinselect2/index.d.ts +16 -0
  71. package/dist/utils/coinselect2/index.js +40 -0
  72. package/dist/utils/coinselect2/utils.d.ts +64 -0
  73. package/dist/utils/coinselect2/utils.js +121 -0
  74. package/dist/utils/paramcoders/IParamReader.d.ts +5 -0
  75. package/dist/utils/paramcoders/IParamReader.js +2 -0
  76. package/dist/utils/paramcoders/IParamWriter.d.ts +4 -0
  77. package/dist/utils/paramcoders/IParamWriter.js +2 -0
  78. package/dist/utils/paramcoders/LegacyParamEncoder.d.ts +10 -0
  79. package/dist/utils/paramcoders/LegacyParamEncoder.js +33 -0
  80. package/dist/utils/paramcoders/ParamDecoder.d.ts +25 -0
  81. package/dist/utils/paramcoders/ParamDecoder.js +234 -0
  82. package/dist/utils/paramcoders/ParamEncoder.d.ts +9 -0
  83. package/dist/utils/paramcoders/ParamEncoder.js +22 -0
  84. package/dist/utils/paramcoders/SchemaVerifier.d.ts +22 -0
  85. package/dist/utils/paramcoders/SchemaVerifier.js +85 -0
  86. package/dist/utils/paramcoders/server/ServerParamDecoder.d.ts +8 -0
  87. package/dist/utils/paramcoders/server/ServerParamDecoder.js +105 -0
  88. package/dist/utils/paramcoders/server/ServerParamEncoder.d.ts +11 -0
  89. package/dist/utils/paramcoders/server/ServerParamEncoder.js +76 -0
  90. package/package.json +43 -0
  91. package/src/fees/IBtcFeeEstimator.ts +7 -0
  92. package/src/fees/OneDollarFeeEstimator.ts +95 -0
  93. package/src/index.ts +46 -0
  94. package/src/info/InfoHandler.ts +106 -0
  95. package/src/plugins/IPlugin.ts +155 -0
  96. package/src/plugins/PluginManager.ts +310 -0
  97. package/src/prices/BinanceSwapPrice.ts +114 -0
  98. package/src/prices/CoinGeckoSwapPrice.ts +88 -0
  99. package/src/storage/IIntermediaryStorage.ts +21 -0
  100. package/src/storagemanager/IntermediaryStorageManager.ts +101 -0
  101. package/src/storagemanager/StorageManager.ts +68 -0
  102. package/src/swaps/FromBtcBaseSwap.ts +21 -0
  103. package/src/swaps/FromBtcBaseSwapHandler.ts +375 -0
  104. package/src/swaps/FromBtcLnBaseSwapHandler.ts +48 -0
  105. package/src/swaps/ISwapPrice.ts +94 -0
  106. package/src/swaps/SwapHandler.ts +404 -0
  107. package/src/swaps/SwapHandlerSwap.ts +133 -0
  108. package/src/swaps/ToBtcBaseSwap.ts +76 -0
  109. package/src/swaps/ToBtcBaseSwapHandler.ts +309 -0
  110. package/src/swaps/frombtc_abstract/FromBtcAbs.ts +484 -0
  111. package/src/swaps/frombtc_abstract/FromBtcSwapAbs.ts +77 -0
  112. package/src/swaps/frombtc_trusted/FromBtcTrusted.ts +661 -0
  113. package/src/swaps/frombtc_trusted/FromBtcTrustedSwap.ts +158 -0
  114. package/src/swaps/frombtcln_abstract/FromBtcLnAbs.ts +864 -0
  115. package/src/swaps/frombtcln_abstract/FromBtcLnSwapAbs.ts +82 -0
  116. package/src/swaps/frombtcln_trusted/FromBtcLnTrusted.ts +592 -0
  117. package/src/swaps/frombtcln_trusted/FromBtcLnTrustedSwap.ts +90 -0
  118. package/src/swaps/tobtc_abstract/ToBtcAbs.ts +1249 -0
  119. package/src/swaps/tobtc_abstract/ToBtcSwapAbs.ts +112 -0
  120. package/src/swaps/tobtcln_abstract/ToBtcLnAbs.ts +1422 -0
  121. package/src/swaps/tobtcln_abstract/ToBtcLnSwapAbs.ts +87 -0
  122. package/src/utils/Utils.ts +108 -0
  123. package/src/utils/coinselect2/accumulative.js +32 -0
  124. package/src/utils/coinselect2/accumulative.ts +58 -0
  125. package/src/utils/coinselect2/blackjack.js +29 -0
  126. package/src/utils/coinselect2/blackjack.ts +54 -0
  127. package/src/utils/coinselect2/index.js +16 -0
  128. package/src/utils/coinselect2/index.ts +50 -0
  129. package/src/utils/coinselect2/utils.js +110 -0
  130. package/src/utils/coinselect2/utils.ts +183 -0
  131. package/src/utils/paramcoders/IParamReader.ts +8 -0
  132. package/src/utils/paramcoders/IParamWriter.ts +8 -0
  133. package/src/utils/paramcoders/LegacyParamEncoder.ts +28 -0
  134. package/src/utils/paramcoders/ParamDecoder.ts +219 -0
  135. package/src/utils/paramcoders/ParamEncoder.ts +30 -0
  136. package/src/utils/paramcoders/SchemaVerifier.ts +97 -0
  137. package/src/utils/paramcoders/server/ServerParamDecoder.ts +115 -0
  138. package/src/utils/paramcoders/server/ServerParamEncoder.ts +76 -0
@@ -0,0 +1,404 @@
1
+ import {Express, Request, Response} from "express";
2
+ import {ISwapPrice} from "./ISwapPrice";
3
+ import {
4
+ AbstractSigner,
5
+ ChainType,
6
+ ClaimEvent,
7
+ InitializeEvent, RefundEvent,
8
+ SwapContract,
9
+ SwapData,
10
+ SwapEvent
11
+ } from "@atomiqlabs/base";
12
+ import {AuthenticatedLnd} from "lightning";
13
+ import {SwapHandlerSwap} from "./SwapHandlerSwap";
14
+ import {PluginManager} from "../plugins/PluginManager";
15
+ import {IIntermediaryStorage} from "../storage/IIntermediaryStorage";
16
+ import * as BN from "bn.js";
17
+ import {ServerParamEncoder} from "../utils/paramcoders/server/ServerParamEncoder";
18
+ import {
19
+ isQuoteAmountTooHigh,
20
+ isQuoteAmountTooLow,
21
+ isQuoteThrow,
22
+ } from "../plugins/IPlugin";
23
+ import {IParamReader} from "../utils/paramcoders/IParamReader";
24
+
25
+ export enum SwapHandlerType {
26
+ TO_BTC = "TO_BTC",
27
+ FROM_BTC = "FROM_BTC",
28
+ TO_BTCLN = "TO_BTCLN",
29
+ FROM_BTCLN = "FROM_BTCLN",
30
+ FROM_BTCLN_TRUSTED = "FROM_BTCLN_TRUSTED",
31
+ FROM_BTC_TRUSTED = "FROM_BTC_TRUSTED",
32
+ }
33
+
34
+ export type SwapHandlerInfoType = {
35
+ swapFeePPM: number,
36
+ swapBaseFee: number,
37
+ min: number,
38
+ max: number,
39
+ tokens: string[],
40
+ chainTokens: {[chainId: string]: string[]};
41
+ data?: any,
42
+ };
43
+
44
+ export type SwapBaseConfig = {
45
+ authorizationTimeout: number,
46
+ bitcoinBlocktime: BN,
47
+ baseFee: BN,
48
+ feePPM: BN,
49
+ max: BN,
50
+ min: BN,
51
+ maxSkew: number,
52
+ safetyFactor: BN,
53
+ swapCheckInterval: number
54
+ };
55
+
56
+ export type MultichainData = {
57
+ chains: {
58
+ [identifier: string]: ChainData
59
+ },
60
+ default: string
61
+ };
62
+
63
+ export type ChainData<T extends ChainType = ChainType> = {
64
+ signer: T["Signer"],
65
+ swapContract: T["Contract"],
66
+ chainEvents: T["Events"],
67
+ allowedTokens: string[],
68
+ btcRelay?: T["BtcRelay"]
69
+ }
70
+
71
+ export type RequestData<T> = {
72
+ chainIdentifier: string,
73
+ raw: Request & {paramReader: IParamReader},
74
+ parsed: T,
75
+ metadata: any
76
+ };
77
+
78
+ /**
79
+ * An abstract class defining a singular swap service
80
+ */
81
+ export abstract class SwapHandler<V extends SwapHandlerSwap<SwapData, S> = SwapHandlerSwap, S = any> {
82
+
83
+ abstract readonly type: SwapHandlerType;
84
+
85
+ readonly storageManager: IIntermediaryStorage<V>;
86
+ readonly path: string;
87
+
88
+ readonly chains: MultichainData;
89
+ readonly allowedTokens: {[chainId: string]: Set<string>};
90
+ readonly swapPricing: ISwapPrice;
91
+ readonly LND: AuthenticatedLnd;
92
+
93
+ abstract config: SwapBaseConfig;
94
+
95
+ logger = {
96
+ debug: (msg: string, ...args: any) => console.debug("SwapHandler("+this.type+"): "+msg, ...args),
97
+ info: (msg: string, ...args: any) => console.info("SwapHandler("+this.type+"): "+msg, ...args),
98
+ warn: (msg: string, ...args: any) => console.warn("SwapHandler("+this.type+"): "+msg, ...args),
99
+ error: (msg: string, ...args: any) => console.error("SwapHandler("+this.type+"): "+msg, ...args)
100
+ };
101
+
102
+ protected swapLogger = {
103
+ debug: (swap: SwapHandlerSwap | SwapEvent<SwapData> | SwapData, msg: string, ...args: any) => this.logger.debug(this.getIdentifier(swap)+": "+msg, ...args),
104
+ info: (swap: SwapHandlerSwap | SwapEvent<SwapData> | SwapData, msg: string, ...args: any) => this.logger.info(this.getIdentifier(swap)+": "+msg, ...args),
105
+ warn: (swap: SwapHandlerSwap | SwapEvent<SwapData> | SwapData, msg: string, ...args: any) => this.logger.warn(this.getIdentifier(swap)+": "+msg, ...args),
106
+ error: (swap: SwapHandlerSwap | SwapEvent<SwapData> | SwapData, msg: string, ...args: any) => this.logger.error(this.getIdentifier(swap)+": "+msg, ...args)
107
+ };
108
+
109
+ protected constructor(
110
+ storageDirectory: IIntermediaryStorage<V>,
111
+ path: string,
112
+ chainsData: MultichainData,
113
+ lnd: AuthenticatedLnd,
114
+ swapPricing: ISwapPrice
115
+ ) {
116
+ this.storageManager = storageDirectory;
117
+ this.chains = chainsData;
118
+ if(this.chains.chains[this.chains.default]==null) throw new Error("Invalid default chain specified");
119
+ this.path = path;
120
+ this.LND = lnd;
121
+ this.swapPricing = swapPricing;
122
+ this.allowedTokens = {};
123
+ for(let chainId in chainsData.chains) {
124
+ this.allowedTokens[chainId] = new Set<string>(chainsData.chains[chainId].allowedTokens);
125
+ }
126
+ }
127
+
128
+ protected getDefaultChain(): ChainData {
129
+ return this.chains.chains[this.chains.default];
130
+ }
131
+
132
+ protected getChain(identifier: string): ChainData {
133
+ if(this.chains.chains[identifier]==null)
134
+ throw {
135
+ code: 20200,
136
+ msg: "Invalid chain specified!"
137
+ };
138
+ return this.chains.chains[identifier];
139
+ }
140
+
141
+ protected abstract processPastSwaps(): Promise<void>;
142
+
143
+ /**
144
+ * Starts the watchdog checking past swaps for expiry or claim eligibility.
145
+ */
146
+ async startWatchdog() {
147
+ let rerun: () => Promise<void>;
148
+ rerun = async () => {
149
+ await this.processPastSwaps().catch( e => console.error(e));
150
+ setTimeout(rerun, this.config.swapCheckInterval);
151
+ };
152
+ await rerun();
153
+ }
154
+
155
+ protected abstract processInitializeEvent(chainIdentifier: string, event: InitializeEvent<SwapData>): Promise<void>;
156
+ protected abstract processClaimEvent(chainIdentifier: string, event: ClaimEvent<SwapData>): Promise<void>;
157
+ protected abstract processRefundEvent(chainIdentifier: string, event: RefundEvent<SwapData>): Promise<void>;
158
+
159
+ /**
160
+ * Chain event processor
161
+ *
162
+ * @param chainIdentifier
163
+ * @param eventData
164
+ */
165
+ protected async processEvent(chainIdentifier: string, eventData: SwapEvent<SwapData>[]): Promise<boolean> {
166
+ for(let event of eventData) {
167
+ if(event instanceof InitializeEvent) {
168
+ // this.swapLogger.debug(event, "SC: InitializeEvent: swap type: "+event.swapType);
169
+ await this.processInitializeEvent(chainIdentifier, event);
170
+ } else if(event instanceof ClaimEvent) {
171
+ // this.swapLogger.debug(event, "SC: ClaimEvent: swap secret: "+event.secret);
172
+ await this.processClaimEvent(chainIdentifier, event);
173
+ } else if(event instanceof RefundEvent) {
174
+ // this.swapLogger.debug(event, "SC: RefundEvent");
175
+ await this.processRefundEvent(chainIdentifier, event);
176
+ }
177
+ }
178
+
179
+ return true;
180
+ }
181
+
182
+ /**
183
+ * Initializes chain events subscription
184
+ */
185
+ protected subscribeToEvents() {
186
+ for(let key in this.chains.chains) {
187
+ this.chains.chains[key].chainEvents.registerListener((events: SwapEvent<SwapData>[]) => this.processEvent(key, events));
188
+ }
189
+ this.logger.info("SC: Events: subscribed to smartchain events");
190
+ }
191
+
192
+ /**
193
+ * Initializes swap handler, loads data and subscribes to chain events
194
+ */
195
+ abstract init(): Promise<void>;
196
+
197
+ /**
198
+ * Sets up required listeners for the REST server
199
+ *
200
+ * @param restServer
201
+ */
202
+ abstract startRestServer(restServer: Express): void;
203
+
204
+ /**
205
+ * Returns data to be returned in swap handler info
206
+ */
207
+ abstract getInfoData(): any;
208
+
209
+ /**
210
+ * Remove swap data
211
+ *
212
+ * @param hash
213
+ * @param sequence
214
+ */
215
+ protected removeSwapData(hash: string, sequence: BN): Promise<void>;
216
+
217
+ /**
218
+ * Remove swap data
219
+ *
220
+ * @param swap
221
+ * @param ultimateState set the ultimate state of the swap before removing
222
+ */
223
+ protected removeSwapData(swap: V, ultimateState?: S): Promise<void>;
224
+
225
+ protected async removeSwapData(hashOrSwap: string | V, sequenceOrUltimateState?: BN | S) {
226
+ let swap: V;
227
+ if(typeof(hashOrSwap)==="string") {
228
+ if(!BN.isBN(sequenceOrUltimateState)) throw new Error("Sequence must be a BN instance!");
229
+ swap = await this.storageManager.getData(hashOrSwap, sequenceOrUltimateState);
230
+ } else {
231
+ swap = hashOrSwap;
232
+ if(sequenceOrUltimateState!=null && !BN.isBN(sequenceOrUltimateState)) await swap.setState(sequenceOrUltimateState);
233
+ }
234
+ if(swap!=null) await PluginManager.swapRemove(swap);
235
+ this.swapLogger.debug(swap, "removeSwapData(): removing swap final state: "+swap.state);
236
+ await this.storageManager.removeData(swap.getHash(), swap.getSequence());
237
+ }
238
+
239
+ /**
240
+ * Checks whether the bitcoin amount is within specified min/max bounds
241
+ *
242
+ * @param amount
243
+ * @protected
244
+ * @throws {DefinedRuntimeError} will throw an error if the amount is outside minimum/maximum bounds
245
+ */
246
+ protected checkBtcAmountInBounds(amount: BN): void {
247
+ if (amount.lt(this.config.min)) {
248
+ throw {
249
+ code: 20003,
250
+ msg: "Amount too low!",
251
+ data: {
252
+ min: this.config.min.toString(10),
253
+ max: this.config.max.toString(10)
254
+ }
255
+ };
256
+ }
257
+
258
+ if(amount.gt(this.config.max)) {
259
+ throw {
260
+ code: 20004,
261
+ msg: "Amount too high!",
262
+ data: {
263
+ min: this.config.min.toString(10),
264
+ max: this.config.max.toString(10)
265
+ }
266
+ };
267
+ }
268
+ }
269
+
270
+ /**
271
+ * Handles and throws plugin errors
272
+ *
273
+ * @param res Response as returned from the PluginManager.onHandlePost{To,From}BtcQuote
274
+ * @protected
275
+ * @throws {DefinedRuntimeError} will throw an error if the response is an error
276
+ */
277
+ protected handlePluginErrorResponses(res: any): void {
278
+ if(isQuoteThrow(res)) throw {
279
+ code: 29999,
280
+ msg: res.message
281
+ };
282
+ if(isQuoteAmountTooHigh(res)) throw {
283
+ code: 20004,
284
+ msg: "Amount too high!",
285
+ data: {
286
+ min: res.data.min.toString(10),
287
+ max: res.data.max.toString(10)
288
+ }
289
+ };
290
+ if(isQuoteAmountTooLow(res)) throw {
291
+ code: 20003,
292
+ msg: "Amount too low!",
293
+ data: {
294
+ min: res.data.min.toString(10),
295
+ max: res.data.max.toString(10)
296
+ }
297
+ };
298
+ }
299
+
300
+ /**
301
+ * Creates an abort controller that extends the responseStream's abort signal
302
+ *
303
+ * @param responseStream
304
+ */
305
+ protected getAbortController(responseStream: ServerParamEncoder): AbortController {
306
+ const abortController = new AbortController();
307
+ const responseStreamAbortController = responseStream.getAbortSignal();
308
+ responseStreamAbortController.addEventListener("abort", () => abortController.abort(responseStreamAbortController.reason));
309
+ return abortController;
310
+ }
311
+
312
+ /**
313
+ * Starts a pre-fetch for signature data
314
+ *
315
+ * @param chainIdentifier
316
+ * @param abortController
317
+ * @param responseStream
318
+ */
319
+ protected getSignDataPrefetch(chainIdentifier: string, abortController: AbortController, responseStream?: ServerParamEncoder): Promise<any> {
320
+ const {swapContract} = this.getChain(chainIdentifier);
321
+ let signDataPrefetchPromise: Promise<any> = swapContract.preFetchBlockDataForSignatures!=null ? swapContract.preFetchBlockDataForSignatures().catch(e => {
322
+ this.logger.error("getSignDataPrefetch(): signDataPrefetch: ", e);
323
+ abortController.abort(e);
324
+ return null;
325
+ }) : null;
326
+
327
+ if(signDataPrefetchPromise!=null && responseStream!=null) {
328
+ signDataPrefetchPromise = signDataPrefetchPromise.then(val => val==null || abortController.signal.aborted ? null : responseStream.writeParams({
329
+ signDataPrefetch: val
330
+ }).then(() => val).catch(e => {
331
+ this.logger.error("getSignDataPrefetch(): signDataPreFetch: error when sending sign data to the client: ", e);
332
+ abortController.abort(e);
333
+ return null;
334
+ }));
335
+ }
336
+
337
+ return signDataPrefetchPromise;
338
+ }
339
+
340
+ protected getIdentifierFromEvent(event: SwapEvent<SwapData>): string {
341
+ if(event.sequence.isZero()) return event.paymentHash;
342
+ return event.paymentHash+"_"+event.sequence.toString(16);
343
+ }
344
+
345
+ protected getIdentifierFromSwapData(swapData: SwapData): string {
346
+ if(swapData.getSequence().isZero()) return swapData.getHash();
347
+ return swapData.getHash()+"_"+swapData.getSequence().toString(16);
348
+ }
349
+
350
+ protected getIdentifier(swap: SwapHandlerSwap | SwapEvent<SwapData> | SwapData) {
351
+ if(swap instanceof SwapHandlerSwap) {
352
+ return swap.getIdentifier();
353
+ }
354
+ if(swap instanceof SwapEvent) {
355
+ return this.getIdentifierFromEvent(swap);
356
+ }
357
+ return this.getIdentifierFromSwapData(swap);
358
+ }
359
+
360
+ /**
361
+ * Checks if the sequence number is between 0-2^64
362
+ *
363
+ * @param sequence
364
+ * @throws {DefinedRuntimeError} will throw an error if sequence number is out of bounds
365
+ */
366
+ protected checkSequence(sequence: BN) {
367
+ if(sequence.isNeg() || sequence.gte(new BN(2).pow(new BN(64)))) {
368
+ throw {
369
+ code: 20060,
370
+ msg: "Invalid sequence"
371
+ };
372
+ }
373
+ }
374
+
375
+ /**
376
+ * Checks whether a given token is supported on a specified chain
377
+ *
378
+ * @param chainId
379
+ * @param token
380
+ * @protected
381
+ */
382
+ protected isTokenSupported(chainId: string, token: string): boolean {
383
+ const chainTokens = this.allowedTokens[chainId];
384
+ if(chainTokens==null) return false;
385
+ return chainTokens.has(token);
386
+ }
387
+
388
+ getInfo(): SwapHandlerInfoType {
389
+ const chainTokens: {[chainId: string]: string[]} = {};
390
+ for(let chainId in this.allowedTokens) {
391
+ chainTokens[chainId] = Array.from<string>(this.allowedTokens[chainId]);
392
+ }
393
+ return {
394
+ swapFeePPM: this.config.feePPM.toNumber(),
395
+ swapBaseFee: this.config.baseFee.toNumber(),
396
+ min: this.config.min.toNumber(),
397
+ max: this.config.max.toNumber(),
398
+ data: this.getInfoData(),
399
+ tokens: Array.from<string>(this.allowedTokens[this.chains.default]),
400
+ chainTokens
401
+ };
402
+ }
403
+
404
+ }
@@ -0,0 +1,133 @@
1
+ import {Lockable, StorageObject, SwapData} from "@atomiqlabs/base";
2
+ import {SwapHandlerType} from "./SwapHandler";
3
+ import {PluginManager} from "../plugins/PluginManager";
4
+ import * as BN from "bn.js";
5
+ import {deserializeBN, serializeBN} from "../utils/Utils";
6
+
7
+ export abstract class SwapHandlerSwap<T extends SwapData = SwapData, S = any> extends Lockable implements StorageObject {
8
+
9
+ chainIdentifier: string;
10
+ state: S;
11
+
12
+ type: SwapHandlerType;
13
+ data: T;
14
+ metadata: {
15
+ request: any,
16
+ times: {[key: string]: number},
17
+ [key: string]: any
18
+ };
19
+ txIds: {
20
+ init?: string,
21
+ claim?: string,
22
+ refund?: string
23
+ } = {};
24
+ readonly swapFee: BN;
25
+ readonly swapFeeInToken: BN;
26
+
27
+ protected constructor(chainIdentifier: string, swapFee: BN, swapFeeInToken: BN);
28
+ protected constructor(obj: any);
29
+
30
+ protected constructor(obj?: any | string, swapFee?: BN, swapFeeInToken?: BN) {
31
+ super();
32
+ if(typeof(obj)==="string" && BN.isBN(swapFee) && BN.isBN(swapFeeInToken)) {
33
+ this.chainIdentifier = obj;
34
+ this.swapFee = swapFee;
35
+ this.swapFeeInToken = swapFeeInToken;
36
+ return;
37
+ } else {
38
+ this.data = obj.data==null ? null : SwapData.deserialize(obj.data);
39
+ this.metadata = obj.metadata;
40
+ this.chainIdentifier = obj.chainIdentifier;
41
+ this.txIds = obj.txIds || {};
42
+ this.state = obj.state;
43
+ this.swapFee = deserializeBN(obj.swapFee);
44
+ this.swapFeeInToken = deserializeBN(obj.swapFeeInToken);
45
+ }
46
+ }
47
+
48
+ serialize(): any {
49
+ return {
50
+ state: this.state,
51
+ data: this.data==null ? null : this.data.serialize(),
52
+ chainIdentifier: this.chainIdentifier,
53
+ metadata: this.metadata,
54
+ txIds: this.txIds,
55
+ swapFee: serializeBN(this.swapFee),
56
+ swapFeeInToken: serializeBN(this.swapFeeInToken)
57
+ }
58
+ }
59
+
60
+ /**
61
+ * Sets the state of the swap and also calls swap change listener on plugins
62
+ *
63
+ * @param newState
64
+ */
65
+ setState(newState: S): Promise<void> {
66
+ const oldState = this.state;
67
+ this.state = newState;
68
+ return PluginManager.swapStateChange(this, oldState);
69
+ }
70
+
71
+ getHash(): string {
72
+ return this.data.getHash();
73
+ }
74
+
75
+ getSequence(): BN {
76
+ return this.data.getSequence();
77
+ }
78
+
79
+ /**
80
+ * Returns unique identifier of the swap in the form <hash>_<sequence> or just <hash> if the swap type doesn't
81
+ * use sequence number
82
+ */
83
+ getIdentifier(): string {
84
+ if(this.getSequence()!=null) {
85
+ return this.chainIdentifier+"_"+this.getHash()+"_"+this.getSequence().toString(16);
86
+ }
87
+ return this.getHash();
88
+ }
89
+
90
+ /**
91
+ * Checks whether the swap is finished, such that it is final and either successful or failed
92
+ */
93
+ isFinished(): boolean {
94
+ return this.isSuccess() || this.isFailed();
95
+ }
96
+
97
+ /**
98
+ * Checks whether the swap was initiated by the user
99
+ */
100
+ abstract isInitiated(): boolean;
101
+
102
+ /**
103
+ * Checks whether the swap was finished and was successful
104
+ */
105
+ abstract isSuccess(): boolean;
106
+
107
+ /**
108
+ * Checks whether the swap was finished and was failed
109
+ */
110
+ abstract isFailed(): boolean;
111
+
112
+ /**
113
+ * Returns the input amount paid by the user (excluding fees)
114
+ */
115
+ abstract getInputAmount(): BN;
116
+
117
+ /**
118
+ * Returns the total input amount paid by the user (including all fees)
119
+ */
120
+ abstract getTotalInputAmount(): BN;
121
+
122
+ /**
123
+ * Returns the actual output amount paid out to the user
124
+ */
125
+ abstract getOutputAmount(): BN;
126
+
127
+ /**
128
+ * Returns swap fee, denominated in input & output tokens (the fee is paid only once, it is just represented here in
129
+ * both denomination for ease of use)
130
+ */
131
+ abstract getSwapFee(): {inInputToken: BN, inOutputToken: BN};
132
+
133
+ }
@@ -0,0 +1,76 @@
1
+ import {SwapHandlerSwap} from "./SwapHandlerSwap";
2
+ import {SwapData} from "@atomiqlabs/base";
3
+ import * as BN from "bn.js";
4
+ import {deserializeBN, serializeBN} from "../utils/Utils";
5
+
6
+
7
+ export abstract class ToBtcBaseSwap<T extends SwapData = SwapData, S = any> extends SwapHandlerSwap<T, S> {
8
+
9
+ quotedNetworkFee: BN;
10
+ readonly quotedNetworkFeeInToken: BN;
11
+ realNetworkFee: BN;
12
+ realNetworkFeeInToken: BN;
13
+
14
+ protected constructor(chainIdentifier: string, swapFee: BN, swapFeeInToken: BN, quotedNetworkFee: BN, quotedNetworkFeeInToken: BN);
15
+ protected constructor(obj: any);
16
+
17
+ protected constructor(obj?: any | string, swapFee?: BN, swapFeeInToken?: BN, quotedNetworkFee?: BN, quotedNetworkFeeInToken?: BN) {
18
+ if(typeof(obj)==="string" && BN.isBN(swapFee) && BN.isBN(swapFeeInToken) && BN.isBN(quotedNetworkFee) && BN.isBN(quotedNetworkFeeInToken)) {
19
+ super(obj, swapFee, swapFeeInToken);
20
+ this.quotedNetworkFee = quotedNetworkFee;
21
+ this.quotedNetworkFeeInToken = quotedNetworkFeeInToken;
22
+ return;
23
+ } else {
24
+ super(obj);
25
+ this.quotedNetworkFee = deserializeBN(obj.quotedNetworkFee);
26
+ this.quotedNetworkFeeInToken = deserializeBN(obj.quotedNetworkFeeInToken);
27
+ this.realNetworkFee = deserializeBN(obj.realNetworkFee);
28
+ this.realNetworkFeeInToken = deserializeBN(obj.realNetworkFeeInToken);
29
+ }
30
+ }
31
+
32
+ serialize(): any {
33
+ const obj = super.serialize();
34
+ obj.quotedNetworkFee = serializeBN(this.quotedNetworkFee);
35
+ obj.quotedNetworkFeeInToken = serializeBN(this.quotedNetworkFeeInToken);
36
+ obj.realNetworkFee = serializeBN(this.realNetworkFee);
37
+ obj.realNetworkFeeInToken = serializeBN(this.realNetworkFeeInToken);
38
+ return obj;
39
+ }
40
+
41
+ setRealNetworkFee(networkFeeInBtc: BN) {
42
+ this.realNetworkFee = networkFeeInBtc;
43
+ if(this.quotedNetworkFee!=null && this.quotedNetworkFeeInToken!=null) {
44
+ this.realNetworkFeeInToken = this.realNetworkFee.mul(this.quotedNetworkFeeInToken).div(this.quotedNetworkFee);
45
+ }
46
+ }
47
+
48
+ getInputAmount(): BN {
49
+ return this.data.getAmount().sub(this.getSwapFee().inInputToken).sub(this.getQuotedNetworkFee().inInputToken);
50
+ }
51
+
52
+ getTotalInputAmount(): BN {
53
+ return this.data.getAmount();
54
+ }
55
+
56
+ getSwapFee(): { inInputToken: BN; inOutputToken: BN } {
57
+ return {inInputToken: this.swapFeeInToken, inOutputToken: this.swapFee};
58
+ }
59
+
60
+ /**
61
+ * Returns quoted (expected) network fee, denominated in input & output tokens (the fee is paid only once, it is
62
+ * just represented here in both denomination for ease of use)
63
+ */
64
+ getQuotedNetworkFee(): { inInputToken: BN; inOutputToken: BN } {
65
+ return {inInputToken: this.quotedNetworkFeeInToken, inOutputToken: this.quotedNetworkFee};
66
+ }
67
+
68
+ /**
69
+ * Returns real network fee paid for the swap, denominated in input & output tokens (the fee is paid only once, it is
70
+ * just represented here in both denomination for ease of use)
71
+ */
72
+ getRealNetworkFee(): { inInputToken: BN; inOutputToken: BN } {
73
+ return {inInputToken: this.realNetworkFeeInToken, inOutputToken: this.realNetworkFee};
74
+ }
75
+
76
+ }