@atomiqlabs/lp-lib 15.0.10 → 15.0.12

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.
@@ -1,5 +1,5 @@
1
1
  import { BitcoinRpc } from "@atomiqlabs/base";
2
- import { FromBtcLnRequestType, FromBtcRequestType, FromBtcTrustedRequestType, ISwapPrice, MultichainData, RequestData, SpvVaultSwapRequestType, SwapHandler, SwapHandlerType, ToBtcLnRequestType, ToBtcRequestType } from "..";
2
+ import { FromBtcLnRequestType, FromBtcRequestType, FromBtcTrustedRequestType, ISwapPrice, MultichainData, RequestData, SpvVaultPostQuote, SpvVaultSwap, SpvVaultSwapRequestType, SwapHandler, SwapHandlerType, ToBtcLnRequestType, ToBtcRequestType } 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";
@@ -128,6 +128,7 @@ export interface IPlugin {
128
128
  feePPM: bigint;
129
129
  networkFeeGetter: (amount: bigint) => Promise<bigint>;
130
130
  }): Promise<QuoteThrow | QuoteSetFees | QuoteAmountTooLow | QuoteAmountTooHigh | ToBtcPluginQuote>;
131
+ onHandlePostedFromBtcQuote?(swapType: SwapHandlerType.FROM_BTC_SPV, request: RequestData<SpvVaultPostQuote>, swap: SpvVaultSwap): Promise<QuoteThrow | null>;
131
132
  onVaultSelection?(chainIdentifier: string, totalSats: bigint, requestedAmount: {
132
133
  amount: bigint;
133
134
  token: string;
@@ -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, SpvVaultSwapRequestType, SwapHandler, SwapHandlerType, ToBtcLnRequestType, ToBtcRequestType } from "..";
3
+ import { FromBtcLnRequestType, FromBtcRequestType, FromBtcTrustedRequestType, ISwapPrice, MultichainData, RequestData, SpvVaultPostQuote, SpvVaultSwap, SpvVaultSwapRequestType, SwapHandler, SwapHandlerType, ToBtcLnRequestType, ToBtcRequestType } 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";
@@ -101,6 +101,7 @@ export declare class PluginManager {
101
101
  baseFeeInBtc: bigint;
102
102
  feePPM: bigint;
103
103
  }): Promise<QuoteThrow | QuoteSetFees | QuoteAmountTooLow | QuoteAmountTooHigh>;
104
+ static onHandlePostedFromBtcQuote(swapType: SwapHandlerType.FROM_BTC_SPV, request: RequestData<SpvVaultPostQuote>, swap: SpvVaultSwap): Promise<QuoteThrow | null>;
104
105
  static onVaultSelection(chainIdentifier: string, totalSats: bigint, requestedAmount: {
105
106
  amount: bigint;
106
107
  token: string;
@@ -214,6 +214,21 @@ class PluginManager {
214
214
  }
215
215
  return null;
216
216
  }
217
+ static async onHandlePostedFromBtcQuote(swapType, request, swap) {
218
+ for (let plugin of PluginManager.plugins.values()) {
219
+ try {
220
+ if (plugin.onHandlePostedFromBtcQuote != null) {
221
+ const result = await plugin.onHandlePostedFromBtcQuote(swapType, request, swap);
222
+ if (result != null && (0, IPlugin_1.isQuoteThrow)(result))
223
+ return result;
224
+ }
225
+ }
226
+ catch (e) {
227
+ pluginLogger.error(plugin, "onHandlePostedFromBtcQuote(): plugin error", e);
228
+ }
229
+ }
230
+ return null;
231
+ }
217
232
  static async onVaultSelection(chainIdentifier, totalSats, requestedAmount, gasAmount) {
218
233
  for (let plugin of PluginManager.plugins.values()) {
219
234
  try {
@@ -13,6 +13,7 @@ const crypto_1 = require("crypto");
13
13
  const btc_signer_1 = require("@scure/btc-signer");
14
14
  const SpvVaults_1 = require("./SpvVaults");
15
15
  const BitcoinUtils_1 = require("../../utils/BitcoinUtils");
16
+ const AmountAssertions_1 = require("../assertions/AmountAssertions");
16
17
  const TX_MAX_VSIZE = 16 * 1024;
17
18
  class SpvVaultSwapHandler extends SwapHandler_1.SwapHandler {
18
19
  constructor(storageDirectory, vaultStorage, path, chainsData, swapPricing, bitcoin, bitcoinRpc, spvVaultSigner, config) {
@@ -355,7 +356,6 @@ class SpvVaultSwapHandler extends SwapHandler_1.SwapHandler {
355
356
  msg: "Error parsing PSBT, hex format required!"
356
357
  };
357
358
  }
358
- //Check correct psbt
359
359
  for (let i = 1; i < transaction.inputsLength; i++) { //Skip first vault input
360
360
  const txIn = transaction.getInput(i);
361
361
  if ((0, BitcoinUtils_1.isLegacyInput)(txIn))
@@ -363,6 +363,12 @@ class SpvVaultSwapHandler extends SwapHandler_1.SwapHandler {
363
363
  code: 20514,
364
364
  msg: "Legacy (pre-segwit) inputs in tx are not allowed!"
365
365
  };
366
+ }
367
+ //Check the posted quote with the plugins
368
+ AmountAssertions_1.AmountAssertions.handlePluginErrorResponses(await PluginManager_1.PluginManager.onHandlePostedFromBtcQuote(this.type, { chainIdentifier: swap.chainIdentifier, raw: req, parsed: parsedBody, metadata }, swap));
369
+ //Check correct psbt
370
+ for (let i = 1; i < transaction.inputsLength; i++) { //Skip first vault input
371
+ const txIn = transaction.getInput(i);
366
372
  //Check UTXOs exist and are unspent
367
373
  if (await this.bitcoinRpc.isSpent(Buffer.from(txIn.txid).toString("hex") + ":" + txIn.index.toString(10)))
368
374
  throw {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atomiqlabs/lp-lib",
3
- "version": "15.0.10",
3
+ "version": "15.0.12",
4
4
  "description": "Main functionality implementation for atomiq LP node",
5
5
  "main": "./dist/index.js",
6
6
  "types:": "./dist/index.d.ts",
@@ -1,8 +1,8 @@
1
- import {BitcoinRpc, SpvWithdrawalTransactionData, SwapData} from "@atomiqlabs/base";
1
+ import {BitcoinRpc} from "@atomiqlabs/base";
2
2
  import {
3
3
  FromBtcLnRequestType,
4
4
  FromBtcRequestType, FromBtcTrustedRequestType,
5
- ISwapPrice, MultichainData, RequestData, SpvVaultSwapRequestType,
5
+ ISwapPrice, MultichainData, RequestData, SpvVaultPostQuote, SpvVaultSwap, SpvVaultSwapRequestType,
6
6
  SwapHandler, SwapHandlerType,
7
7
  ToBtcLnRequestType,
8
8
  ToBtcRequestType
@@ -151,6 +151,12 @@ export interface IPlugin {
151
151
  fees: {baseFeeInBtc: bigint, feePPM: bigint, networkFeeGetter: (amount: bigint) => Promise<bigint>}
152
152
  ): Promise<QuoteThrow | QuoteSetFees | QuoteAmountTooLow | QuoteAmountTooHigh | ToBtcPluginQuote>;
153
153
 
154
+ onHandlePostedFromBtcQuote?(
155
+ swapType: SwapHandlerType.FROM_BTC_SPV,
156
+ request: RequestData<SpvVaultPostQuote>,
157
+ swap: SpvVaultSwap
158
+ ): Promise<QuoteThrow | null>;
159
+
154
160
  onVaultSelection?(
155
161
  chainIdentifier: string,
156
162
  totalSats: bigint,
@@ -1,4 +1,4 @@
1
- import {BitcoinRpc, SpvWithdrawalTransactionData, SwapData} from "@atomiqlabs/base";
1
+ import {BitcoinRpc, SwapData} from "@atomiqlabs/base";
2
2
  import {
3
3
  IPlugin, isPluginQuote, isQuoteAmountTooHigh, isQuoteAmountTooLow, isQuoteSetFees,
4
4
  isQuoteThrow, isToBtcPluginQuote, PluginQuote,
@@ -10,7 +10,7 @@ import {
10
10
  import {
11
11
  FromBtcLnRequestType,
12
12
  FromBtcRequestType, FromBtcTrustedRequestType,
13
- ISwapPrice, MultichainData, RequestData, SpvVaultSwapRequestType,
13
+ ISwapPrice, MultichainData, RequestData, SpvVaultPostQuote, SpvVaultSwap, SpvVaultSwapRequestType,
14
14
  SwapHandler, SwapHandlerType,
15
15
  ToBtcLnRequestType,
16
16
  ToBtcRequestType
@@ -291,6 +291,24 @@ export class PluginManager {
291
291
  return null;
292
292
  }
293
293
 
294
+ static async onHandlePostedFromBtcQuote(
295
+ swapType: SwapHandlerType.FROM_BTC_SPV,
296
+ request: RequestData<SpvVaultPostQuote>,
297
+ swap: SpvVaultSwap
298
+ ): Promise<QuoteThrow | null> {
299
+ for(let plugin of PluginManager.plugins.values()) {
300
+ try {
301
+ if(plugin.onHandlePostedFromBtcQuote!=null) {
302
+ const result = await plugin.onHandlePostedFromBtcQuote(swapType, request, swap);
303
+ if(result!=null && isQuoteThrow(result)) return result;
304
+ }
305
+ } catch (e) {
306
+ pluginLogger.error(plugin, "onHandlePostedFromBtcQuote(): plugin error", e);
307
+ }
308
+ }
309
+ return null;
310
+ }
311
+
294
312
  static async onVaultSelection(
295
313
  chainIdentifier: string,
296
314
  totalSats: bigint,
@@ -30,6 +30,7 @@ import {randomBytes} from "crypto";
30
30
  import {Transaction} from "@scure/btc-signer";
31
31
  import {SpvVaults, VAULT_DUST_AMOUNT} from "./SpvVaults";
32
32
  import {isLegacyInput} from "../../utils/BitcoinUtils";
33
+ import {AmountAssertions} from "../assertions/AmountAssertions";
33
34
 
34
35
  export type SpvVaultSwapHandlerConfig = SwapBaseConfig & {
35
36
  vaultsCheckInterval: number,
@@ -482,13 +483,24 @@ export class SpvVaultSwapHandler extends SwapHandler<SpvVaultSwap, SpvVaultSwapS
482
483
  };
483
484
  }
484
485
 
485
- //Check correct psbt
486
486
  for(let i=1;i<transaction.inputsLength;i++) { //Skip first vault input
487
487
  const txIn = transaction.getInput(i);
488
- if(isLegacyInput(txIn)) throw {
488
+ if (isLegacyInput(txIn)) throw {
489
489
  code: 20514,
490
490
  msg: "Legacy (pre-segwit) inputs in tx are not allowed!"
491
491
  };
492
+ }
493
+
494
+ //Check the posted quote with the plugins
495
+ AmountAssertions.handlePluginErrorResponses(await PluginManager.onHandlePostedFromBtcQuote(
496
+ this.type,
497
+ {chainIdentifier: swap.chainIdentifier, raw: req, parsed: parsedBody, metadata},
498
+ swap
499
+ ));
500
+
501
+ //Check correct psbt
502
+ for(let i=1;i<transaction.inputsLength;i++) { //Skip first vault input
503
+ const txIn = transaction.getInput(i);
492
504
  //Check UTXOs exist and are unspent
493
505
  if(await this.bitcoinRpc.isSpent(Buffer.from(txIn.txid).toString("hex")+":"+txIn.index.toString(10))) throw {
494
506
  code: 20515,