@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
@@ -1,7 +1,8 @@
1
1
  import {BigIntBufferUtils, BtcTx, SwapData} from "@atomiqlabs/base";
2
- import {FromBtcBaseSwap} from "../FromBtcBaseSwap";
3
- import {deserializeBN, serializeBN} from "../../utils/Utils";
2
+ import {deserializeBN, serializeBN} from "../../../utils/Utils";
4
3
  import {createHash, randomBytes} from "crypto";
4
+ import {SwapHandlerSwap} from "../../SwapHandlerSwap";
5
+ import {SwapHandlerType} from "../../SwapHandler";
5
6
 
6
7
 
7
8
  export enum FromBtcTrustedSwapState {
@@ -17,8 +18,9 @@ export enum FromBtcTrustedSwapState {
17
18
  FINISHED = 5
18
19
  }
19
20
 
20
- export class FromBtcTrustedSwap<T extends SwapData = SwapData> extends FromBtcBaseSwap<T, FromBtcTrustedSwapState> {
21
+ export class FromBtcTrustedSwap extends SwapHandlerSwap<FromBtcTrustedSwapState> {
21
22
 
23
+ readonly amount: bigint;
22
24
  readonly sequence: bigint;
23
25
  readonly btcAddress: string;
24
26
 
@@ -79,9 +81,10 @@ export class FromBtcTrustedSwap<T extends SwapData = SwapData> extends FromBtcBa
79
81
  token?: string
80
82
  ) {
81
83
  if(typeof(objOrChainIdentifier)==="string") {
82
- super(objOrChainIdentifier, inputSats, swapFee, swapFeeInToken);
84
+ super(objOrChainIdentifier, swapFee, swapFeeInToken);
83
85
  this.state = FromBtcTrustedSwapState.CREATED;
84
86
  this.doubleSpent = false;
87
+ this.amount = inputSats;
85
88
  this.sequence = BigIntBufferUtils.fromBuffer(randomBytes(8));
86
89
  this.btcAddress = btcAddress;
87
90
  this.dstAddress = dstAddress;
@@ -94,6 +97,7 @@ export class FromBtcTrustedSwap<T extends SwapData = SwapData> extends FromBtcBa
94
97
  } else {
95
98
  super(objOrChainIdentifier);
96
99
  this.btcAddress = objOrChainIdentifier.btcAddress;
100
+ this.amount = deserializeBN(objOrChainIdentifier.amount);
97
101
  this.sequence = deserializeBN(objOrChainIdentifier.sequence);
98
102
  this.dstAddress = objOrChainIdentifier.dstAddress;
99
103
  this.outputTokens = deserializeBN(objOrChainIdentifier.outputTokens);
@@ -114,11 +118,13 @@ export class FromBtcTrustedSwap<T extends SwapData = SwapData> extends FromBtcBa
114
118
  this.refundTxId = objOrChainIdentifier.refundTxId;
115
119
  this.token = objOrChainIdentifier.token;
116
120
  }
121
+ this.type = SwapHandlerType.FROM_BTC_TRUSTED;
117
122
  }
118
123
 
119
124
  serialize(): any {
120
125
  const partialSerialized = super.serialize();
121
126
  partialSerialized.btcAddress = this.btcAddress;
127
+ partialSerialized.amount = serializeBN(this.amount);
122
128
  partialSerialized.sequence = serializeBN(this.sequence);
123
129
  partialSerialized.dstAddress = this.dstAddress;
124
130
  partialSerialized.outputTokens = serializeBN(this.outputTokens);
@@ -141,10 +147,6 @@ export class FromBtcTrustedSwap<T extends SwapData = SwapData> extends FromBtcBa
141
147
  return partialSerialized;
142
148
  }
143
149
 
144
- getClaimHash(): string {
145
- return createHash("sha256").update(this.btcAddress).digest().toString("hex");
146
- }
147
-
148
150
  getSequence(): bigint {
149
151
  return this.sequence;
150
152
  }
@@ -161,6 +163,10 @@ export class FromBtcTrustedSwap<T extends SwapData = SwapData> extends FromBtcBa
161
163
  return this.adjustedInput || this.amount;
162
164
  }
163
165
 
166
+ getSwapFee(): { inInputToken: bigint; inOutputToken: bigint } {
167
+ return {inInputToken: this.swapFee, inOutputToken: this.swapFeeInToken};
168
+ }
169
+
164
170
  isFailed(): boolean {
165
171
  return this.state===FromBtcTrustedSwapState.EXPIRED || this.state===FromBtcTrustedSwapState.REFUNDED || this.state===FromBtcTrustedSwapState.DOUBLE_SPENT;
166
172
  }
@@ -173,4 +179,8 @@ export class FromBtcTrustedSwap<T extends SwapData = SwapData> extends FromBtcBa
173
179
  return this.state===FromBtcTrustedSwapState.CONFIRMED;
174
180
  }
175
181
 
182
+ getIdentifierHash(): string {
183
+ return createHash("sha256").update(this.btcAddress).digest().toString("hex");
184
+ }
185
+
176
186
  }
@@ -1,30 +1,24 @@
1
1
  import {Express, Request, Response} from "express";
2
2
  import {createHash, randomBytes} from "crypto";
3
- import {
4
- ClaimEvent,
5
- InitializeEvent,
6
- RefundEvent,
7
- SwapData,
8
- } from "@atomiqlabs/base";
9
3
  import {FromBtcLnTrustedSwap, FromBtcLnTrustedSwapState} from "./FromBtcLnTrustedSwap";
10
- import {FromBtcBaseConfig} from "../FromBtcBaseSwapHandler";
11
- import {ISwapPrice} from "../ISwapPrice";
12
- import {MultichainData, SwapHandlerType} from "../SwapHandler";
13
- import {IIntermediaryStorage} from "../../storage/IIntermediaryStorage";
14
- import {expressHandlerWrapper, HEX_REGEX} from "../../utils/Utils";
15
- import {IParamReader} from "../../utils/paramcoders/IParamReader";
16
- import {ServerParamEncoder} from "../../utils/paramcoders/server/ServerParamEncoder";
17
- import {FieldTypeEnum, verifySchema} from "../../utils/paramcoders/SchemaVerifier";
18
- import {PluginManager} from "../../plugins/PluginManager";
19
- import {FromBtcLnBaseSwapHandler} from "../FromBtcLnBaseSwapHandler";
4
+ import {ISwapPrice} from "../../../prices/ISwapPrice";
5
+ import {MultichainData, SwapBaseConfig, SwapHandler, SwapHandlerType} from "../../SwapHandler";
6
+ import {IIntermediaryStorage} from "../../../storage/IIntermediaryStorage";
7
+ import {expressHandlerWrapper, getAbortController, HEX_REGEX} from "../../../utils/Utils";
8
+ import {IParamReader} from "../../../utils/paramcoders/IParamReader";
9
+ import {ServerParamEncoder} from "../../../utils/paramcoders/server/ServerParamEncoder";
10
+ import {FieldTypeEnum, verifySchema} from "../../../utils/paramcoders/SchemaVerifier";
11
+ import {PluginManager} from "../../../plugins/PluginManager";
20
12
  import {
21
13
  HodlInvoiceInit,
22
14
  ILightningWallet,
23
15
  LightningNetworkChannel,
24
16
  LightningNetworkInvoice
25
- } from "../../wallets/ILightningWallet";
17
+ } from "../../../wallets/ILightningWallet";
18
+ import {FromBtcAmountAssertions} from "../../assertions/FromBtcAmountAssertions";
19
+ import { LightningAssertions } from "../../assertions/LightningAssertions";
26
20
 
27
- export type SwapForGasServerConfig = FromBtcBaseConfig & {
21
+ export type SwapForGasServerConfig = SwapBaseConfig & {
28
22
  minCltv: bigint,
29
23
 
30
24
  invoiceTimeoutSeconds?: number
@@ -40,14 +34,16 @@ export type FromBtcLnTrustedRequestType = {
40
34
  /**
41
35
  * Swap handler handling from BTCLN swaps using submarine swaps
42
36
  */
43
- export class FromBtcLnTrusted extends FromBtcLnBaseSwapHandler<FromBtcLnTrustedSwap, FromBtcLnTrustedSwapState> {
44
- readonly type: SwapHandlerType = SwapHandlerType.FROM_BTCLN_TRUSTED;
45
- readonly swapType = null;
37
+ export class FromBtcLnTrusted extends SwapHandler<FromBtcLnTrustedSwap, FromBtcLnTrustedSwapState> {
38
+ readonly type = SwapHandlerType.FROM_BTCLN_TRUSTED;
46
39
 
47
40
  activeSubscriptions: Map<string, AbortController> = new Map<string, AbortController>();
48
41
  processedTxIds: Map<string, string> = new Map<string, string>();
49
42
 
50
43
  readonly config: SwapForGasServerConfig;
44
+ readonly lightning: ILightningWallet;
45
+ readonly LightningAssertions: LightningAssertions;
46
+ readonly AmountAssertions: FromBtcAmountAssertions;
51
47
 
52
48
  constructor(
53
49
  storageDirectory: IIntermediaryStorage<FromBtcLnTrustedSwap>,
@@ -57,7 +53,10 @@ export class FromBtcLnTrusted extends FromBtcLnBaseSwapHandler<FromBtcLnTrustedS
57
53
  swapPricing: ISwapPrice,
58
54
  config: SwapForGasServerConfig
59
55
  ) {
60
- super(storageDirectory, path, chains, lightning, swapPricing);
56
+ super(storageDirectory, path, chains, swapPricing);
57
+ this.lightning = lightning;
58
+ this.LightningAssertions = new LightningAssertions(this.logger, lightning);
59
+ this.AmountAssertions = new FromBtcAmountAssertions(config, swapPricing);
61
60
  this.config = config;
62
61
  this.config.invoiceTimeoutSeconds = this.config.invoiceTimeoutSeconds || 90;
63
62
  }
@@ -193,7 +192,7 @@ export class FromBtcLnTrusted extends FromBtcLnBaseSwapHandler<FromBtcLnTrustedS
193
192
  */
194
193
  private async htlcReceived(invoiceData: FromBtcLnTrustedSwap, invoice: { id: string }) {
195
194
 
196
- const {swapContract, signer} = this.getChain(invoiceData.chainIdentifier);
195
+ const { signer, chainInterface} = this.getChain(invoiceData.chainIdentifier);
197
196
 
198
197
  //Important to prevent race condition and issuing 2 signed init messages at the same time
199
198
  if(invoiceData.state===FromBtcLnTrustedSwapState.CREATED) {
@@ -203,7 +202,7 @@ export class FromBtcLnTrusted extends FromBtcLnBaseSwapHandler<FromBtcLnTrustedS
203
202
  }
204
203
 
205
204
  if(invoiceData.state===FromBtcLnTrustedSwapState.RECEIVED) {
206
- const balance: Promise<bigint> = swapContract.getBalance(signer.getAddress(), invoiceData.token, false);
205
+ const balance: Promise<bigint> = chainInterface.getBalance(signer.getAddress(), invoiceData.token);
207
206
  try {
208
207
  await this.checkBalance(invoiceData.output, balance, null);
209
208
  if(invoiceData.metadata!=null) invoiceData.metadata.times.htlcBalanceChecked = Date.now();
@@ -214,12 +213,12 @@ export class FromBtcLnTrusted extends FromBtcLnBaseSwapHandler<FromBtcLnTrustedS
214
213
 
215
214
  if(invoiceData.state!==FromBtcLnTrustedSwapState.RECEIVED) return;
216
215
 
217
- const txns = await swapContract.txsTransfer(signer.getAddress(), invoiceData.token, invoiceData.output, invoiceData.dstAddress);
216
+ const txns = await chainInterface.txsTransfer(signer.getAddress(), invoiceData.token, invoiceData.output, invoiceData.dstAddress);
218
217
 
219
218
  let unlock = invoiceData.lock(Infinity);
220
219
  if(unlock==null) return;
221
220
 
222
- const result = await swapContract.sendAndConfirm(signer, txns, true, null, false, async (txId: string, rawTx: string) => {
221
+ const result = await chainInterface.sendAndConfirm(signer, txns, true, null, false, async (txId: string, rawTx: string) => {
223
222
  invoiceData.txIds = {init: txId};
224
223
  invoiceData.scRawTx = rawTx;
225
224
  if(invoiceData.state===FromBtcLnTrustedSwapState.RECEIVED) {
@@ -253,7 +252,7 @@ export class FromBtcLnTrusted extends FromBtcLnBaseSwapHandler<FromBtcLnTrustedS
253
252
  if(invoiceData.state===FromBtcLnTrustedSwapState.SENT) {
254
253
  if(invoiceData.isLocked()) return;
255
254
 
256
- const txStatus = await swapContract.getTxStatus(invoiceData.scRawTx);
255
+ const txStatus = await chainInterface.getTxStatus(invoiceData.scRawTx);
257
256
  if(txStatus==="not_found") {
258
257
  //Retry
259
258
  invoiceData.txIds = {init: null};
@@ -324,8 +323,8 @@ export class FromBtcLnTrusted extends FromBtcLnBaseSwapHandler<FromBtcLnTrustedS
324
323
  chainIdentifier = this.chains.default;
325
324
  address = invoice.description;
326
325
  }
327
- const {swapContract} = this.getChain(chainIdentifier);
328
- if(!swapContract.isValidAddress(address)) throw {
326
+ const { chainInterface} = this.getChain(chainIdentifier);
327
+ if(!chainInterface.isValidAddress(address)) throw {
329
328
  _httpStatus: 200,
330
329
  code: 10001,
331
330
  msg: "Invoice expired/canceled"
@@ -371,7 +370,7 @@ export class FromBtcLnTrusted extends FromBtcLnBaseSwapHandler<FromBtcLnTrustedS
371
370
  } = {request: {}, times: {}};
372
371
 
373
372
  const chainIdentifier = req.query.chain as string ?? this.chains.default;
374
- const {swapContract, signer} = this.getChain(chainIdentifier);
373
+ const {signer, chainInterface} = this.getChain(chainIdentifier);
375
374
 
376
375
  metadata.times.requestReceived = Date.now();
377
376
  /**
@@ -379,12 +378,12 @@ export class FromBtcLnTrusted extends FromBtcLnBaseSwapHandler<FromBtcLnTrustedS
379
378
  * amount: string amount (in lamports/smart chain base units) of the invoice
380
379
  */
381
380
 
382
- req.query.token ??= swapContract.getNativeCurrencyAddress();
381
+ req.query.token ??= chainInterface.getNativeCurrencyAddress();
383
382
 
384
383
  const parsedBody: FromBtcLnTrustedRequestType = verifySchema(req.query,{
385
384
  address: (val: string) => val!=null &&
386
385
  typeof(val)==="string" &&
387
- swapContract.isValidAddress(val) ? val : null,
386
+ chainInterface.isValidAddress(val) ? val : null,
388
387
  token: (val: string) => val!=null &&
389
388
  typeof(val)==="string" &&
390
389
  this.isTokenSupported(chainIdentifier, val) ? val : null,
@@ -398,7 +397,7 @@ export class FromBtcLnTrusted extends FromBtcLnBaseSwapHandler<FromBtcLnTrustedS
398
397
  };
399
398
  metadata.request = parsedBody;
400
399
 
401
- const requestedAmount = {input: parsedBody.exactIn, amount: parsedBody.amount};
400
+ const requestedAmount = {input: parsedBody.exactIn, amount: parsedBody.amount, token: parsedBody.token};
402
401
  const request = {
403
402
  chainIdentifier,
404
403
  raw: req,
@@ -408,21 +407,25 @@ export class FromBtcLnTrusted extends FromBtcLnBaseSwapHandler<FromBtcLnTrustedS
408
407
  const useToken = parsedBody.token;
409
408
 
410
409
  //Check request params
411
- const fees = await this.preCheckAmounts(request, requestedAmount, useToken);
410
+ const fees = await this.AmountAssertions.preCheckFromBtcAmounts(this.type, request, requestedAmount);
412
411
  metadata.times.requestChecked = Date.now();
413
412
 
414
413
  //Create abortController for parallel prefetches
415
414
  const responseStream = res.responseStream;
416
- const abortController = this.getAbortController(responseStream);
415
+ const abortController = getAbortController(responseStream);
417
416
 
418
417
  //Pre-fetch data
419
- const {pricePrefetchPromise} = this.getFromBtcPricePrefetches(chainIdentifier, useToken, useToken, abortController);
420
- const balancePrefetch = swapContract.getBalance(signer.getAddress(), useToken, false).catch(e => {
418
+ const pricePrefetchPromise: Promise<bigint> = this.swapPricing.preFetchPrice(useToken, chainIdentifier).catch(e => {
419
+ this.logger.error("pricePrefetchPromise(): pricePrefetch error: ", e);
420
+ abortController.abort(e);
421
+ return null;
422
+ });
423
+ const balancePrefetch = chainInterface.getBalance(signer.getAddress(), useToken).catch(e => {
421
424
  this.logger.error("getBalancePrefetch(): balancePrefetch error: ", e);
422
425
  abortController.abort(e);
423
426
  return null;
424
427
  });
425
- const channelsPrefetch: Promise<LightningNetworkChannel[]> = this.getChannelsPrefetch(abortController);
428
+ const channelsPrefetch: Promise<LightningNetworkChannel[]> = this.LightningAssertions.getChannelsPrefetch(abortController);
426
429
 
427
430
  //Check valid amount specified (min/max)
428
431
  const {
@@ -430,12 +433,12 @@ export class FromBtcLnTrusted extends FromBtcLnBaseSwapHandler<FromBtcLnTrustedS
430
433
  swapFee,
431
434
  swapFeeInToken,
432
435
  totalInToken
433
- } = await this.checkFromBtcAmount(request, requestedAmount, fees, useToken, abortController.signal, pricePrefetchPromise);
436
+ } = await this.AmountAssertions.checkFromBtcAmount(this.type, request, {...requestedAmount, pricePrefetch: pricePrefetchPromise}, fees, abortController.signal);
434
437
  metadata.times.priceCalculated = Date.now();
435
438
 
436
439
  //Check if we have enough funds to honor the request
437
440
  await this.checkBalance(totalInToken, balancePrefetch, abortController.signal)
438
- await this.checkInboundLiquidity(amountBD, channelsPrefetch, abortController.signal);
441
+ await this.LightningAssertions.checkInboundLiquidity(amountBD, channelsPrefetch, abortController.signal);
439
442
  metadata.times.balanceChecked = Date.now();
440
443
 
441
444
  const secret = randomBytes(32);
@@ -584,17 +587,5 @@ export class FromBtcLnTrusted extends FromBtcLnBaseSwapHandler<FromBtcLnTrustedS
584
587
  };
585
588
  }
586
589
 
587
- protected processClaimEvent(chainIdentifier: string, swap: FromBtcLnTrustedSwap, event: ClaimEvent<SwapData>): Promise<void> {
588
- return Promise.resolve();
589
- }
590
-
591
- protected processInitializeEvent(chainIdentifier: string, swap: FromBtcLnTrustedSwap, event: InitializeEvent<SwapData>): Promise<void> {
592
- return Promise.resolve();
593
- }
594
-
595
- protected processRefundEvent(chainIdentifier: string, swap: FromBtcLnTrustedSwap, event: RefundEvent<SwapData>): Promise<void> {
596
- return Promise.resolve();
597
- }
598
-
599
590
  }
600
591
 
@@ -1,7 +1,7 @@
1
- import {SwapData} from "@atomiqlabs/base";
2
1
  import {createHash} from "crypto";
3
- import {FromBtcBaseSwap} from "../FromBtcBaseSwap";
4
- import {deserializeBN, serializeBN} from "../../utils/Utils";
2
+ import {deserializeBN, serializeBN} from "../../../utils/Utils";
3
+ import {SwapHandlerSwap} from "../../SwapHandlerSwap";
4
+ import {SwapHandlerType} from "../../SwapHandler";
5
5
 
6
6
  export enum FromBtcLnTrustedSwapState {
7
7
  REFUNDED = -2,
@@ -13,9 +13,10 @@ export enum FromBtcLnTrustedSwapState {
13
13
  SETTLED = 4,
14
14
  }
15
15
 
16
- export class FromBtcLnTrustedSwap<T extends SwapData = SwapData> extends FromBtcBaseSwap<T, FromBtcLnTrustedSwapState> {
16
+ export class FromBtcLnTrustedSwap extends SwapHandlerSwap<FromBtcLnTrustedSwapState> {
17
17
 
18
18
  readonly pr: string;
19
+ amount: bigint;
19
20
  readonly output: bigint;
20
21
  readonly dstAddress: string;
21
22
  readonly secret: string;
@@ -48,9 +49,10 @@ export class FromBtcLnTrustedSwap<T extends SwapData = SwapData> extends FromBtc
48
49
  token?: string
49
50
  ) {
50
51
  if(typeof(chainIdOrObj)==="string") {
51
- super(chainIdOrObj, (inputMtokens + 999n) / 1000n, swapFee, swapFeeInToken);
52
+ super(chainIdOrObj, swapFee, swapFeeInToken);
52
53
  this.state = FromBtcLnTrustedSwapState.CREATED;
53
54
  this.pr = pr;
55
+ this.amount = (inputMtokens + 999n) / 1000n;
54
56
  this.output = output;
55
57
  this.secret = secret;
56
58
  this.dstAddress = dstAddress;
@@ -58,13 +60,14 @@ export class FromBtcLnTrustedSwap<T extends SwapData = SwapData> extends FromBtc
58
60
  } else {
59
61
  super(chainIdOrObj);
60
62
  this.pr = chainIdOrObj.pr;
63
+ this.amount = deserializeBN(chainIdOrObj.amount);
61
64
  this.output = deserializeBN(chainIdOrObj.output);
62
65
  this.secret = chainIdOrObj.secret;
63
66
  this.dstAddress = chainIdOrObj.dstAddress;
64
67
  this.token = chainIdOrObj.token;
65
68
  this.scRawTx = chainIdOrObj.scRawTx;
66
69
  }
67
- this.type = null;
70
+ this.type = SwapHandlerType.FROM_BTCLN_TRUSTED;
68
71
  }
69
72
 
70
73
  getToken(): string {
@@ -75,8 +78,12 @@ export class FromBtcLnTrustedSwap<T extends SwapData = SwapData> extends FromBtc
75
78
  return this.output;
76
79
  }
77
80
 
78
- getClaimHash(): string {
79
- return createHash("sha256").update(Buffer.from(this.secret, "hex")).digest().toString("hex");
81
+ getSwapFee(): { inInputToken: bigint; inOutputToken: bigint } {
82
+ return {inInputToken: this.swapFee, inOutputToken: this.swapFeeInToken};
83
+ }
84
+
85
+ getTotalInputAmount(): bigint {
86
+ return this.amount;
80
87
  }
81
88
 
82
89
  getSequence(): bigint {
@@ -86,6 +93,7 @@ export class FromBtcLnTrustedSwap<T extends SwapData = SwapData> extends FromBtc
86
93
  serialize(): any {
87
94
  const partialSerialized = super.serialize();
88
95
  partialSerialized.pr = this.pr;
96
+ partialSerialized.amount = serializeBN(this.amount);
89
97
  partialSerialized.output = serializeBN(this.output);
90
98
  partialSerialized.secret = this.secret;
91
99
  partialSerialized.dstAddress = this.dstAddress;
@@ -106,4 +114,8 @@ export class FromBtcLnTrustedSwap<T extends SwapData = SwapData> extends FromBtc
106
114
  return this.state===FromBtcLnTrustedSwapState.SETTLED;
107
115
  }
108
116
 
117
+ getIdentifierHash(): string {
118
+ return createHash("sha256").update(Buffer.from(this.secret, "hex")).digest().toString("hex");
119
+ }
120
+
109
121
  }
@@ -56,7 +56,14 @@ export function expressHandlerWrapper(func: (
56
56
  }
57
57
  }
58
58
 
59
- export function getLogger(prefix: string) {
59
+ export type LoggerType = {
60
+ debug: (msg: string, ...args: any[]) => void,
61
+ info: (msg: string, ...args: any[]) => void,
62
+ warn: (msg: string, ...args: any[]) => void,
63
+ error: (msg: string, ...args: any[]) => void
64
+ };
65
+
66
+ export function getLogger(prefix: string): LoggerType {
60
67
  return {
61
68
  debug: (msg, ...args) => console.debug(prefix+msg, ...args),
62
69
  info: (msg, ...args) => console.info(prefix+msg, ...args),
@@ -74,3 +81,22 @@ export function serializeBN(bn: bigint | null): string | null {
74
81
  export function deserializeBN(str: string | null): bigint | null {
75
82
  return str==null ? null : BigInt(str);
76
83
  }
84
+
85
+ export function bigIntSorter(a: bigint, b: bigint): -1 | 0 | 1 {
86
+ if(a < b) return -1;
87
+ if(a > b) return 1;
88
+ return 0;
89
+ }
90
+
91
+ /**
92
+ * Creates an abort controller that extends the responseStream's abort signal
93
+ *
94
+ * @param responseStream
95
+ */
96
+ export function getAbortController(responseStream: ServerParamEncoder): AbortController {
97
+ const abortController = new AbortController();
98
+ if(responseStream==null || responseStream.getAbortSignal==null) return abortController;
99
+ const responseStreamAbortController = responseStream.getAbortSignal();
100
+ responseStreamAbortController.addEventListener("abort", () => abortController.abort(responseStreamAbortController.reason));
101
+ return abortController;
102
+ }
@@ -52,13 +52,17 @@ export interface IBitcoinWallet {
52
52
  getWalletTransaction(txId: string): Promise<BtcTx | null>;
53
53
  subscribeToWalletTransactions(callback: (tx: BtcTx) => void, abortSignal?: AbortSignal): void;
54
54
 
55
+ fundPsbt(psbt: Transaction, feeRate?: number): Promise<Transaction>;
55
56
  signPsbt(psbt: Transaction): Promise<SignPsbtResponse>;
56
57
  sendRawTransaction(tx: string): Promise<void>;
57
58
  getSignedTransaction(destination: string, amount: number, feeRate?: number, nonce?: bigint, maxAllowedFeeRate?: number): Promise<SignPsbtResponse>;
59
+ getSignedMultiTransaction(destinations: {address: string, amount: number}[], feeRate?: number, nonce?: bigint, maxAllowedFeeRate?: number): Promise<SignPsbtResponse>;
58
60
  estimateFee(destination: string, amount: number, feeRate?: number, feeRateMultiplier?: number): Promise<{satsPerVbyte: number, networkFee: number}>;
59
61
  drainAll(destination: string | Buffer, inputs: Omit<BitcoinUtxo, "address">[], feeRate?: number): Promise<SignPsbtResponse>;
60
62
  burnAll(inputs: Omit<BitcoinUtxo, "address">[]): Promise<SignPsbtResponse>;
61
63
 
64
+ parsePsbt(psbt: Transaction): Promise<BtcTx>;
65
+
62
66
  getBlockheight(): Promise<number>;
63
67
  getFeeRate(): Promise<number>;
64
68
 
@@ -0,0 +1,11 @@
1
+ import {Transaction} from "@scure/btc-signer";
2
+
3
+ export interface ISpvVaultSigner {
4
+
5
+ init(): Promise<void>;
6
+
7
+ getAddressType(): "p2wpkh" | "p2tr";
8
+ getAddress(chainId: string, vaultId: bigint): Promise<string>;
9
+ signPsbt(chainId: string, vaultId: bigint, psbt: Transaction, inputs: number[]): Promise<Transaction>;
10
+
11
+ }
@@ -1,26 +0,0 @@
1
- import { SwapHandlerSwap } from "./SwapHandlerSwap";
2
- import { SwapData } from "@atomiqlabs/base";
3
- import { FromBtcBaseSwapHandler } from "./FromBtcBaseSwapHandler";
4
- import { ILightningWallet, LightningNetworkChannel } from "../wallets/ILightningWallet";
5
- import { IIntermediaryStorage } from "../storage/IIntermediaryStorage";
6
- import { MultichainData } from "./SwapHandler";
7
- import { ISwapPrice } from "./ISwapPrice";
8
- export declare abstract class FromBtcLnBaseSwapHandler<V extends SwapHandlerSwap<SwapData, S>, S> extends FromBtcBaseSwapHandler<V, S> {
9
- readonly lightning: ILightningWallet;
10
- constructor(storageDirectory: IIntermediaryStorage<V>, path: string, chains: MultichainData, lightning: ILightningWallet, swapPricing: ISwapPrice);
11
- /**
12
- * Checks if we have enough inbound liquidity to be able to receive an LN payment (without MPP)
13
- *
14
- * @param amountBD
15
- * @param channelsPrefetch
16
- * @param signal
17
- * @throws {DefinedRuntimeError} will throw an error if there isn't enough inbound liquidity to receive the LN payment
18
- */
19
- protected checkInboundLiquidity(amountBD: bigint, channelsPrefetch: Promise<LightningNetworkChannel[]>, signal: AbortSignal): Promise<void>;
20
- /**
21
- * Starts LN channels pre-fetch
22
- *
23
- * @param abortController
24
- */
25
- protected getChannelsPrefetch(abortController: AbortController): Promise<LightningNetworkChannel[]>;
26
- }
@@ -1,46 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.FromBtcLnBaseSwapHandler = void 0;
4
- const FromBtcBaseSwapHandler_1 = require("./FromBtcBaseSwapHandler");
5
- class FromBtcLnBaseSwapHandler extends FromBtcBaseSwapHandler_1.FromBtcBaseSwapHandler {
6
- constructor(storageDirectory, path, chains, lightning, swapPricing) {
7
- super(storageDirectory, path, chains, swapPricing);
8
- this.lightning = lightning;
9
- }
10
- /**
11
- * Checks if we have enough inbound liquidity to be able to receive an LN payment (without MPP)
12
- *
13
- * @param amountBD
14
- * @param channelsPrefetch
15
- * @param signal
16
- * @throws {DefinedRuntimeError} will throw an error if there isn't enough inbound liquidity to receive the LN payment
17
- */
18
- async checkInboundLiquidity(amountBD, channelsPrefetch, signal) {
19
- const channelsResponse = await channelsPrefetch;
20
- signal.throwIfAborted();
21
- let hasEnoughInboundLiquidity = false;
22
- channelsResponse.forEach(channel => {
23
- if (channel.remoteBalance >= amountBD)
24
- hasEnoughInboundLiquidity = true;
25
- });
26
- if (!hasEnoughInboundLiquidity) {
27
- throw {
28
- code: 20050,
29
- msg: "Not enough LN inbound liquidity"
30
- };
31
- }
32
- }
33
- /**
34
- * Starts LN channels pre-fetch
35
- *
36
- * @param abortController
37
- */
38
- getChannelsPrefetch(abortController) {
39
- return this.lightning.getChannels(true).catch(e => {
40
- this.logger.error("getChannelsPrefetch(): error", e);
41
- abortController.abort(e);
42
- return null;
43
- });
44
- }
45
- }
46
- exports.FromBtcLnBaseSwapHandler = FromBtcLnBaseSwapHandler;
@@ -1,95 +0,0 @@
1
- import { RequestData, SwapBaseConfig, SwapHandler } from "./SwapHandler";
2
- import { SwapHandlerSwap } from "./SwapHandlerSwap";
3
- import { SwapData } from "@atomiqlabs/base";
4
- import { ServerParamEncoder } from "../utils/paramcoders/server/ServerParamEncoder";
5
- import { IParamReader } from "../utils/paramcoders/IParamReader";
6
- import { ToBtcLnRequestType } from "./tobtcln_abstract/ToBtcLnAbs";
7
- import { ToBtcRequestType } from "./tobtc_abstract/ToBtcAbs";
8
- import { Request } from "express";
9
- export type ToBtcBaseConfig = SwapBaseConfig & {
10
- gracePeriod: bigint;
11
- refundAuthorizationTimeout: number;
12
- };
13
- export declare abstract class ToBtcBaseSwapHandler<V extends SwapHandlerSwap<SwapData, S>, S> extends SwapHandler<V, S> {
14
- readonly pdaExistsForToken: {
15
- [chainIdentifier: string]: {
16
- [token: string]: boolean;
17
- };
18
- };
19
- abstract config: ToBtcBaseConfig;
20
- protected checkVaultInitialized(chainIdentifier: string, token: string): Promise<void>;
21
- /**
22
- * Checks minimums/maximums, calculates the fee & total amount
23
- *
24
- * @param request
25
- * @param requestedAmount
26
- * @param useToken
27
- * @throws {DefinedRuntimeError} will throw an error if the amount is outside minimum/maximum bounds
28
- */
29
- protected preCheckAmounts(request: RequestData<ToBtcLnRequestType | ToBtcRequestType>, requestedAmount: {
30
- input: boolean;
31
- amount: bigint;
32
- }, useToken: string): Promise<{
33
- baseFee: bigint;
34
- feePPM: bigint;
35
- }>;
36
- /**
37
- * Checks minimums/maximums, calculates network fee (based on the callback passed), swap fee & total amount
38
- *
39
- * @param request
40
- * @param requestedAmount
41
- * @param fees
42
- * @param useToken
43
- * @param getNetworkFee
44
- * @param signal
45
- * @param pricePrefetchPromise
46
- * @throws {DefinedRuntimeError} will throw an error if the amount is outside minimum/maximum bounds,
47
- * or if we don't have enough funds (getNetworkFee callback throws)
48
- */
49
- protected checkToBtcAmount<T extends {
50
- networkFee: bigint;
51
- }>(request: RequestData<ToBtcLnRequestType | ToBtcRequestType>, requestedAmount: {
52
- input: boolean;
53
- amount: bigint;
54
- }, fees: {
55
- baseFee: bigint;
56
- feePPM: bigint;
57
- }, useToken: string, getNetworkFee: (amount: bigint) => Promise<T>, signal: AbortSignal, pricePrefetchPromise?: Promise<bigint>): Promise<{
58
- amountBD: bigint;
59
- networkFeeData: T;
60
- swapFee: bigint;
61
- swapFeeInToken: bigint;
62
- networkFee: bigint;
63
- networkFeeInToken: bigint;
64
- totalInToken: bigint;
65
- }>;
66
- /**
67
- * Starts pre-fetches for swap pricing & signature data
68
- *
69
- * @param chainIdentifier
70
- * @param token
71
- * @param responseStream
72
- * @param abortController
73
- */
74
- protected getToBtcPrefetches(chainIdentifier: string, token: string, responseStream: ServerParamEncoder, abortController: AbortController): {
75
- pricePrefetchPromise?: Promise<bigint>;
76
- signDataPrefetchPromise?: Promise<any>;
77
- };
78
- /**
79
- * Signs the created swap
80
- *
81
- * @param chainIdentifier
82
- * @param swapObject
83
- * @param req
84
- * @param abortSignal
85
- * @param signDataPrefetchPromise
86
- */
87
- protected getToBtcSignatureData(chainIdentifier: string, swapObject: SwapData, req: Request & {
88
- paramReader: IParamReader;
89
- }, abortSignal: AbortSignal, signDataPrefetchPromise?: Promise<any>): Promise<{
90
- prefix: string;
91
- timeout: string;
92
- signature: string;
93
- feeRate: string;
94
- }>;
95
- }