@atomiqlabs/lp-lib 16.0.10 → 16.0.11

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.
@@ -180,37 +180,75 @@ class SpvVaultSwapHandler extends SwapHandler_1.SwapHandler {
180
180
  const chainIdentifier = req.query.chain;
181
181
  const { signer, chainInterface, spvVaultContract } = this.getChain(chainIdentifier);
182
182
  metadata.times.requestReceived = Date.now();
183
+ /**
184
+ * token: string Desired token to use
185
+ * gasToken: string
186
+ */
187
+ const preFetchParsedBody = await req.paramReader.getParams({
188
+ token: (val) => val != null &&
189
+ typeof (val) === "string" &&
190
+ this.isTokenSupported(chainIdentifier, val) ? val : null,
191
+ gasToken: (val) => val != null &&
192
+ typeof (val) === "string" &&
193
+ chainInterface.isValidToken(val) ? val : null
194
+ });
195
+ if (preFetchParsedBody == null)
196
+ throw {
197
+ code: 20100,
198
+ msg: "Invalid request body"
199
+ };
200
+ //Create abortController for parallel prefetches
201
+ const responseStream = res.responseStream;
202
+ const abortController = (0, Utils_1.getAbortController)(responseStream);
203
+ //Pre-fetch data
204
+ const { pricePrefetchPromise, gasTokenPricePrefetchPromise } = this.getPricePrefetches(chainIdentifier, preFetchParsedBody.token, preFetchParsedBody.gasToken, abortController);
205
+ const nativeBalancePrefetch = this.prefetchNativeBalanceIfNeeded(chainIdentifier, abortController);
206
+ const btcFeeRatePrefetch = this.bitcoin.getFeeRate().catch(e => {
207
+ abortController.abort(e);
208
+ return null;
209
+ });
210
+ //Listener that re-adds the returned bitcoin address to the unused address list if request fails or closes
211
+ let abortAddUnusedAddressListener;
212
+ const bitcoinAddressPrefetch = this.bitcoin.getAddress().then(value => {
213
+ //Already aborted
214
+ if (abortController.signal.aborted) {
215
+ this.bitcoin.addUnusedAddress(value);
216
+ return null;
217
+ }
218
+ //Not aborted yet, add an event listener to re-add the address to the unused list
219
+ abortController.signal.addEventListener("abort", abortAddUnusedAddressListener = () => {
220
+ this.bitcoin.addUnusedAddress(value);
221
+ });
222
+ return value;
223
+ }).catch(e => {
224
+ abortController.abort(e);
225
+ return null;
226
+ });
183
227
  /**
184
228
  * address: string smart chain address of the recipient
185
229
  * amount: string amount (in sats)
186
- * token: string Desired token to use
187
230
  * gasAmount: string Desired amount in gas token to also get
188
- * gasToken: string
189
231
  * exactOut: boolean Whether the swap should be an exact out instead of exact in swap
190
232
  * callerFeeRate: string Caller/watchtower fee (in output token) to assign to the swap
191
233
  * frontingFeeRate: string Fronting fee (in output token) to assign to the swap
192
234
  */
193
- const parsedBody = await req.paramReader.getParams({
235
+ const actualParsedBody = await req.paramReader.getParams({
194
236
  address: (val) => val != null &&
195
237
  typeof (val) === "string" &&
196
238
  chainInterface.isValidAddress(val, true) ? val : null,
197
239
  amount: SchemaVerifier_1.FieldTypeEnum.BigInt,
198
- token: (val) => val != null &&
199
- typeof (val) === "string" &&
200
- this.isTokenSupported(chainIdentifier, val) ? val : null,
201
240
  gasAmount: SchemaVerifier_1.FieldTypeEnum.BigInt,
202
- gasToken: (val) => val != null &&
203
- typeof (val) === "string" &&
204
- chainInterface.isValidToken(val) ? val : null,
205
241
  exactOut: SchemaVerifier_1.FieldTypeEnum.BooleanOptional,
206
242
  callerFeeRate: SchemaVerifier_1.FieldTypeEnum.BigInt,
207
243
  frontingFeeRate: SchemaVerifier_1.FieldTypeEnum.BigInt,
208
244
  });
209
- if (parsedBody == null)
245
+ abortController.signal.throwIfAborted();
246
+ if (actualParsedBody == null)
210
247
  throw {
211
248
  code: 20100,
212
249
  msg: "Invalid request body"
213
250
  };
251
+ const parsedBody = { ...preFetchParsedBody, ...actualParsedBody };
214
252
  metadata.request = parsedBody;
215
253
  if (parsedBody.gasToken !== chainInterface.getNativeCurrencyAddress())
216
254
  throw {
@@ -251,12 +289,6 @@ class SpvVaultSwapHandler extends SwapHandler_1.SwapHandler {
251
289
  //Check request params
252
290
  const fees = await this.AmountAssertions.preCheckFromBtcAmounts(this.type, request, requestedAmount, gasTokenAmount);
253
291
  metadata.times.requestChecked = Date.now();
254
- //Create abortController for parallel prefetches
255
- const responseStream = res.responseStream;
256
- const abortController = (0, Utils_1.getAbortController)(responseStream);
257
- //Pre-fetch data
258
- const { pricePrefetchPromise, gasTokenPricePrefetchPromise } = this.getPricePrefetches(chainIdentifier, useToken, gasToken, abortController);
259
- const nativeBalancePrefetch = this.prefetchNativeBalanceIfNeeded(chainIdentifier, abortController);
260
292
  await this.checkNativeBalance(chainIdentifier, nativeBalancePrefetch, abortController.signal);
261
293
  //Check valid amount specified (min/max)
262
294
  let { amountBD, swapFee, swapFeeInToken, totalInToken, amountBDgas, gasSwapFee, gasSwapFeeInToken, totalInGasToken } = await this.AmountAssertions.checkFromBtcAmount(this.type, request, { ...requestedAmount, pricePrefetch: pricePrefetchPromise }, fees, abortController.signal, { ...gasTokenAmount, pricePrefetch: gasTokenPricePrefetchPromise });
@@ -270,8 +302,8 @@ class SpvVaultSwapHandler extends SwapHandler_1.SwapHandler {
270
302
  abortController.signal.throwIfAborted();
271
303
  metadata.times.vaultPicked = Date.now();
272
304
  //Create swap receive bitcoin address
273
- const btcFeeRate = await this.bitcoin.getFeeRate();
274
- const receiveAddress = await this.bitcoin.getAddress();
305
+ const btcFeeRate = await btcFeeRatePrefetch;
306
+ const receiveAddress = await bitcoinAddressPrefetch;
275
307
  abortController.signal.throwIfAborted();
276
308
  metadata.times.addressCreated = Date.now();
277
309
  //Adjust the amounts based on passed fees
@@ -294,6 +326,8 @@ class SpvVaultSwapHandler extends SwapHandler_1.SwapHandler {
294
326
  const quoteId = (0, crypto_1.randomBytes)(32).toString("hex");
295
327
  const swap = new SpvVaultSwap_1.SpvVaultSwap(chainIdentifier, quoteId, expiry, vault, utxo, receiveAddress, btcFeeRate, parsedBody.address, totalBtcOutput, totalInToken, totalInGasToken, swapFee, swapFeeInToken, gasSwapFee, gasSwapFeeInToken, callerFeeShare, frontingFeeShare, executionFeeShare, useToken, gasToken);
296
328
  swap.metadata = metadata;
329
+ //We can remove the listener to add unused address now, as we are about to save the swap
330
+ abortController.signal.removeEventListener("abort", abortAddUnusedAddressListener);
297
331
  await PluginManager_1.PluginManager.swapCreate(swap);
298
332
  await this.saveSwapData(swap);
299
333
  this.swapLogger.info(swap, "REST: /getQuote: Created swap address: " + receiveAddress + " amount: " + totalBtcOutput.toString(10));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atomiqlabs/lp-lib",
3
- "version": "16.0.10",
3
+ "version": "16.0.11",
4
4
  "description": "Main functionality implementation for atomiq LP node",
5
5
  "main": "./dist/index.js",
6
6
  "types:": "./dist/index.d.ts",
@@ -251,36 +251,82 @@ export class SpvVaultSwapHandler extends SwapHandler<SpvVaultSwap, SpvVaultSwapS
251
251
  const {signer, chainInterface, spvVaultContract} = this.getChain(chainIdentifier);
252
252
 
253
253
  metadata.times.requestReceived = Date.now();
254
+
255
+ /**
256
+ * token: string Desired token to use
257
+ * gasToken: string
258
+ */
259
+ const preFetchParsedBody = await req.paramReader.getParams({
260
+ token: (val: string) => val!=null &&
261
+ typeof(val)==="string" &&
262
+ this.isTokenSupported(chainIdentifier, val) ? val : null,
263
+ gasToken: (val: string) => val!=null &&
264
+ typeof(val)==="string" &&
265
+ chainInterface.isValidToken(val) ? val : null
266
+ });
267
+ if(preFetchParsedBody==null) throw {
268
+ code: 20100,
269
+ msg: "Invalid request body"
270
+ };
271
+
272
+ //Create abortController for parallel prefetches
273
+ const responseStream = res.responseStream;
274
+ const abortController = getAbortController(responseStream);
275
+
276
+ //Pre-fetch data
277
+ const {
278
+ pricePrefetchPromise,
279
+ gasTokenPricePrefetchPromise
280
+ } = this.getPricePrefetches(chainIdentifier, preFetchParsedBody.token, preFetchParsedBody.gasToken, abortController);
281
+ const nativeBalancePrefetch = this.prefetchNativeBalanceIfNeeded(chainIdentifier, abortController);
282
+ const btcFeeRatePrefetch = this.bitcoin.getFeeRate().catch(e => {
283
+ abortController.abort(e);
284
+ return null;
285
+ });
286
+
287
+ //Listener that re-adds the returned bitcoin address to the unused address list if request fails or closes
288
+ let abortAddUnusedAddressListener: () => void;
289
+ const bitcoinAddressPrefetch = this.bitcoin.getAddress().then(value => {
290
+ //Already aborted
291
+ if(abortController.signal.aborted) {
292
+ this.bitcoin.addUnusedAddress(value);
293
+ return null;
294
+ }
295
+ //Not aborted yet, add an event listener to re-add the address to the unused list
296
+ abortController.signal.addEventListener("abort", abortAddUnusedAddressListener = () => {
297
+ this.bitcoin.addUnusedAddress(value);
298
+ });
299
+ return value;
300
+ }).catch(e => {
301
+ abortController.abort(e);
302
+ return null;
303
+ });
304
+
254
305
  /**
255
306
  * address: string smart chain address of the recipient
256
307
  * amount: string amount (in sats)
257
- * token: string Desired token to use
258
308
  * gasAmount: string Desired amount in gas token to also get
259
- * gasToken: string
260
309
  * exactOut: boolean Whether the swap should be an exact out instead of exact in swap
261
310
  * callerFeeRate: string Caller/watchtower fee (in output token) to assign to the swap
262
311
  * frontingFeeRate: string Fronting fee (in output token) to assign to the swap
263
312
  */
264
- const parsedBody: SpvVaultSwapRequestType = await req.paramReader.getParams({
313
+ const actualParsedBody = await req.paramReader.getParams({
265
314
  address: (val: string) => val!=null &&
266
315
  typeof(val)==="string" &&
267
316
  chainInterface.isValidAddress(val, true) ? val : null,
268
317
  amount: FieldTypeEnum.BigInt,
269
- token: (val: string) => val!=null &&
270
- typeof(val)==="string" &&
271
- this.isTokenSupported(chainIdentifier, val) ? val : null,
272
318
  gasAmount: FieldTypeEnum.BigInt,
273
- gasToken: (val: string) => val!=null &&
274
- typeof(val)==="string" &&
275
- chainInterface.isValidToken(val) ? val : null,
276
319
  exactOut: FieldTypeEnum.BooleanOptional,
277
320
  callerFeeRate: FieldTypeEnum.BigInt,
278
321
  frontingFeeRate: FieldTypeEnum.BigInt,
279
322
  });
280
- if(parsedBody==null) throw {
323
+ abortController.signal.throwIfAborted();
324
+ if(actualParsedBody==null) throw {
281
325
  code: 20100,
282
326
  msg: "Invalid request body"
283
327
  };
328
+
329
+ const parsedBody: SpvVaultSwapRequestType = {...preFetchParsedBody, ...actualParsedBody};
284
330
  metadata.request = parsedBody;
285
331
 
286
332
  if(parsedBody.gasToken!==chainInterface.getNativeCurrencyAddress()) throw {
@@ -324,17 +370,6 @@ export class SpvVaultSwapHandler extends SwapHandler<SpvVaultSwap, SpvVaultSwapS
324
370
  const fees = await this.AmountAssertions.preCheckFromBtcAmounts(this.type, request, requestedAmount, gasTokenAmount);
325
371
  metadata.times.requestChecked = Date.now();
326
372
 
327
- //Create abortController for parallel prefetches
328
- const responseStream = res.responseStream;
329
- const abortController = getAbortController(responseStream);
330
-
331
- //Pre-fetch data
332
- const {
333
- pricePrefetchPromise,
334
- gasTokenPricePrefetchPromise
335
- } = this.getPricePrefetches(chainIdentifier, useToken, gasToken, abortController);
336
- const nativeBalancePrefetch = this.prefetchNativeBalanceIfNeeded(chainIdentifier, abortController);
337
-
338
373
  await this.checkNativeBalance(chainIdentifier, nativeBalancePrefetch, abortController.signal);
339
374
 
340
375
  //Check valid amount specified (min/max)
@@ -368,8 +403,8 @@ export class SpvVaultSwapHandler extends SwapHandler<SpvVaultSwap, SpvVaultSwapS
368
403
  metadata.times.vaultPicked = Date.now();
369
404
 
370
405
  //Create swap receive bitcoin address
371
- const btcFeeRate = await this.bitcoin.getFeeRate();
372
- const receiveAddress = await this.bitcoin.getAddress();
406
+ const btcFeeRate = await btcFeeRatePrefetch;
407
+ const receiveAddress = await bitcoinAddressPrefetch;
373
408
  abortController.signal.throwIfAborted();
374
409
  metadata.times.addressCreated = Date.now();
375
410
 
@@ -404,6 +439,8 @@ export class SpvVaultSwapHandler extends SwapHandler<SpvVaultSwap, SpvVaultSwapS
404
439
  );
405
440
  swap.metadata = metadata;
406
441
 
442
+ //We can remove the listener to add unused address now, as we are about to save the swap
443
+ abortController.signal.removeEventListener("abort", abortAddUnusedAddressListener);
407
444
  await PluginManager.swapCreate(swap);
408
445
  await this.saveSwapData(swap);
409
446