@atomiqlabs/lp-lib 12.1.0 → 13.0.0-beta.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 (119) hide show
  1. package/dist/index.d.ts +18 -13
  2. package/dist/index.js +18 -13
  3. package/dist/plugins/IPlugin.d.ts +35 -12
  4. package/dist/plugins/PluginManager.d.ts +38 -15
  5. package/dist/plugins/PluginManager.js +33 -9
  6. package/dist/prices/BinanceSwapPrice.d.ts +1 -1
  7. package/dist/prices/BinanceSwapPrice.js +1 -1
  8. package/dist/prices/CoinGeckoSwapPrice.d.ts +1 -1
  9. package/dist/prices/CoinGeckoSwapPrice.js +1 -1
  10. package/dist/{swaps → prices}/ISwapPrice.js +4 -0
  11. package/dist/prices/OKXSwapPrice.d.ts +1 -1
  12. package/dist/prices/OKXSwapPrice.js +1 -1
  13. package/dist/swaps/SwapHandler.d.ts +20 -58
  14. package/dist/swaps/SwapHandler.js +17 -186
  15. package/dist/swaps/SwapHandlerSwap.d.ts +8 -23
  16. package/dist/swaps/SwapHandlerSwap.js +7 -39
  17. package/dist/swaps/assertions/AmountAssertions.d.ts +28 -0
  18. package/dist/swaps/assertions/AmountAssertions.js +72 -0
  19. package/dist/swaps/assertions/FromBtcAmountAssertions.d.ts +76 -0
  20. package/dist/swaps/assertions/FromBtcAmountAssertions.js +162 -0
  21. package/dist/swaps/assertions/LightningAssertions.d.ts +44 -0
  22. package/dist/swaps/assertions/LightningAssertions.js +86 -0
  23. package/dist/swaps/assertions/ToBtcAmountAssertions.d.ts +53 -0
  24. package/dist/swaps/{ToBtcBaseSwapHandler.js → assertions/ToBtcAmountAssertions.js} +20 -94
  25. package/dist/swaps/escrow/EscrowHandler.d.ts +51 -0
  26. package/dist/swaps/escrow/EscrowHandler.js +158 -0
  27. package/dist/swaps/escrow/EscrowHandlerSwap.d.ts +35 -0
  28. package/dist/swaps/escrow/EscrowHandlerSwap.js +69 -0
  29. package/dist/swaps/{FromBtcBaseSwap.d.ts → escrow/FromBtcBaseSwap.d.ts} +2 -3
  30. package/dist/swaps/{FromBtcBaseSwap.js → escrow/FromBtcBaseSwap.js} +4 -7
  31. package/dist/swaps/{FromBtcBaseSwapHandler.d.ts → escrow/FromBtcBaseSwapHandler.d.ts} +10 -49
  32. package/dist/swaps/{FromBtcBaseSwapHandler.js → escrow/FromBtcBaseSwapHandler.js} +16 -137
  33. package/dist/swaps/{ToBtcBaseSwap.d.ts → escrow/ToBtcBaseSwap.d.ts} +2 -2
  34. package/dist/swaps/{ToBtcBaseSwap.js → escrow/ToBtcBaseSwap.js} +4 -4
  35. package/dist/swaps/escrow/ToBtcBaseSwapHandler.d.ts +53 -0
  36. package/dist/swaps/escrow/ToBtcBaseSwapHandler.js +81 -0
  37. package/dist/swaps/{frombtc_abstract → escrow/frombtc_abstract}/FromBtcAbs.d.ts +4 -4
  38. package/dist/swaps/{frombtc_abstract → escrow/frombtc_abstract}/FromBtcAbs.js +15 -15
  39. package/dist/swaps/{frombtc_abstract → escrow/frombtc_abstract}/FromBtcSwapAbs.js +1 -1
  40. package/dist/swaps/{frombtcln_abstract → escrow/frombtcln_abstract}/FromBtcLnAbs.d.ts +9 -7
  41. package/dist/swaps/{frombtcln_abstract → escrow/frombtcln_abstract}/FromBtcLnAbs.js +22 -19
  42. package/dist/swaps/{frombtcln_abstract → escrow/frombtcln_abstract}/FromBtcLnSwapAbs.js +3 -3
  43. package/dist/swaps/{tobtc_abstract → escrow/tobtc_abstract}/ToBtcAbs.d.ts +4 -4
  44. package/dist/swaps/{tobtc_abstract → escrow/tobtc_abstract}/ToBtcAbs.js +14 -13
  45. package/dist/swaps/{tobtc_abstract → escrow/tobtc_abstract}/ToBtcSwapAbs.js +3 -3
  46. package/dist/swaps/{tobtcln_abstract → escrow/tobtcln_abstract}/ToBtcLnAbs.d.ts +6 -26
  47. package/dist/swaps/{tobtcln_abstract → escrow/tobtcln_abstract}/ToBtcLnAbs.js +20 -57
  48. package/dist/swaps/{tobtcln_abstract → escrow/tobtcln_abstract}/ToBtcLnSwapAbs.js +3 -3
  49. package/dist/swaps/spv_vault_swap/SpvVault.d.ts +41 -0
  50. package/dist/swaps/spv_vault_swap/SpvVault.js +111 -0
  51. package/dist/swaps/spv_vault_swap/SpvVaultSwap.d.ts +63 -0
  52. package/dist/swaps/spv_vault_swap/SpvVaultSwap.js +145 -0
  53. package/dist/swaps/spv_vault_swap/SpvVaultSwapHandler.d.ts +68 -0
  54. package/dist/swaps/spv_vault_swap/SpvVaultSwapHandler.js +469 -0
  55. package/dist/swaps/spv_vault_swap/SpvVaults.d.ts +57 -0
  56. package/dist/swaps/spv_vault_swap/SpvVaults.js +369 -0
  57. package/dist/swaps/{frombtc_trusted → trusted/frombtc_trusted}/FromBtcTrusted.d.ts +10 -13
  58. package/dist/swaps/{frombtc_trusted → trusted/frombtc_trusted}/FromBtcTrusted.js +25 -30
  59. package/dist/swaps/{frombtc_trusted → trusted/frombtc_trusted}/FromBtcTrustedSwap.d.ts +9 -4
  60. package/dist/swaps/{frombtc_trusted → trusted/frombtc_trusted}/FromBtcTrustedSwap.js +15 -7
  61. package/dist/swaps/{frombtcln_trusted → trusted/frombtcln_trusted}/FromBtcLnTrusted.d.ts +12 -14
  62. package/dist/swaps/{frombtcln_trusted → trusted/frombtcln_trusted}/FromBtcLnTrusted.js +33 -35
  63. package/dist/swaps/{frombtcln_trusted → trusted/frombtcln_trusted}/FromBtcLnTrustedSwap.d.ts +9 -4
  64. package/dist/swaps/{frombtcln_trusted → trusted/frombtcln_trusted}/FromBtcLnTrustedSwap.js +17 -7
  65. package/dist/utils/Utils.d.ts +13 -5
  66. package/dist/utils/Utils.js +23 -1
  67. package/dist/wallets/IBitcoinWallet.d.ts +6 -0
  68. package/dist/wallets/ISpvVaultSigner.d.ts +7 -0
  69. package/dist/wallets/ISpvVaultSigner.js +2 -0
  70. package/dist/wallets/ISpvVaultWallet.d.ts +42 -0
  71. package/dist/wallets/ISpvVaultWallet.js +2 -0
  72. package/package.json +2 -2
  73. package/src/index.ts +21 -15
  74. package/src/plugins/IPlugin.ts +27 -19
  75. package/src/plugins/PluginManager.ts +51 -26
  76. package/src/prices/BinanceSwapPrice.ts +1 -1
  77. package/src/prices/CoinGeckoSwapPrice.ts +1 -1
  78. package/src/{swaps → prices}/ISwapPrice.ts +4 -0
  79. package/src/prices/OKXSwapPrice.ts +1 -1
  80. package/src/swaps/SwapHandler.ts +22 -205
  81. package/src/swaps/SwapHandlerSwap.ts +10 -46
  82. package/src/swaps/assertions/AmountAssertions.ts +77 -0
  83. package/src/swaps/assertions/FromBtcAmountAssertions.ts +228 -0
  84. package/src/swaps/assertions/LightningAssertions.ts +103 -0
  85. package/src/swaps/{ToBtcBaseSwapHandler.ts → assertions/ToBtcAmountAssertions.ts} +27 -142
  86. package/src/swaps/escrow/EscrowHandler.ts +179 -0
  87. package/src/swaps/escrow/EscrowHandlerSwap.ts +87 -0
  88. package/src/swaps/{FromBtcBaseSwap.ts → escrow/FromBtcBaseSwap.ts} +4 -8
  89. package/src/swaps/{FromBtcBaseSwapHandler.ts → escrow/FromBtcBaseSwapHandler.ts} +30 -190
  90. package/src/swaps/{ToBtcBaseSwap.ts → escrow/ToBtcBaseSwap.ts} +4 -5
  91. package/src/swaps/escrow/ToBtcBaseSwapHandler.ts +130 -0
  92. package/src/swaps/{frombtc_abstract → escrow/frombtc_abstract}/FromBtcAbs.ts +20 -20
  93. package/src/swaps/{frombtc_abstract → escrow/frombtc_abstract}/FromBtcSwapAbs.ts +1 -1
  94. package/src/swaps/{frombtcln_abstract → escrow/frombtcln_abstract}/FromBtcLnAbs.ts +29 -25
  95. package/src/swaps/{frombtcln_abstract → escrow/frombtcln_abstract}/FromBtcLnSwapAbs.ts +2 -2
  96. package/src/swaps/{tobtc_abstract → escrow/tobtc_abstract}/ToBtcAbs.ts +19 -18
  97. package/src/swaps/{tobtc_abstract → escrow/tobtc_abstract}/ToBtcSwapAbs.ts +2 -2
  98. package/src/swaps/{tobtcln_abstract → escrow/tobtcln_abstract}/ToBtcLnAbs.ts +26 -66
  99. package/src/swaps/{tobtcln_abstract → escrow/tobtcln_abstract}/ToBtcLnSwapAbs.ts +2 -2
  100. package/src/swaps/spv_vault_swap/SpvVault.ts +143 -0
  101. package/src/swaps/spv_vault_swap/SpvVaultSwap.ts +207 -0
  102. package/src/swaps/spv_vault_swap/SpvVaultSwapHandler.ts +606 -0
  103. package/src/swaps/spv_vault_swap/SpvVaults.ts +441 -0
  104. package/src/swaps/{frombtc_trusted → trusted/frombtc_trusted}/FromBtcTrusted.ts +36 -51
  105. package/src/swaps/{frombtc_trusted → trusted/frombtc_trusted}/FromBtcTrustedSwap.ts +18 -8
  106. package/src/swaps/{frombtcln_trusted → trusted/frombtcln_trusted}/FromBtcLnTrusted.ts +43 -52
  107. package/src/swaps/{frombtcln_trusted → trusted/frombtcln_trusted}/FromBtcLnTrustedSwap.ts +20 -8
  108. package/src/utils/Utils.ts +27 -1
  109. package/src/wallets/IBitcoinWallet.ts +4 -0
  110. package/src/wallets/ISpvVaultSigner.ts +11 -0
  111. package/dist/swaps/FromBtcLnBaseSwapHandler.d.ts +0 -26
  112. package/dist/swaps/FromBtcLnBaseSwapHandler.js +0 -46
  113. package/dist/swaps/ToBtcBaseSwapHandler.d.ts +0 -95
  114. package/src/swaps/FromBtcLnBaseSwapHandler.ts +0 -63
  115. /package/dist/{swaps → prices}/ISwapPrice.d.ts +0 -0
  116. /package/dist/swaps/{frombtc_abstract → escrow/frombtc_abstract}/FromBtcSwapAbs.d.ts +0 -0
  117. /package/dist/swaps/{frombtcln_abstract → escrow/frombtcln_abstract}/FromBtcLnSwapAbs.d.ts +0 -0
  118. /package/dist/swaps/{tobtc_abstract → escrow/tobtc_abstract}/ToBtcSwapAbs.d.ts +0 -0
  119. /package/dist/swaps/{tobtcln_abstract → escrow/tobtcln_abstract}/ToBtcLnSwapAbs.d.ts +0 -0
@@ -2,27 +2,28 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ToBtcLnAbs = void 0;
4
4
  const ToBtcLnSwapAbs_1 = require("./ToBtcLnSwapAbs");
5
- const SwapHandler_1 = require("../SwapHandler");
5
+ const SwapHandler_1 = require("../../SwapHandler");
6
6
  const base_1 = require("@atomiqlabs/base");
7
- const Utils_1 = require("../../utils/Utils");
8
- const PluginManager_1 = require("../../plugins/PluginManager");
7
+ const Utils_1 = require("../../../utils/Utils");
8
+ const PluginManager_1 = require("../../../plugins/PluginManager");
9
9
  const crypto_1 = require("crypto");
10
- const ServerParamDecoder_1 = require("../../utils/paramcoders/server/ServerParamDecoder");
11
- const SchemaVerifier_1 = require("../../utils/paramcoders/SchemaVerifier");
10
+ const ServerParamDecoder_1 = require("../../../utils/paramcoders/server/ServerParamDecoder");
11
+ const SchemaVerifier_1 = require("../../../utils/paramcoders/SchemaVerifier");
12
12
  const ToBtcBaseSwapHandler_1 = require("../ToBtcBaseSwapHandler");
13
- const ILightningWallet_1 = require("../../wallets/ILightningWallet");
13
+ const ILightningWallet_1 = require("../../../wallets/ILightningWallet");
14
+ const LightningAssertions_1 = require("../../assertions/LightningAssertions");
14
15
  /**
15
16
  * Swap handler handling to BTCLN swaps using submarine swaps
16
17
  */
17
18
  class ToBtcLnAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
18
19
  constructor(storageDirectory, path, chainData, lightning, swapPricing, config) {
19
- super(storageDirectory, path, chainData, swapPricing);
20
- this.LIGHTNING_LIQUIDITY_CACHE_TIMEOUT = 5 * 1000;
20
+ super(storageDirectory, path, chainData, swapPricing, config);
21
21
  this.activeSubscriptions = new Set();
22
22
  this.type = SwapHandler_1.SwapHandlerType.TO_BTCLN;
23
23
  this.swapType = base_1.ChainSwapType.HTLC;
24
24
  this.exactInAuths = {};
25
25
  this.lightning = lightning;
26
+ this.LightningAssertions = new LightningAssertions_1.LightningAssertions(this.logger, lightning);
26
27
  const anyConfig = config;
27
28
  anyConfig.minTsSendCltv = config.gracePeriod + (config.bitcoinBlocktime * config.minSendCltv * config.safetyFactor);
28
29
  this.config = anyConfig;
@@ -405,46 +406,6 @@ class ToBtcLnAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
405
406
  };
406
407
  }
407
408
  }
408
- /**
409
- * Checks if the prior payment with the same paymentHash exists
410
- *
411
- * @param paymentHash
412
- * @param abortSignal
413
- * @throws {DefinedRuntimeError} will throw an error if payment already exists
414
- */
415
- async checkPriorPayment(paymentHash, abortSignal) {
416
- const payment = await this.lightning.getPayment(paymentHash);
417
- if (payment != null)
418
- throw {
419
- code: 20010,
420
- msg: "Already processed"
421
- };
422
- abortSignal.throwIfAborted();
423
- }
424
- /**
425
- * Checks if the underlying LND backend has enough liquidity in channels to honor the swap
426
- *
427
- * @param amount
428
- * @param abortSignal
429
- * @param useCached Whether to use cached liquidity values
430
- * @throws {DefinedRuntimeError} will throw an error if there isn't enough liquidity
431
- */
432
- async checkLiquidity(amount, abortSignal, useCached = false) {
433
- if (!useCached || this.lightningLiquidityCache == null || this.lightningLiquidityCache.timestamp < Date.now() - this.LIGHTNING_LIQUIDITY_CACHE_TIMEOUT) {
434
- const channelBalances = await this.lightning.getLightningBalance();
435
- this.lightningLiquidityCache = {
436
- liquidity: channelBalances.localBalance,
437
- timestamp: Date.now()
438
- };
439
- }
440
- if (amount > this.lightningLiquidityCache.liquidity) {
441
- throw {
442
- code: 20002,
443
- msg: "Not enough liquidity"
444
- };
445
- }
446
- abortSignal.throwIfAborted();
447
- }
448
409
  /**
449
410
  * Estimates the routing fee & confidence by either probing or routing (if probing fails), the fee is also adjusted
450
411
  * according to routing fee multiplier, and subject to minimums set in config
@@ -513,6 +474,7 @@ class ToBtcLnAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
513
474
  if (actualRoutingFee > maxFee) {
514
475
  actualRoutingFee = maxFee;
515
476
  }
477
+ this.logger.debug("checkAndGetNetworkFee(): network fee calculated, amount: " + amountBD.toString(10) + " fee: " + actualRoutingFee.toString(10));
516
478
  return {
517
479
  networkFee: actualRoutingFee,
518
480
  confidence: probeOrRouteResp.confidence
@@ -637,7 +599,7 @@ class ToBtcLnAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
637
599
  restServer.post(this.path + "/payInvoice", (0, Utils_1.expressHandlerWrapper)(async (req, res) => {
638
600
  const metadata = { request: {}, times: {} };
639
601
  const chainIdentifier = req.query.chain ?? this.chains.default;
640
- const { swapContract, signer } = this.getChain(chainIdentifier);
602
+ const { swapContract, signer, chainInterface } = this.getChain(chainIdentifier);
641
603
  metadata.times.requestReceived = Date.now();
642
604
  /**
643
605
  *Sent initially:
@@ -661,7 +623,7 @@ class ToBtcLnAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
661
623
  this.isTokenSupported(chainIdentifier, val) ? val : null,
662
624
  offerer: (val) => val != null &&
663
625
  typeof (val) === "string" &&
664
- swapContract.isValidAddress(val) ? val : null,
626
+ chainInterface.isValidAddress(val) ? val : null,
665
627
  exactIn: SchemaVerifier_1.FieldTypeEnum.BooleanOptional,
666
628
  amount: SchemaVerifier_1.FieldTypeEnum.BigIntOptional
667
629
  });
@@ -689,27 +651,28 @@ class ToBtcLnAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
689
651
  const { parsedPR, halfConfidence } = await this.checkPaymentRequest(chainIdentifier, parsedBody.pr);
690
652
  const requestedAmount = {
691
653
  input: !!parsedBody.exactIn,
692
- amount: !!parsedBody.exactIn ? parsedBody.amount : (parsedPR.mtokens + 999n) / 1000n
654
+ amount: !!parsedBody.exactIn ? parsedBody.amount : (parsedPR.mtokens + 999n) / 1000n,
655
+ token: useToken
693
656
  };
694
- const fees = await this.preCheckAmounts(request, requestedAmount, useToken);
657
+ const fees = await this.AmountAssertions.preCheckToBtcAmounts(this.type, request, requestedAmount);
695
658
  metadata.times.requestChecked = Date.now();
696
659
  //Create abort controller for parallel pre-fetches
697
- const abortController = this.getAbortController(responseStream);
660
+ const abortController = (0, Utils_1.getAbortController)(responseStream);
698
661
  //Pre-fetch
699
662
  const { pricePrefetchPromise, signDataPrefetchPromise } = this.getToBtcPrefetches(chainIdentifier, useToken, responseStream, abortController);
700
663
  //Check if prior payment has been made
701
- await this.checkPriorPayment(parsedPR.id, abortController.signal);
664
+ await this.LightningAssertions.checkPriorPayment(parsedPR.id, abortController.signal);
702
665
  metadata.times.priorPaymentChecked = Date.now();
703
666
  //Check amounts
704
- const { amountBD, networkFeeData, totalInToken, swapFee, swapFeeInToken, networkFeeInToken } = await this.checkToBtcAmount(request, requestedAmount, fees, useToken, async (amountBD) => {
667
+ const { amountBD, networkFeeData, totalInToken, swapFee, swapFeeInToken, networkFeeInToken } = await this.AmountAssertions.checkToBtcAmount(this.type, request, { ...requestedAmount, pricePrefetch: pricePrefetchPromise }, fees, async (amountBD) => {
705
668
  //Check if we have enough liquidity to process the swap
706
- await this.checkLiquidity(amountBD, abortController.signal, true);
669
+ await this.LightningAssertions.checkLiquidity(amountBD, abortController.signal, true);
707
670
  metadata.times.liquidityChecked = Date.now();
708
671
  const maxFee = parsedBody.exactIn ?
709
672
  await this.swapPricing.getToBtcSwapAmount(parsedBody.maxFee, useToken, chainIdentifier, null, pricePrefetchPromise) :
710
673
  parsedBody.maxFee;
711
674
  return await this.checkAndGetNetworkFee(amountBD, maxFee, parsedBody.expiryTimestamp, currentTimestamp, parsedBody.pr, metadata, abortController.signal);
712
- }, abortController.signal, pricePrefetchPromise);
675
+ }, abortController.signal);
713
676
  metadata.times.priceCalculated = Date.now();
714
677
  //For exactIn swap, just save and wait for the actual invoice to be submitted
715
678
  if (parsedBody.exactIn) {
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ToBtcLnSwapAbs = exports.ToBtcLnSwapState = void 0;
4
- const __1 = require("../..");
5
- const Utils_1 = require("../../utils/Utils");
4
+ const index_1 = require("../../../index");
5
+ const Utils_1 = require("../../../utils/Utils");
6
6
  const ToBtcBaseSwap_1 = require("../ToBtcBaseSwap");
7
7
  var ToBtcLnSwapState;
8
8
  (function (ToBtcLnSwapState) {
@@ -31,7 +31,7 @@ class ToBtcLnSwapAbs extends ToBtcBaseSwap_1.ToBtcBaseSwap {
31
31
  this.quotedNetworkFee ?? (this.quotedNetworkFee = (0, Utils_1.deserializeBN)(chainIdOrObj.maxFee));
32
32
  this.realNetworkFee ?? (this.realNetworkFee = (0, Utils_1.deserializeBN)(chainIdOrObj.realRoutingFee));
33
33
  }
34
- this.type = __1.SwapHandlerType.TO_BTCLN;
34
+ this.type = index_1.SwapHandlerType.TO_BTCLN;
35
35
  }
36
36
  getIdentifierHash() {
37
37
  return this.lnPaymentHash;
@@ -0,0 +1,41 @@
1
+ import { Lockable, SpvVaultClaimEvent, SpvVaultCloseEvent, SpvVaultData, SpvVaultDepositEvent, SpvVaultOpenEvent, SpvVaultTokenBalance, SpvWithdrawalTransactionData, StorageObject } from "@atomiqlabs/base";
2
+ export declare enum SpvVaultState {
3
+ CLOSED = -1,
4
+ BTC_INITIATED = 0,
5
+ BTC_CONFIRMED = 1,
6
+ OPENED = 2
7
+ }
8
+ export declare class SpvVault<D extends SpvWithdrawalTransactionData = SpvWithdrawalTransactionData, T extends SpvVaultData = SpvVaultData> extends Lockable implements StorageObject {
9
+ readonly chainId: string;
10
+ readonly initialUtxo: string;
11
+ readonly btcAddress: string;
12
+ readonly pendingWithdrawals: D[];
13
+ data: T;
14
+ state: SpvVaultState;
15
+ balances: SpvVaultTokenBalance[];
16
+ scOpenTx: {
17
+ txId: string;
18
+ rawTx: string;
19
+ };
20
+ constructor(chainId: string, vault: T, btcAddress: string);
21
+ constructor(obj: any);
22
+ update(event: SpvVaultOpenEvent | SpvVaultDepositEvent | SpvVaultCloseEvent | SpvVaultClaimEvent): void;
23
+ addWithdrawal(withdrawalData: D): void;
24
+ removeWithdrawal(withdrawalData: D): boolean;
25
+ toRawAmounts(amounts: bigint[]): bigint[];
26
+ fromRawAmounts(rawAmounts: bigint[]): bigint[];
27
+ /**
28
+ * Returns the vault balance after processing all currently confirmed (at least 1 btc confirmation) withdrawals
29
+ */
30
+ getConfirmedBalance(): SpvVaultTokenBalance[];
31
+ serialize(): any;
32
+ getIdentifier(): string;
33
+ /**
34
+ * Returns the latest vault utxo
35
+ */
36
+ getLatestUtxo(): string;
37
+ /**
38
+ * Returns whether the vault is ready for the next swap
39
+ */
40
+ isReady(): boolean;
41
+ }
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SpvVault = exports.SpvVaultState = void 0;
4
+ const base_1 = require("@atomiqlabs/base");
5
+ var SpvVaultState;
6
+ (function (SpvVaultState) {
7
+ SpvVaultState[SpvVaultState["CLOSED"] = -1] = "CLOSED";
8
+ SpvVaultState[SpvVaultState["BTC_INITIATED"] = 0] = "BTC_INITIATED";
9
+ SpvVaultState[SpvVaultState["BTC_CONFIRMED"] = 1] = "BTC_CONFIRMED";
10
+ SpvVaultState[SpvVaultState["OPENED"] = 2] = "OPENED";
11
+ })(SpvVaultState = exports.SpvVaultState || (exports.SpvVaultState = {}));
12
+ class SpvVault extends base_1.Lockable {
13
+ constructor(chainIdOrObj, vault, btcAddress) {
14
+ super();
15
+ if (typeof (chainIdOrObj) === "string") {
16
+ this.state = SpvVaultState.BTC_INITIATED;
17
+ this.chainId = chainIdOrObj;
18
+ this.data = vault;
19
+ this.initialUtxo = vault.getUtxo();
20
+ this.btcAddress = btcAddress;
21
+ this.pendingWithdrawals = [];
22
+ }
23
+ else {
24
+ this.state = chainIdOrObj.state;
25
+ this.chainId = chainIdOrObj.chainId;
26
+ this.data = base_1.SpvVaultData.deserialize(chainIdOrObj.data);
27
+ this.initialUtxo = chainIdOrObj.initialUtxo;
28
+ this.btcAddress = chainIdOrObj.btcAddress;
29
+ this.pendingWithdrawals = chainIdOrObj.pendingWithdrawals.map((base_1.SpvWithdrawalTransactionData.deserialize));
30
+ this.scOpenTx = chainIdOrObj.scOpenTx;
31
+ }
32
+ this.balances = this.data.calculateStateAfter(this.pendingWithdrawals).balances;
33
+ }
34
+ update(event) {
35
+ if (event instanceof base_1.SpvVaultClaimEvent || event instanceof base_1.SpvVaultCloseEvent) {
36
+ const processedWithdrawalIndex = this.pendingWithdrawals.findIndex(val => val.btcTx.txid === event.btcTxId);
37
+ if (processedWithdrawalIndex !== -1)
38
+ this.pendingWithdrawals.splice(0, processedWithdrawalIndex + 1);
39
+ }
40
+ this.data.updateState(event);
41
+ this.balances = this.data.calculateStateAfter(this.pendingWithdrawals).balances;
42
+ }
43
+ addWithdrawal(withdrawalData) {
44
+ //Make sure this is a valid state transition before adding the tx to pending withdrawals
45
+ this.balances = this.data.calculateStateAfter([...this.pendingWithdrawals, withdrawalData]).balances;
46
+ this.pendingWithdrawals.push(withdrawalData);
47
+ }
48
+ removeWithdrawal(withdrawalData) {
49
+ const index = this.pendingWithdrawals.indexOf(withdrawalData);
50
+ if (index === -1)
51
+ return false;
52
+ this.pendingWithdrawals.splice(index, 1);
53
+ this.balances = this.data.calculateStateAfter(this.pendingWithdrawals).balances;
54
+ return true;
55
+ }
56
+ toRawAmounts(amounts) {
57
+ return amounts.map((amt, index) => {
58
+ const tokenData = this.data.getTokenData()[index];
59
+ if (tokenData == null)
60
+ throw new Error("Amount index out of bounds!");
61
+ return amt / tokenData.multiplier;
62
+ });
63
+ }
64
+ fromRawAmounts(rawAmounts) {
65
+ return rawAmounts.map((amt, index) => {
66
+ const tokenData = this.data.getTokenData()[index];
67
+ if (tokenData == null)
68
+ throw new Error("Amount index out of bounds!");
69
+ return amt * tokenData.multiplier;
70
+ });
71
+ }
72
+ /**
73
+ * Returns the vault balance after processing all currently confirmed (at least 1 btc confirmation) withdrawals
74
+ */
75
+ getConfirmedBalance() {
76
+ return this.data.calculateStateAfter(this.pendingWithdrawals.filter(val => val.btcTx.confirmations >= 1)).balances;
77
+ }
78
+ serialize() {
79
+ return {
80
+ state: this.state,
81
+ chainId: this.chainId,
82
+ data: this.data.serialize(),
83
+ initialUtxo: this.initialUtxo,
84
+ btcAddress: this.btcAddress,
85
+ pendingWithdrawals: this.pendingWithdrawals.map(val => val.serialize()),
86
+ scOpenTx: this.scOpenTx
87
+ };
88
+ }
89
+ getIdentifier() {
90
+ return this.chainId + "_" + this.data.getOwner() + "_" + this.data.getVaultId().toString(10);
91
+ }
92
+ /**
93
+ * Returns the latest vault utxo
94
+ */
95
+ getLatestUtxo() {
96
+ if (this.pendingWithdrawals.length === 0) {
97
+ return this.data.getUtxo();
98
+ }
99
+ const latestWithdrawal = this.pendingWithdrawals[this.pendingWithdrawals.length - 1];
100
+ if (latestWithdrawal.btcTx.confirmations >= 1)
101
+ return latestWithdrawal.btcTx.txid + ":0";
102
+ return null;
103
+ }
104
+ /**
105
+ * Returns whether the vault is ready for the next swap
106
+ */
107
+ isReady() {
108
+ return this.data.isOpened() && this.getLatestUtxo() != null;
109
+ }
110
+ }
111
+ exports.SpvVault = SpvVault;
@@ -0,0 +1,63 @@
1
+ import { SwapHandlerSwap } from "../SwapHandlerSwap";
2
+ import { SpvVault } from "./SpvVault";
3
+ export declare enum SpvVaultSwapState {
4
+ FAILED = -3,
5
+ DOUBLE_SPENT = -2,
6
+ EXPIRED = -1,
7
+ CREATED = 0,
8
+ SIGNED = 1,
9
+ SENT = 2,
10
+ BTC_CONFIRMED = 3,
11
+ CLAIMED = 4
12
+ }
13
+ export declare class SpvVaultSwap extends SwapHandlerSwap<SpvVaultSwapState> {
14
+ readonly quoteId: string;
15
+ readonly vaultOwner: string;
16
+ readonly vaultId: bigint;
17
+ readonly vaultUtxo: string;
18
+ readonly vaultAddress: string;
19
+ readonly expiry: number;
20
+ readonly tokenSwapFee: bigint;
21
+ readonly tokenSwapFeeInToken: bigint;
22
+ readonly gasSwapFee: bigint;
23
+ readonly gasSwapFeeInToken: bigint;
24
+ readonly btcFeeRate: number;
25
+ readonly btcAddress: string;
26
+ readonly recipient: string;
27
+ readonly amountBtc: bigint;
28
+ readonly amountToken: bigint;
29
+ readonly amountGasToken: bigint;
30
+ readonly rawAmountToken: bigint;
31
+ readonly rawAmountGasToken: bigint;
32
+ readonly callerFeeShare: bigint;
33
+ readonly frontingFeeShare: bigint;
34
+ readonly executionFeeShare: bigint;
35
+ readonly token: string;
36
+ readonly gasToken: string;
37
+ btcTxId: string;
38
+ constructor(chainIdentifier: string, quoteId: string, expiry: number, vault: SpvVault, vaultUtxo: string, btcAddress: string, btcFeeRate: number, recipient: string, amountBtc: bigint, amountToken: bigint, amountGasToken: bigint, swapFee: bigint, swapFeeInToken: bigint, gasSwapFee: bigint, gasSwapFeeInToken: bigint, callerFeeShare: bigint, frontingFeeShare: bigint, executionFeeShare: bigint, token: string, gasToken: string);
39
+ constructor(data: any);
40
+ serialize(): any;
41
+ getIdentifierHash(): string;
42
+ getOutputGasAmount(): bigint;
43
+ getOutputAmount(): bigint;
44
+ getSequence(): bigint | null;
45
+ getSwapFee(): {
46
+ inInputToken: bigint;
47
+ inOutputToken: bigint;
48
+ };
49
+ getTokenSwapFee(): {
50
+ inInputToken: bigint;
51
+ inOutputToken: bigint;
52
+ };
53
+ getGasSwapFee(): {
54
+ inInputToken: bigint;
55
+ inOutputToken: bigint;
56
+ };
57
+ getToken(): string;
58
+ getGasToken(): string;
59
+ getTotalInputAmount(): bigint;
60
+ isFailed(): boolean;
61
+ isInitiated(): boolean;
62
+ isSuccess(): boolean;
63
+ }
@@ -0,0 +1,145 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SpvVaultSwap = exports.SpvVaultSwapState = void 0;
4
+ const SwapHandlerSwap_1 = require("../SwapHandlerSwap");
5
+ const Utils_1 = require("../../utils/Utils");
6
+ const SwapHandler_1 = require("../SwapHandler");
7
+ var SpvVaultSwapState;
8
+ (function (SpvVaultSwapState) {
9
+ SpvVaultSwapState[SpvVaultSwapState["FAILED"] = -3] = "FAILED";
10
+ SpvVaultSwapState[SpvVaultSwapState["DOUBLE_SPENT"] = -2] = "DOUBLE_SPENT";
11
+ SpvVaultSwapState[SpvVaultSwapState["EXPIRED"] = -1] = "EXPIRED";
12
+ SpvVaultSwapState[SpvVaultSwapState["CREATED"] = 0] = "CREATED";
13
+ SpvVaultSwapState[SpvVaultSwapState["SIGNED"] = 1] = "SIGNED";
14
+ SpvVaultSwapState[SpvVaultSwapState["SENT"] = 2] = "SENT";
15
+ SpvVaultSwapState[SpvVaultSwapState["BTC_CONFIRMED"] = 3] = "BTC_CONFIRMED";
16
+ SpvVaultSwapState[SpvVaultSwapState["CLAIMED"] = 4] = "CLAIMED";
17
+ })(SpvVaultSwapState = exports.SpvVaultSwapState || (exports.SpvVaultSwapState = {}));
18
+ class SpvVaultSwap extends SwapHandlerSwap_1.SwapHandlerSwap {
19
+ constructor(chainIdentifierOrObj, quoteId, expiry, vault, vaultUtxo, btcAddress, btcFeeRate, recipient, amountBtc, amountToken, amountGasToken, swapFee, swapFeeInToken, gasSwapFee, gasSwapFeeInToken, callerFeeShare, frontingFeeShare, executionFeeShare, token, gasToken) {
20
+ if (typeof (chainIdentifierOrObj) === "string") {
21
+ super(chainIdentifierOrObj, swapFee + gasSwapFee, swapFeeInToken * (swapFee + gasSwapFee) / swapFee);
22
+ this.state = SpvVaultSwapState.CREATED;
23
+ this.quoteId = quoteId;
24
+ this.expiry = expiry;
25
+ this.vaultOwner = vault.data.getOwner();
26
+ this.vaultId = vault.data.getVaultId();
27
+ this.vaultAddress = vault.btcAddress;
28
+ this.vaultUtxo = vaultUtxo;
29
+ this.tokenSwapFee = swapFee;
30
+ this.tokenSwapFeeInToken = swapFeeInToken;
31
+ this.gasSwapFee = gasSwapFee;
32
+ this.gasSwapFeeInToken = gasSwapFeeInToken;
33
+ this.btcFeeRate = btcFeeRate;
34
+ this.btcAddress = btcAddress;
35
+ this.recipient = recipient;
36
+ this.amountBtc = amountBtc;
37
+ this.amountToken = amountToken;
38
+ this.amountGasToken = amountGasToken;
39
+ const [rawAmountToken, rawAmountGasToken] = vault.toRawAmounts([amountToken, amountGasToken]);
40
+ this.rawAmountToken = rawAmountToken;
41
+ this.rawAmountGasToken = rawAmountGasToken;
42
+ this.callerFeeShare = callerFeeShare;
43
+ this.frontingFeeShare = frontingFeeShare;
44
+ this.executionFeeShare = executionFeeShare;
45
+ this.token = token;
46
+ this.gasToken = gasToken;
47
+ }
48
+ else {
49
+ super(chainIdentifierOrObj);
50
+ this.quoteId = chainIdentifierOrObj.quoteId;
51
+ this.expiry = chainIdentifierOrObj.expiry;
52
+ this.vaultOwner = chainIdentifierOrObj.owner;
53
+ this.vaultId = (0, Utils_1.deserializeBN)(chainIdentifierOrObj.vaultId);
54
+ this.vaultAddress = chainIdentifierOrObj.vaultAddress;
55
+ this.vaultUtxo = chainIdentifierOrObj.vaultUtxo;
56
+ this.tokenSwapFee = (0, Utils_1.deserializeBN)(chainIdentifierOrObj.swapFee);
57
+ this.tokenSwapFeeInToken = (0, Utils_1.deserializeBN)(chainIdentifierOrObj.swapFeeInToken);
58
+ this.gasSwapFee = (0, Utils_1.deserializeBN)(chainIdentifierOrObj.gasSwapFee);
59
+ this.gasSwapFeeInToken = (0, Utils_1.deserializeBN)(chainIdentifierOrObj.gasSwapFeeInToken);
60
+ this.btcFeeRate = chainIdentifierOrObj.btcFeeRate;
61
+ this.btcAddress = chainIdentifierOrObj.btcAddress;
62
+ this.recipient = chainIdentifierOrObj.recipient;
63
+ this.amountBtc = (0, Utils_1.deserializeBN)(chainIdentifierOrObj.amountBtc);
64
+ this.amountToken = (0, Utils_1.deserializeBN)(chainIdentifierOrObj.amountToken);
65
+ this.amountGasToken = (0, Utils_1.deserializeBN)(chainIdentifierOrObj.amountGasToken);
66
+ this.rawAmountToken = (0, Utils_1.deserializeBN)(chainIdentifierOrObj.rawAmountToken);
67
+ this.rawAmountGasToken = (0, Utils_1.deserializeBN)(chainIdentifierOrObj.rawAmountGasToken);
68
+ this.callerFeeShare = (0, Utils_1.deserializeBN)(chainIdentifierOrObj.callerFeeShare);
69
+ this.frontingFeeShare = (0, Utils_1.deserializeBN)(chainIdentifierOrObj.frontingFeeShare);
70
+ this.executionFeeShare = (0, Utils_1.deserializeBN)(chainIdentifierOrObj.executionFeeShare);
71
+ this.token = chainIdentifierOrObj.token;
72
+ this.gasToken = chainIdentifierOrObj.gasToken;
73
+ this.btcTxId = chainIdentifierOrObj.btcTxId;
74
+ }
75
+ this.type = SwapHandler_1.SwapHandlerType.FROM_BTC_SPV;
76
+ }
77
+ serialize() {
78
+ return {
79
+ ...super.serialize(),
80
+ quoteId: this.quoteId,
81
+ owner: this.vaultOwner,
82
+ vaultId: (0, Utils_1.serializeBN)(this.vaultId),
83
+ vaultAddress: this.vaultAddress,
84
+ vaultUtxo: this.vaultUtxo,
85
+ tokenSwapFee: (0, Utils_1.serializeBN)(this.tokenSwapFee),
86
+ tokenSwapFeeInToken: (0, Utils_1.serializeBN)(this.tokenSwapFeeInToken),
87
+ gasSwapFee: (0, Utils_1.serializeBN)(this.gasSwapFee),
88
+ gasSwapFeeInToken: (0, Utils_1.serializeBN)(this.gasSwapFeeInToken),
89
+ btcFeeRate: this.btcFeeRate,
90
+ btcAddress: this.btcAddress,
91
+ recipient: this.recipient,
92
+ amountBtc: (0, Utils_1.serializeBN)(this.amountBtc),
93
+ amountToken: (0, Utils_1.serializeBN)(this.amountToken),
94
+ amountGasToken: (0, Utils_1.serializeBN)(this.amountGasToken),
95
+ rawAmountToken: (0, Utils_1.serializeBN)(this.rawAmountToken),
96
+ rawAmountGasToken: (0, Utils_1.serializeBN)(this.rawAmountGasToken),
97
+ callerFeeShare: (0, Utils_1.serializeBN)(this.callerFeeShare),
98
+ frontingFeeShare: (0, Utils_1.serializeBN)(this.frontingFeeShare),
99
+ executionFeeShare: (0, Utils_1.serializeBN)(this.executionFeeShare),
100
+ token: this.token,
101
+ gasToken: this.gasToken,
102
+ btcTxId: this.btcTxId
103
+ };
104
+ }
105
+ getIdentifierHash() {
106
+ return this.quoteId;
107
+ }
108
+ getOutputGasAmount() {
109
+ return this.amountGasToken;
110
+ }
111
+ getOutputAmount() {
112
+ return this.amountToken;
113
+ }
114
+ getSequence() {
115
+ return 0n;
116
+ }
117
+ getSwapFee() {
118
+ return { inInputToken: this.swapFee, inOutputToken: this.swapFeeInToken };
119
+ }
120
+ getTokenSwapFee() {
121
+ return { inInputToken: this.tokenSwapFee, inOutputToken: this.tokenSwapFeeInToken };
122
+ }
123
+ getGasSwapFee() {
124
+ return { inInputToken: this.gasSwapFee, inOutputToken: this.gasSwapFeeInToken };
125
+ }
126
+ getToken() {
127
+ return this.token;
128
+ }
129
+ getGasToken() {
130
+ return this.gasToken;
131
+ }
132
+ getTotalInputAmount() {
133
+ return this.amountBtc;
134
+ }
135
+ isFailed() {
136
+ return this.state === SpvVaultSwapState.FAILED || this.state === SpvVaultSwapState.DOUBLE_SPENT;
137
+ }
138
+ isInitiated() {
139
+ return this.state !== SpvVaultSwapState.CREATED;
140
+ }
141
+ isSuccess() {
142
+ return this.state === SpvVaultSwapState.CLAIMED;
143
+ }
144
+ }
145
+ exports.SpvVaultSwap = SpvVaultSwap;
@@ -0,0 +1,68 @@
1
+ import { MultichainData, SwapBaseConfig, SwapHandler, SwapHandlerType } from "../SwapHandler";
2
+ import { Express } from "express";
3
+ import { IBitcoinWallet } from "../../wallets/IBitcoinWallet";
4
+ import { BitcoinRpc, BtcBlock, ChainEvent, IStorageManager, SpvVaultClaimEvent, SwapData } from "@atomiqlabs/base";
5
+ import { IIntermediaryStorage } from "../../storage/IIntermediaryStorage";
6
+ import { ISwapPrice } from "../../prices/ISwapPrice";
7
+ import { SpvVaultSwap, SpvVaultSwapState } from "./SpvVaultSwap";
8
+ import { ISpvVaultSigner } from "../../wallets/ISpvVaultSigner";
9
+ import { SpvVault } from "./SpvVault";
10
+ import { FromBtcAmountAssertions } from "../assertions/FromBtcAmountAssertions";
11
+ import { SpvVaults } from "./SpvVaults";
12
+ export type SpvVaultSwapHandlerConfig = SwapBaseConfig & {
13
+ vaultsCheckInterval: number;
14
+ gasTokenMax: {
15
+ [chainId: string]: bigint;
16
+ };
17
+ maxUnclaimedWithdrawals?: number;
18
+ };
19
+ export type SpvVaultSwapRequestType = {
20
+ address: string;
21
+ amount: bigint;
22
+ token: string;
23
+ gasAmount: bigint;
24
+ gasToken: string;
25
+ exactOut?: boolean;
26
+ callerFeeRate: bigint;
27
+ frontingFeeRate: bigint;
28
+ };
29
+ export type SpvVaultPostQuote = {
30
+ quoteId: string;
31
+ psbtHex: string;
32
+ };
33
+ export declare class SpvVaultSwapHandler extends SwapHandler<SpvVaultSwap, SpvVaultSwapState> {
34
+ readonly type = SwapHandlerType.FROM_BTC_SPV;
35
+ readonly bitcoin: IBitcoinWallet;
36
+ readonly bitcoinRpc: BitcoinRpc<BtcBlock>;
37
+ readonly vaultSigner: ISpvVaultSigner;
38
+ readonly btcTxIdIndex: Map<string, SpvVaultSwap>;
39
+ readonly AmountAssertions: FromBtcAmountAssertions;
40
+ readonly Vaults: SpvVaults;
41
+ config: SpvVaultSwapHandlerConfig;
42
+ constructor(storageDirectory: IIntermediaryStorage<SpvVaultSwap>, vaultStorage: IStorageManager<SpvVault>, path: string, chainsData: MultichainData, swapPricing: ISwapPrice, bitcoin: IBitcoinWallet, bitcoinRpc: BitcoinRpc<BtcBlock>, spvVaultSigner: ISpvVaultSigner, config: SpvVaultSwapHandlerConfig);
43
+ protected processClaimEvent(swap: SpvVaultSwap | null, event: SpvVaultClaimEvent): Promise<void>;
44
+ /**
45
+ * Chain event processor
46
+ *
47
+ * @param chainIdentifier
48
+ * @param eventData
49
+ */
50
+ protected processEvent(chainIdentifier: string, eventData: ChainEvent<SwapData>[]): Promise<boolean>;
51
+ /**
52
+ * Initializes chain events subscription
53
+ */
54
+ protected subscribeToEvents(): void;
55
+ startWatchdog(): Promise<void>;
56
+ init(): Promise<void>;
57
+ protected processPastSwap(swap: SpvVaultSwap): Promise<void>;
58
+ protected processPastSwaps(): Promise<void>;
59
+ protected getPricePrefetches(chainIdentifier: string, token: string, gasToken: string, abortController: AbortController): {
60
+ pricePrefetchPromise: Promise<bigint>;
61
+ gasTokenPricePrefetchPromise: Promise<bigint>;
62
+ };
63
+ startRestServer(restServer: Express): void;
64
+ getInfoData(): any;
65
+ protected saveSwapData(swap: SpvVaultSwap): Promise<void>;
66
+ protected removeSwapData(hash: string, sequence: bigint): Promise<void>;
67
+ protected removeSwapData(swap: SpvVaultSwap, ultimateState?: SpvVaultSwapState): Promise<void>;
68
+ }