@atomiqlabs/sdk 8.6.0 → 8.6.3

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 (61) hide show
  1. package/dist/http/paramcoders/ParamDecoder.js +9 -4
  2. package/dist/http/paramcoders/ParamEncoder.js +6 -1
  3. package/dist/intermediaries/IntermediaryDiscovery.js +4 -3
  4. package/dist/storage/UnifiedSwapStorage.js +13 -8
  5. package/dist/swapper/Swapper.d.ts +1 -12
  6. package/dist/swapper/Swapper.js +31 -28
  7. package/dist/swapper/SwapperFactory.d.ts +1 -0
  8. package/dist/swapper/SwapperFactory.js +9 -4
  9. package/dist/swaps/ISwap.d.ts +8 -0
  10. package/dist/swaps/ISwap.js +8 -0
  11. package/dist/swaps/ISwapWrapper.d.ts +23 -1
  12. package/dist/swaps/ISwapWrapper.js +88 -28
  13. package/dist/swaps/escrow_swaps/IEscrowSwapWrapper.js +4 -1
  14. package/dist/swaps/escrow_swaps/frombtc/IFromBTCSelfInitSwap.d.ts +2 -2
  15. package/dist/swaps/escrow_swaps/frombtc/IFromBTCSelfInitSwap.js +1 -1
  16. package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.d.ts +2 -2
  17. package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.js +16 -6
  18. package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.js +8 -2
  19. package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.d.ts +1 -1
  20. package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.js +14 -4
  21. package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.js +8 -6
  22. package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.d.ts +2 -1
  23. package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.js +7 -5
  24. package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.js +8 -2
  25. package/dist/swaps/escrow_swaps/tobtc/IToBTCSwap.js +1 -1
  26. package/dist/swaps/escrow_swaps/tobtc/IToBTCWrapper.js +0 -6
  27. package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.js +8 -3
  28. package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.js +8 -2
  29. package/dist/swaps/spv_swaps/SpvFromBTCSwap.d.ts +1 -0
  30. package/dist/swaps/spv_swaps/SpvFromBTCSwap.js +3 -2
  31. package/dist/swaps/spv_swaps/SpvFromBTCWrapper.js +1 -3
  32. package/dist/swaps/trusted/ln/LnForGasWrapper.js +0 -1
  33. package/dist/swaps/trusted/onchain/OnchainForGasWrapper.js +0 -1
  34. package/dist/utils/RetryUtils.d.ts +2 -1
  35. package/dist/utils/RetryUtils.js +3 -2
  36. package/package.json +1 -1
  37. package/src/http/paramcoders/ParamDecoder.ts +8 -4
  38. package/src/http/paramcoders/ParamEncoder.ts +5 -1
  39. package/src/intermediaries/IntermediaryDiscovery.ts +6 -4
  40. package/src/storage/UnifiedSwapStorage.ts +13 -8
  41. package/src/swapper/Swapper.ts +35 -28
  42. package/src/swapper/SwapperFactory.ts +12 -6
  43. package/src/swaps/ISwap.ts +8 -0
  44. package/src/swaps/ISwapWrapper.ts +104 -28
  45. package/src/swaps/escrow_swaps/IEscrowSwapWrapper.ts +5 -1
  46. package/src/swaps/escrow_swaps/frombtc/IFromBTCSelfInitSwap.ts +3 -3
  47. package/src/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.ts +17 -8
  48. package/src/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.ts +8 -3
  49. package/src/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.ts +13 -5
  50. package/src/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.ts +8 -7
  51. package/src/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.ts +9 -5
  52. package/src/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.ts +7 -2
  53. package/src/swaps/escrow_swaps/tobtc/IToBTCSwap.ts +1 -1
  54. package/src/swaps/escrow_swaps/tobtc/IToBTCWrapper.ts +0 -3
  55. package/src/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.ts +7 -3
  56. package/src/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.ts +7 -2
  57. package/src/swaps/spv_swaps/SpvFromBTCSwap.ts +5 -2
  58. package/src/swaps/spv_swaps/SpvFromBTCWrapper.ts +1 -3
  59. package/src/swaps/trusted/ln/LnForGasWrapper.ts +0 -1
  60. package/src/swaps/trusted/onchain/OnchainForGasWrapper.ts +0 -1
  61. package/src/utils/RetryUtils.ts +11 -4
@@ -1,11 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ISwapWrapper = void 0;
3
+ exports.ISwapWrapper = exports.DEFAULT_MAX_PARALLEL_SWAP_SYNCS = exports.DEFAULT_MAX_PARALLEL_SWAP_TICKS = void 0;
4
4
  const events_1 = require("events");
5
5
  const IntermediaryError_1 = require("../errors/IntermediaryError");
6
6
  const Logger_1 = require("../utils/Logger");
7
7
  const TokenUtils_1 = require("../utils/TokenUtils");
8
8
  const UserError_1 = require("../errors/UserError");
9
+ exports.DEFAULT_MAX_PARALLEL_SWAP_TICKS = 50;
10
+ exports.DEFAULT_MAX_PARALLEL_SWAP_SYNCS = 50;
9
11
  /**
10
12
  * Base abstract class for swap handler implementations
11
13
  *
@@ -29,6 +31,10 @@ class ISwapWrapper {
29
31
  * @internal
30
32
  */
31
33
  this.isInitialized = false;
34
+ if (options?.maxParallelSwapTicks != null && options.maxParallelSwapTicks < 1)
35
+ throw new Error("maxParallelSwapTicks must be at least 1!");
36
+ if (options?.maxParallelSwapSyncs != null && options.maxParallelSwapSyncs < 1)
37
+ throw new Error("maxParallelSwapSyncs must be at least 1!");
32
38
  this.unifiedStorage = unifiedStorage;
33
39
  this.unifiedChainEvents = unifiedChainEvents;
34
40
  this.chainIdentifier = chainIdentifier;
@@ -128,9 +134,25 @@ class ISwapWrapper {
128
134
  startTickInterval() {
129
135
  if (this.tickSwapState == null || this.tickSwapState.length === 0)
130
136
  return;
131
- this.tickInterval = setInterval(() => {
132
- this.tick();
133
- }, 1000);
137
+ if (this.tickAbortController != null)
138
+ this.tickAbortController.abort("New tick interval has been started!");
139
+ const abortController = this.tickAbortController = new AbortController();
140
+ let run;
141
+ run = async () => {
142
+ if (!this.isInitialized)
143
+ return;
144
+ await this.tick(undefined, abortController.signal).catch(e => {
145
+ if (abortController.signal.aborted)
146
+ return;
147
+ this.logger.warn("startTickInterval(): Tick on swaps failed, error: ", e);
148
+ });
149
+ if (abortController.signal.aborted)
150
+ return;
151
+ if (!this.isInitialized)
152
+ return;
153
+ this.tickInterval = setTimeout(run, 1000);
154
+ };
155
+ run();
134
156
  }
135
157
  /**
136
158
  * Runs checks on passed swaps, syncing their state from on-chain data
@@ -186,10 +208,10 @@ class ISwapWrapper {
186
208
  }
187
209
  if (this.processEvent != null)
188
210
  this.unifiedChainEvents.registerListener(this.TYPE, this.processEvent.bind(this), this._swapDeserializer.bind(null, this));
211
+ this.isInitialized = true;
189
212
  if (!noTimers)
190
213
  this.startTickInterval();
191
214
  // this.logger.info("init(): Swap wrapper initialized");
192
- this.isInitialized = true;
193
215
  }
194
216
  /**
195
217
  * Un-subscribes from event listeners on the smart chain, terminates the tick interval and stops this wrapper
@@ -198,12 +220,20 @@ class ISwapWrapper {
198
220
  this.isInitialized = false;
199
221
  this.unifiedChainEvents.unregisterListener(this.TYPE);
200
222
  this.logger.info("stop(): Swap wrapper stopped");
201
- if (this.tickInterval != null)
202
- clearInterval(this.tickInterval);
223
+ if (this.tickInterval != null) {
224
+ clearTimeout(this.tickInterval);
225
+ delete this.tickInterval;
226
+ }
227
+ if (this.tickAbortController != null) {
228
+ this.tickAbortController.abort("Wrapper instance stopped!");
229
+ delete this.tickAbortController;
230
+ }
203
231
  }
204
232
  /**
205
233
  * Runs checks on all the known pending swaps, syncing their state from on-chain data
206
234
  *
235
+ * @remarks Doesn't work properly if you pass non-persisted swaps
236
+ *
207
237
  * @param pastSwaps Optional array of past swaps to check, otherwise all relevant swaps will be fetched
208
238
  * from the persistent storage
209
239
  * @param noSave Whether to skip saving the swap changes in the persistent storage
@@ -211,16 +241,23 @@ class ISwapWrapper {
211
241
  async checkPastSwaps(pastSwaps, noSave) {
212
242
  if (pastSwaps == null)
213
243
  pastSwaps = await this.unifiedStorage.query([[{ key: "type", value: this.TYPE }, { key: "state", value: this._pendingSwapStates }]], (val) => new this._swapDeserializer(this, val));
214
- const { removeSwaps, changedSwaps } = await this._checkPastSwaps(pastSwaps);
215
- if (!noSave) {
216
- await this.unifiedStorage.removeAll(removeSwaps);
217
- await this.unifiedStorage.saveAll(changedSwaps);
218
- changedSwaps.forEach(swap => swap._emitEvent());
219
- removeSwaps.forEach(swap => swap._emitEvent());
244
+ const maxParallelSyncs = this._options.maxParallelSwapSyncs ?? exports.DEFAULT_MAX_PARALLEL_SWAP_SYNCS;
245
+ const totalRemoveSwaps = [];
246
+ const totalChangedSwaps = [];
247
+ for (let i = 0; i < pastSwaps.length; i += maxParallelSyncs) {
248
+ const { removeSwaps, changedSwaps } = await this._checkPastSwaps(pastSwaps.slice(i, i + maxParallelSyncs));
249
+ if (!noSave) {
250
+ await this.unifiedStorage.removeAll(removeSwaps);
251
+ await this.unifiedStorage.saveAll(changedSwaps);
252
+ changedSwaps.forEach(swap => swap._emitEvent());
253
+ removeSwaps.forEach(swap => swap._emitEvent());
254
+ }
255
+ totalRemoveSwaps.push(...removeSwaps);
256
+ totalChangedSwaps.push(...changedSwaps);
220
257
  }
221
258
  return {
222
- removeSwaps,
223
- changedSwaps
259
+ removeSwaps: totalRemoveSwaps,
260
+ changedSwaps: totalChangedSwaps
224
261
  };
225
262
  }
226
263
  /**
@@ -228,18 +265,39 @@ class ISwapWrapper {
228
265
  *
229
266
  * @param swaps Optional array of swaps to invoke `_tick()` on, otherwise all relevant swaps will be fetched
230
267
  * from the persistent storage
268
+ * @param abortSignal Abort signal
231
269
  */
232
- async tick(swaps) {
270
+ async tick(swaps, abortSignal) {
233
271
  if (swaps == null)
234
272
  swaps = await this.unifiedStorage.query([[{ key: "type", value: this.TYPE }, { key: "state", value: this.tickSwapState }]], (val) => new this._swapDeserializer(this, val));
273
+ abortSignal?.throwIfAborted();
274
+ const parallelTicks = this._options.maxParallelSwapTicks ?? exports.DEFAULT_MAX_PARALLEL_SWAP_TICKS;
275
+ let promises = [];
235
276
  for (let pendingSwap of this.pendingSwaps.values()) {
236
277
  const value = pendingSwap.deref();
237
278
  if (value != null)
238
- value._tick(true);
279
+ promises.push(value._tick(true).catch(e => {
280
+ this.logger.warn(`tick(): Error ticking swap ${value.getId()}: `, e);
281
+ }));
282
+ if (promises.length >= parallelTicks) {
283
+ await Promise.all(promises);
284
+ abortSignal?.throwIfAborted();
285
+ promises = [];
286
+ }
239
287
  }
240
- swaps.forEach(value => {
241
- value._tick(true);
242
- });
288
+ for (let value of swaps) {
289
+ promises.push(value._tick(true).catch(e => {
290
+ this.logger.warn(`tick(): Error ticking swap ${value.getId()}: `, e);
291
+ }));
292
+ if (promises.length >= parallelTicks) {
293
+ await Promise.all(promises);
294
+ abortSignal?.throwIfAborted();
295
+ promises = [];
296
+ }
297
+ }
298
+ if (promises.length > 0)
299
+ await Promise.all(promises);
300
+ abortSignal?.throwIfAborted();
243
301
  }
244
302
  /**
245
303
  * Returns the smart chain's native token used to pay for fees
@@ -256,13 +314,15 @@ class ISwapWrapper {
256
314
  * @internal
257
315
  */
258
316
  _saveSwapData(swap) {
259
- if (!swap.isInitiated()) {
260
- this.logger.debug("saveSwapData(): Swap " + swap.getId() + " not initiated, saving to pending swaps");
261
- this.pendingSwaps.set(swap.getId(), new WeakRef(swap));
262
- return Promise.resolve();
263
- }
264
- else {
265
- this.pendingSwaps.delete(swap.getId());
317
+ if (!this._options.saveUninitializedSwaps) {
318
+ if (!swap.isInitiated()) {
319
+ this.logger.debug("saveSwapData(): Swap " + swap.getId() + " not initiated, saving to pending swaps");
320
+ this.pendingSwaps.set(swap.getId(), new WeakRef(swap));
321
+ return Promise.resolve();
322
+ }
323
+ else {
324
+ this.pendingSwaps.delete(swap.getId());
325
+ }
266
326
  }
267
327
  return this.unifiedStorage.save(swap);
268
328
  }
@@ -275,7 +335,7 @@ class ISwapWrapper {
275
335
  */
276
336
  _removeSwapData(swap) {
277
337
  this.pendingSwaps.delete(swap.getId());
278
- if (!swap.isInitiated())
338
+ if (!swap._persisted)
279
339
  return Promise.resolve();
280
340
  return this.unifiedStorage.remove(swap);
281
341
  }
@@ -23,8 +23,11 @@ class IEscrowSwapWrapper extends ISwapWrapper_1.ISwapWrapper {
23
23
  * @internal
24
24
  */
25
25
  preFetchSignData(signDataPrefetch) {
26
- if (this._contract.preFetchForInitSignatureVerification == null)
26
+ if (this._contract.preFetchForInitSignatureVerification == null) {
27
+ // Catch promise rejections, should they happen
28
+ signDataPrefetch.catch(() => { });
27
29
  return Promise.resolve(undefined);
30
+ }
28
31
  return signDataPrefetch.then(obj => {
29
32
  if (obj == null)
30
33
  return undefined;
@@ -42,7 +42,7 @@ export declare abstract class IFromBTCSelfInitSwap<T extends ChainType = ChainTy
42
42
  * Returns if the swap can be committed
43
43
  * @internal
44
44
  */
45
- protected abstract canCommit(): boolean;
45
+ protected abstract canCommit(skipQuoteExpiryChecks?: boolean): boolean;
46
46
  /**
47
47
  * @inheritDoc
48
48
  * @internal
@@ -150,7 +150,7 @@ export declare abstract class IFromBTCSelfInitSwap<T extends ChainType = ChainTy
150
150
  /**
151
151
  * @inheritDoc
152
152
  */
153
- abstract txsClaim(signer?: T["Signer"]): Promise<T["TX"][]>;
153
+ abstract txsClaim(signer?: string | T["Signer"] | T["NativeSigner"]): Promise<T["TX"][]>;
154
154
  /**
155
155
  * @inheritDoc
156
156
  */
@@ -166,7 +166,7 @@ class IFromBTCSelfInitSwap extends IEscrowSelfInitSwap_1.IEscrowSelfInitSwap {
166
166
  * @throws {Error} When in invalid state to commit the swap
167
167
  */
168
168
  async txsCommit(skipChecks) {
169
- if (!this.canCommit())
169
+ if (!this.canCommit(skipChecks))
170
170
  throw new Error("Must be in CREATED state!");
171
171
  if (this._data == null || this.signatureData == null)
172
172
  throw new Error("data or signature data is null, invalid state?");
@@ -152,7 +152,7 @@ export declare class FromBTCLNSwap<T extends ChainType = ChainType> extends IFro
152
152
  * @inheritDoc
153
153
  * @internal
154
154
  */
155
- protected canCommit(): boolean;
155
+ protected canCommit(skipQuoteExpiryChecks?: boolean): boolean;
156
156
  /**
157
157
  * @inheritDoc
158
158
  */
@@ -400,7 +400,7 @@ export declare class FromBTCLNSwap<T extends ChainType = ChainType> extends IFro
400
400
  *
401
401
  * @throws {Error} If in invalid state (must be {@link FromBTCLNSwapState.CLAIM_COMMITED})
402
402
  */
403
- txsClaim(_signer?: T["Signer"] | T["NativeSigner"], secret?: string): Promise<T["TX"][]>;
403
+ txsClaim(_signer?: string | T["Signer"] | T["NativeSigner"], secret?: string): Promise<T["TX"][]>;
404
404
  /**
405
405
  * @inheritDoc
406
406
  *
@@ -224,8 +224,8 @@ class FromBTCLNSwap extends IFromBTCSelfInitSwap_1.IFromBTCSelfInitSwap {
224
224
  * @inheritDoc
225
225
  * @internal
226
226
  */
227
- canCommit() {
228
- return this._state === FromBTCLNSwapState.PR_PAID;
227
+ canCommit(skipQuoteExpiryChecks) {
228
+ return this._state === FromBTCLNSwapState.PR_PAID || (!!skipQuoteExpiryChecks && this._state === FromBTCLNSwapState.QUOTE_SOFT_EXPIRED);
229
229
  }
230
230
  /**
231
231
  * @inheritDoc
@@ -773,7 +773,7 @@ class FromBTCLNSwap extends IFromBTCSelfInitSwap_1.IFromBTCSelfInitSwap {
773
773
  return Promise.resolve();
774
774
  });
775
775
  this._commitTxId = result[result.length - 1];
776
- if (this._state === FromBTCLNSwapState.PR_PAID || this._state === FromBTCLNSwapState.QUOTE_SOFT_EXPIRED) {
776
+ if (this._state === FromBTCLNSwapState.PR_PAID || this._state === FromBTCLNSwapState.QUOTE_SOFT_EXPIRED || this._state === FromBTCLNSwapState.QUOTE_EXPIRED) {
777
777
  await this._saveAndEmit(FromBTCLNSwapState.CLAIM_COMMITED);
778
778
  }
779
779
  return this._commitTxId;
@@ -821,6 +821,18 @@ class FromBTCLNSwap extends IFromBTCSelfInitSwap_1.IFromBTCSelfInitSwap {
821
821
  * @internal
822
822
  */
823
823
  async _txsClaim(_signer, secret) {
824
+ let address = undefined;
825
+ if (_signer != null) {
826
+ if (typeof (_signer) === "string") {
827
+ address = _signer;
828
+ }
829
+ else if ((0, base_1.isAbstractSigner)(_signer)) {
830
+ address = _signer.getAddress();
831
+ }
832
+ else {
833
+ address = (await this.wrapper._chain.wrapSigner(_signer)).getAddress();
834
+ }
835
+ }
824
836
  if (this._data == null)
825
837
  throw new Error("Unknown data, wrong state?");
826
838
  const useSecret = secret ?? this.secret;
@@ -828,9 +840,7 @@ class FromBTCLNSwap extends IFromBTCSelfInitSwap_1.IFromBTCSelfInitSwap {
828
840
  throw new Error("Swap secret pre-image not known and not provided, please provide the swap secret pre-image as an argument");
829
841
  if (!this.isValidSecretPreimage(useSecret))
830
842
  throw new Error("Invalid swap secret pre-image provided!");
831
- return this.wrapper._contract.txsClaimWithSecret(_signer == null ?
832
- this._getInitiator() :
833
- ((0, base_1.isAbstractSigner)(_signer) ? _signer : await this.wrapper._chain.wrapSigner(_signer)), this._data, useSecret, true, true);
843
+ return this.wrapper._contract.txsClaimWithSecret(address ?? this._getInitiator(), this._data, useSecret, true, true);
834
844
  }
835
845
  /**
836
846
  * @inheritDoc
@@ -36,6 +36,7 @@ class FromBTCLNWrapper extends IFromBTCLNWrapper_1.IFromBTCLNWrapper {
36
36
  */
37
37
  constructor(chainIdentifier, unifiedStorage, unifiedChainEvents, chain, contract, prices, tokens, swapDataDeserializer, lnApi, options, events) {
38
38
  super(chainIdentifier, unifiedStorage, unifiedChainEvents, chain, contract, prices, tokens, swapDataDeserializer, lnApi, {
39
+ ...options,
39
40
  safetyFactor: options?.safetyFactor ?? 2,
40
41
  bitcoinBlocktime: options?.bitcoinBlocktime ?? 10 * 60,
41
42
  unsafeSkipLnNodeCheck: options?.unsafeSkipLnNodeCheck ?? false
@@ -199,8 +200,14 @@ class FromBTCLNWrapper extends IFromBTCLNWrapper_1.IFromBTCLNWrapper {
199
200
  feeRate: (0, Utils_1.throwIfUndefined)(_preFetches.feeRatePromise),
200
201
  additionalParams
201
202
  }, this._options.postRequestTimeout, abortController.signal, retryCount > 0 ? false : undefined);
203
+ let lnCapacityPromise;
204
+ if (!_options.unsafeSkipLnNodeCheck) {
205
+ lnCapacityPromise = this.preFetchLnCapacity(lnPublicKey);
206
+ }
207
+ else
208
+ lnPublicKey.catch(() => { });
202
209
  return {
203
- lnCapacityPromise: _options.unsafeSkipLnNodeCheck ? null : this.preFetchLnCapacity(lnPublicKey),
210
+ lnCapacityPromise,
204
211
  resp: await response
205
212
  };
206
213
  }, undefined, RequestError_1.RequestError, abortController.signal);
@@ -229,7 +236,6 @@ class FromBTCLNWrapper extends IFromBTCLNWrapper_1.IFromBTCLNWrapper {
229
236
  secret: secret?.toString("hex"),
230
237
  exactIn: amountData.exactIn ?? true
231
238
  });
232
- await quote._save();
233
239
  return quote;
234
240
  }
235
241
  catch (e) {
@@ -482,7 +482,7 @@ export declare class FromBTCLNAutoSwap<T extends ChainType = ChainType> extends
482
482
  *
483
483
  * @throws {Error} If in invalid state (must be {@link FromBTCLNAutoSwapState.CLAIM_COMMITED})
484
484
  */
485
- txsClaim(_signer?: T["Signer"] | T["NativeSigner"], secret?: string): Promise<T["TX"][]>;
485
+ txsClaim(_signer?: string | T["Signer"] | T["NativeSigner"], secret?: string): Promise<T["TX"][]>;
486
486
  /**
487
487
  * @inheritDoc
488
488
  *
@@ -441,7 +441,7 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
441
441
  * @internal
442
442
  */
443
443
  getInputAmountWithoutFee() {
444
- if (this.btcAmountGas == null || this.btcAmountSwap)
444
+ if (this.btcAmountGas == null || this.btcAmountSwap == null)
445
445
  return null;
446
446
  return this.getInputSwapAmountWithoutFee() + this.getInputGasAmountWithoutFee() - this.getWatchtowerFeeAmountBtc();
447
447
  }
@@ -963,6 +963,18 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
963
963
  * @throws {Error} If in invalid state (must be {@link FromBTCLNAutoSwapState.CLAIM_COMMITED})
964
964
  */
965
965
  async txsClaim(_signer, secret) {
966
+ let address = undefined;
967
+ if (_signer != null) {
968
+ if (typeof (_signer) === "string") {
969
+ address = _signer;
970
+ }
971
+ else if ((0, base_1.isAbstractSigner)(_signer)) {
972
+ address = _signer.getAddress();
973
+ }
974
+ else {
975
+ address = (await this.wrapper._chain.wrapSigner(_signer)).getAddress();
976
+ }
977
+ }
966
978
  if (this._state !== FromBTCLNAutoSwapState.CLAIM_COMMITED)
967
979
  throw new Error("Must be in CLAIM_COMMITED state!");
968
980
  if (this._data == null)
@@ -972,9 +984,7 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
972
984
  throw new Error("Swap secret pre-image not known and not provided, please provide the swap secret pre-image as an argument");
973
985
  if (!this.isValidSecretPreimage(useSecret))
974
986
  throw new Error("Invalid swap secret pre-image provided!");
975
- return await this.wrapper._contract.txsClaimWithSecret(_signer == null ?
976
- this._getInitiator() :
977
- ((0, base_1.isAbstractSigner)(_signer) ? _signer : await this.wrapper._chain.wrapSigner(_signer)), this._data, useSecret, true, true);
987
+ return await this.wrapper._contract.txsClaimWithSecret(address ?? this._getInitiator(), this._data, useSecret, true, true);
978
988
  }
979
989
  /**
980
990
  * @inheritDoc
@@ -39,6 +39,7 @@ class FromBTCLNAutoWrapper extends IFromBTCLNWrapper_1.IFromBTCLNWrapper {
39
39
  */
40
40
  constructor(chainIdentifier, unifiedStorage, unifiedChainEvents, chain, contract, prices, tokens, swapDataDeserializer, lnApi, messenger, options, events) {
41
41
  super(chainIdentifier, unifiedStorage, unifiedChainEvents, chain, contract, prices, tokens, swapDataDeserializer, lnApi, {
42
+ ...options,
42
43
  safetyFactor: options?.safetyFactor ?? 2,
43
44
  bitcoinBlocktime: options?.bitcoinBlocktime ?? 10 * 60,
44
45
  unsafeSkipLnNodeCheck: options?.unsafeSkipLnNodeCheck ?? false
@@ -99,7 +100,6 @@ class FromBTCLNAutoWrapper extends IFromBTCLNWrapper_1.IFromBTCLNWrapper {
99
100
  this.logger.error("processEventInitialize(" + swap.getId() + "): Error when processing event, escrow hashes don't match!");
100
101
  return false;
101
102
  }
102
- swap._commitTxId = event.meta?.txId;
103
103
  swap._commitedAt ??= Date.now();
104
104
  swap._state = FromBTCLNAutoSwap_1.FromBTCLNAutoSwapState.CLAIM_COMMITED;
105
105
  if (swap.hasSecretPreimage())
@@ -116,7 +116,6 @@ class FromBTCLNAutoWrapper extends IFromBTCLNWrapper_1.IFromBTCLNWrapper {
116
116
  */
117
117
  processEventClaim(swap, event) {
118
118
  if (swap._state !== FromBTCLNAutoSwap_1.FromBTCLNAutoSwapState.FAILED && swap._state !== FromBTCLNAutoSwap_1.FromBTCLNAutoSwapState.CLAIM_CLAIMED) {
119
- swap._claimTxId = event.meta?.txId;
120
119
  swap._state = FromBTCLNAutoSwap_1.FromBTCLNAutoSwapState.CLAIM_CLAIMED;
121
120
  swap._setSwapSecret(event.result);
122
121
  return Promise.resolve(true);
@@ -129,7 +128,6 @@ class FromBTCLNAutoWrapper extends IFromBTCLNWrapper_1.IFromBTCLNWrapper {
129
128
  */
130
129
  processEventRefund(swap, event) {
131
130
  if (swap._state !== FromBTCLNAutoSwap_1.FromBTCLNAutoSwapState.CLAIM_CLAIMED && swap._state !== FromBTCLNAutoSwap_1.FromBTCLNAutoSwapState.FAILED) {
132
- swap._refundTxId ??= event.meta?.txId;
133
131
  swap._state = FromBTCLNAutoSwap_1.FromBTCLNAutoSwapState.FAILED;
134
132
  return Promise.resolve(true);
135
133
  }
@@ -276,8 +274,14 @@ class FromBTCLNAutoWrapper extends IFromBTCLNWrapper_1.IFromBTCLNWrapper {
276
274
  gasAmount: _options.gasAmount,
277
275
  claimerBounty: (0, Utils_1.throwIfUndefined)(_preFetches.claimerBountyPrefetch)
278
276
  }, this._options.postRequestTimeout, abortController.signal, retryCount > 0 ? false : undefined);
277
+ let lnCapacityPromise;
278
+ if (!_options.unsafeSkipLnNodeCheck) {
279
+ lnCapacityPromise = this.preFetchLnCapacity(lnPublicKey);
280
+ }
281
+ else
282
+ lnPublicKey.catch(() => { });
279
283
  return {
280
- lnCapacityPromise: _options.unsafeSkipLnNodeCheck ? undefined : this.preFetchLnCapacity(lnPublicKey),
284
+ lnCapacityPromise,
281
285
  resp: await response
282
286
  };
283
287
  }, undefined, RequestError_1.RequestError, abortController.signal);
@@ -314,8 +318,6 @@ class FromBTCLNAutoWrapper extends IFromBTCLNWrapper_1.IFromBTCLNWrapper {
314
318
  exactIn: amountData.exactIn ?? true
315
319
  };
316
320
  const quote = new FromBTCLNAutoSwap_1.FromBTCLNAutoSwap(this, swapInit);
317
- await quote._save();
318
- this.logger.debug("create(): Created new FromBTCLNAutoSwap quote, claimHash (pseudo escrowHash): ", quote._getEscrowHash());
319
321
  return quote;
320
322
  }
321
323
  catch (e) {
@@ -191,7 +191,7 @@ export declare class FromBTCSwap<T extends ChainType = ChainType> extends IFromB
191
191
  * @inheritDoc
192
192
  * @internal
193
193
  */
194
- protected canCommit(): boolean;
194
+ protected canCommit(skipQuoteExpiryChecks?: boolean): boolean;
195
195
  /**
196
196
  * @inheritDoc
197
197
  */
@@ -444,6 +444,7 @@ export declare class FromBTCSwap<T extends ChainType = ChainType> extends IFromB
444
444
  * @internal
445
445
  */
446
446
  _sync(save?: boolean, quoteDefinitelyExpired?: boolean, commitStatus?: SwapCommitState): Promise<boolean>;
447
+ private btcTxLastChecked?;
447
448
  /**
448
449
  * @inheritDoc
449
450
  * @internal
@@ -260,8 +260,8 @@ class FromBTCSwap extends IFromBTCSelfInitSwap_1.IFromBTCSelfInitSwap {
260
260
  * @inheritDoc
261
261
  * @internal
262
262
  */
263
- canCommit() {
264
- if (this._state !== FromBTCSwapState.PR_CREATED)
263
+ canCommit(skipQuoteExpiryChecks) {
264
+ if (this._state !== FromBTCSwapState.PR_CREATED && (!skipQuoteExpiryChecks || this._state !== FromBTCSwapState.QUOTE_SOFT_EXPIRED))
265
265
  return false;
266
266
  if (this.requiredConfirmations == null)
267
267
  return false;
@@ -742,7 +742,7 @@ class FromBTCSwap extends IFromBTCSelfInitSwap_1.IFromBTCSelfInitSwap {
742
742
  return Promise.resolve();
743
743
  });
744
744
  this._commitTxId = result[result.length - 1];
745
- if (this._state === FromBTCSwapState.PR_CREATED || this._state === FromBTCSwapState.QUOTE_SOFT_EXPIRED) {
745
+ if (this._state === FromBTCSwapState.PR_CREATED || this._state === FromBTCSwapState.QUOTE_SOFT_EXPIRED || this._state === FromBTCSwapState.QUOTE_EXPIRED) {
746
746
  await this._saveAndEmit(FromBTCSwapState.CLAIM_COMMITED);
747
747
  }
748
748
  return this._commitTxId;
@@ -1045,6 +1045,7 @@ class FromBTCSwap extends IFromBTCSelfInitSwap_1.IFromBTCSelfInitSwap {
1045
1045
  }
1046
1046
  if (this.address == null)
1047
1047
  return save;
1048
+ this.btcTxLastChecked = Date.now();
1048
1049
  const res = await this.getBitcoinPayment();
1049
1050
  if (res != null) {
1050
1051
  if (this.txId !== res.txId) {
@@ -1086,10 +1087,11 @@ class FromBTCSwap extends IFromBTCSelfInitSwap_1.IFromBTCSelfInitSwap {
1086
1087
  return true;
1087
1088
  }
1088
1089
  case FromBTCSwapState.EXPIRED:
1089
- //Check if bitcoin payment was received every 2 minutes
1090
- if (Math.floor(Date.now() / 1000) % 120 === 0) {
1090
+ //Check if bitcoin payment was received at least every 2 minutes
1091
+ if (this.btcTxLastChecked == null || Date.now() - this.btcTxLastChecked > 120000) {
1091
1092
  if (this.address != null)
1092
1093
  try {
1094
+ this.btcTxLastChecked = Date.now();
1093
1095
  const res = await this.getBitcoinPayment();
1094
1096
  if (res != null) {
1095
1097
  let shouldSave = false;
@@ -37,6 +37,7 @@ class FromBTCWrapper extends IFromBTCWrapper_1.IFromBTCWrapper {
37
37
  */
38
38
  constructor(chainIdentifier, unifiedStorage, unifiedChainEvents, chain, contract, prices, tokens, swapDataDeserializer, btcRelay, synchronizer, btcRpc, options, events) {
39
39
  super(chainIdentifier, unifiedStorage, unifiedChainEvents, chain, contract, prices, tokens, swapDataDeserializer, {
40
+ ...options,
40
41
  bitcoinNetwork: options?.bitcoinNetwork ?? utils_1.TEST_NETWORK,
41
42
  safetyFactor: options?.safetyFactor ?? 2,
42
43
  blocksTillTxConfirms: options?.blocksTillTxConfirms ?? 12,
@@ -295,8 +296,14 @@ class FromBTCWrapper extends IFromBTCWrapper_1.IFromBTCWrapper {
295
296
  feeRate: (0, Utils_1.throwIfUndefined)(feeRatePromise),
296
297
  additionalParams
297
298
  }, this._options.postRequestTimeout, abortController.signal, retryCount > 0 ? false : undefined);
299
+ let signDataPromise = _signDataPromise;
300
+ if (signDataPromise == null) {
301
+ signDataPromise = this.preFetchSignData(signDataPrefetch);
302
+ }
303
+ else
304
+ signDataPrefetch.catch(() => { });
298
305
  return {
299
- signDataPromise: _signDataPromise ?? this.preFetchSignData(signDataPrefetch),
306
+ signDataPromise,
300
307
  resp: await response
301
308
  };
302
309
  }, undefined, e => e instanceof RequestError_1.RequestError, abortController.signal);
@@ -323,7 +330,6 @@ class FromBTCWrapper extends IFromBTCWrapper_1.IFromBTCWrapper {
323
330
  exactIn: amountData.exactIn ?? true,
324
331
  requiredConfirmations: resp.confirmations
325
332
  });
326
- await quote._save();
327
333
  return quote;
328
334
  }
329
335
  catch (e) {
@@ -453,7 +453,7 @@ class IToBTCSwap extends IEscrowSelfInitSwap_1.IEscrowSelfInitSwap {
453
453
  * @throws {Error} When in invalid state (not {@link ToBTCSwapState.CREATED})
454
454
  */
455
455
  async txsCommit(skipChecks) {
456
- if (this._state !== ToBTCSwapState.CREATED)
456
+ if (this._state !== ToBTCSwapState.CREATED && (!skipChecks || this._state !== ToBTCSwapState.QUOTE_SOFT_EXPIRED))
457
457
  throw new Error("Must be in CREATED state!");
458
458
  if (this.signatureData == null)
459
459
  throw new Error("Init signature data not known, cannot commit!");
@@ -78,8 +78,6 @@ class IToBTCWrapper extends IEscrowSwapWrapper_1.IEscrowSwapWrapper {
78
78
  async processEventInitialize(swap, event) {
79
79
  if (swap._state === IToBTCSwap_1.ToBTCSwapState.CREATED || swap._state === IToBTCSwap_1.ToBTCSwapState.QUOTE_SOFT_EXPIRED) {
80
80
  swap._state = IToBTCSwap_1.ToBTCSwapState.COMMITED;
81
- if (swap._commitTxId == null)
82
- swap._commitTxId = event.meta?.txId;
83
81
  return true;
84
82
  }
85
83
  return false;
@@ -96,8 +94,6 @@ class IToBTCWrapper extends IEscrowSwapWrapper_1.IEscrowSwapWrapper {
96
94
  this.logger.warn(`processEventClaim(): Failed to set payment result ${event.result}: `, e);
97
95
  });
98
96
  swap._state = IToBTCSwap_1.ToBTCSwapState.CLAIMED;
99
- if (swap._claimTxId == null)
100
- swap._claimTxId = event.meta?.txId;
101
97
  return true;
102
98
  }
103
99
  return false;
@@ -108,8 +104,6 @@ class IToBTCWrapper extends IEscrowSwapWrapper_1.IEscrowSwapWrapper {
108
104
  processEventRefund(swap, event) {
109
105
  if (swap._state !== IToBTCSwap_1.ToBTCSwapState.CLAIMED && swap._state !== IToBTCSwap_1.ToBTCSwapState.REFUNDED) {
110
106
  swap._state = IToBTCSwap_1.ToBTCSwapState.REFUNDED;
111
- if (swap._refundTxId == null)
112
- swap._refundTxId = event.meta?.txId;
113
107
  return Promise.resolve(true);
114
108
  }
115
109
  return Promise.resolve(false);
@@ -23,6 +23,7 @@ const RetryUtils_1 = require("../../../../utils/RetryUtils");
23
23
  class ToBTCLNWrapper extends IToBTCWrapper_1.IToBTCWrapper {
24
24
  constructor(chainIdentifier, unifiedStorage, unifiedChainEvents, chain, contract, prices, tokens, swapDataDeserializer, options, events) {
25
25
  super(chainIdentifier, unifiedStorage, unifiedChainEvents, chain, contract, prices, tokens, swapDataDeserializer, {
26
+ ...options,
26
27
  paymentTimeoutSeconds: options?.paymentTimeoutSeconds ?? 5 * 24 * 60 * 60,
27
28
  lightningBaseFee: options?.lightningBaseFee ?? 10,
28
29
  lightningFeePPM: options?.lightningFeePPM ?? 2000
@@ -160,8 +161,14 @@ class ToBTCLNWrapper extends IToBTCWrapper_1.IToBTCWrapper {
160
161
  feeRate: (0, Utils_1.throwIfUndefined)(preFetches.feeRatePromise),
161
162
  additionalParams
162
163
  }, this._options.postRequestTimeout, abortController.signal, retryCount > 0 ? false : undefined);
164
+ let signDataPromise = preFetches.signDataPrefetchPromise;
165
+ if (signDataPromise == null) {
166
+ signDataPromise = this.preFetchSignData(signDataPrefetch);
167
+ }
168
+ else
169
+ signDataPrefetch.catch(() => { });
163
170
  return {
164
- signDataPromise: preFetches.signDataPrefetchPromise ?? this.preFetchSignData(signDataPrefetch),
171
+ signDataPromise,
165
172
  resp: await response
166
173
  };
167
174
  }, undefined, e => e instanceof RequestError_1.RequestError, abortController.signal);
@@ -196,7 +203,6 @@ class ToBTCLNWrapper extends IToBTCWrapper_1.IToBTCWrapper {
196
203
  pr,
197
204
  exactIn: false
198
205
  });
199
- await quote._save();
200
206
  return quote;
201
207
  }
202
208
  catch (e) {
@@ -346,7 +352,6 @@ class ToBTCLNWrapper extends IToBTCWrapper_1.IToBTCWrapper {
346
352
  pr: invoice,
347
353
  exactIn: true
348
354
  });
349
- await quote._save();
350
355
  return quote;
351
356
  }
352
357
  catch (e) {
@@ -35,6 +35,7 @@ class ToBTCWrapper extends IToBTCWrapper_1.IToBTCWrapper {
35
35
  */
36
36
  constructor(chainIdentifier, unifiedStorage, unifiedChainEvents, chain, contract, prices, tokens, swapDataDeserializer, btcRpc, options, events) {
37
37
  super(chainIdentifier, unifiedStorage, unifiedChainEvents, chain, contract, prices, tokens, swapDataDeserializer, {
38
+ ...options,
38
39
  bitcoinNetwork: options?.bitcoinNetwork ?? utils_1.TEST_NETWORK,
39
40
  safetyFactor: options?.safetyFactor ?? 2,
40
41
  maxConfirmations: options?.maxConfirmations ?? 6,
@@ -179,8 +180,14 @@ class ToBTCWrapper extends IToBTCWrapper_1.IToBTCWrapper {
179
180
  feeRate: (0, Utils_1.throwIfUndefined)(feeRatePromise),
180
181
  additionalParams
181
182
  }, this._options.postRequestTimeout, abortController.signal, retryCount > 0 ? false : undefined);
183
+ let signDataPromise = _signDataPromise;
184
+ if (signDataPromise == null) {
185
+ signDataPromise = this.preFetchSignData(signDataPrefetch);
186
+ }
187
+ else
188
+ signDataPrefetch.catch(() => { });
182
189
  return {
183
- signDataPromise: _signDataPromise ?? this.preFetchSignData(signDataPrefetch),
190
+ signDataPromise,
184
191
  resp: await response
185
192
  };
186
193
  }, undefined, RequestError_1.RequestError, abortController.signal);
@@ -218,7 +225,6 @@ class ToBTCWrapper extends IToBTCWrapper_1.IToBTCWrapper {
218
225
  requiredConfirmations: _options.confirmations,
219
226
  nonce
220
227
  });
221
- await quote._save();
222
228
  return quote;
223
229
  }
224
230
  catch (e) {