@xchainjs/xchain-thorchain-query 0.4.5 → 0.4.7

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.
package/lib/index.esm.js CHANGED
@@ -543,6 +543,25 @@ class Midgard {
543
543
  throw Error(`Midgard not responding`);
544
544
  });
545
545
  }
546
+ /**
547
+ * Function to return member details based on valid liquidity position
548
+ * @param address - query can also be multiple addresses should be separated by comma
549
+ * @returns - object type of Member Detail
550
+ */
551
+ getSavers(address) {
552
+ return __awaiter(this, void 0, void 0, function* () {
553
+ for (const api of this.midgardApis) {
554
+ try {
555
+ const saverDetails = (yield api.getSaverDetail(address)).data;
556
+ return saverDetails;
557
+ }
558
+ catch (e) {
559
+ //console.error(e)
560
+ }
561
+ }
562
+ throw Error(`Midgard not responding`);
563
+ });
564
+ }
546
565
  /**
547
566
  * Function to return pool statistics for a particular asset
548
567
  * @param asset - asset string to query its pool stats
@@ -960,11 +979,11 @@ class Thornode {
960
979
  * @param height - block height
961
980
  * @returns quotes swap object response
962
981
  */
963
- getSwapQuote(fromAsset, toAsset, amount, destinationAddress, fromAddress, toleranceBps, affiliateBps, affiliate, height) {
982
+ getSwapQuote(fromAsset, toAsset, amount, destinationAddress, streamingInterval, streamingQuantity, fromAddress, toleranceBps, affiliateBps, affiliate, height) {
964
983
  return __awaiter(this, void 0, void 0, function* () {
965
984
  for (const api of this.quoteApi) {
966
985
  try {
967
- const resp = (yield api.quoteswap(height, fromAsset, toAsset, amount, destinationAddress, fromAddress, toleranceBps, affiliateBps, affiliate)).data;
986
+ const resp = (yield api.quoteswap(height, fromAsset, toAsset, amount, destinationAddress, streamingInterval, streamingQuantity, fromAddress, toleranceBps, affiliateBps, affiliate)).data;
968
987
  return resp;
969
988
  }
970
989
  catch (e) {
@@ -1376,26 +1395,23 @@ class ThorchainQuery {
1376
1395
  * @param quoteSwapParams - input params
1377
1396
  * @returns
1378
1397
  */
1379
- quoteSwap({ fromAsset, destinationAsset, amount, destinationAddress, fromAddress, toleranceBps, interfaceID = '555', affiliateBps, affiliateAddress, height, }) {
1398
+ quoteSwap({ fromAsset, destinationAsset, amount, destinationAddress, streamingInterval, streamingQuantity, fromAddress, toleranceBps, affiliateBps, affiliateAddress, height, }) {
1380
1399
  return __awaiter(this, void 0, void 0, function* () {
1381
1400
  const errors = [];
1382
1401
  const fromAssetString = assetToString(fromAsset);
1383
1402
  const toAssetString = assetToString(destinationAsset);
1384
1403
  const inputAmount = getBaseAmountWithDiffDecimals(amount, 8);
1385
1404
  // fetch quote
1386
- const swapQuote = yield this.thorchainCache.thornode.getSwapQuote(fromAssetString, toAssetString, inputAmount.toNumber(), destinationAddress, fromAddress, toleranceBps, affiliateBps, affiliateAddress, height);
1387
- // error handling
1405
+ const swapQuote = yield this.thorchainCache.thornode.getSwapQuote(fromAssetString, toAssetString, inputAmount.toNumber(), destinationAddress, streamingInterval, streamingQuantity, fromAddress, toleranceBps, affiliateBps, affiliateAddress, height);
1406
+ // error handling for fetch response
1388
1407
  const response = JSON.parse(JSON.stringify(swapQuote));
1389
1408
  if (response.error)
1390
1409
  errors.push(`Thornode request quote: ${response.error}`);
1391
- //The recommended minimum inbound amount for this transaction type & inbound asset.
1392
- // Sending less than this amount could result in failed refunds
1393
- if (swapQuote.recommended_min_amount_in && inputAmount.toNumber() < +swapQuote.recommended_min_amount_in)
1394
- errors.push(`Error amount in: ${inputAmount.toNumber()} is less than reccommended Min Amount: ${swapQuote.recommended_min_amount_in}`);
1395
1410
  if (errors.length > 0) {
1396
1411
  return {
1397
1412
  memo: ``,
1398
1413
  toAddress: ``,
1414
+ dustThreshold: new CryptoAmount(baseAmount(0), AssetRuneNative),
1399
1415
  expiry: new Date(),
1400
1416
  txEstimate: {
1401
1417
  totalFees: {
@@ -1409,14 +1425,29 @@ class ThorchainQuery {
1409
1425
  inboundConfirmationSeconds: 0,
1410
1426
  canSwap: false,
1411
1427
  errors,
1428
+ netOutputStreaming: new CryptoAmount(baseAmount(0), AssetRuneNative),
1429
+ maxStreamingQuantity: 0,
1430
+ outboundDelayBlocks: 0,
1431
+ streamingSlipBasisPoints: 0,
1432
+ streamingSwapBlocks: 0,
1433
+ totalSwapSeconds: 0,
1434
+ warning: '',
1412
1435
  },
1413
1436
  };
1414
1437
  }
1415
- // Return quote
1438
+ // The recommended minimum inbound amount for this transaction type & inbound asset.
1439
+ // Sending less than this amount could result in failed refunds
1416
1440
  const feeAsset = assetFromStringEx(swapQuote.fees.asset);
1441
+ if (swapQuote.recommended_min_amount_in && inputAmount.toNumber() < +swapQuote.recommended_min_amount_in)
1442
+ errors.push(`Error amount in: ${inputAmount.toNumber()} is less than reccommended Min Amount: ${swapQuote.recommended_min_amount_in}`);
1443
+ // Check to see if memo is undefined
1444
+ if (swapQuote.memo === undefined)
1445
+ errors.push(`Error parsing swap quote: Memo is ${swapQuote.memo}`);
1446
+ // No errors ? and memo is returned ? return quote flag canSwap to true
1417
1447
  const txDetails = {
1418
- memo: this.constructSwapMemo(`${swapQuote.memo}`, interfaceID),
1419
- toAddress: `${swapQuote.inbound_address}`,
1448
+ memo: swapQuote.memo ? swapQuote.memo : '',
1449
+ dustThreshold: new CryptoAmount(baseAmount(swapQuote.dust_threshold), fromAsset),
1450
+ toAddress: swapQuote.inbound_address ? swapQuote.inbound_address : '',
1420
1451
  expiry: new Date(swapQuote.expiry * 1000),
1421
1452
  txEstimate: {
1422
1453
  totalFees: {
@@ -1426,34 +1457,41 @@ class ThorchainQuery {
1426
1457
  },
1427
1458
  slipBasisPoints: swapQuote.slippage_bps,
1428
1459
  netOutput: new CryptoAmount(baseAmount(swapQuote.expected_amount_out), destinationAsset),
1460
+ netOutputStreaming: new CryptoAmount(baseAmount(swapQuote.expected_amount_out), destinationAsset),
1429
1461
  outboundDelaySeconds: swapQuote.outbound_delay_seconds,
1430
1462
  inboundConfirmationSeconds: swapQuote.inbound_confirmation_seconds,
1431
1463
  recommendedMinAmountIn: swapQuote.recommended_min_amount_in,
1432
- canSwap: true,
1464
+ maxStreamingQuantity: swapQuote.max_streaming_quantity ? swapQuote.max_streaming_quantity : 0,
1465
+ outboundDelayBlocks: swapQuote.outbound_delay_blocks,
1466
+ streamingSlipBasisPoints: swapQuote.streaming_slippage_bps,
1467
+ streamingSwapBlocks: swapQuote.streaming_swap_blocks ? swapQuote.streaming_swap_blocks : 0,
1468
+ totalSwapSeconds: swapQuote.total_swap_seconds ? swapQuote.total_swap_seconds : 0,
1469
+ canSwap: !swapQuote.memo || errors.length > 0 ? false : true,
1433
1470
  errors,
1471
+ warning: swapQuote.warning,
1434
1472
  },
1435
1473
  };
1436
1474
  return txDetails;
1437
1475
  });
1438
1476
  }
1439
- /**
1440
- *
1441
- * @param params - swap object
1442
- * @returns - constructed memo string
1443
- */
1444
- constructSwapMemo(memo, interfaceID) {
1445
- const memoPart = memo.split(':');
1446
- if (memoPart.length > 3) {
1447
- memoPart[3] =
1448
- memoPart[3].length >= 3 ? memoPart[3].substring(0, memoPart[3].length - 3).concat(interfaceID) : interfaceID;
1449
- let outmemo = '';
1450
- for (let i = 0; i < memoPart.length; i++) {
1451
- outmemo = outmemo.concat(`${memoPart[i]}:`);
1452
- }
1453
- return outmemo.substring(0, outmemo.length - 1);
1454
- }
1455
- return memo;
1456
- }
1477
+ // /**
1478
+ // * This is no longer used
1479
+ // * @param params - swap object
1480
+ // * @returns - constructed memo string
1481
+ // */
1482
+ // private constructSwapMemo(memo: string, interfaceID: string): string {
1483
+ // const memoPart = memo.split(':')
1484
+ // if (memoPart.length > 3) {
1485
+ // memoPart[3] =
1486
+ // memoPart[3].length >= 3 ? memoPart[3].substring(0, memoPart[3].length - 3).concat(interfaceID) : interfaceID
1487
+ // let outmemo = ''
1488
+ // for (let i = 0; i < memoPart.length; i++) {
1489
+ // outmemo = outmemo.concat(`${memoPart[i]}:`)
1490
+ // }
1491
+ // return outmemo.substring(0, outmemo.length - 1)
1492
+ // }
1493
+ // return memo
1494
+ // }
1457
1495
  /**
1458
1496
  * Works out how long an outbound Tx will be held by THORChain before sending.
1459
1497
  *
@@ -2035,11 +2073,53 @@ class ThorchainQuery {
2035
2073
  percentageGrowth: saverGrowth.assetAmount.amount().toNumber(),
2036
2074
  ageInYears: saversAge,
2037
2075
  ageInDays: saversAge * 365,
2076
+ asset: params.asset,
2038
2077
  errors,
2039
2078
  };
2040
2079
  return saversPos;
2041
2080
  });
2042
2081
  }
2082
+ getSaverPositions(params) {
2083
+ return __awaiter(this, void 0, void 0, function* () {
2084
+ const addresses = new Set();
2085
+ params.forEach((param) => addresses.add(param.address));
2086
+ const addressesString = Array.from(addresses).join(',');
2087
+ const saversDetail = yield this.thorchainCache.midgard.getSavers(addressesString);
2088
+ const pools = yield this.thorchainCache.getPools();
2089
+ const inboundDetails = yield this.thorchainCache.getInboundDetails();
2090
+ const errors = [];
2091
+ const saversPositions = [];
2092
+ saversDetail.pools.forEach((saver) => {
2093
+ const asset = assetFromString(saver.pool);
2094
+ if (asset) {
2095
+ const outboundFee = calcOutboundFee(asset, inboundDetails[asset.chain]);
2096
+ const convertToBaseEight = getBaseAmountWithDiffDecimals(outboundFee, 8);
2097
+ if (Number(saver === null || saver === void 0 ? void 0 : saver.assetRedeem) < convertToBaseEight.toNumber())
2098
+ errors.push(`Unlikely to withdraw balance as outbound fee is greater than redeemable amount`);
2099
+ const liquidityPool = pools[`${asset.chain}.${asset.ticker}`];
2100
+ const depositAmount = new CryptoAmount(baseAmount(saver.assetAdded).minus(saver.assetWithdrawn), asset);
2101
+ const ownerUnits = Number(saver === null || saver === void 0 ? void 0 : saver.saverUnits);
2102
+ const saverUnits = Number(liquidityPool.pool.saversUnits);
2103
+ const assetDepth = Number(liquidityPool.pool.saversDepth);
2104
+ const redeemableValue = (ownerUnits / saverUnits) * assetDepth;
2105
+ const redeemableAssetAmount = new CryptoAmount(baseAmount(redeemableValue), asset);
2106
+ const saverGrowth = redeemableAssetAmount.minus(depositAmount).div(depositAmount).times(100);
2107
+ const saversAge = (Date.now() / 1000 - Number(saver.dateLastAdded)) / (365 * 86400);
2108
+ saversPositions.push({
2109
+ depositValue: depositAmount,
2110
+ redeemableValue: redeemableAssetAmount,
2111
+ lastAddHeight: -1,
2112
+ percentageGrowth: saverGrowth.assetAmount.amount().toNumber(),
2113
+ ageInYears: saversAge,
2114
+ ageInDays: saversAge * 365,
2115
+ asset,
2116
+ errors,
2117
+ });
2118
+ }
2119
+ });
2120
+ return saversPositions;
2121
+ });
2122
+ }
2043
2123
  getAddSaversEstimateErrors(addAmount) {
2044
2124
  return __awaiter(this, void 0, void 0, function* () {
2045
2125
  const errors = [];