@atomiqlabs/lp-lib 17.1.2 → 17.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/dist/info/InfoHandler.js +2 -1
  2. package/dist/plugins/IPlugin.d.ts +17 -3
  3. package/dist/plugins/IPlugin.js +9 -8
  4. package/dist/plugins/PluginManager.d.ts +5 -3
  5. package/dist/plugins/PluginManager.js +30 -0
  6. package/dist/swaps/SwapHandler.d.ts +1 -0
  7. package/dist/swaps/SwapHandlerSwap.d.ts +1 -0
  8. package/dist/swaps/assertions/FromBtcAmountAssertions.js +2 -2
  9. package/dist/swaps/assertions/ToBtcAmountAssertions.js +2 -2
  10. package/dist/swaps/escrow/frombtc_abstract/FromBtcAbs.js +7 -0
  11. package/dist/swaps/escrow/frombtc_abstract/FromBtcSwapAbs.d.ts +1 -0
  12. package/dist/swaps/escrow/frombtc_abstract/FromBtcSwapAbs.js +3 -0
  13. package/dist/swaps/escrow/frombtcln_abstract/FromBtcLnAbs.js +31 -11
  14. package/dist/swaps/escrow/frombtcln_abstract/FromBtcLnSwapAbs.d.ts +1 -0
  15. package/dist/swaps/escrow/frombtcln_abstract/FromBtcLnSwapAbs.js +3 -0
  16. package/dist/swaps/escrow/frombtcln_autoinit/FromBtcLnAuto.js +14 -2
  17. package/dist/swaps/escrow/frombtcln_autoinit/FromBtcLnAutoSwap.d.ts +1 -0
  18. package/dist/swaps/escrow/frombtcln_autoinit/FromBtcLnAutoSwap.js +3 -0
  19. package/dist/swaps/escrow/tobtc_abstract/ToBtcAbs.js +25 -2
  20. package/dist/swaps/escrow/tobtc_abstract/ToBtcSwapAbs.d.ts +1 -0
  21. package/dist/swaps/escrow/tobtc_abstract/ToBtcSwapAbs.js +3 -0
  22. package/dist/swaps/escrow/tobtcln_abstract/ToBtcLnAbs.js +13 -1
  23. package/dist/swaps/escrow/tobtcln_abstract/ToBtcLnSwapAbs.d.ts +1 -0
  24. package/dist/swaps/escrow/tobtcln_abstract/ToBtcLnSwapAbs.js +3 -0
  25. package/dist/swaps/spv_vault_swap/SpvVaultSwap.d.ts +1 -0
  26. package/dist/swaps/spv_vault_swap/SpvVaultSwap.js +3 -0
  27. package/dist/swaps/spv_vault_swap/SpvVaultSwapHandler.js +14 -2
  28. package/dist/swaps/trusted/frombtc_trusted/FromBtcTrusted.js +47 -32
  29. package/dist/swaps/trusted/frombtc_trusted/FromBtcTrustedSwap.d.ts +1 -0
  30. package/dist/swaps/trusted/frombtc_trusted/FromBtcTrustedSwap.js +3 -0
  31. package/dist/swaps/trusted/frombtcln_trusted/FromBtcLnTrusted.js +14 -0
  32. package/dist/swaps/trusted/frombtcln_trusted/FromBtcLnTrustedSwap.d.ts +1 -0
  33. package/dist/swaps/trusted/frombtcln_trusted/FromBtcLnTrustedSwap.js +3 -0
  34. package/package.json +2 -2
  35. package/src/info/InfoHandler.ts +6 -3
  36. package/src/plugins/IPlugin.ts +36 -14
  37. package/src/plugins/PluginManager.ts +41 -6
  38. package/src/swaps/SwapHandler.ts +2 -1
  39. package/src/swaps/SwapHandlerSwap.ts +2 -0
  40. package/src/swaps/assertions/FromBtcAmountAssertions.ts +2 -2
  41. package/src/swaps/assertions/ToBtcAmountAssertions.ts +2 -2
  42. package/src/swaps/escrow/frombtc_abstract/FromBtcAbs.ts +11 -0
  43. package/src/swaps/escrow/frombtc_abstract/FromBtcSwapAbs.ts +4 -0
  44. package/src/swaps/escrow/frombtcln_abstract/FromBtcLnAbs.ts +23 -1
  45. package/src/swaps/escrow/frombtcln_abstract/FromBtcLnSwapAbs.ts +4 -0
  46. package/src/swaps/escrow/frombtcln_autoinit/FromBtcLnAuto.ts +15 -1
  47. package/src/swaps/escrow/frombtcln_autoinit/FromBtcLnAutoSwap.ts +4 -0
  48. package/src/swaps/escrow/tobtc_abstract/ToBtcAbs.ts +29 -3
  49. package/src/swaps/escrow/tobtc_abstract/ToBtcSwapAbs.ts +4 -0
  50. package/src/swaps/escrow/tobtcln_abstract/ToBtcLnAbs.ts +19 -2
  51. package/src/swaps/escrow/tobtcln_abstract/ToBtcLnSwapAbs.ts +4 -0
  52. package/src/swaps/spv_vault_swap/SpvVaultSwap.ts +4 -0
  53. package/src/swaps/spv_vault_swap/SpvVaultSwapHandler.ts +17 -2
  54. package/src/swaps/trusted/frombtc_trusted/FromBtcTrusted.ts +53 -33
  55. package/src/swaps/trusted/frombtc_trusted/FromBtcTrustedSwap.ts +4 -0
  56. package/src/swaps/trusted/frombtcln_trusted/FromBtcLnTrusted.ts +20 -1
  57. package/src/swaps/trusted/frombtcln_trusted/FromBtcLnTrustedSwap.ts +4 -0
@@ -105,4 +105,8 @@ export class ToBtcSwapAbs<T extends SwapData = SwapData> extends ToBtcBaseSwap<T
105
105
  return this.state===ToBtcSwapState.CLAIMED;
106
106
  }
107
107
 
108
+ getDestinationAddress(): string {
109
+ return this.address;
110
+ }
111
+
108
112
  }
@@ -28,6 +28,8 @@ import {
28
28
  routesMatch
29
29
  } from "../../../wallets/ILightningWallet";
30
30
  import { LightningAssertions } from "../../assertions/LightningAssertions";
31
+ import {isQuoteThrow} from "../../../plugins/IPlugin";
32
+ import {ToBtcSwapState} from "../tobtc_abstract/ToBtcSwapAbs";
31
33
 
32
34
  export type ToBtcLnConfig = ToBtcBaseConfig & {
33
35
  routingFeeMultiplier: bigint,
@@ -305,7 +307,7 @@ export class ToBtcLnAbs extends ToBtcBaseSwapHandler<ToBtcLnSwapAbs, ToBtcLnSwap
305
307
  return true;
306
308
  }
307
309
 
308
- private async sendLightningPayment(swap: ToBtcLnSwapAbs): Promise<void> {
310
+ private async sendLightningPayment(swap: ToBtcLnSwapAbs): Promise<boolean> {
309
311
  const decodedPR = await this.lightning.parsePaymentRequest(swap.pr);
310
312
  const expiryTimestamp: bigint = swap.data.getExpiry();
311
313
  const currentTimestamp: bigint = BigInt(Math.floor(Date.now()/1000));
@@ -336,6 +338,19 @@ export class ToBtcLnAbs extends ToBtcBaseSwapHandler<ToBtcLnSwapAbs, ToBtcLnSwap
336
338
 
337
339
  const blockHeight = await this.lightning.getBlockheight();
338
340
 
341
+ const pluginCheckResult = await PluginManager.onHandlePreToBtcExecute(
342
+ SwapHandlerType.TO_BTCLN,
343
+ swap
344
+ );
345
+ if(isQuoteThrow(pluginCheckResult)) {
346
+ throw {
347
+ code: 29999,
348
+ msg: pluginCheckResult.message
349
+ };
350
+ }
351
+
352
+ if(swap.state!==ToBtcLnSwapState.COMMITED) return false;
353
+
339
354
  swap.payInitiated = true;
340
355
  await this.saveSwapData(swap);
341
356
  try {
@@ -354,6 +369,8 @@ export class ToBtcLnAbs extends ToBtcBaseSwapHandler<ToBtcLnSwapAbs, ToBtcLnSwap
354
369
  }
355
370
  }
356
371
  if(swap.metadata!=null) swap.metadata.times.payComplete = Date.now();
372
+
373
+ return true;
357
374
  }
358
375
 
359
376
  /**
@@ -404,7 +421,7 @@ export class ToBtcLnAbs extends ToBtcBaseSwapHandler<ToBtcLnSwapAbs, ToBtcLnSwap
404
421
  await swap.setState(ToBtcLnSwapState.COMMITED);
405
422
  await this.saveSwapData(swap);
406
423
  try {
407
- await this.sendLightningPayment(swap);
424
+ if(!await this.sendLightningPayment(swap)) return;
408
425
  } catch (e) {
409
426
  this.swapLogger.error(swap, "processInitialized(): lightning payment error", e);
410
427
  if(isDefinedRuntimeError(e)) {
@@ -78,4 +78,8 @@ export class ToBtcLnSwapAbs<T extends SwapData = SwapData> extends ToBtcBaseSwap
78
78
  return this.state===ToBtcLnSwapState.CLAIMED;
79
79
  }
80
80
 
81
+ getDestinationAddress(): string {
82
+ return this.pr;
83
+ }
84
+
81
85
  }
@@ -225,4 +225,8 @@ export class SpvVaultSwap extends SwapHandlerSwap<SpvVaultSwapState> {
225
225
  return this.state===SpvVaultSwapState.CLAIMED;
226
226
  }
227
227
 
228
+ getDestinationAddress(): string {
229
+ return this.recipient;
230
+ }
231
+
228
232
  }
@@ -37,6 +37,7 @@ import {Transaction} from "@scure/btc-signer";
37
37
  import {SpvVaults, VAULT_DUST_AMOUNT} from "./SpvVaults";
38
38
  import {isLegacyInput} from "../../utils/BitcoinUtils";
39
39
  import {AmountAssertions} from "../assertions/AmountAssertions";
40
+ import {isQuoteThrow} from "../../plugins/IPlugin";
40
41
 
41
42
  export type SpvVaultSwapHandlerConfig = SwapBaseConfig & {
42
43
  vaultsCheckInterval: number,
@@ -599,7 +600,7 @@ export class SpvVaultSwapHandler extends SwapHandler<SpvVaultSwap, SpvVaultSwapS
599
600
  if(swap.vaultUtxo!==vault.getLatestUtxo()) {
600
601
  throw {
601
602
  code: 20510,
602
- msg: "Vault UTXO already spent, please try again!"
603
+ msg: "Vault UTXO already spent, please get another quote and try again!"
603
604
  };
604
605
  }
605
606
 
@@ -624,11 +625,25 @@ export class SpvVaultSwapHandler extends SwapHandler<SpvVaultSwap, SpvVaultSwapS
624
625
  msg: "Bitcoin transaction size too large, maximum: "+TX_MAX_VSIZE+" actual: "+txVsize
625
626
  };
626
627
 
628
+ const pluginCheckResult = await PluginManager.onHandlePreFromBtcExecute(
629
+ SwapHandlerType.FROM_BTC_SPV,
630
+ swap
631
+ );
632
+ if(isQuoteThrow(pluginCheckResult)) {
633
+ const error = {
634
+ code: 29999,
635
+ msg: pluginCheckResult.message
636
+ }
637
+ if(swap.metadata!=null) swap.metadata.postQuoteError = error;
638
+ await this.removeSwapData(swap, SpvVaultSwapState.FAILED);
639
+ throw error;
640
+ }
641
+
627
642
  await this.Vaults.checkVaultReplacedTransactions(vault, true);
628
643
  if(swap.vaultUtxo!==vault.getLatestUtxo()) {
629
644
  throw {
630
645
  code: 20510,
631
- msg: "Vault UTXO already spent, please try again!"
646
+ msg: "Vault UTXO already spent, please get another quote and try again!"
632
647
  };
633
648
  }
634
649
 
@@ -11,6 +11,7 @@ import {ServerParamEncoder} from "../../../utils/paramcoders/server/ServerParamE
11
11
  import {FieldTypeEnum, verifySchema} from "../../../utils/paramcoders/SchemaVerifier";
12
12
  import {IBitcoinWallet} from "../../../wallets/IBitcoinWallet";
13
13
  import {FromBtcAmountAssertions} from "../../assertions/FromBtcAmountAssertions";
14
+ import {isQuoteThrow} from "../../../plugins/IPlugin";
14
15
 
15
16
  export type FromBtcTrustedConfig = SwapBaseConfig & {
16
17
  doubleSpendCheckInterval: number,
@@ -67,49 +68,51 @@ export class FromBtcTrusted extends SwapHandler<FromBtcTrustedSwap, FromBtcTrust
67
68
  }
68
69
 
69
70
  private async refundSwap(swap: FromBtcTrustedSwap) {
70
- if(swap.refundAddress==null) {
71
- if(swap.state!==FromBtcTrustedSwapState.REFUNDABLE) {
72
- await swap.setState(FromBtcTrustedSwapState.REFUNDABLE);
73
- await this.storageManager.saveData(swap.getIdentifierHash(), swap.getSequence(), swap);
74
- }
75
- return;
71
+ if(swap.state!==FromBtcTrustedSwapState.REFUNDABLE) {
72
+ await swap.setState(FromBtcTrustedSwapState.REFUNDABLE);
73
+ await this.storageManager.saveData(swap.getIdentifierHash(), swap.getSequence(), swap);
76
74
  }
77
75
 
78
- let unlock = swap.lock(30*1000);
76
+ if(swap.refundAddress==null) return;
77
+
78
+ let unlock = swap.lock(Infinity);
79
79
  if(unlock==null) return;
80
80
 
81
- const feeRate = await this.bitcoin.getFeeRate();
81
+ try {
82
+ const feeRate = await this.bitcoin.getFeeRate();
82
83
 
83
- const ourOutput = swap.btcTx.outs[swap.vout];
84
+ const ourOutput = swap.btcTx.outs[swap.vout];
84
85
 
85
- const resp = await this.bitcoin.drainAll(swap.refundAddress, [{
86
- type: this.bitcoin.getAddressType(),
87
- confirmations: swap.btcTx.confirmations,
88
- outputScript: Buffer.from(ourOutput.scriptPubKey.hex, "hex"),
89
- value: ourOutput.value,
90
- txId: swap.btcTx.txid,
91
- vout: swap.vout
92
- }], feeRate);
86
+ const resp = await this.bitcoin.drainAll(swap.refundAddress, [{
87
+ type: this.bitcoin.getAddressType(),
88
+ confirmations: swap.btcTx.confirmations,
89
+ outputScript: Buffer.from(ourOutput.scriptPubKey.hex, "hex"),
90
+ value: ourOutput.value,
91
+ txId: swap.btcTx.txid,
92
+ vout: swap.vout
93
+ }], feeRate);
93
94
 
94
- if(resp==null) {
95
- this.swapLogger.error(swap, "refundSwap(): cannot refund swap because of dust limit, txId: "+swap.txId);
96
- unlock();
97
- return;
98
- }
95
+ if(resp==null) {
96
+ this.swapLogger.error(swap, "refundSwap(): cannot refund swap because of dust limit, txId: "+swap.txId);
97
+ unlock();
98
+ return;
99
+ }
99
100
 
100
- if(swap.metadata!=null) swap.metadata.times.refundSignPSBT = Date.now();
101
- this.swapLogger.debug(swap, "refundSwap(): signed raw transaction: "+resp.raw);
101
+ if(swap.metadata!=null) swap.metadata.times.refundSignPSBT = Date.now();
102
+ this.swapLogger.debug(swap, "refundSwap(): signed raw transaction: "+resp.raw);
102
103
 
103
- const refundTxId = resp.txId;
104
- swap.refundTxId = refundTxId;
104
+ const refundTxId = resp.txId;
105
+ swap.refundTxId = refundTxId;
105
106
 
106
- //Send the refund TX
107
- await this.bitcoin.sendRawTransaction(resp.raw);
108
- this.swapLogger.debug(swap, "refundSwap(): sent refund transaction: "+refundTxId);
107
+ //Send the refund TX
108
+ await this.bitcoin.sendRawTransaction(resp.raw);
109
+ this.swapLogger.debug(swap, "refundSwap(): sent refund transaction: "+refundTxId);
109
110
 
110
- this.refundedSwaps.set(swap.getIdentifierHash(), refundTxId);
111
- await this.removeSwapData(swap, FromBtcTrustedSwapState.REFUNDED);
112
- unlock();
111
+ this.refundedSwaps.set(swap.getIdentifierHash(), refundTxId);
112
+ await this.removeSwapData(swap, FromBtcTrustedSwapState.REFUNDED);
113
+ } finally {
114
+ unlock();
115
+ }
113
116
  }
114
117
 
115
118
  private async burn(swap: FromBtcTrustedSwap) {
@@ -293,10 +296,27 @@ export class FromBtcTrusted extends SwapHandler<FromBtcTrustedSwap, FromBtcTrust
293
296
 
294
297
  if(swap.state!==FromBtcTrustedSwapState.BTC_CONFIRMED) return;
295
298
 
299
+ const txns = await chainInterface.txsTransfer(signer.getAddress(), swap.token, swap.adjustedOutput, swap.dstAddress);
300
+
296
301
  let unlock = swap.lock(30*1000);
297
302
  if(unlock==null) return;
298
303
 
299
- const txns = await chainInterface.txsTransfer(signer.getAddress(), swap.token, swap.adjustedOutput, swap.dstAddress);
304
+ const pluginCheckResult = await PluginManager.onHandlePreFromBtcExecute(
305
+ SwapHandlerType.FROM_BTC_TRUSTED,
306
+ swap
307
+ );
308
+ if(isQuoteThrow(pluginCheckResult)) {
309
+ this.swapLogger.error(swap, "processPastSwap(): Error, got negative response from plugin: ", pluginCheckResult);
310
+ await this.refundSwap(swap);
311
+ unlock();
312
+ return;
313
+ }
314
+
315
+ if(swap.state!==FromBtcTrustedSwapState.BTC_CONFIRMED) {
316
+ unlock();
317
+ return;
318
+ }
319
+
300
320
  await chainInterface.sendAndConfirm(signer, txns, true, null, false, async (txId: string, rawTx: string) => {
301
321
  swap.txIds = {init: txId};
302
322
  swap.scRawTx = rawTx;
@@ -183,4 +183,8 @@ export class FromBtcTrustedSwap extends SwapHandlerSwap<FromBtcTrustedSwapState>
183
183
  return createHash("sha256").update(this.btcAddress).digest().toString("hex");
184
184
  }
185
185
 
186
+ getDestinationAddress(): string {
187
+ return this.dstAddress;
188
+ }
189
+
186
190
  }
@@ -16,7 +16,8 @@ import {
16
16
  LightningNetworkInvoice
17
17
  } from "../../../wallets/ILightningWallet";
18
18
  import {FromBtcAmountAssertions} from "../../assertions/FromBtcAmountAssertions";
19
- import { LightningAssertions } from "../../assertions/LightningAssertions";
19
+ import {LightningAssertions} from "../../assertions/LightningAssertions";
20
+ import {isQuoteThrow} from "../../../plugins/IPlugin";
20
21
 
21
22
  export type SwapForGasServerConfig = SwapBaseConfig & {
22
23
  minCltv: bigint,
@@ -227,6 +228,24 @@ export class FromBtcLnTrusted extends SwapHandler<FromBtcLnTrustedSwap, FromBtcL
227
228
  let unlock = invoiceData.lock(Infinity);
228
229
  if(unlock==null) return;
229
230
 
231
+ const pluginCheckResult = await PluginManager.onHandlePreFromBtcExecute(
232
+ SwapHandlerType.FROM_BTCLN_TRUSTED,
233
+ invoiceData
234
+ );
235
+ if(isQuoteThrow(pluginCheckResult)) {
236
+ await this.cancelSwapAndInvoice(invoiceData);
237
+ unlock();
238
+ throw {
239
+ code: 29999,
240
+ msg: pluginCheckResult.message
241
+ };
242
+ }
243
+
244
+ if(invoiceData.state!==FromBtcLnTrustedSwapState.RECEIVED) {
245
+ unlock();
246
+ return;
247
+ }
248
+
230
249
  const result = await chainInterface.sendAndConfirm(signer, txns, true, null, false, async (txId: string, rawTx: string) => {
231
250
  invoiceData.txIds = {init: txId};
232
251
  invoiceData.scRawTx = rawTx;
@@ -118,4 +118,8 @@ export class FromBtcLnTrustedSwap extends SwapHandlerSwap<FromBtcLnTrustedSwapSt
118
118
  return createHash("sha256").update(Buffer.from(this.secret, "hex")).digest().toString("hex");
119
119
  }
120
120
 
121
+ getDestinationAddress(): string {
122
+ return this.dstAddress;
123
+ }
124
+
121
125
  }