@atomiqlabs/lp-lib 15.0.13 → 16.0.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 (66) hide show
  1. package/dist/index.d.ts +2 -0
  2. package/dist/index.js +2 -0
  3. package/dist/info/InfoHandler.js +0 -3
  4. package/dist/plugins/IPlugin.d.ts +2 -2
  5. package/dist/plugins/PluginManager.d.ts +2 -2
  6. package/dist/storagemanager/IntermediaryStorageManager.d.ts +1 -0
  7. package/dist/storagemanager/IntermediaryStorageManager.js +9 -2
  8. package/dist/storagemanager/StorageManager.d.ts +1 -0
  9. package/dist/storagemanager/StorageManager.js +9 -2
  10. package/dist/swaps/SwapHandler.d.ts +4 -10
  11. package/dist/swaps/SwapHandler.js +4 -13
  12. package/dist/swaps/assertions/FromBtcAmountAssertions.d.ts +2 -2
  13. package/dist/swaps/assertions/FromBtcAmountAssertions.js +13 -5
  14. package/dist/swaps/escrow/EscrowHandlerSwap.js +2 -2
  15. package/dist/swaps/escrow/FromBtcBaseSwapHandler.d.ts +2 -1
  16. package/dist/swaps/escrow/FromBtcBaseSwapHandler.js +8 -5
  17. package/dist/swaps/escrow/frombtc_abstract/FromBtcAbs.js +2 -2
  18. package/dist/swaps/escrow/frombtcln_abstract/FromBtcLnAbs.js +11 -13
  19. package/dist/swaps/escrow/frombtcln_abstract/FromBtcLnSwapAbs.d.ts +1 -0
  20. package/dist/swaps/escrow/frombtcln_abstract/FromBtcLnSwapAbs.js +3 -0
  21. package/dist/swaps/escrow/frombtcln_autoinit/FromBtcLnAuto.d.ts +111 -0
  22. package/dist/swaps/escrow/frombtcln_autoinit/FromBtcLnAuto.js +682 -0
  23. package/dist/swaps/escrow/frombtcln_autoinit/FromBtcLnAutoSwap.d.ts +55 -0
  24. package/dist/swaps/escrow/frombtcln_autoinit/FromBtcLnAutoSwap.js +120 -0
  25. package/dist/swaps/escrow/tobtc_abstract/ToBtcAbs.d.ts +0 -2
  26. package/dist/swaps/escrow/tobtc_abstract/ToBtcAbs.js +44 -27
  27. package/dist/swaps/escrow/tobtcln_abstract/ToBtcLnAbs.js +12 -10
  28. package/dist/swaps/spv_vault_swap/SpvVault.d.ts +2 -3
  29. package/dist/swaps/spv_vault_swap/SpvVault.js +2 -2
  30. package/dist/swaps/spv_vault_swap/SpvVaultSwapHandler.js +10 -8
  31. package/dist/swaps/spv_vault_swap/SpvVaults.d.ts +4 -9
  32. package/dist/swaps/spv_vault_swap/SpvVaults.js +114 -80
  33. package/dist/swaps/trusted/frombtc_trusted/FromBtcTrusted.js +3 -3
  34. package/dist/swaps/trusted/frombtcln_trusted/FromBtcLnTrusted.js +14 -17
  35. package/dist/utils/Utils.d.ts +7 -7
  36. package/dist/utils/Utils.js +12 -11
  37. package/dist/utils/paramcoders/server/ServerParamDecoder.js +8 -6
  38. package/dist/wallets/IBitcoinWallet.d.ts +7 -0
  39. package/package.json +3 -3
  40. package/src/index.ts +2 -0
  41. package/src/info/InfoHandler.ts +0 -6
  42. package/src/plugins/IPlugin.ts +2 -2
  43. package/src/plugins/PluginManager.ts +2 -2
  44. package/src/storagemanager/IntermediaryStorageManager.ts +11 -2
  45. package/src/storagemanager/StorageManager.ts +12 -2
  46. package/src/swaps/SwapHandler.ts +6 -17
  47. package/src/swaps/assertions/FromBtcAmountAssertions.ts +16 -8
  48. package/src/swaps/escrow/EscrowHandlerSwap.ts +2 -2
  49. package/src/swaps/escrow/FromBtcBaseSwapHandler.ts +8 -5
  50. package/src/swaps/escrow/frombtc_abstract/FromBtcAbs.ts +2 -2
  51. package/src/swaps/escrow/frombtcln_abstract/FromBtcLnAbs.ts +11 -12
  52. package/src/swaps/escrow/frombtcln_abstract/FromBtcLnSwapAbs.ts +4 -0
  53. package/src/swaps/escrow/frombtcln_autoinit/FromBtcLnAuto.ts +847 -0
  54. package/src/swaps/escrow/frombtcln_autoinit/FromBtcLnAutoSwap.ts +196 -0
  55. package/src/swaps/escrow/tobtc_abstract/ToBtcAbs.ts +55 -36
  56. package/src/swaps/escrow/tobtcln_abstract/ToBtcLnAbs.ts +19 -15
  57. package/src/swaps/spv_vault_swap/SpvVault.ts +3 -3
  58. package/src/swaps/spv_vault_swap/SpvVaultSwapHandler.ts +10 -8
  59. package/src/swaps/spv_vault_swap/SpvVaults.ts +130 -91
  60. package/src/swaps/trusted/frombtc_trusted/FromBtcTrusted.ts +3 -3
  61. package/src/swaps/trusted/frombtcln_trusted/FromBtcLnTrusted.ts +13 -16
  62. package/src/utils/Utils.ts +19 -17
  63. package/src/utils/paramcoders/server/ServerParamDecoder.ts +9 -6
  64. package/src/wallets/IBitcoinWallet.ts +8 -0
  65. package/dist/wallets/ISpvVaultWallet.d.ts +0 -42
  66. package/dist/wallets/ISpvVaultWallet.js +0 -2
@@ -0,0 +1,55 @@
1
+ import { SwapData } from "@atomiqlabs/base";
2
+ import { FromBtcBaseSwap } from "../FromBtcBaseSwap";
3
+ export declare enum FromBtcLnAutoSwapState {
4
+ REFUNDED = -2,
5
+ CANCELED = -1,
6
+ CREATED = 0,
7
+ RECEIVED = 1,
8
+ TXS_SENT = 2,
9
+ COMMITED = 3,
10
+ CLAIMED = 4,
11
+ SETTLED = 5
12
+ }
13
+ export declare class FromBtcLnAutoSwap<T extends SwapData = SwapData> extends FromBtcBaseSwap<T, FromBtcLnAutoSwapState> {
14
+ readonly pr: string;
15
+ readonly lnPaymentHash: string;
16
+ readonly claimHash: string;
17
+ readonly claimer: string;
18
+ readonly token: string;
19
+ readonly gasToken: string;
20
+ readonly amountToken: bigint;
21
+ readonly amountGasToken: bigint;
22
+ readonly tokenSwapFee: bigint;
23
+ readonly tokenSwapFeeInToken: bigint;
24
+ readonly gasSwapFee: bigint;
25
+ readonly gasSwapFeeInToken: bigint;
26
+ readonly claimerBounty: bigint;
27
+ secret: string;
28
+ constructor(chainIdentifier: string, pr: string, lnPaymentHash: string, claimHash: string, amountMtokens: bigint, claimer: string, token: string, gasToken: string, amountToken: bigint, amountGasToken: bigint, tokenSwapFee: bigint, tokenSwapFeeInToken: bigint, gasSwapFee: bigint, gasSwapFeeInToken: bigint, claimerBounty: bigint);
29
+ constructor(obj: any);
30
+ serialize(): any;
31
+ getClaimHash(): string;
32
+ getIdentifierHash(): string;
33
+ getOutputGasAmount(): bigint;
34
+ getOutputAmount(): bigint;
35
+ getTotalOutputAmount(): bigint;
36
+ getTotalOutputGasAmount(): bigint;
37
+ getSequence(): bigint;
38
+ getSwapFee(): {
39
+ inInputToken: bigint;
40
+ inOutputToken: bigint;
41
+ };
42
+ getTokenSwapFee(): {
43
+ inInputToken: bigint;
44
+ inOutputToken: bigint;
45
+ };
46
+ getGasSwapFee(): {
47
+ inInputToken: bigint;
48
+ inOutputToken: bigint;
49
+ };
50
+ getToken(): string;
51
+ getGasToken(): string;
52
+ isInitiated(): boolean;
53
+ isFailed(): boolean;
54
+ isSuccess(): boolean;
55
+ }
@@ -0,0 +1,120 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FromBtcLnAutoSwap = exports.FromBtcLnAutoSwapState = void 0;
4
+ const index_1 = require("../../../index");
5
+ const FromBtcBaseSwap_1 = require("../FromBtcBaseSwap");
6
+ const Utils_1 = require("../../../utils/Utils");
7
+ var FromBtcLnAutoSwapState;
8
+ (function (FromBtcLnAutoSwapState) {
9
+ FromBtcLnAutoSwapState[FromBtcLnAutoSwapState["REFUNDED"] = -2] = "REFUNDED";
10
+ FromBtcLnAutoSwapState[FromBtcLnAutoSwapState["CANCELED"] = -1] = "CANCELED";
11
+ FromBtcLnAutoSwapState[FromBtcLnAutoSwapState["CREATED"] = 0] = "CREATED";
12
+ FromBtcLnAutoSwapState[FromBtcLnAutoSwapState["RECEIVED"] = 1] = "RECEIVED";
13
+ FromBtcLnAutoSwapState[FromBtcLnAutoSwapState["TXS_SENT"] = 2] = "TXS_SENT";
14
+ FromBtcLnAutoSwapState[FromBtcLnAutoSwapState["COMMITED"] = 3] = "COMMITED";
15
+ FromBtcLnAutoSwapState[FromBtcLnAutoSwapState["CLAIMED"] = 4] = "CLAIMED";
16
+ FromBtcLnAutoSwapState[FromBtcLnAutoSwapState["SETTLED"] = 5] = "SETTLED";
17
+ })(FromBtcLnAutoSwapState = exports.FromBtcLnAutoSwapState || (exports.FromBtcLnAutoSwapState = {}));
18
+ class FromBtcLnAutoSwap extends FromBtcBaseSwap_1.FromBtcBaseSwap {
19
+ constructor(chainIdOrObj, pr, lnPaymentHash, claimHash, amountMtokens, claimer, token, gasToken, amountToken, amountGasToken, tokenSwapFee, tokenSwapFeeInToken, gasSwapFee, gasSwapFeeInToken, claimerBounty) {
20
+ if (typeof (chainIdOrObj) === "string") {
21
+ super(chainIdOrObj, (amountMtokens + 999n) / 1000n, tokenSwapFee + gasSwapFee, tokenSwapFeeInToken);
22
+ this.state = FromBtcLnAutoSwapState.CREATED;
23
+ this.pr = pr;
24
+ this.lnPaymentHash = lnPaymentHash;
25
+ this.claimHash = claimHash;
26
+ this.claimer = claimer;
27
+ this.token = token;
28
+ this.gasToken = gasToken;
29
+ this.amountToken = amountToken;
30
+ this.amountGasToken = amountGasToken;
31
+ this.tokenSwapFee = tokenSwapFee;
32
+ this.tokenSwapFeeInToken = tokenSwapFeeInToken;
33
+ this.gasSwapFee = gasSwapFee;
34
+ this.gasSwapFeeInToken = gasSwapFeeInToken;
35
+ this.claimerBounty = claimerBounty;
36
+ }
37
+ else {
38
+ super(chainIdOrObj);
39
+ this.pr = chainIdOrObj.pr;
40
+ this.lnPaymentHash = chainIdOrObj.lnPaymentHash;
41
+ this.claimHash = chainIdOrObj.claimHash;
42
+ this.claimer = chainIdOrObj.claimer;
43
+ this.token = chainIdOrObj.token;
44
+ this.gasToken = chainIdOrObj.gasToken;
45
+ this.amountToken = (0, Utils_1.deserializeBN)(chainIdOrObj.amountToken);
46
+ this.amountGasToken = (0, Utils_1.deserializeBN)(chainIdOrObj.amountGasToken);
47
+ this.tokenSwapFee = (0, Utils_1.deserializeBN)(chainIdOrObj.tokenSwapFee);
48
+ this.tokenSwapFeeInToken = (0, Utils_1.deserializeBN)(chainIdOrObj.tokenSwapFeeInToken);
49
+ this.gasSwapFee = (0, Utils_1.deserializeBN)(chainIdOrObj.gasSwapFee);
50
+ this.gasSwapFeeInToken = (0, Utils_1.deserializeBN)(chainIdOrObj.gasSwapFeeInToken);
51
+ this.claimerBounty = (0, Utils_1.deserializeBN)(chainIdOrObj.claimerBounty);
52
+ this.secret = chainIdOrObj.secret;
53
+ }
54
+ this.type = index_1.SwapHandlerType.FROM_BTCLN_AUTO;
55
+ }
56
+ serialize() {
57
+ const partialSerialized = super.serialize();
58
+ partialSerialized.pr = this.pr;
59
+ partialSerialized.secret = this.secret;
60
+ partialSerialized.lnPaymentHash = this.lnPaymentHash;
61
+ partialSerialized.claimHash = this.claimHash;
62
+ partialSerialized.claimer = this.claimer;
63
+ partialSerialized.token = this.token;
64
+ partialSerialized.gasToken = this.gasToken;
65
+ partialSerialized.amountToken = (0, Utils_1.serializeBN)(this.amountToken);
66
+ partialSerialized.amountGasToken = (0, Utils_1.serializeBN)(this.amountGasToken);
67
+ partialSerialized.tokenSwapFee = (0, Utils_1.serializeBN)(this.tokenSwapFee);
68
+ partialSerialized.tokenSwapFeeInToken = (0, Utils_1.serializeBN)(this.tokenSwapFeeInToken);
69
+ partialSerialized.gasSwapFee = (0, Utils_1.serializeBN)(this.gasSwapFee);
70
+ partialSerialized.gasSwapFeeInToken = (0, Utils_1.serializeBN)(this.gasSwapFeeInToken);
71
+ partialSerialized.claimerBounty = (0, Utils_1.serializeBN)(this.claimerBounty);
72
+ return partialSerialized;
73
+ }
74
+ getClaimHash() {
75
+ return this.claimHash;
76
+ }
77
+ getIdentifierHash() {
78
+ return this.lnPaymentHash;
79
+ }
80
+ getOutputGasAmount() {
81
+ return this.amountGasToken;
82
+ }
83
+ getOutputAmount() {
84
+ return this.amountToken;
85
+ }
86
+ getTotalOutputAmount() {
87
+ return this.amountToken;
88
+ }
89
+ getTotalOutputGasAmount() {
90
+ return this.amountGasToken + this.claimerBounty;
91
+ }
92
+ getSequence() {
93
+ return 0n;
94
+ }
95
+ getSwapFee() {
96
+ return { inInputToken: this.swapFee, inOutputToken: this.swapFeeInToken };
97
+ }
98
+ getTokenSwapFee() {
99
+ return { inInputToken: this.tokenSwapFee, inOutputToken: this.tokenSwapFeeInToken };
100
+ }
101
+ getGasSwapFee() {
102
+ return { inInputToken: this.gasSwapFee, inOutputToken: this.gasSwapFeeInToken };
103
+ }
104
+ getToken() {
105
+ return this.token;
106
+ }
107
+ getGasToken() {
108
+ return this.gasToken;
109
+ }
110
+ isInitiated() {
111
+ return this.state !== FromBtcLnAutoSwapState.CREATED;
112
+ }
113
+ isFailed() {
114
+ return this.state === FromBtcLnAutoSwapState.CANCELED || this.state === FromBtcLnAutoSwapState.REFUNDED;
115
+ }
116
+ isSuccess() {
117
+ return this.state === FromBtcLnAutoSwapState.SETTLED;
118
+ }
119
+ }
120
+ exports.FromBtcLnAutoSwap = FromBtcLnAutoSwap;
@@ -5,7 +5,6 @@ import { ISwapPrice } from "../../../prices/ISwapPrice";
5
5
  import { BtcTx, ChainSwapType, ClaimEvent, InitializeEvent, RefundEvent, SwapData, BitcoinRpc, BtcBlock } from "@atomiqlabs/base";
6
6
  import { IIntermediaryStorage } from "../../../storage/IIntermediaryStorage";
7
7
  import { ToBtcBaseConfig, ToBtcBaseSwapHandler } from "../ToBtcBaseSwapHandler";
8
- import { PromiseQueue } from "promise-queue-ts";
9
8
  import { IBitcoinWallet } from "../../../wallets/IBitcoinWallet";
10
9
  export type ToBtcConfig = ToBtcBaseConfig & {
11
10
  sendSafetyFactor: bigint;
@@ -38,7 +37,6 @@ export declare class ToBtcAbs extends ToBtcBaseSwapHandler<ToBtcSwapAbs, ToBtcSw
38
37
  };
39
38
  bitcoinRpc: BitcoinRpc<BtcBlock>;
40
39
  bitcoin: IBitcoinWallet;
41
- sendBtcQueue: PromiseQueue;
42
40
  readonly config: ToBtcConfig;
43
41
  constructor(storageDirectory: IIntermediaryStorage<ToBtcSwapAbs>, path: string, chainData: MultichainData, bitcoin: IBitcoinWallet, swapPricing: ISwapPrice, bitcoinRpc: BitcoinRpc<BtcBlock>, config: ToBtcConfig);
44
42
  /**
@@ -10,9 +10,9 @@ const crypto_1 = require("crypto");
10
10
  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
- const promise_queue_ts_1 = require("promise-queue-ts");
14
13
  const BitcoinUtils_1 = require("../../../utils/BitcoinUtils");
15
14
  const OUTPUT_SCRIPT_MAX_LENGTH = 200;
15
+ const MAX_PARALLEL_TX_PROCESSED = 10;
16
16
  /**
17
17
  * Handler for to BTC swaps, utilizing PTLCs (proof-time locked contracts) using btc relay (on-chain bitcoin SPV)
18
18
  */
@@ -22,7 +22,6 @@ class ToBtcAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
22
22
  this.type = SwapHandler_1.SwapHandlerType.TO_BTC;
23
23
  this.swapType = base_1.ChainSwapType.CHAIN_NONCED;
24
24
  this.activeSubscriptions = {};
25
- this.sendBtcQueue = new promise_queue_ts_1.PromiseQueue();
26
25
  this.bitcoinRpc = bitcoinRpc;
27
26
  this.bitcoin = bitcoin;
28
27
  this.config = config;
@@ -49,17 +48,25 @@ class ToBtcAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
49
48
  * @param vout
50
49
  */
51
50
  async tryClaimSwap(tx, swap, vout) {
52
- const { swapContract, signer } = this.getChain(swap.chainIdentifier);
51
+ const { chainInterface, swapContract, signer } = this.getChain(swap.chainIdentifier);
53
52
  const blockHeader = await this.bitcoinRpc.getBlockHeader(tx.blockhash);
54
53
  //Set flag that we are sending the transaction already, so we don't end up with race condition
54
+ if (swap.isLocked())
55
+ return false;
56
+ let txns;
57
+ try {
58
+ txns = await swapContract.txsClaimWithTxData(signer, swap.data, { ...tx, height: blockHeader.getHeight() }, swap.requiredConfirmations, vout, null, null, false);
59
+ }
60
+ catch (e) {
61
+ this.swapLogger.error(swap, "tryClaimSwap(): error occurred creating swap claim transactions, height: " + blockHeader.getHeight() + " utxo: " + tx.txid + ":" + vout + " address: " + swap.address, e);
62
+ return false;
63
+ }
55
64
  const unlock = swap.lock(swapContract.claimWithTxDataTimeout);
56
65
  if (unlock == null)
57
66
  return false;
58
67
  try {
59
68
  this.swapLogger.debug(swap, "tryClaimSwap(): initiate claim of swap, height: " + blockHeader.getHeight() + " utxo: " + tx.txid + ":" + vout);
60
- const result = await swapContract.claimWithTxData(signer, swap.data, { ...tx, height: blockHeader.getHeight() }, swap.requiredConfirmations, vout, null, null, false, {
61
- waitForConfirmation: true
62
- });
69
+ await chainInterface.sendAndConfirm(signer, txns, true);
63
70
  this.swapLogger.info(swap, "tryClaimSwap(): swap claimed successfully, height: " + blockHeader.getHeight() + " utxo: " + tx.txid + ":" + vout + " address: " + swap.address);
64
71
  if (swap.metadata != null)
65
72
  swap.metadata.times.txClaimed = Date.now();
@@ -171,22 +178,30 @@ class ToBtcAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
171
178
  */
172
179
  async processBtcTxs() {
173
180
  const unsubscribeSwaps = [];
181
+ let promises = [];
174
182
  for (let txId in this.activeSubscriptions) {
175
183
  const swap = this.activeSubscriptions[txId];
176
184
  //TODO: RBF the transaction if it's already taking too long to confirm
177
- try {
178
- let tx = await this.bitcoin.getWalletTransaction(txId);
179
- if (tx == null)
180
- continue;
181
- if (await this.processBtcTx(swap, tx)) {
182
- this.swapLogger.info(swap, "processBtcTxs(): swap claimed successfully, txId: " + tx.txid + " address: " + swap.address);
183
- unsubscribeSwaps.push(swap);
185
+ promises.push((async () => {
186
+ try {
187
+ let tx = await this.bitcoin.getWalletTransaction(txId);
188
+ if (tx == null)
189
+ return;
190
+ if (await this.processBtcTx(swap, tx)) {
191
+ this.swapLogger.info(swap, "processBtcTxs(): swap claimed successfully, txId: " + tx.txid + " address: " + swap.address);
192
+ unsubscribeSwaps.push(swap);
193
+ }
184
194
  }
185
- }
186
- catch (e) {
187
- this.swapLogger.error(swap, "processBtcTxs(): error processing btc transaction", e);
195
+ catch (e) {
196
+ this.swapLogger.error(swap, "processBtcTxs(): error processing btc transaction", e);
197
+ }
198
+ })());
199
+ if (promises.length >= MAX_PARALLEL_TX_PROCESSED) {
200
+ await Promise.all(promises);
201
+ promises = [];
188
202
  }
189
203
  }
204
+ await Promise.all(promises);
190
205
  unsubscribeSwaps.forEach(swap => {
191
206
  this.unsubscribePayment(swap);
192
207
  });
@@ -260,7 +275,7 @@ class ToBtcAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
260
275
  sendBitcoinPayment(swap) {
261
276
  //Make sure that bitcoin payouts are processed sequentially to avoid race conditions between multiple payouts,
262
277
  // e.g. that 2 payouts share the same input and would effectively double-spend each other
263
- return this.sendBtcQueue.enqueue(async () => {
278
+ return this.bitcoin.execute(async () => {
264
279
  //Run checks
265
280
  this.checkExpiresTooSoon(swap);
266
281
  if (swap.metadata != null)
@@ -502,7 +517,7 @@ class ToBtcAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
502
517
  restServer.use(this.path + "/payInvoice", (0, ServerParamDecoder_1.serverParamDecoder)(10 * 1000));
503
518
  restServer.post(this.path + "/payInvoice", (0, Utils_1.expressHandlerWrapper)(async (req, res) => {
504
519
  const metadata = { request: {}, times: {} };
505
- const chainIdentifier = req.query.chain ?? this.chains.default;
520
+ const chainIdentifier = req.query.chain;
506
521
  const { swapContract, signer, chainInterface } = this.getChain(chainIdentifier);
507
522
  metadata.times.requestReceived = Date.now();
508
523
  /**
@@ -530,7 +545,7 @@ class ToBtcAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
530
545
  this.isTokenSupported(chainIdentifier, val) ? val : null,
531
546
  offerer: (val) => val != null &&
532
547
  typeof (val) === "string" &&
533
- chainInterface.isValidAddress(val) ? val : null,
548
+ chainInterface.isValidAddress(val, true) ? val : null,
534
549
  exactIn: SchemaVerifier_1.FieldTypeEnum.BooleanOptional
535
550
  });
536
551
  if (parsedBody == null)
@@ -631,21 +646,23 @@ class ToBtcAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
631
646
  msg: "Payment not found"
632
647
  };
633
648
  await this.checkExpired(payment);
634
- if (payment.state === ToBtcSwapAbs_1.ToBtcSwapState.COMMITED)
635
- throw {
636
- _httpStatus: 200,
649
+ if (payment.state === ToBtcSwapAbs_1.ToBtcSwapState.COMMITED) {
650
+ res.status(200).json({
637
651
  code: 20008,
638
652
  msg: "Payment processing"
639
- };
640
- if (payment.state === ToBtcSwapAbs_1.ToBtcSwapState.BTC_SENT || payment.state === ToBtcSwapAbs_1.ToBtcSwapState.BTC_SENDING)
641
- throw {
642
- _httpStatus: 200,
653
+ });
654
+ return;
655
+ }
656
+ if (payment.state === ToBtcSwapAbs_1.ToBtcSwapState.BTC_SENT || payment.state === ToBtcSwapAbs_1.ToBtcSwapState.BTC_SENDING) {
657
+ res.status(200).json({
643
658
  code: 20006,
644
659
  msg: "Already paid",
645
660
  data: {
646
661
  txId: payment.txId
647
662
  }
648
- };
663
+ });
664
+ return;
665
+ }
649
666
  const { swapContract, signer } = this.getChain(payment.chainIdentifier);
650
667
  if (payment.state === ToBtcSwapAbs_1.ToBtcSwapState.NON_PAYABLE) {
651
668
  const isCommited = await swapContract.isCommited(payment.data);
@@ -604,7 +604,7 @@ class ToBtcLnAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
604
604
  restServer.use(this.path + "/payInvoice", (0, ServerParamDecoder_1.serverParamDecoder)(10 * 1000));
605
605
  restServer.post(this.path + "/payInvoice", (0, Utils_1.expressHandlerWrapper)(async (req, res) => {
606
606
  const metadata = { request: {}, times: {} };
607
- const chainIdentifier = req.query.chain ?? this.chains.default;
607
+ const chainIdentifier = req.query.chain;
608
608
  const { swapContract, signer, chainInterface } = this.getChain(chainIdentifier);
609
609
  metadata.times.requestReceived = Date.now();
610
610
  /**
@@ -629,7 +629,7 @@ class ToBtcLnAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
629
629
  this.isTokenSupported(chainIdentifier, val) ? val : null,
630
630
  offerer: (val) => val != null &&
631
631
  typeof (val) === "string" &&
632
- chainInterface.isValidAddress(val) ? val : null,
632
+ chainInterface.isValidAddress(val, true) ? val : null,
633
633
  exactIn: SchemaVerifier_1.FieldTypeEnum.BooleanOptional,
634
634
  amount: SchemaVerifier_1.FieldTypeEnum.BigIntOptional
635
635
  });
@@ -811,21 +811,23 @@ class ToBtcLnAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
811
811
  code: 20007,
812
812
  msg: "Payment not found"
813
813
  };
814
- if (payment.status === "pending")
815
- throw {
816
- _httpStatus: 200,
814
+ if (payment.status === "pending") {
815
+ res.status(200).json({
817
816
  code: 20008,
818
817
  msg: "Payment in-flight"
819
- };
820
- if (payment.status === "confirmed")
821
- throw {
822
- _httpStatus: 200,
818
+ });
819
+ return;
820
+ }
821
+ if (payment.status === "confirmed") {
822
+ res.status(200).json({
823
823
  code: 20006,
824
824
  msg: "Already paid",
825
825
  data: {
826
826
  secret: payment.secret
827
827
  }
828
- };
828
+ });
829
+ return;
830
+ }
829
831
  if (payment.status === "failed")
830
832
  throw {
831
833
  _httpStatus: 200,
@@ -16,9 +16,8 @@ export declare class SpvVault<D extends SpvWithdrawalTransactionData = SpvWithdr
16
16
  data: T;
17
17
  state: SpvVaultState;
18
18
  balances: SpvVaultTokenBalance[];
19
- scOpenTx: {
20
- txId: string;
21
- rawTx: string;
19
+ scOpenTxs: {
20
+ [txId: string]: string;
22
21
  };
23
22
  constructor(chainId: string, vault: T, btcAddress: string);
24
23
  constructor(obj: any);
@@ -28,7 +28,7 @@ class SpvVault extends base_1.Lockable {
28
28
  this.initialUtxo = chainIdOrObj.initialUtxo;
29
29
  this.btcAddress = chainIdOrObj.btcAddress;
30
30
  this.pendingWithdrawals = chainIdOrObj.pendingWithdrawals.map((base_1.SpvWithdrawalTransactionData.deserialize));
31
- this.scOpenTx = chainIdOrObj.scOpenTx;
31
+ this.scOpenTxs = chainIdOrObj.scOpenTxs;
32
32
  this.replacedWithdrawals = new Map();
33
33
  if (chainIdOrObj.replacedWithdrawals != null) {
34
34
  chainIdOrObj.replacedWithdrawals.forEach((val) => {
@@ -117,7 +117,7 @@ class SpvVault extends base_1.Lockable {
117
117
  btcAddress: this.btcAddress,
118
118
  pendingWithdrawals: this.pendingWithdrawals.map(val => val.serialize()),
119
119
  replacedWithdrawals,
120
- scOpenTx: this.scOpenTx
120
+ scOpenTxs: this.scOpenTxs
121
121
  };
122
122
  }
123
123
  getIdentifier() {
@@ -25,7 +25,7 @@ class SpvVaultSwapHandler extends SwapHandler_1.SwapHandler {
25
25
  this.vaultSigner = spvVaultSigner;
26
26
  this.config = config;
27
27
  this.AmountAssertions = new FromBtcAmountAssertions_1.FromBtcAmountAssertions(config, swapPricing);
28
- this.Vaults = new SpvVaults_1.SpvVaults(vaultStorage, bitcoin, spvVaultSigner, bitcoinRpc, this.getChain.bind(this), config);
28
+ this.Vaults = new SpvVaults_1.SpvVaults(vaultStorage, bitcoin, spvVaultSigner, bitcoinRpc, this.chains, config);
29
29
  }
30
30
  async processClaimEvent(swap, event) {
31
31
  if (swap == null)
@@ -121,7 +121,7 @@ class SpvVaultSwapHandler extends SwapHandler_1.SwapHandler {
121
121
  await this.saveSwapData(swap);
122
122
  }
123
123
  }
124
- if (swap.state === SpvVaultSwap_1.SpvVaultSwapState.SENT) {
124
+ if (swap.state === SpvVaultSwap_1.SpvVaultSwapState.SENT || swap.state === SpvVaultSwap_1.SpvVaultSwapState.BTC_CONFIRMED) {
125
125
  //Check if confirmed or double-spent
126
126
  if (swap.sending)
127
127
  return;
@@ -135,8 +135,10 @@ class SpvVaultSwapHandler extends SwapHandler_1.SwapHandler {
135
135
  return;
136
136
  }
137
137
  else if (tx.confirmations > 0) {
138
- await swap.setState(SpvVaultSwap_1.SpvVaultSwapState.BTC_CONFIRMED);
139
- await this.saveSwapData(swap);
138
+ if (swap.state !== SpvVaultSwap_1.SpvVaultSwapState.BTC_CONFIRMED) {
139
+ await swap.setState(SpvVaultSwap_1.SpvVaultSwapState.BTC_CONFIRMED);
140
+ await this.saveSwapData(swap);
141
+ }
140
142
  }
141
143
  }
142
144
  }
@@ -174,7 +176,7 @@ class SpvVaultSwapHandler extends SwapHandler_1.SwapHandler {
174
176
  restServer.use(this.path + "/getQuote", (0, ServerParamDecoder_1.serverParamDecoder)(10 * 1000));
175
177
  restServer.post(this.path + "/getQuote", (0, Utils_1.expressHandlerWrapper)(async (req, res) => {
176
178
  const metadata = { request: {}, times: {} };
177
- const chainIdentifier = req.query.chain ?? this.chains.default;
179
+ const chainIdentifier = req.query.chain;
178
180
  const { signer, chainInterface, spvVaultContract } = this.getChain(chainIdentifier);
179
181
  metadata.times.requestReceived = Date.now();
180
182
  /**
@@ -190,7 +192,7 @@ class SpvVaultSwapHandler extends SwapHandler_1.SwapHandler {
190
192
  const parsedBody = await req.paramReader.getParams({
191
193
  address: (val) => val != null &&
192
194
  typeof (val) === "string" &&
193
- chainInterface.isValidAddress(val) ? val : null,
195
+ chainInterface.isValidAddress(val, true) ? val : null,
194
196
  amount: SchemaVerifier_1.FieldTypeEnum.BigInt,
195
197
  token: (val) => val != null &&
196
198
  typeof (val) === "string" &&
@@ -388,7 +390,7 @@ class SpvVaultSwapHandler extends SwapHandler_1.SwapHandler {
388
390
  msg: "PSBT transaction cannot be parsed!"
389
391
  };
390
392
  }
391
- if (data.recipient !== swap.recipient ||
393
+ if (!data.isRecipient(swap.recipient) ||
392
394
  data.callerFeeRate !== swap.callerFeeShare ||
393
395
  data.frontingFeeRate !== swap.frontingFeeShare ||
394
396
  data.executionFeeRate !== swap.executionFeeShare ||
@@ -423,7 +425,7 @@ class SpvVaultSwapHandler extends SwapHandler_1.SwapHandler {
423
425
  msg: "One or more PSBT inputs not finalized!"
424
426
  };
425
427
  const effectiveFeeRate = await this.bitcoinRpc.getEffectiveFeeRate(await this.bitcoin.parsePsbt(signedTx));
426
- if (effectiveFeeRate.feeRate < swap.btcFeeRate)
428
+ if (effectiveFeeRate.feeRate < 1 || Math.round(effectiveFeeRate.feeRate) < swap.btcFeeRate)
427
429
  throw {
428
430
  code: 20511,
429
431
  msg: "Bitcoin transaction fee too low, expected minimum: " + swap.btcFeeRate + " adjusted effective fee rate: " + effectiveFeeRate.feeRate
@@ -3,7 +3,7 @@ import { BitcoinRpc, IStorageManager, SpvVaultClaimEvent, SpvVaultCloseEvent, Sp
3
3
  import { SpvVaultSwap } from "./SpvVaultSwap";
4
4
  import { IBitcoinWallet } from "../../wallets/IBitcoinWallet";
5
5
  import { ISpvVaultSigner } from "../../wallets/ISpvVaultSigner";
6
- import { ChainData } from "../SwapHandler";
6
+ import { MultichainData } from "../SwapHandler";
7
7
  export declare const VAULT_DUST_AMOUNT = 600;
8
8
  export declare class SpvVaults {
9
9
  readonly vaultStorage: IStorageManager<SpvVault>;
@@ -14,14 +14,9 @@ export declare class SpvVaults {
14
14
  vaultsCheckInterval: number;
15
15
  maxUnclaimedWithdrawals?: number;
16
16
  };
17
- readonly getChain: (chainId: string) => ChainData;
18
- readonly logger: {
19
- debug: (msg: string, ...args: any) => void;
20
- info: (msg: string, ...args: any) => void;
21
- warn: (msg: string, ...args: any) => void;
22
- error: (msg: string, ...args: any) => void;
23
- };
24
- constructor(vaultStorage: IStorageManager<SpvVault>, bitcoin: IBitcoinWallet, vaultSigner: ISpvVaultSigner, bitcoinRpc: BitcoinRpc<any>, getChain: (chainId: string) => ChainData, config: {
17
+ readonly chains: MultichainData;
18
+ readonly logger: import("../../utils/Utils").LoggerType;
19
+ constructor(vaultStorage: IStorageManager<SpvVault>, bitcoin: IBitcoinWallet, vaultSigner: ISpvVaultSigner, bitcoinRpc: BitcoinRpc<any>, chains: MultichainData, config: {
25
20
  vaultsCheckInterval: number;
26
21
  maxUnclaimedWithdrawals?: number;
27
22
  });