@atomiqlabs/lp-lib 17.1.2 → 17.3.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.
Files changed (53) hide show
  1. package/dist/info/InfoHandler.js +2 -1
  2. package/dist/plugins/IPlugin.d.ts +15 -1
  3. package/dist/plugins/IPlugin.js +9 -8
  4. package/dist/plugins/PluginManager.d.ts +3 -1
  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/escrow/frombtc_abstract/FromBtcAbs.js +7 -0
  9. package/dist/swaps/escrow/frombtc_abstract/FromBtcSwapAbs.d.ts +1 -0
  10. package/dist/swaps/escrow/frombtc_abstract/FromBtcSwapAbs.js +3 -0
  11. package/dist/swaps/escrow/frombtcln_abstract/FromBtcLnAbs.js +31 -11
  12. package/dist/swaps/escrow/frombtcln_abstract/FromBtcLnSwapAbs.d.ts +1 -0
  13. package/dist/swaps/escrow/frombtcln_abstract/FromBtcLnSwapAbs.js +3 -0
  14. package/dist/swaps/escrow/frombtcln_autoinit/FromBtcLnAuto.js +14 -2
  15. package/dist/swaps/escrow/frombtcln_autoinit/FromBtcLnAutoSwap.d.ts +1 -0
  16. package/dist/swaps/escrow/frombtcln_autoinit/FromBtcLnAutoSwap.js +3 -0
  17. package/dist/swaps/escrow/tobtc_abstract/ToBtcAbs.js +25 -2
  18. package/dist/swaps/escrow/tobtc_abstract/ToBtcSwapAbs.d.ts +1 -0
  19. package/dist/swaps/escrow/tobtc_abstract/ToBtcSwapAbs.js +3 -0
  20. package/dist/swaps/escrow/tobtcln_abstract/ToBtcLnAbs.js +13 -1
  21. package/dist/swaps/escrow/tobtcln_abstract/ToBtcLnSwapAbs.d.ts +1 -0
  22. package/dist/swaps/escrow/tobtcln_abstract/ToBtcLnSwapAbs.js +3 -0
  23. package/dist/swaps/spv_vault_swap/SpvVaultSwap.d.ts +1 -0
  24. package/dist/swaps/spv_vault_swap/SpvVaultSwap.js +3 -0
  25. package/dist/swaps/spv_vault_swap/SpvVaultSwapHandler.js +14 -2
  26. package/dist/swaps/trusted/frombtc_trusted/FromBtcTrusted.js +47 -32
  27. package/dist/swaps/trusted/frombtc_trusted/FromBtcTrustedSwap.d.ts +1 -0
  28. package/dist/swaps/trusted/frombtc_trusted/FromBtcTrustedSwap.js +3 -0
  29. package/dist/swaps/trusted/frombtcln_trusted/FromBtcLnTrusted.js +14 -0
  30. package/dist/swaps/trusted/frombtcln_trusted/FromBtcLnTrustedSwap.d.ts +1 -0
  31. package/dist/swaps/trusted/frombtcln_trusted/FromBtcLnTrustedSwap.js +3 -0
  32. package/package.json +2 -2
  33. package/src/info/InfoHandler.ts +6 -3
  34. package/src/plugins/IPlugin.ts +34 -12
  35. package/src/plugins/PluginManager.ts +39 -4
  36. package/src/swaps/SwapHandler.ts +2 -1
  37. package/src/swaps/SwapHandlerSwap.ts +2 -0
  38. package/src/swaps/escrow/frombtc_abstract/FromBtcAbs.ts +11 -0
  39. package/src/swaps/escrow/frombtc_abstract/FromBtcSwapAbs.ts +4 -0
  40. package/src/swaps/escrow/frombtcln_abstract/FromBtcLnAbs.ts +23 -1
  41. package/src/swaps/escrow/frombtcln_abstract/FromBtcLnSwapAbs.ts +4 -0
  42. package/src/swaps/escrow/frombtcln_autoinit/FromBtcLnAuto.ts +15 -1
  43. package/src/swaps/escrow/frombtcln_autoinit/FromBtcLnAutoSwap.ts +4 -0
  44. package/src/swaps/escrow/tobtc_abstract/ToBtcAbs.ts +29 -3
  45. package/src/swaps/escrow/tobtc_abstract/ToBtcSwapAbs.ts +4 -0
  46. package/src/swaps/escrow/tobtcln_abstract/ToBtcLnAbs.ts +19 -2
  47. package/src/swaps/escrow/tobtcln_abstract/ToBtcLnSwapAbs.ts +4 -0
  48. package/src/swaps/spv_vault_swap/SpvVaultSwap.ts +4 -0
  49. package/src/swaps/spv_vault_swap/SpvVaultSwapHandler.ts +17 -2
  50. package/src/swaps/trusted/frombtc_trusted/FromBtcTrusted.ts +53 -33
  51. package/src/swaps/trusted/frombtc_trusted/FromBtcTrustedSwap.ts +4 -0
  52. package/src/swaps/trusted/frombtcln_trusted/FromBtcLnTrusted.ts +20 -1
  53. package/src/swaps/trusted/frombtcln_trusted/FromBtcLnTrustedSwap.ts +4 -0
@@ -43,7 +43,8 @@ class InfoHandler {
43
43
  const singleChain = this.chainData.chains[chainIdentifier];
44
44
  chains[chainIdentifier] = {
45
45
  address: singleChain.signer.getAddress(),
46
- signature: await singleChain.swapContract.getDataSignature(singleChain.signer, envelopeBuffer)
46
+ signature: await singleChain.swapContract.getDataSignature(singleChain.signer, envelopeBuffer),
47
+ contractVersion: singleChain.contractVersion ?? "v1"
47
48
  };
48
49
  }
49
50
  const response = {
@@ -1,5 +1,5 @@
1
1
  import { BitcoinRpc } from "@atomiqlabs/base";
2
- import { FromBtcLnRequestType, FromBtcRequestType, FromBtcTrustedRequestType, ISwapPrice, MultichainData, RequestData, SpvVaultPostQuote, SpvVaultSwap, SpvVaultSwapRequestType, SwapHandler, SwapHandlerType, ToBtcLnRequestType, ToBtcRequestType } from "..";
2
+ import { FromBtcLnAutoSwap, FromBtcLnRequestType, FromBtcLnSwapAbs, FromBtcLnTrustedSwap, FromBtcRequestType, FromBtcSwapAbs, FromBtcTrustedRequestType, FromBtcTrustedSwap, ISwapPrice, MultichainData, RequestData, SpvVaultPostQuote, SpvVaultSwap, SpvVaultSwapRequestType, SwapHandler, SwapHandlerType, ToBtcLnRequestType, ToBtcLnSwapAbs, ToBtcRequestType, ToBtcSwapAbs } from "..";
3
3
  import { SwapHandlerSwap } from "../swaps/SwapHandlerSwap";
4
4
  import { Command } from "@atomiqlabs/server-base";
5
5
  import { FromBtcLnTrustedRequestType } from "../swaps/trusted/frombtcln_trusted/FromBtcLnTrusted";
@@ -104,6 +104,19 @@ export interface IPlugin {
104
104
  token: string;
105
105
  pricePrefetch?: Promise<bigint>;
106
106
  }): Promise<QuoteThrow | QuoteSetFees | QuoteAmountTooLow | QuoteAmountTooHigh | PluginQuote>;
107
+ /**
108
+ * Triggered when the quote is about to get executed, this means:
109
+ * - FROM_BTCLN - lightning network payment received and the LP is about to sign an authorization allowing the user to settle
110
+ * - FROM_BTC - triggered on quote request, before the final authorization is given to the user
111
+ * - FROM_BTCLN_TRUSTED - triggered when the LP receives the funds on the source chain and before destination funds are sent
112
+ * - FROM_BTC_TRUSTED - triggered when the LP receives the funds on the source chain and before destination funds are sent
113
+ * - FROM_BTC_SPV - triggered before LP broadcasts the co-signed swap PSBT
114
+ * - FROM_BTCLN_AUTO - lightning network payment received and the LP is about to offer an HTLC to the user
115
+ *
116
+ * @param swapType
117
+ * @param swap
118
+ */
119
+ onHandlePreFromBtcExecute?(swapType: SwapHandlerType.FROM_BTCLN | SwapHandlerType.FROM_BTC | SwapHandlerType.FROM_BTCLN_TRUSTED | SwapHandlerType.FROM_BTC_TRUSTED | SwapHandlerType.FROM_BTC_SPV | SwapHandlerType.FROM_BTCLN_AUTO, swap: FromBtcLnSwapAbs | FromBtcSwapAbs | FromBtcLnTrustedSwap | FromBtcTrustedSwap | SpvVaultSwap | FromBtcLnAutoSwap): Promise<QuoteThrow | null>;
107
120
  onHandlePreToBtcQuote?(swapType: SwapHandlerType.TO_BTCLN | SwapHandlerType.TO_BTC, request: RequestData<ToBtcLnRequestType | ToBtcRequestType>, requestedAmount: {
108
121
  input: boolean;
109
122
  amount: bigint;
@@ -128,6 +141,7 @@ export interface IPlugin {
128
141
  feePPM: bigint;
129
142
  networkFeeGetter: (amount: bigint) => Promise<bigint>;
130
143
  }): Promise<QuoteThrow | QuoteSetFees | QuoteAmountTooLow | QuoteAmountTooHigh | ToBtcPluginQuote>;
144
+ onHandlePreToBtcExecute?(swapType: SwapHandlerType.TO_BTCLN | SwapHandlerType.TO_BTC, swap: ToBtcLnSwapAbs | ToBtcSwapAbs): Promise<QuoteThrow | null>;
131
145
  onHandlePostedFromBtcQuote?(swapType: SwapHandlerType.FROM_BTC_SPV, request: RequestData<SpvVaultPostQuote>, swap: SpvVaultSwap): Promise<QuoteThrow | null>;
132
146
  onVaultSelection?(chainIdentifier: string, totalSats: bigint, requestedAmount: {
133
147
  amount: bigint;
@@ -2,11 +2,12 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.isToBtcPluginQuote = exports.isPluginQuote = exports.isQuoteAmountTooHigh = exports.isQuoteAmountTooLow = exports.isQuoteSetFees = exports.isQuoteThrow = void 0;
4
4
  function isQuoteThrow(obj) {
5
- return obj.type === "throw" && typeof (obj.message) === "string";
5
+ return obj != null && obj.type === "throw" && typeof (obj.message) === "string";
6
6
  }
7
7
  exports.isQuoteThrow = isQuoteThrow;
8
8
  function isQuoteSetFees(obj) {
9
- return obj.type === "fees" &&
9
+ return obj != null &&
10
+ obj.type === "fees" &&
10
11
  (obj.baseFee == null || typeof (obj.baseFee) === "bigint") &&
11
12
  (obj.feePPM == null || typeof (obj.feePPM) === "bigint") &&
12
13
  (obj.securityDepositApyPPM == null || typeof (obj.securityDepositApyPPM) === "bigint") &&
@@ -14,21 +15,21 @@ function isQuoteSetFees(obj) {
14
15
  }
15
16
  exports.isQuoteSetFees = isQuoteSetFees;
16
17
  function isQuoteAmountTooLow(obj) {
17
- return obj.type === "low" && typeof (obj.data) === "object" && typeof (obj.data.min) === "bigint" && typeof (obj.data.max) === "bigint";
18
+ return obj != null && obj.type === "low" && obj.data != null && typeof (obj.data) === "object" && typeof (obj.data.min) === "bigint" && typeof (obj.data.max) === "bigint";
18
19
  }
19
20
  exports.isQuoteAmountTooLow = isQuoteAmountTooLow;
20
21
  function isQuoteAmountTooHigh(obj) {
21
- return obj.type === "high" && typeof (obj.data) === "object" && typeof (obj.data.min) === "bigint" && typeof (obj.data.max) === "bigint";
22
+ return obj != null && obj.type === "high" && obj.data != null && typeof (obj.data) === "object" && typeof (obj.data.min) === "bigint" && typeof (obj.data.max) === "bigint";
22
23
  }
23
24
  exports.isQuoteAmountTooHigh = isQuoteAmountTooHigh;
24
25
  function isPluginQuote(obj) {
25
- return obj.type === "success" &&
26
- typeof (obj.amount) === "object" && typeof (obj.amount.input) === "boolean" && typeof (obj.amount.amount) === "bigint" &&
27
- typeof (obj.swapFee) === "object" && typeof (obj.swapFee.inInputTokens) === "bigint" && typeof (obj.swapFee.inOutputTokens) === "bigint";
26
+ return obj != null && obj.type === "success" &&
27
+ obj.amount != null && typeof (obj.amount) === "object" && typeof (obj.amount.input) === "boolean" && typeof (obj.amount.amount) === "bigint" &&
28
+ obj.swapFee != null && typeof (obj.swapFee) === "object" && typeof (obj.swapFee.inInputTokens) === "bigint" && typeof (obj.swapFee.inOutputTokens) === "bigint";
28
29
  }
29
30
  exports.isPluginQuote = isPluginQuote;
30
31
  function isToBtcPluginQuote(obj) {
31
- return typeof (obj.networkFee) === "object" && typeof (obj.networkFee.inInputTokens) === "bigint" && typeof (obj.networkFee.inOutputTokens) === "bigint" &&
32
+ return obj != null && obj.networkFee != null && typeof (obj.networkFee) === "object" && typeof (obj.networkFee.inInputTokens) === "bigint" && typeof (obj.networkFee.inOutputTokens) === "bigint" &&
32
33
  isPluginQuote(obj);
33
34
  }
34
35
  exports.isToBtcPluginQuote = isToBtcPluginQuote;
@@ -1,6 +1,6 @@
1
1
  import { BitcoinRpc, SwapData } from "@atomiqlabs/base";
2
2
  import { IPlugin, PluginQuote, QuoteAmountTooHigh, QuoteAmountTooLow, QuoteSetFees, QuoteThrow, ToBtcPluginQuote } from "./IPlugin";
3
- import { FromBtcLnRequestType, FromBtcRequestType, FromBtcTrustedRequestType, ISwapPrice, MultichainData, RequestData, SpvVaultPostQuote, SpvVaultSwap, SpvVaultSwapRequestType, SwapHandler, SwapHandlerType, ToBtcLnRequestType, ToBtcRequestType } from "..";
3
+ import { FromBtcLnAutoSwap, FromBtcLnRequestType, FromBtcLnSwapAbs, FromBtcLnTrustedSwap, FromBtcRequestType, FromBtcSwapAbs, FromBtcTrustedRequestType, FromBtcTrustedSwap, ISwapPrice, MultichainData, RequestData, SpvVaultPostQuote, SpvVaultSwap, SpvVaultSwapRequestType, SwapHandler, SwapHandlerType, ToBtcLnRequestType, ToBtcLnSwapAbs, ToBtcRequestType, ToBtcSwapAbs } from "..";
4
4
  import { SwapHandlerSwap } from "../swaps/SwapHandlerSwap";
5
5
  import { FromBtcLnTrustedRequestType } from "../swaps/trusted/frombtcln_trusted/FromBtcLnTrusted";
6
6
  import { IBitcoinWallet } from "../wallets/IBitcoinWallet";
@@ -73,6 +73,7 @@ export declare class PluginManager {
73
73
  amount: bigint;
74
74
  token: string;
75
75
  }): Promise<QuoteThrow | QuoteSetFees | QuoteAmountTooLow | QuoteAmountTooHigh>;
76
+ static onHandlePreFromBtcExecute(swapType: SwapHandlerType.FROM_BTCLN | SwapHandlerType.FROM_BTC | SwapHandlerType.FROM_BTCLN_TRUSTED | SwapHandlerType.FROM_BTC_TRUSTED | SwapHandlerType.FROM_BTC_SPV | SwapHandlerType.FROM_BTCLN_AUTO, swap: FromBtcLnSwapAbs | FromBtcSwapAbs | FromBtcLnTrustedSwap | FromBtcTrustedSwap | SpvVaultSwap | FromBtcLnAutoSwap): Promise<QuoteThrow | null>;
76
77
  static onHandlePostToBtcQuote<T extends {
77
78
  networkFee: bigint;
78
79
  }>(swapType: SwapHandlerType.TO_BTCLN | SwapHandlerType.TO_BTC, request: RequestData<ToBtcLnRequestType | ToBtcRequestType>, requestedAmount: {
@@ -101,6 +102,7 @@ export declare class PluginManager {
101
102
  baseFeeInBtc: bigint;
102
103
  feePPM: bigint;
103
104
  }): Promise<QuoteThrow | QuoteSetFees | QuoteAmountTooLow | QuoteAmountTooHigh>;
105
+ static onHandlePreToBtcExecute(swapType: SwapHandlerType.TO_BTCLN | SwapHandlerType.TO_BTC, swap: ToBtcLnSwapAbs | ToBtcSwapAbs): Promise<QuoteThrow | null>;
104
106
  static onHandlePostedFromBtcQuote(swapType: SwapHandlerType.FROM_BTC_SPV, request: RequestData<SpvVaultPostQuote>, swap: SpvVaultSwap): Promise<QuoteThrow | null>;
105
107
  static onVaultSelection(chainIdentifier: string, totalSats: bigint, requestedAmount: {
106
108
  amount: bigint;
@@ -152,6 +152,21 @@ class PluginManager {
152
152
  }
153
153
  return null;
154
154
  }
155
+ static async onHandlePreFromBtcExecute(swapType, swap) {
156
+ for (let plugin of PluginManager.plugins.values()) {
157
+ try {
158
+ if (plugin.onHandlePreFromBtcExecute != null) {
159
+ const result = await plugin.onHandlePreFromBtcExecute(swapType, swap);
160
+ if (result != null && (0, IPlugin_1.isQuoteThrow)(result))
161
+ return result;
162
+ }
163
+ }
164
+ catch (e) {
165
+ pluginLogger.error(plugin, "onHandlePreFromBtcExecute(): plugin error", e);
166
+ }
167
+ }
168
+ return null;
169
+ }
155
170
  static async onHandlePostToBtcQuote(swapType, request, requestedAmount, chainIdentifier, constraints, fees) {
156
171
  for (let plugin of PluginManager.plugins.values()) {
157
172
  try {
@@ -214,6 +229,21 @@ class PluginManager {
214
229
  }
215
230
  return null;
216
231
  }
232
+ static async onHandlePreToBtcExecute(swapType, swap) {
233
+ for (let plugin of PluginManager.plugins.values()) {
234
+ try {
235
+ if (plugin.onHandlePreToBtcExecute != null) {
236
+ const result = await plugin.onHandlePreToBtcExecute(swapType, swap);
237
+ if (result != null && (0, IPlugin_1.isQuoteThrow)(result))
238
+ return result;
239
+ }
240
+ }
241
+ catch (e) {
242
+ pluginLogger.error(plugin, "onHandlePreToBtcExecute(): plugin error", e);
243
+ }
244
+ }
245
+ return null;
246
+ }
217
247
  static async onHandlePostedFromBtcQuote(swapType, request, swap) {
218
248
  for (let plugin of PluginManager.plugins.values()) {
219
249
  try {
@@ -59,6 +59,7 @@ export type ChainData<T extends ChainType = ChainType> = {
59
59
  };
60
60
  allowedDepositTokens?: string[];
61
61
  btcRelay?: T["BtcRelay"];
62
+ contractVersion?: string;
62
63
  };
63
64
  export type RequestData<T> = {
64
65
  chainIdentifier: string;
@@ -76,4 +76,5 @@ export declare abstract class SwapHandlerSwap<S = any> extends Lockable implemen
76
76
  inInputToken: bigint;
77
77
  inOutputToken: bigint;
78
78
  };
79
+ abstract getDestinationAddress(): string;
79
80
  }
@@ -10,6 +10,7 @@ const PluginManager_1 = require("../../../plugins/PluginManager");
10
10
  const SchemaVerifier_1 = require("../../../utils/paramcoders/SchemaVerifier");
11
11
  const ServerParamDecoder_1 = require("../../../utils/paramcoders/server/ServerParamDecoder");
12
12
  const FromBtcBaseSwapHandler_1 = require("../FromBtcBaseSwapHandler");
13
+ const IPlugin_1 = require("../../../plugins/IPlugin");
13
14
  /**
14
15
  * Swap handler handling from BTC swaps using PTLCs (proof-time locked contracts) and btc relay (on-chain bitcoin SPV)
15
16
  */
@@ -281,6 +282,12 @@ class FromBtcAbs extends FromBtcBaseSwapHandler_1.FromBtcBaseSwapHandler {
281
282
  createdSwap.timeout = sigData.timeout;
282
283
  createdSwap.signature = sigData.signature;
283
284
  createdSwap.feeRate = sigData.feeRate;
285
+ const pluginCheckResult = await PluginManager_1.PluginManager.onHandlePreFromBtcExecute(SwapHandler_1.SwapHandlerType.FROM_BTC, createdSwap);
286
+ if ((0, IPlugin_1.isQuoteThrow)(pluginCheckResult))
287
+ throw {
288
+ code: 29999,
289
+ msg: pluginCheckResult.message
290
+ };
284
291
  await PluginManager_1.PluginManager.swapCreate(createdSwap);
285
292
  await this.saveSwapData(createdSwap);
286
293
  this.swapLogger.info(createdSwap, "REST: /getAddress: Created swap address: " + receiveAddress + " amount: " + amountBD.toString(10));
@@ -18,4 +18,5 @@ export declare class FromBtcSwapAbs<T extends SwapData = SwapData> extends FromB
18
18
  isFailed(): boolean;
19
19
  isSuccess(): boolean;
20
20
  getTotalInputAmount(): bigint;
21
+ getDestinationAddress(): string;
21
22
  }
@@ -46,5 +46,8 @@ class FromBtcSwapAbs extends FromBtcBaseSwap_1.FromBtcBaseSwap {
46
46
  getTotalInputAmount() {
47
47
  return this.amount;
48
48
  }
49
+ getDestinationAddress() {
50
+ return this.data.getClaimer();
51
+ }
49
52
  }
50
53
  exports.FromBtcSwapAbs = FromBtcSwapAbs;
@@ -11,6 +11,7 @@ const SchemaVerifier_1 = require("../../../utils/paramcoders/SchemaVerifier");
11
11
  const ServerParamDecoder_1 = require("../../../utils/paramcoders/server/ServerParamDecoder");
12
12
  const FromBtcBaseSwapHandler_1 = require("../FromBtcBaseSwapHandler");
13
13
  const LightningAssertions_1 = require("../../assertions/LightningAssertions");
14
+ const IPlugin_1 = require("../../../plugins/IPlugin");
14
15
  /**
15
16
  * Swap handler handling from BTCLN swaps using submarine swaps
16
17
  */
@@ -291,6 +292,18 @@ class FromBtcLnAbs extends FromBtcBaseSwapHandler_1.FromBtcBaseSwapHandler {
291
292
  //No need to check abortController anymore since all pending promises are resolved by now
292
293
  if (invoiceData.metadata != null)
293
294
  invoiceData.metadata.times.htlcSwapSigned = Date.now();
295
+ const pluginCheckResult = await PluginManager_1.PluginManager.onHandlePreFromBtcExecute(SwapHandler_1.SwapHandlerType.FROM_BTCLN, invoiceData);
296
+ if ((0, IPlugin_1.isQuoteThrow)(pluginCheckResult)) {
297
+ const error = {
298
+ code: 29999,
299
+ msg: pluginCheckResult.message
300
+ };
301
+ if (invoiceData.metadata != null)
302
+ invoiceData.metadata.htlcReceiveError = error;
303
+ if (invoiceData.state === FromBtcLnSwapAbs_1.FromBtcLnSwapState.CREATED)
304
+ await this.cancelSwapAndInvoice(invoiceData);
305
+ throw error;
306
+ }
294
307
  //Important to prevent race condition and issuing 2 signed init messages at the same time
295
308
  if (invoiceData.state === FromBtcLnSwapAbs_1.FromBtcLnSwapState.CREATED) {
296
309
  //Re-check right before signing
@@ -662,17 +675,24 @@ class FromBtcLnAbs extends FromBtcBaseSwapHandler_1.FromBtcBaseSwapHandler {
662
675
  code: 10004,
663
676
  msg: "Invoice already committed"
664
677
  };
665
- res.status(200).json({
666
- code: 10000,
667
- msg: "Success",
668
- data: {
669
- address: signer.getAddress(),
670
- data: swap.data.serialize(),
671
- prefix: swap.prefix,
672
- timeout: swap.timeout,
673
- signature: swap.signature
674
- }
675
- });
678
+ if (swap.state === FromBtcLnSwapAbs_1.FromBtcLnSwapState.CLAIMED)
679
+ throw {
680
+ _httpStatus: 200,
681
+ code: 10005,
682
+ msg: "Invoice already committed & claimed"
683
+ };
684
+ if (swap.state === FromBtcLnSwapAbs_1.FromBtcLnSwapState.RECEIVED)
685
+ res.status(200).json({
686
+ code: 10000,
687
+ msg: "Success",
688
+ data: {
689
+ address: signer.getAddress(),
690
+ data: swap.data.serialize(),
691
+ prefix: swap.prefix,
692
+ timeout: swap.timeout,
693
+ signature: swap.signature
694
+ }
695
+ });
676
696
  });
677
697
  restServer.post(this.path + "/getInvoicePaymentAuth", getInvoicePaymentAuth);
678
698
  restServer.get(this.path + "/getInvoicePaymentAuth", getInvoicePaymentAuth);
@@ -30,4 +30,5 @@ export declare class FromBtcLnSwapAbs<T extends SwapData = SwapData> extends Fro
30
30
  isInitiated(): boolean;
31
31
  isFailed(): boolean;
32
32
  isSuccess(): boolean;
33
+ getDestinationAddress(): string;
33
34
  }
@@ -87,5 +87,8 @@ class FromBtcLnSwapAbs extends FromBtcBaseSwap_1.FromBtcBaseSwap {
87
87
  isSuccess() {
88
88
  return this.state === FromBtcLnSwapState.SETTLED;
89
89
  }
90
+ getDestinationAddress() {
91
+ return this.claimer;
92
+ }
90
93
  }
91
94
  exports.FromBtcLnSwapAbs = FromBtcLnSwapAbs;
@@ -11,6 +11,7 @@ const SchemaVerifier_1 = require("../../../utils/paramcoders/SchemaVerifier");
11
11
  const ServerParamDecoder_1 = require("../../../utils/paramcoders/server/ServerParamDecoder");
12
12
  const FromBtcBaseSwapHandler_1 = require("../FromBtcBaseSwapHandler");
13
13
  const LightningAssertions_1 = require("../../assertions/LightningAssertions");
14
+ const IPlugin_1 = require("../../../plugins/IPlugin");
14
15
  /**
15
16
  * Swap handler handling from BTCLN swaps using submarine swaps
16
17
  */
@@ -340,6 +341,18 @@ class FromBtcLnAuto extends FromBtcBaseSwapHandler_1.FromBtcBaseSwapHandler {
340
341
  timeout: invoiceData.timeout,
341
342
  signature: invoiceData.signature
342
343
  }, true);
344
+ const pluginCheckResult = await PluginManager_1.PluginManager.onHandlePreFromBtcExecute(SwapHandler_1.SwapHandlerType.FROM_BTCLN_AUTO, invoiceData);
345
+ if ((0, IPlugin_1.isQuoteThrow)(pluginCheckResult)) {
346
+ const error = {
347
+ code: 29999,
348
+ msg: pluginCheckResult.message
349
+ };
350
+ if (invoiceData.metadata != null)
351
+ invoiceData.metadata.htlcOfferError = error;
352
+ if (invoiceData.state === FromBtcLnAutoSwap_1.FromBtcLnAutoSwapState.RECEIVED)
353
+ await this.cancelSwapAndInvoice(invoiceData);
354
+ throw error;
355
+ }
343
356
  if (invoiceData.state === FromBtcLnAutoSwap_1.FromBtcLnAutoSwapState.RECEIVED) {
344
357
  //Re-check the current HTLC count
345
358
  try {
@@ -667,8 +680,7 @@ class FromBtcLnAuto extends FromBtcBaseSwapHandler_1.FromBtcBaseSwapHandler {
667
680
  code: 10001,
668
681
  msg: "Invoice expired/canceled"
669
682
  };
670
- if (swap.state === FromBtcLnAutoSwap_1.FromBtcLnAutoSwapState.RECEIVED ||
671
- swap.state === FromBtcLnAutoSwap_1.FromBtcLnAutoSwapState.TXS_SENT ||
683
+ if (swap.state === FromBtcLnAutoSwap_1.FromBtcLnAutoSwapState.TXS_SENT ||
672
684
  swap.state === FromBtcLnAutoSwap_1.FromBtcLnAutoSwapState.COMMITED) {
673
685
  res.status(200).json({
674
686
  code: 10000,
@@ -52,4 +52,5 @@ export declare class FromBtcLnAutoSwap<T extends SwapData = SwapData> extends Fr
52
52
  isInitiated(): boolean;
53
53
  isFailed(): boolean;
54
54
  isSuccess(): boolean;
55
+ getDestinationAddress(): string;
55
56
  }
@@ -116,5 +116,8 @@ class FromBtcLnAutoSwap extends FromBtcBaseSwap_1.FromBtcBaseSwap {
116
116
  isSuccess() {
117
117
  return this.state === FromBtcLnAutoSwapState.SETTLED;
118
118
  }
119
+ getDestinationAddress() {
120
+ return this.claimer;
121
+ }
119
122
  }
120
123
  exports.FromBtcLnAutoSwap = FromBtcLnAutoSwap;
@@ -11,6 +11,7 @@ const SchemaVerifier_1 = require("../../../utils/paramcoders/SchemaVerifier");
11
11
  const ServerParamDecoder_1 = require("../../../utils/paramcoders/server/ServerParamDecoder");
12
12
  const ToBtcBaseSwapHandler_1 = require("../ToBtcBaseSwapHandler");
13
13
  const BitcoinUtils_1 = require("../../../utils/BitcoinUtils");
14
+ const IPlugin_1 = require("../../../plugins/IPlugin");
14
15
  const OUTPUT_SCRIPT_MAX_LENGTH = 200;
15
16
  const MAX_PARALLEL_TX_PROCESSED = 10;
16
17
  /**
@@ -346,9 +347,29 @@ class ToBtcAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
346
347
  await this.saveSwapData(swap);
347
348
  }
348
349
  if (swap.state === ToBtcSwapAbs_1.ToBtcSwapState.COMMITED) {
349
- const unlock = swap.lock(60);
350
+ const unlock = swap.lock(Infinity);
350
351
  if (unlock == null)
351
352
  return;
353
+ const pluginCheckResult = await PluginManager_1.PluginManager.onHandlePreToBtcExecute(SwapHandler_1.SwapHandlerType.TO_BTC, swap);
354
+ if ((0, IPlugin_1.isQuoteThrow)(pluginCheckResult)) {
355
+ const error = {
356
+ code: 29999,
357
+ msg: pluginCheckResult.message
358
+ };
359
+ this.swapLogger.error(swap, "processInitialized(state=COMMITED): setting state to NON_PAYABLE due to send bitcoin payment error", error);
360
+ if (swap.metadata != null)
361
+ swap.metadata.payError = error;
362
+ unlock();
363
+ if (swap.state === ToBtcSwapAbs_1.ToBtcSwapState.COMMITED) {
364
+ await swap.setState(ToBtcSwapAbs_1.ToBtcSwapState.NON_PAYABLE);
365
+ await this.saveSwapData(swap);
366
+ }
367
+ return;
368
+ }
369
+ if (swap.state !== ToBtcSwapAbs_1.ToBtcSwapState.COMMITED) {
370
+ unlock();
371
+ return;
372
+ }
352
373
  this.swapLogger.debug(swap, "processInitialized(state=COMMITED): sending bitcoin transaction, address: " + swap.address);
353
374
  try {
354
375
  await this.sendBitcoinPayment(swap);
@@ -367,7 +388,9 @@ class ToBtcAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
367
388
  throw e;
368
389
  }
369
390
  }
370
- unlock();
391
+ finally {
392
+ unlock();
393
+ }
371
394
  }
372
395
  if (swap.state === ToBtcSwapAbs_1.ToBtcSwapState.NON_PAYABLE)
373
396
  return;
@@ -25,4 +25,5 @@ export declare class ToBtcSwapAbs<T extends SwapData = SwapData> extends ToBtcBa
25
25
  isInitiated(): boolean;
26
26
  isFailed(): boolean;
27
27
  isSuccess(): boolean;
28
+ getDestinationAddress(): string;
28
29
  }
@@ -60,5 +60,8 @@ class ToBtcSwapAbs extends ToBtcBaseSwap_1.ToBtcBaseSwap {
60
60
  isSuccess() {
61
61
  return this.state === ToBtcSwapState.CLAIMED;
62
62
  }
63
+ getDestinationAddress() {
64
+ return this.address;
65
+ }
63
66
  }
64
67
  exports.ToBtcSwapAbs = ToBtcSwapAbs;
@@ -12,6 +12,7 @@ const SchemaVerifier_1 = require("../../../utils/paramcoders/SchemaVerifier");
12
12
  const ToBtcBaseSwapHandler_1 = require("../ToBtcBaseSwapHandler");
13
13
  const ILightningWallet_1 = require("../../../wallets/ILightningWallet");
14
14
  const LightningAssertions_1 = require("../../assertions/LightningAssertions");
15
+ const IPlugin_1 = require("../../../plugins/IPlugin");
15
16
  /**
16
17
  * Swap handler handling to BTCLN swaps using submarine swaps
17
18
  */
@@ -229,6 +230,15 @@ class ToBtcLnAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
229
230
  " maxFee: " + maxFee.toString(10) +
230
231
  " invoice: " + swap.pr);
231
232
  const blockHeight = await this.lightning.getBlockheight();
233
+ const pluginCheckResult = await PluginManager_1.PluginManager.onHandlePreToBtcExecute(SwapHandler_1.SwapHandlerType.TO_BTCLN, swap);
234
+ if ((0, IPlugin_1.isQuoteThrow)(pluginCheckResult)) {
235
+ throw {
236
+ code: 29999,
237
+ msg: pluginCheckResult.message
238
+ };
239
+ }
240
+ if (swap.state !== ToBtcLnSwapAbs_1.ToBtcLnSwapState.COMMITED)
241
+ return false;
232
242
  swap.payInitiated = true;
233
243
  await this.saveSwapData(swap);
234
244
  try {
@@ -249,6 +259,7 @@ class ToBtcLnAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
249
259
  }
250
260
  if (swap.metadata != null)
251
261
  swap.metadata.times.payComplete = Date.now();
262
+ return true;
252
263
  }
253
264
  /**
254
265
  * Begins a lightning network payment attempt, if not attempted already
@@ -303,7 +314,8 @@ class ToBtcLnAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
303
314
  await swap.setState(ToBtcLnSwapAbs_1.ToBtcLnSwapState.COMMITED);
304
315
  await this.saveSwapData(swap);
305
316
  try {
306
- await this.sendLightningPayment(swap);
317
+ if (!await this.sendLightningPayment(swap))
318
+ return;
307
319
  }
308
320
  catch (e) {
309
321
  this.swapLogger.error(swap, "processInitialized(): lightning payment error", e);
@@ -21,4 +21,5 @@ export declare class ToBtcLnSwapAbs<T extends SwapData = SwapData> extends ToBtc
21
21
  isInitiated(): boolean;
22
22
  isFailed(): boolean;
23
23
  isSuccess(): boolean;
24
+ getDestinationAddress(): string;
24
25
  }
@@ -54,5 +54,8 @@ class ToBtcLnSwapAbs extends ToBtcBaseSwap_1.ToBtcBaseSwap {
54
54
  isSuccess() {
55
55
  return this.state === ToBtcLnSwapState.CLAIMED;
56
56
  }
57
+ getDestinationAddress() {
58
+ return this.pr;
59
+ }
57
60
  }
58
61
  exports.ToBtcLnSwapAbs = ToBtcLnSwapAbs;
@@ -65,4 +65,5 @@ export declare class SpvVaultSwap extends SwapHandlerSwap<SpvVaultSwapState> {
65
65
  isFailed(): boolean;
66
66
  isInitiated(): boolean;
67
67
  isSuccess(): boolean;
68
+ getDestinationAddress(): string;
68
69
  }
@@ -154,5 +154,8 @@ class SpvVaultSwap extends SwapHandlerSwap_1.SwapHandlerSwap {
154
154
  isSuccess() {
155
155
  return this.state === SpvVaultSwapState.CLAIMED;
156
156
  }
157
+ getDestinationAddress() {
158
+ return this.recipient;
159
+ }
157
160
  }
158
161
  exports.SpvVaultSwap = SpvVaultSwap;
@@ -14,6 +14,7 @@ const btc_signer_1 = require("@scure/btc-signer");
14
14
  const SpvVaults_1 = require("./SpvVaults");
15
15
  const BitcoinUtils_1 = require("../../utils/BitcoinUtils");
16
16
  const AmountAssertions_1 = require("../assertions/AmountAssertions");
17
+ const IPlugin_1 = require("../../plugins/IPlugin");
17
18
  const TX_MAX_VSIZE = 16 * 1024;
18
19
  class SpvVaultSwapHandler extends SwapHandler_1.SwapHandler {
19
20
  constructor(storageDirectory, vaultStorage, path, chainsData, swapPricing, bitcoin, bitcoinRpc, spvVaultSigner, config) {
@@ -452,7 +453,7 @@ class SpvVaultSwapHandler extends SwapHandler_1.SwapHandler {
452
453
  if (swap.vaultUtxo !== vault.getLatestUtxo()) {
453
454
  throw {
454
455
  code: 20510,
455
- msg: "Vault UTXO already spent, please try again!"
456
+ msg: "Vault UTXO already spent, please get another quote and try again!"
456
457
  };
457
458
  }
458
459
  //Create abortController for parallel prefetches
@@ -475,11 +476,22 @@ class SpvVaultSwapHandler extends SwapHandler_1.SwapHandler {
475
476
  code: 20516,
476
477
  msg: "Bitcoin transaction size too large, maximum: " + TX_MAX_VSIZE + " actual: " + txVsize
477
478
  };
479
+ const pluginCheckResult = await PluginManager_1.PluginManager.onHandlePreFromBtcExecute(SwapHandler_1.SwapHandlerType.FROM_BTC_SPV, swap);
480
+ if ((0, IPlugin_1.isQuoteThrow)(pluginCheckResult)) {
481
+ const error = {
482
+ code: 29999,
483
+ msg: pluginCheckResult.message
484
+ };
485
+ if (swap.metadata != null)
486
+ swap.metadata.postQuoteError = error;
487
+ await this.removeSwapData(swap, SpvVaultSwap_1.SpvVaultSwapState.FAILED);
488
+ throw error;
489
+ }
478
490
  await this.Vaults.checkVaultReplacedTransactions(vault, true);
479
491
  if (swap.vaultUtxo !== vault.getLatestUtxo()) {
480
492
  throw {
481
493
  code: 20510,
482
- msg: "Vault UTXO already spent, please try again!"
494
+ msg: "Vault UTXO already spent, please get another quote and try again!"
483
495
  };
484
496
  }
485
497
  try {