@xchainjs/xchain-thorchain-query 0.7.2 → 0.7.4

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
@@ -31,55 +31,56 @@ function __awaiter(thisArg, _arguments, P, generator) {
31
31
  });
32
32
  }
33
33
 
34
+ // Default attributes for each chain
34
35
  const DefaultChainAttributes = {
35
36
  BCH: {
36
37
  blockReward: 6.25,
37
- avgBlockTimeInSecs: 600,
38
+ avgBlockTimeInSecs: 600, // Average block time for Bitcoin Cash in seconds
38
39
  },
39
40
  BTC: {
40
41
  blockReward: 6.25,
41
- avgBlockTimeInSecs: 600,
42
+ avgBlockTimeInSecs: 600, // Average block time for Bitcoin in seconds
42
43
  },
43
44
  ETH: {
44
45
  blockReward: 2,
45
- avgBlockTimeInSecs: 13,
46
+ avgBlockTimeInSecs: 13, // Average block time for Ethereum in seconds
46
47
  },
47
48
  AVAX: {
48
49
  blockReward: 2,
49
- avgBlockTimeInSecs: 3,
50
+ avgBlockTimeInSecs: 3, // Average block time for Avalanche in seconds
50
51
  },
51
52
  LTC: {
52
53
  blockReward: 12.5,
53
- avgBlockTimeInSecs: 150,
54
+ avgBlockTimeInSecs: 150, // Average block time for Litecoin in seconds
54
55
  },
55
56
  DOGE: {
56
57
  blockReward: 10000,
57
- avgBlockTimeInSecs: 60,
58
+ avgBlockTimeInSecs: 60, // Average block time for Dogecoin in seconds
58
59
  },
59
60
  GAIA: {
60
61
  blockReward: 0,
61
- avgBlockTimeInSecs: 6,
62
+ avgBlockTimeInSecs: 6, // Average block time for Gaia in seconds
62
63
  },
63
64
  BNB: {
64
65
  blockReward: 0,
65
- avgBlockTimeInSecs: 6,
66
+ avgBlockTimeInSecs: 6, // Average block time for Binance Coin in seconds
66
67
  },
67
68
  THOR: {
68
69
  blockReward: 0,
69
- avgBlockTimeInSecs: 6,
70
+ avgBlockTimeInSecs: 6, // Average block time for THORChain in seconds
70
71
  },
71
72
  BSC: {
72
73
  blockReward: 0,
73
- avgBlockTimeInSecs: 3,
74
+ avgBlockTimeInSecs: 3, // Average block time for Binance Smart Chain in seconds
74
75
  },
75
76
  MAYA: {
76
77
  blockReward: 0,
77
- avgBlockTimeInSecs: 6,
78
+ avgBlockTimeInSecs: 6, // Average block time for MAYAChain in seconds
78
79
  },
79
80
  };
80
81
 
81
82
  /**
82
- * Represent a Liquidity Pool in Thorchain
83
+ * Represents a Liquidity Pool in Thorchain
83
84
  */
84
85
  class LiquidityPool {
85
86
  constructor(thornodeDetails) {
@@ -92,9 +93,14 @@ class LiquidityPool {
92
93
  this.assetString = this.thornodeDetails.asset;
93
94
  this.assetBalance = baseAmount(this.thornodeDetails.balance_asset);
94
95
  this.runeBalance = baseAmount(this.thornodeDetails.balance_rune);
96
+ // Calculate the ratio of Rune to the asset and the ratio of the asset to Rune
95
97
  this.runeToAssetRatio = this.runeBalance.amount().div(this.assetBalance.amount());
96
98
  this.assetToRuneRatio = this.assetBalance.amount().div(this.runeBalance.amount());
97
99
  }
100
+ /**
101
+ * Checks if the liquidity pool is available
102
+ * @returns {boolean} True if the liquidity pool is available, otherwise false
103
+ */
98
104
  isAvailable() {
99
105
  return this.thornodeDetails.status.toLowerCase() === 'available';
100
106
  }
@@ -809,36 +815,37 @@ class Thornode {
809
815
  }
810
816
  }
811
817
 
818
+ // Constants
812
819
  const SAME_ASSET_EXCHANGE_RATE = new BigNumber(1);
813
820
  const TEN_MINUTES = 10 * 60 * 1000;
821
+ // Default instances
814
822
  const defaultThornode = new Thornode();
815
823
  const defaultMidgardQuery = new MidgardQuery();
816
824
  /**
817
- * This class manages retrieving information from up to date Thorchain
825
+ * This class manages retrieving information from up-to-date Thorchain.
818
826
  */
819
827
  class ThorchainCache {
820
828
  /**
821
829
  * Constructor to create a ThorchainCache
822
- *
823
- * @param thornode - an instance of the thornode API (could be pointing to stagenet,testnet,mainnet)
824
- * @param midgardQuery - an instance of the midgard query class (could be pointing to stagenet,testnet,mainnet)
825
- * @param expirePoolCacheMillis - how long should the pools be cached before expiry
826
- * @param expireInboundDetailsCacheMillis - how long should the InboundDetails be cached before expiry
827
- * @param expireNetworkValuesCacheMillis - how long should the Mimir/Constants be cached before expiry
830
+ * @param thornode - An instance of the Thornode API (could be pointing to stagenet, testnet, or mainnet).
831
+ * @param midgardQuery - An instance of the MidgardQuery class (could be pointing to stagenet, testnet, or mainnet).
832
+ * @param expirePoolCacheMillis - How long the pools should be cached before expiry.
833
+ * @param expireInboundDetailsCacheMillis - How long the InboundDetails should be cached before expiry.
834
+ * @param expireNetworkValuesCacheMillis - How long the Mimir/Constants should be cached before expiry.
828
835
  * @returns ThorchainCache
829
836
  */
830
837
  constructor(thornode = defaultThornode, midgardQuery = defaultMidgardQuery, expirePoolCacheMillis = 6000, expireInboundDetailsCacheMillis = 6000, expireNetworkValuesCacheMillis = TEN_MINUTES) {
831
838
  this.thornode = thornode;
832
839
  this.midgardQuery = midgardQuery;
840
+ // Initialize cached values
833
841
  this.poolCache = new CachedValue(() => this.refreshPoolCache(), expirePoolCacheMillis);
834
842
  this.inboundDetailCache = new CachedValue(() => this.refreshInboundDetailCache(), expireInboundDetailsCacheMillis);
835
843
  this.networkValuesCache = new CachedValue(() => thornode.getNetworkValues(), expireNetworkValuesCacheMillis);
836
844
  }
837
845
  /**
838
- * Gets the exchange rate of the from asset in terms on the to asset
839
- *
840
- * @param asset - cannot be RUNE.
841
- * @returns Promise<BigNumber>
846
+ * Gets the exchange rate of the `from` asset in terms of the `to` asset.
847
+ * @param asset - The asset to swap from.
848
+ * @returns Promise<BigNumber> - The exchange rate.
842
849
  */
843
850
  getExchangeRate(from, to) {
844
851
  return __awaiter(this, void 0, void 0, function* () {
@@ -868,10 +875,9 @@ class ThorchainCache {
868
875
  });
869
876
  }
870
877
  /**
871
- * Gets the Liquidity Pool for a given Asset
872
- *
873
- * @param asset - cannot be RUNE, since Rune is the other side of each pool.
874
- * @returns Promise<LiquidityPool>
878
+ * Gets the Liquidity Pool for a given Asset.
879
+ * @param asset - The asset to retrieve the pool for.
880
+ * @returns Promise<LiquidityPool> - The liquidity pool.
875
881
  */
876
882
  getPoolForAsset(asset) {
877
883
  return __awaiter(this, void 0, void 0, function* () {
@@ -889,9 +895,8 @@ class ThorchainCache {
889
895
  }
890
896
  /**
891
897
  * Get all the Liquidity Pools currently cached.
892
- * if the cache is expired, the pools wioll be re-fetched from thornode
893
- *
894
- * @returns Promise<Record<string, LiquidityPool>>
898
+ * If the cache is expired, the pools will be re-fetched from Thornode.
899
+ * @returns Promise<Record<string, LiquidityPool>> - The liquidity pools.
895
900
  */
896
901
  getPools() {
897
902
  return __awaiter(this, void 0, void 0, function* () {
@@ -905,7 +910,8 @@ class ThorchainCache {
905
910
  });
906
911
  }
907
912
  /**
908
- * Refreshes the Pool Cache
913
+ * Refreshes the Pool Cache.
914
+ * @returns Promise<Record<string, LiquidityPool> |
909
915
  */
910
916
  refreshPoolCache() {
911
917
  return __awaiter(this, void 0, void 0, function* () {
@@ -935,14 +941,17 @@ class ThorchainCache {
935
941
  });
936
942
  }
937
943
  /**
938
- * Refreshes the InboundDetailCache Cache
944
+ * Refreshes the InboundDetailCache Cache.
945
+ * @returns Promise<Record<string, InboundDetail>> - The refreshed inbound detail cache.
939
946
  */
940
947
  refreshInboundDetailCache() {
941
948
  return __awaiter(this, void 0, void 0, function* () {
949
+ // Fetching mimir details and all inbound addresses concurrently
942
950
  const [mimirDetails, allInboundAddresses] = yield Promise.all([
943
951
  this.thornode.getMimir(),
944
952
  this.thornode.getInboundAddresses(),
945
953
  ]);
954
+ // Mapping inbound details
946
955
  const inboundDetails = {};
947
956
  for (const inbound of allInboundAddresses) {
948
957
  const chain = inbound.chain;
@@ -954,6 +963,7 @@ class ThorchainCache {
954
963
  !inbound.outbound_fee ||
955
964
  !inbound.gas_rate_units)
956
965
  throw new Error(`Missing required inbound info`);
966
+ // Adding mock THORCHAIN inbound details
957
967
  const details = {
958
968
  chain: chain,
959
969
  address: inbound.address,
@@ -986,13 +996,10 @@ class ThorchainCache {
986
996
  });
987
997
  }
988
998
  /**
989
- * Returns the exchange of a CryptoAmount to a different Asset
990
- *
991
- * Ex. convert(input:100 BUSD, outAsset: BTC) -> 0.0001234 BTC
992
- *
993
- * @param input - amount/asset to convert to outAsset
994
- * @param outAsset - the Asset you want to convert to
995
- * @returns CryptoAmount of input
999
+ * Returns the exchange of a CryptoAmount to a different Asset.
1000
+ * @param input - The amount/asset to convert.
1001
+ * @param outAsset - The asset you want to convert to.
1002
+ * @returns Promise<CryptoAmount> - The converted amount.
996
1003
  */
997
1004
  convert(input, outAsset) {
998
1005
  return __awaiter(this, void 0, void 0, function* () {
@@ -1007,6 +1014,11 @@ class ThorchainCache {
1007
1014
  return result;
1008
1015
  });
1009
1016
  }
1017
+ /**
1018
+ * Gets the router address for a given chain.
1019
+ * @param chain - The chain to get the router address for.
1020
+ * @returns Promise<Address> - The router address.
1021
+ */
1010
1022
  getRouterAddressForChain(chain) {
1011
1023
  return __awaiter(this, void 0, void 0, function* () {
1012
1024
  const inboundAsgard = (yield this.getInboundDetails())[chain];
@@ -1017,8 +1029,8 @@ class ThorchainCache {
1017
1029
  });
1018
1030
  }
1019
1031
  /**
1020
- *
1021
- * @returns - inbound details
1032
+ * Gets the inbound details.
1033
+ * @returns Promise<Record<string, InboundDetail>> - The inbound details.
1022
1034
  */
1023
1035
  getInboundDetails() {
1024
1036
  return __awaiter(this, void 0, void 0, function* () {
@@ -1031,8 +1043,8 @@ class ThorchainCache {
1031
1043
  });
1032
1044
  }
1033
1045
  /**
1034
- *
1035
- * @returns - network values
1046
+ * Gets the network values.
1047
+ * @returns Promise<Record<string, number>> - The network values.
1036
1048
  */
1037
1049
  getNetworkValues() {
1038
1050
  return __awaiter(this, void 0, void 0, function* () {
@@ -1048,7 +1060,7 @@ class ThorchainCache {
1048
1060
 
1049
1061
  const defaultCache = new ThorchainCache();
1050
1062
  /**
1051
- * THORChain Class for interacting with THORChain.
1063
+ * ThorchainQuery Class for interacting with THORChain.
1052
1064
  * Recommended main class to use for swapping with THORChain
1053
1065
  * Has access to Midgard and THORNode data
1054
1066
  */
@@ -1064,14 +1076,14 @@ class ThorchainQuery {
1064
1076
  this.thorchainCache = thorchainCache;
1065
1077
  this.chainAttributes = chainAttributes;
1066
1078
  }
1067
- /**
1079
+ /** Quote a swap transaction.
1068
1080
  *
1069
- * @param quoteSwapParams - input params
1070
- * @returns
1081
+ * @param quoteSwapParams - Input parameters for the swap quote.
1082
+ * @returns Transaction details including memo, address, fees, etc.
1071
1083
  */
1072
1084
  quoteSwap({ fromAsset, destinationAsset, amount, destinationAddress, streamingInterval, streamingQuantity, toleranceBps, affiliateBps, affiliateAddress, height, }) {
1073
1085
  return __awaiter(this, void 0, void 0, function* () {
1074
- // validates swap, and pushes error if there is one
1086
+ // Validates swap and pushes error if there is one
1075
1087
  const errors = [];
1076
1088
  const error = yield this.validateAmount(amount);
1077
1089
  if (error)
@@ -1079,13 +1091,14 @@ class ThorchainQuery {
1079
1091
  const fromAssetString = assetToString(fromAsset);
1080
1092
  const toAssetString = assetToString(destinationAsset);
1081
1093
  const inputAmount = getBaseAmountWithDiffDecimals(amount, 8);
1082
- // fetch quote
1094
+ // Fetch quote
1083
1095
  const swapQuote = yield this.thorchainCache.thornode.getSwapQuote(fromAssetString, toAssetString, inputAmount.toNumber(), destinationAddress, streamingInterval, streamingQuantity, toleranceBps, affiliateBps, affiliateAddress, height);
1084
- // error handling for fetch response
1096
+ // Error handling for fetch response
1085
1097
  const response = JSON.parse(JSON.stringify(swapQuote));
1086
1098
  if (response.error)
1087
1099
  errors.push(`Thornode request quote: ${response.error}`);
1088
1100
  if (errors.length > 0) {
1101
+ // If there are errors, construct and return a transaction details object with error information
1089
1102
  return {
1090
1103
  memo: ``,
1091
1104
  toAddress: ``,
@@ -1163,63 +1176,70 @@ class ThorchainQuery {
1163
1176
  */
1164
1177
  validateAmount(cryptoAmount) {
1165
1178
  return __awaiter(this, void 0, void 0, function* () {
1179
+ // Get the number of decimals for the asset
1166
1180
  const assetDecimals = yield this.thorchainCache.midgardQuery.getDecimalForAsset(cryptoAmount.asset);
1181
+ // Check if the base amount decimal is equal to the asset's decimal
1167
1182
  if (cryptoAmount.baseAmount.decimal !== assetDecimals)
1168
1183
  return new Error(`Invalid number of decimals: ${assetToString(cryptoAmount.asset)} must have ${assetDecimals} decimals`);
1169
1184
  });
1170
1185
  }
1171
1186
  /**
1172
1187
  * Works out how long an outbound Tx will be held by THORChain before sending.
1173
- *
1174
1188
  * @param outboundAmount: CryptoAmount being sent.
1175
1189
  * @returns required delay in seconds
1176
1190
  * @see https://gitlab.com/thorchain/thornode/-/blob/develop/x/thorchain/manager_txout_current.go#L548
1177
1191
  */
1178
1192
  outboundDelay(outboundAmount) {
1179
1193
  return __awaiter(this, void 0, void 0, function* () {
1194
+ // Retrieve network values
1180
1195
  const networkValues = yield this.thorchainCache.getNetworkValues();
1196
+ // Create CryptoAmounts for minimum transaction out volume threshold and maximum transaction out offset
1181
1197
  const minTxOutVolumeThreshold = new CryptoAmount(baseAmount(networkValues['MINTXOUTVOLUMETHRESHOLD']), AssetRuneNative);
1182
1198
  const maxTxOutOffset = networkValues['MAXTXOUTOFFSET'];
1199
+ // Get the delay rate for outbound transactions
1183
1200
  let txOutDelayRate = new CryptoAmount(baseAmount(networkValues['TXOUTDELAYRATE']), AssetRuneNative).assetAmount
1184
1201
  .amount()
1185
1202
  .toNumber();
1203
+ // Get the outbound queue
1186
1204
  const getQueue = yield this.thorchainCache.thornode.getQueue();
1205
+ // Create a CryptoAmount for the scheduled outbound value
1187
1206
  const outboundValue = new CryptoAmount(baseAmount(getQueue.scheduled_outbound_value), AssetRuneNative);
1207
+ // Get the average block time for THORChain
1188
1208
  const thorChainblocktime = this.chainAttributes[THORChain].avgBlockTimeInSecs; // blocks required to confirm tx
1189
- // If asset is equal to Rune set runeValue as outbound amount else set it to the asset's value in rune
1209
+ // Convert the outbound amount to its value in RUNE
1190
1210
  const runeValue = yield this.thorchainCache.convert(outboundAmount, AssetRuneNative);
1191
- // Check rune value amount
1211
+ // Check if the rune value is less than the minimum transaction out volume threshold
1192
1212
  if (runeValue.lt(minTxOutVolumeThreshold)) {
1193
1213
  return thorChainblocktime;
1194
1214
  }
1195
- // Rune value in the outbound queue
1215
+ // Check if the outbound value is undefined
1196
1216
  if (outboundValue == undefined) {
1197
1217
  throw new Error(`Could not return Scheduled Outbound Value`);
1198
1218
  }
1199
- // Add OutboundAmount in rune to the oubound queue
1219
+ // Calculate the total outbound amount in rune
1200
1220
  const outboundAmountTotal = runeValue.plus(outboundValue);
1201
- // calculate the if outboundAmountTotal is over the volume threshold
1221
+ // Calculate the volume threshold
1202
1222
  const volumeThreshold = outboundAmountTotal.div(minTxOutVolumeThreshold);
1203
- // check delay rate
1223
+ // Adjust the delay rate based on the volume threshold
1204
1224
  txOutDelayRate = txOutDelayRate - volumeThreshold.assetAmount.amount().toNumber() <= 1 ? 1 : txOutDelayRate;
1205
- // calculate the minimum number of blocks in the future the txn has to be
1225
+ // Calculate the minimum number of blocks required for the transaction to be confirmed
1206
1226
  let minBlocks = runeValue.assetAmount.amount().toNumber() / txOutDelayRate;
1207
1227
  minBlocks = minBlocks > maxTxOutOffset ? maxTxOutOffset : minBlocks;
1228
+ // Return the required delay in seconds
1208
1229
  return minBlocks * thorChainblocktime;
1209
1230
  });
1210
1231
  }
1211
1232
  /**
1212
1233
  * Convenience method to convert TotalFees to a different CryptoAmount
1213
- *
1214
1234
  * TotalFees are always calculated and returned in RUNE, this method can
1215
1235
  * be used to show the equivalent fees in another Asset Type
1216
- *
1217
1236
  * @param fees: TotalFees - the fees you want to convert
1218
1237
  * @param asset: Asset - the asset you want the fees converted to
1219
1238
  * @returns TotalFees in asset
1220
1239
  */
1221
1240
  getFeesIn(fees, asset) {
1222
1241
  return __awaiter(this, void 0, void 0, function* () {
1242
+ // Return the fees converted to the specified asset
1223
1243
  return {
1224
1244
  asset: fees.asset,
1225
1245
  // swapFee: await this.convert(fees.swapFee, asset),
@@ -1231,73 +1251,78 @@ class ThorchainQuery {
1231
1251
  }
1232
1252
  /**
1233
1253
  * Returns the exchange of a CryptoAmount to a different Asset
1234
- *
1235
1254
  * Ex. convert(input:100 BUSD, outAsset: BTC) -> 0.0001234 BTC
1236
- *
1237
1255
  * @param input - amount/asset to convert to outAsset
1238
1256
  * @param ouAsset - the Asset you want to convert to
1239
1257
  * @returns CryptoAmount of input
1240
1258
  */
1241
1259
  convert(input, outAsset) {
1242
1260
  return __awaiter(this, void 0, void 0, function* () {
1261
+ // Convert the input amount to the specified asset
1243
1262
  return yield this.thorchainCache.convert(input, outAsset);
1244
1263
  });
1245
1264
  }
1246
1265
  /**
1247
1266
  * Finds the required confCount required for an inbound or outbound Tx to THORChain. Estimate based on Midgard data only.
1248
- *
1249
1267
  * Finds the gas asset of the given asset (e.g. BUSD is on BNB), finds the value of asset in Gas Asset then finds the required confirmation count.
1250
1268
  * ConfCount is then times by 6 seconds.
1251
- *
1252
1269
  * @param inbound: CryptoAmount - amount/asset of the outbound amount.
1253
1270
  * @returns time in seconds before a Tx is confirmed by THORChain
1254
1271
  * @see https://docs.thorchain.org/chain-clients/overview
1255
1272
  */
1256
1273
  confCounting(inbound) {
1257
1274
  return __awaiter(this, void 0, void 0, function* () {
1258
- // RUNE, BNB and Synths have near instant finality, so no conf counting required. - need to make a BFT only case.
1275
+ // Check for instant finality assets or synths
1259
1276
  if (isAssetRuneNative(inbound.asset) ||
1260
1277
  inbound.asset.chain == BNBChain ||
1261
1278
  inbound.asset.chain == GAIAChain ||
1262
1279
  inbound.asset.synth) {
1280
+ // Return the average block time for THORChain
1263
1281
  return this.chainAttributes[THORChain].avgBlockTimeInSecs;
1264
1282
  }
1265
- // Get the gas asset for the inbound.asset.chain
1283
+ // Get the gas asset for the inbound asset's chain
1266
1284
  const chainGasAsset = getChainAsset(inbound.asset.chain);
1267
- // check for chain asset, else need to convert asset value to chain asset.
1285
+ // Convert the inbound amount to the gas asset
1268
1286
  const amountInGasAsset = yield this.thorchainCache.convert(inbound, chainGasAsset);
1269
- // Convert to Asset Amount
1287
+ // Get the number of confirmations required based on the asset's value in the gas asset
1270
1288
  const amountInGasAssetInAsset = amountInGasAsset.assetAmount;
1271
1289
  const confConfig = this.chainAttributes[inbound.asset.chain];
1272
- // find the required confs
1273
1290
  const requiredConfs = Math.ceil(amountInGasAssetInAsset.amount().div(confConfig.blockReward).toNumber());
1274
- // convert that into seconds
1291
+ // Convert the number of confirmations to seconds
1275
1292
  return requiredConfs * confConfig.avgBlockTimeInSecs;
1276
1293
  });
1277
1294
  }
1278
1295
  /**
1279
- * Estimates a liquidity position for given crypto amount value, both asymmetrical and symetrical
1280
- * @param params - parameters needed for a estimated liquidity position
1281
- * @returns - type object EstimateLP
1296
+ * Estimates a liquidity position for given crypto amount value, both asymmetrical and symmetrical
1297
+ * @param params - parameters needed for an estimated liquidity position
1298
+ * @returns - object of type EstimateLP
1282
1299
  */
1283
1300
  estimateAddLP(params) {
1284
1301
  return __awaiter(this, void 0, void 0, function* () {
1285
1302
  const errors = [];
1303
+ // Check if either of the assets are synths or if the rune is not THOR.RUNE
1286
1304
  if (params.asset.asset.synth || params.rune.asset.synth)
1287
1305
  errors.push('you cannot add liquidity with a synth');
1288
1306
  if (!isAssetRuneNative(params.rune.asset))
1289
1307
  errors.push('params.rune must be THOR.RUNE');
1308
+ // Get the pool for the asset
1290
1309
  const assetPool = yield this.thorchainCache.getPoolForAsset(params.asset.asset);
1310
+ // Calculate liquidity units
1291
1311
  const lpUnits = getLiquidityUnits({ asset: params.asset, rune: params.rune }, assetPool);
1312
+ // Get inbound details
1292
1313
  const inboundDetails = yield this.thorchainCache.getInboundDetails();
1314
+ // Create unit data
1293
1315
  const unitData = {
1294
1316
  liquidityUnits: lpUnits,
1295
1317
  totalUnits: new BigNumber(assetPool.thornodeDetails.LP_units),
1296
1318
  };
1319
+ // Calculate pool share
1297
1320
  const poolShare = getPoolShare(unitData, assetPool);
1321
+ // Calculate wait time
1298
1322
  const assetWaitTimeSeconds = yield this.confCounting(params.asset);
1299
1323
  const runeWaitTimeSeconds = yield this.confCounting(params.rune);
1300
1324
  const waitTimeSeconds = assetWaitTimeSeconds > runeWaitTimeSeconds ? assetWaitTimeSeconds : runeWaitTimeSeconds;
1325
+ // Calculate inbound fees
1301
1326
  let assetInboundFee = new CryptoAmount(baseAmount(0), params.asset.asset);
1302
1327
  let runeInboundFee = new CryptoAmount(baseAmount(0), AssetRuneNative);
1303
1328
  if (!params.asset.assetAmount.eq(0)) {
@@ -1310,8 +1335,11 @@ class ThorchainQuery {
1310
1335
  if (runeInboundFee.assetAmount.amount().times(3).gt(params.rune.assetAmount.amount()))
1311
1336
  errors.push(`Rune amount is less than fees`);
1312
1337
  }
1338
+ // Calculate total fees
1313
1339
  const totalFees = (yield this.convert(assetInboundFee, AssetRuneNative)).plus(runeInboundFee);
1340
+ // Calculate slip
1314
1341
  const slip = getSlipOnLiquidity({ asset: params.asset, rune: params.rune }, assetPool);
1342
+ // Create estimate LP object
1315
1343
  const estimateLP = {
1316
1344
  assetPool: assetPool.thornodeDetails.asset,
1317
1345
  slipPercent: slip.times(100),
@@ -1333,9 +1361,9 @@ class ThorchainQuery {
1333
1361
  });
1334
1362
  }
1335
1363
  /**
1336
- * @param - Asset for lp
1337
- * @param address - address used for Lp
1338
- * @returns - Type Object liquidityPosition
1364
+ * @param - Asset for LP
1365
+ * @param address - address used for LP
1366
+ * @returns - Object of type LiquidityPosition
1339
1367
  */
1340
1368
  checkLiquidityPosition(asset, assetOrRuneAddress) {
1341
1369
  return __awaiter(this, void 0, void 0, function* () {
@@ -1344,6 +1372,7 @@ class ThorchainQuery {
1344
1372
  throw Error(`Could not find pool for ${asset}`);
1345
1373
  if (!assetOrRuneAddress)
1346
1374
  throw Error(`No address provided ${assetOrRuneAddress}`);
1375
+ // Get the current block number for that chain
1347
1376
  const liquidityProvider = yield this.thorchainCache.thornode.getLiquidityProvider(poolAsset.assetString, assetOrRuneAddress);
1348
1377
  if (!liquidityProvider)
1349
1378
  throw Error(`Could not find LP for ${assetOrRuneAddress}`);
@@ -1357,28 +1386,35 @@ class ThorchainQuery {
1357
1386
  liquidityUnits: new BigNumber(liquidityProvider.units),
1358
1387
  };
1359
1388
  const networkValues = yield this.thorchainCache.thornode.getNetworkValues();
1389
+ // Create block object
1360
1390
  const block = {
1361
1391
  current: blockData.thorchain,
1362
1392
  lastAdded: liquidityProvider.last_add_height,
1363
1393
  fullProtection: networkValues['FULLIMPLOSSPROTECTIONBLOCKS'],
1364
1394
  };
1365
1395
  const assetDecimals = yield this.thorchainCache.midgardQuery.getDecimalForAsset(asset);
1396
+ // Get the current LP
1366
1397
  const currentLP = {
1367
1398
  asset: baseAmount(liquidityProvider.asset_deposit_value, assetDecimals),
1368
1399
  rune: baseAmount(liquidityProvider.rune_deposit_value),
1369
1400
  };
1401
+ // Calculate pool share
1370
1402
  const poolShare = getPoolShare(unitData, poolAsset);
1371
1403
  // Liquidity Unit Value Index = sprt(assetdepth * runeDepth) / Poolunits
1372
1404
  // Using this formula we can work out an individual position to find LUVI and then the growth rate
1405
+ // Calculate deposit and redeem Liquidity Unit Value Index (LUVI)
1373
1406
  const depositLuvi = Math.sqrt(currentLP.asset.times(currentLP.rune).div(unitData.liquidityUnits).amount().toNumber());
1374
1407
  const redeemLuvi = Math.sqrt(poolShare.assetShare.baseAmount
1375
1408
  .times(poolShare.runeShare.baseAmount)
1376
1409
  .div(unitData.liquidityUnits)
1377
1410
  .amount()
1378
1411
  .toNumber());
1412
+ // Calculate LP growth
1379
1413
  const lpGrowth = redeemLuvi - depositLuvi;
1380
1414
  const currentLpGrowth = lpGrowth > 0 ? lpGrowth / depositLuvi : 0;
1415
+ // Get impermanent loss protection data
1381
1416
  const impermanentLossProtection = getLiquidityProtectionData(currentLP, poolShare, block);
1417
+ // Create Liquidity Position object
1382
1418
  const lpPosition = {
1383
1419
  poolShare,
1384
1420
  lpGrowth: `${(currentLpGrowth * 100).toFixed(2)} %`,
@@ -1395,7 +1431,9 @@ class ThorchainQuery {
1395
1431
  */
1396
1432
  getPoolRatios(asset) {
1397
1433
  return __awaiter(this, void 0, void 0, function* () {
1434
+ // Get pool data for the asset
1398
1435
  const assetPool = yield this.thorchainCache.getPoolForAsset(asset);
1436
+ // Create pool ratios object
1399
1437
  const poolRatio = {
1400
1438
  assetToRune: assetPool.assetToRuneRatio,
1401
1439
  runeToAsset: assetPool.runeToAssetRatio,
@@ -1404,27 +1442,31 @@ class ThorchainQuery {
1404
1442
  });
1405
1443
  }
1406
1444
  /**
1407
- *
1408
- * @param params
1445
+ * Estimates the result of withdrawing liquidity from a pool
1446
+ * @param params - parameters needed for estimating withdrawal of liquidity
1447
+ * @returns - object of type EstimateWithdrawLP
1409
1448
  */
1410
1449
  estimateWithdrawLP(params) {
1411
1450
  return __awaiter(this, void 0, void 0, function* () {
1412
1451
  // Caution Dust Limits: BTC,BCH,LTC chains 10k sats; DOGE 1m Sats; ETH 0 wei; THOR 0 RUNE.
1413
1452
  const assetOrRuneAddress = params.assetAddress ? params.assetAddress : params.runeAddress;
1453
+ // Check liquidity position for the provided asset
1414
1454
  const memberDetail = yield this.checkLiquidityPosition(params.asset, assetOrRuneAddress);
1455
+ // Get dust values
1415
1456
  const dustValues = yield this.getDustValues(params.asset); // returns asset and rune dust values
1457
+ // Get asset pool
1416
1458
  const assetPool = yield this.thorchainCache.getPoolForAsset(params.asset);
1417
- // get pool share from unit data
1459
+ // Calculate pool share
1418
1460
  const poolShare = getPoolShare({
1419
1461
  liquidityUnits: new BigNumber(memberDetail.position.units),
1420
1462
  totalUnits: new BigNumber(assetPool.thornodeDetails.LP_units),
1421
1463
  }, assetPool);
1422
- // get slip on liquidity removal
1464
+ // Calculate slip on liquidity removal
1423
1465
  const slip = getSlipOnLiquidity({
1424
1466
  asset: poolShare.assetShare,
1425
1467
  rune: poolShare.runeShare,
1426
1468
  }, assetPool);
1427
- // TODO make sure we compare wait times for withdrawing both rune and asset OR just rune OR just asset
1469
+ // Calculate wait time
1428
1470
  const waitTimeSecondsForAsset = yield this.confCounting(poolShare.assetShare.div(params.percentage / 100));
1429
1471
  const waitTimeSecondsForRune = yield this.confCounting(poolShare.runeShare.div(params.percentage / 100));
1430
1472
  let waitTimeSeconds = 0;
@@ -1438,51 +1480,59 @@ class ThorchainQuery {
1438
1480
  else {
1439
1481
  waitTimeSeconds = waitTimeSecondsForRune;
1440
1482
  }
1483
+ // Get inbound and outbound fees
1441
1484
  const allInboundDetails = yield this.thorchainCache.getInboundDetails();
1442
1485
  const inboundDetails = allInboundDetails[params.asset.chain];
1443
1486
  const runeInbound = calcNetworkFee(AssetRuneNative, inboundDetails);
1444
1487
  const assetInbound = calcNetworkFee(params.asset, inboundDetails);
1445
1488
  const runeOutbound = calcOutboundFee(AssetRuneNative, inboundDetails);
1446
1489
  const assetOutbound = calcOutboundFee(params.asset, inboundDetails);
1490
+ // Create an EstimateWithdrawLP object
1447
1491
  const estimateLP = {
1448
1492
  assetAddress: memberDetail.position.asset_address,
1449
1493
  runeAddress: memberDetail.position.rune_address,
1450
1494
  slipPercent: slip.times(100),
1451
1495
  inbound: {
1452
1496
  minToSend: {
1497
+ // Minimum amount to send
1453
1498
  rune: dustValues.rune,
1454
1499
  asset: dustValues.asset,
1455
- total: (yield this.convert(dustValues.asset, AssetRuneNative)).plus(dustValues.rune),
1500
+ total: (yield this.convert(dustValues.asset, AssetRuneNative)).plus(dustValues.rune), // Total amount
1456
1501
  },
1457
1502
  fees: {
1503
+ // Inbound fees
1458
1504
  rune: runeInbound,
1459
1505
  asset: assetInbound,
1460
- total: (yield this.convert(assetInbound, AssetRuneNative)).plus(runeInbound),
1506
+ total: (yield this.convert(assetInbound, AssetRuneNative)).plus(runeInbound), // Total fees
1461
1507
  },
1462
1508
  },
1463
1509
  outboundFee: {
1510
+ // Outbound fees
1464
1511
  asset: assetOutbound,
1465
1512
  rune: runeOutbound,
1466
- total: (yield this.convert(assetOutbound, AssetRuneNative)).plus(runeOutbound),
1513
+ total: (yield this.convert(assetOutbound, AssetRuneNative)).plus(runeOutbound), // Total fees
1467
1514
  },
1468
1515
  assetAmount: poolShare.assetShare,
1469
1516
  runeAmount: poolShare.runeShare,
1470
1517
  lpGrowth: memberDetail.lpGrowth,
1471
1518
  estimatedWaitSeconds: waitTimeSeconds,
1472
1519
  impermanentLossProtection: memberDetail.impermanentLossProtection,
1473
- assetPool: assetPool.thornodeDetails.asset,
1520
+ assetPool: assetPool.thornodeDetails.asset, // Asset pool
1474
1521
  };
1475
- return estimateLP;
1522
+ return estimateLP; // Return the EstimateWithdrawLP object
1476
1523
  });
1477
1524
  }
1478
1525
  /**
1479
- * // can this become a quried constant? added to inbound_addresses or something
1480
- * @param asset - asset needed to retrieve dust values
1481
- * @returns - object type dust values
1526
+ * Can this become a queried constant? added to inbound_addresses or something
1527
+ * Retrieves dust values for the given asset
1528
+ * @param asset - The asset for which to retrieve dust values
1529
+ * @returns - Object containing dust values
1482
1530
  */
1483
1531
  getDustValues(asset) {
1484
1532
  return __awaiter(this, void 0, void 0, function* () {
1533
+ // Get the number of decimals for the asset
1485
1534
  const assetDecimals = yield this.thorchainCache.midgardQuery.getDecimalForAsset(asset);
1535
+ // Determine the dust values based on the asset's chain
1486
1536
  switch (asset.chain) {
1487
1537
  case 'BNB':
1488
1538
  return {
@@ -1492,80 +1542,88 @@ class ThorchainQuery {
1492
1542
  case 'BTC':
1493
1543
  case `BCH`:
1494
1544
  case `LTC`:
1495
- // 10k sats
1545
+ // Dust value: 10k sats
1496
1546
  return {
1497
1547
  asset: new CryptoAmount(assetToBase(assetAmount(0.0001, assetDecimals)), asset),
1498
1548
  rune: new CryptoAmount(assetToBase(assetAmount(0)), AssetRuneNative),
1499
1549
  };
1500
1550
  case 'ETH':
1501
- // 0 wei
1551
+ // Dust value: 0 wei
1502
1552
  return {
1503
1553
  asset: new CryptoAmount(assetToBase(assetAmount(0, assetDecimals)), asset),
1504
1554
  rune: new CryptoAmount(assetToBase(assetAmount(0)), AssetRuneNative),
1505
1555
  };
1506
1556
  case 'THOR':
1507
- // 0 Rune
1557
+ // Dust value: 0 Rune
1508
1558
  return {
1509
1559
  asset: new CryptoAmount(assetToBase(assetAmount(0, assetDecimals)), asset),
1510
1560
  rune: new CryptoAmount(assetToBase(assetAmount(0)), AssetRuneNative),
1511
1561
  };
1512
1562
  case 'GAIA':
1513
- // 0 GAIA
1563
+ // Dust value: 0 GAIA
1514
1564
  return {
1515
1565
  asset: new CryptoAmount(assetToBase(assetAmount(0, assetDecimals)), asset),
1516
1566
  rune: new CryptoAmount(assetToBase(assetAmount(0)), AssetRuneNative),
1517
1567
  };
1518
1568
  case 'DOGE':
1519
- // 1 million sats
1569
+ // Dust value: 1 million sats
1520
1570
  return {
1521
1571
  asset: new CryptoAmount(assetToBase(assetAmount(0.01, assetDecimals)), asset),
1522
1572
  rune: new CryptoAmount(assetToBase(assetAmount(0)), AssetRuneNative),
1523
1573
  };
1524
1574
  case 'AVAX':
1525
- // 0 AVAX
1575
+ // Dust value: 0 AVAX
1526
1576
  return {
1527
1577
  asset: new CryptoAmount(assetToBase(assetAmount(0, assetDecimals)), asset),
1528
1578
  rune: new CryptoAmount(assetToBase(assetAmount(0)), AssetRuneNative),
1529
1579
  };
1530
1580
  case 'BSC':
1531
- // 0 BSC
1581
+ // Dust value: 0 BSC
1532
1582
  return {
1533
1583
  asset: new CryptoAmount(assetToBase(assetAmount(0, assetDecimals)), asset),
1534
1584
  rune: new CryptoAmount(assetToBase(assetAmount(0)), AssetRuneNative),
1535
1585
  };
1536
1586
  case 'MAYA':
1537
- // 0 MAYA
1587
+ // Dust value: 0 MAYA
1538
1588
  return {
1539
1589
  asset: new CryptoAmount(assetToBase(assetAmount(0, assetDecimals)), asset),
1540
1590
  rune: new CryptoAmount(assetToBase(assetAmount(0)), AssetRuneNative),
1541
1591
  };
1542
1592
  default:
1543
- throw Error('Unknown chain');
1593
+ throw Error('Unknown chain'); // Throw error for unknown chain
1544
1594
  }
1545
1595
  });
1546
1596
  }
1547
1597
  // Savers Queries
1548
1598
  // Derrived from https://dev.thorchain.org/thorchain-dev/connection-guide/savers-guide
1599
+ /**
1600
+ * Estimates the result of adding to a saver
1601
+ * @param addAmount - The amount to be added to the saver
1602
+ * @returns - Object of type EstimateAddSaver
1603
+ */
1549
1604
  estimateAddSaver(addAmount) {
1550
1605
  return __awaiter(this, void 0, void 0, function* () {
1551
- let errors = [];
1552
- // check for errors before sending quote
1606
+ let errors = []; // Initialize errors array
1607
+ // Check for errors before sending quote
1553
1608
  errors = yield this.getAddSaversEstimateErrors(addAmount);
1554
- // request param amount should always be in 1e8 which is why we pass in adjusted decimals if chain decimals != 8
1609
+ // Request parameter amount should always be in 1e8
1610
+ // Adjust decimals if chain decimals != 8
1555
1611
  const newAddAmount = addAmount.baseAmount.decimal != 8 ? getBaseAmountWithDiffDecimals(addAmount, 8) : addAmount.baseAmount.amount();
1556
1612
  // Fetch quote
1557
- const depositQuote = yield this.thorchainCache.thornode.getSaversDepositQuote(assetToString(addAmount.asset), newAddAmount.toNumber());
1558
- // error handling
1613
+ const depositQuote = yield this.thorchainCache.thornode.getSaversDepositQuote(assetToString(addAmount.asset), // Convert asset to string
1614
+ newAddAmount.toNumber());
1615
+ // Error handling
1559
1616
  const response = JSON.parse(JSON.stringify(depositQuote));
1560
1617
  if (response.error)
1561
- errors.push(`Thornode request quote failed: ${response.error}`);
1562
- //The recommended minimum inbound amount for this transaction type & inbound asset.
1618
+ errors.push(`Thornode request quote failed: ${response.error}`); // Push error to array if exists
1619
+ // The recommended minimum inbound amount for this transaction type & inbound asset.
1563
1620
  // Sending less than this amount could result in failed refunds
1564
1621
  if (depositQuote.recommended_min_amount_in &&
1565
1622
  addAmount.baseAmount.amount().toNumber() < Number(depositQuote.recommended_min_amount_in))
1566
- errors.push(`Error amount in: ${addAmount.baseAmount.amount().toNumber()} is less than reccommended Min Amount: ${depositQuote.recommended_min_amount_in}`);
1623
+ errors.push(`Error amount in: ${addAmount.baseAmount.amount().toNumber()} is less than recommended Min Amount: ${depositQuote.recommended_min_amount_in}`);
1567
1624
  // Return errors if there is any
1568
1625
  if (errors.length > 0) {
1626
+ // Return an object with default values and errors
1569
1627
  return {
1570
1628
  assetAmount: addAmount,
1571
1629
  estimatedDepositValue: new CryptoAmount(baseAmount(0), addAmount.asset),
@@ -1584,26 +1642,44 @@ class ThorchainQuery {
1584
1642
  slipBasisPoints: -1,
1585
1643
  recommendedMinAmountIn: depositQuote.recommended_min_amount_in,
1586
1644
  canAddSaver: false,
1587
- errors,
1645
+ errors, // Errors
1588
1646
  };
1589
1647
  }
1648
+ // Get pool details
1590
1649
  const pool = (yield this.thorchainCache.getPoolForAsset(addAmount.asset)).thornodeDetails;
1650
+ // Get asset decimals
1591
1651
  const assetDecimals = yield this.thorchainCache.midgardQuery.getDecimalForAsset(addAmount.asset);
1652
+ // Get fee asset decimals
1592
1653
  const feeAssetDecimals = yield this.thorchainCache.midgardQuery.getDecimalForAsset(addAmount.asset);
1593
- // Organise fees
1654
+ // Organize fees
1594
1655
  const saverFees = {
1595
- affiliate: getCryptoAmountWithNotation(new CryptoAmount(baseAmount(depositQuote.fees.affiliate), addAmount.asset), assetDecimals),
1656
+ affiliate: getCryptoAmountWithNotation(
1657
+ // Affiliate fee
1658
+ new CryptoAmount(baseAmount(depositQuote.fees.affiliate), addAmount.asset), // Convert to base amount
1659
+ assetDecimals),
1596
1660
  asset: assetFromStringEx(depositQuote.fees.asset),
1597
- outbound: getCryptoAmountWithNotation(new CryptoAmount(baseAmount(depositQuote.fees.outbound), assetFromStringEx(depositQuote.fees.asset)), feeAssetDecimals),
1598
- liquidity: getCryptoAmountWithNotation(new CryptoAmount(baseAmount(depositQuote.fees.liquidity), assetFromStringEx(depositQuote.fees.asset)), feeAssetDecimals),
1599
- totalBps: depositQuote.fees.total_bps || 0,
1661
+ outbound: getCryptoAmountWithNotation(
1662
+ // Outbound fee
1663
+ new CryptoAmount(baseAmount(depositQuote.fees.outbound), assetFromStringEx(depositQuote.fees.asset)), // Convert to base amount
1664
+ feeAssetDecimals),
1665
+ liquidity: getCryptoAmountWithNotation(
1666
+ // Liquidity fee
1667
+ new CryptoAmount(baseAmount(depositQuote.fees.liquidity), assetFromStringEx(depositQuote.fees.asset)), // Convert to base amount
1668
+ feeAssetDecimals),
1669
+ totalBps: depositQuote.fees.total_bps || 0, // Total basis points
1600
1670
  };
1601
- // define savers filled capacity
1671
+ // Define saver filled capacity
1602
1672
  const saverCapFilledPercent = (Number(pool.synth_supply) / Number(pool.balance_asset)) * 100;
1603
- // return object
1673
+ // Return object
1604
1674
  const estimateAddSaver = {
1605
- assetAmount: getCryptoAmountWithNotation(new CryptoAmount(baseAmount(depositQuote.expected_amount_out), addAmount.asset), assetDecimals),
1606
- estimatedDepositValue: getCryptoAmountWithNotation(new CryptoAmount(baseAmount(depositQuote.expected_amount_deposit), addAmount.asset), assetDecimals),
1675
+ assetAmount: getCryptoAmountWithNotation(
1676
+ // Asset amount
1677
+ new CryptoAmount(baseAmount(depositQuote.expected_amount_out), addAmount.asset), // Convert to base amount
1678
+ assetDecimals),
1679
+ estimatedDepositValue: getCryptoAmountWithNotation(
1680
+ // Estimated deposit value
1681
+ new CryptoAmount(baseAmount(depositQuote.expected_amount_deposit), addAmount.asset), // Convert to base amount
1682
+ assetDecimals),
1607
1683
  fee: saverFees,
1608
1684
  expiry: new Date(depositQuote.expiry),
1609
1685
  toAddress: depositQuote.inbound_address,
@@ -1613,25 +1689,27 @@ class ThorchainQuery {
1613
1689
  slipBasisPoints: depositQuote.slippage_bps,
1614
1690
  saverCapFilledPercent,
1615
1691
  recommendedMinAmountIn: depositQuote.recommended_min_amount_in,
1616
- errors,
1692
+ errors, // Errors
1617
1693
  };
1618
- return estimateAddSaver;
1694
+ return estimateAddSaver; // Return the EstimateAddSaver object
1619
1695
  });
1620
1696
  }
1621
1697
  /**
1622
- *
1623
- * @param withdrawParams - height?, asset, address, withdrawalBasisPoints
1624
- * @returns - savers withdrawal quote with extras
1698
+ * Estimates the result of withdrawing from a saver
1699
+ * @param withdrawParams - Withdrawal parameters including height, asset, address, and withdrawal basis points
1700
+ * @returns - Object of type EstimateWithdrawSaver
1625
1701
  */
1626
1702
  estimateWithdrawSaver(withdrawParams) {
1627
1703
  return __awaiter(this, void 0, void 0, function* () {
1628
- const errors = [];
1629
- // return error if Asset in is incorrect
1704
+ const errors = []; // Initialize errors array
1705
+ // Return error if asset in is incorrect
1630
1706
  if (isAssetRuneNative(withdrawParams.asset) || withdrawParams.asset.synth)
1631
1707
  errors.push(`Native Rune and synth assets are not supported only L1's`);
1708
+ // Get inbound details
1632
1709
  const inboundDetails = yield this.thorchainCache.getInboundDetails();
1633
- // Check to see if there is a position before calling withdraw quote
1710
+ // Check if there is a position before calling withdraw quote
1634
1711
  const checkPositon = yield this.getSaverPosition(withdrawParams);
1712
+ // If there are errors in the position, return those errors
1635
1713
  if (checkPositon.errors.length > 0) {
1636
1714
  for (let i = 0; i < checkPositon.errors.length; i++) {
1637
1715
  errors.push(checkPositon.errors[i]);
@@ -1639,13 +1717,16 @@ class ThorchainQuery {
1639
1717
  return {
1640
1718
  dustAmount: new CryptoAmount(baseAmount(0), getChainAsset(withdrawParams.asset.chain)),
1641
1719
  dustThreshold: new CryptoAmount(baseAmount(0), getChainAsset(withdrawParams.asset.chain)),
1642
- expectedAssetAmount: new CryptoAmount(assetToBase(assetAmount(checkPositon.redeemableValue.assetAmount.amount())), withdrawParams.asset),
1720
+ expectedAssetAmount: new CryptoAmount(// Expected asset amount
1721
+ assetToBase(assetAmount(checkPositon.redeemableValue.assetAmount.amount())), // Convert to base amount
1722
+ withdrawParams.asset),
1643
1723
  fee: {
1644
1724
  affiliate: new CryptoAmount(assetToBase(assetAmount(0)), withdrawParams.asset),
1645
1725
  asset: withdrawParams.asset,
1646
1726
  liquidity: new CryptoAmount(baseAmount(0), withdrawParams.asset),
1647
- outbound: new CryptoAmount(assetToBase(assetAmount(calcOutboundFee(withdrawParams.asset, inboundDetails[withdrawParams.asset.chain]).assetAmount.amount())), withdrawParams.asset),
1648
- totalBps: 0,
1727
+ outbound: new CryptoAmount(// Outbound fee
1728
+ assetToBase(assetAmount(calcOutboundFee(withdrawParams.asset, inboundDetails[withdrawParams.asset.chain]).assetAmount.amount())), withdrawParams.asset),
1729
+ totalBps: 0, // Total basis points
1649
1730
  },
1650
1731
  expiry: new Date(0),
1651
1732
  toAddress: '',
@@ -1655,7 +1736,7 @@ class ThorchainQuery {
1655
1736
  outBoundDelayBlocks: 0,
1656
1737
  outBoundDelaySeconds: 0,
1657
1738
  slipBasisPoints: -1,
1658
- errors,
1739
+ errors, // Errors array
1659
1740
  };
1660
1741
  }
1661
1742
  // Request withdraw quote
@@ -1665,6 +1746,7 @@ class ThorchainQuery {
1665
1746
  if (response.error)
1666
1747
  errors.push(`Thornode request quote failed: ${response.error}`);
1667
1748
  if (errors.length > 0) {
1749
+ // Return default values and errors if there are any errors
1668
1750
  return {
1669
1751
  dustAmount: new CryptoAmount(baseAmount(0), getChainAsset(withdrawParams.asset.chain)),
1670
1752
  dustThreshold: new CryptoAmount(baseAmount(0), getChainAsset(withdrawParams.asset.chain)),
@@ -1687,14 +1769,21 @@ class ThorchainQuery {
1687
1769
  errors,
1688
1770
  };
1689
1771
  }
1772
+ // Extract the withdraw asset and chain asset from the withdraw quote
1690
1773
  const withdrawAsset = assetFromStringEx(withdrawQuote.fees.asset);
1691
1774
  const chainAsset = getChainAsset(withdrawParams.asset.chain);
1775
+ // Get the decimals for the withdraw asset and chain asset
1692
1776
  const withdrawAssetDecimals = yield this.thorchainCache.midgardQuery.getDecimalForAsset(withdrawAsset);
1693
1777
  const chainAssetDecimals = yield this.thorchainCache.midgardQuery.getDecimalForAsset(chainAsset);
1778
+ // Create an EstimateWithdrawSaver object with the necessary data
1694
1779
  const estimateWithdrawSaver = {
1780
+ // Format the dust amount with appropriate notation and decimals
1695
1781
  dustAmount: getCryptoAmountWithNotation(new CryptoAmount(baseAmount(withdrawQuote.dust_amount), chainAsset), chainAssetDecimals),
1782
+ // Format the dust threshold with appropriate notation and decimals
1696
1783
  dustThreshold: getCryptoAmountWithNotation(new CryptoAmount(baseAmount(withdrawQuote.dust_threshold), chainAsset), chainAssetDecimals),
1784
+ // Format the expected asset amount with appropriate notation and decimals
1697
1785
  expectedAssetAmount: getCryptoAmountWithNotation(new CryptoAmount(baseAmount(withdrawQuote.expected_amount_out), withdrawParams.asset), withdrawAssetDecimals),
1786
+ // Format the withdrawal fees with appropriate notation and decimals
1698
1787
  fee: {
1699
1788
  affiliate: getCryptoAmountWithNotation(new CryptoAmount(baseAmount(withdrawQuote.fees.affiliate), withdrawAsset), withdrawAssetDecimals),
1700
1789
  asset: withdrawAsset,
@@ -1702,53 +1791,77 @@ class ThorchainQuery {
1702
1791
  outbound: getCryptoAmountWithNotation(new CryptoAmount(baseAmount(withdrawQuote.fees.outbound), withdrawAsset), withdrawAssetDecimals),
1703
1792
  totalBps: withdrawQuote.fees.total_bps || 0,
1704
1793
  },
1794
+ // Set the expiry date
1705
1795
  expiry: new Date(withdrawQuote.expiry),
1796
+ // Set the recipient address
1706
1797
  toAddress: withdrawQuote.inbound_address,
1798
+ // Set the memo
1707
1799
  memo: withdrawQuote.memo,
1800
+ // Set the inbound delay blocks
1708
1801
  inboundDelayBlocks: withdrawQuote.inbound_confirmation_blocks || 0,
1802
+ // Set the inbound delay seconds
1709
1803
  inboundDelaySeconds: withdrawQuote.inbound_confirmation_seconds || 0,
1804
+ // Set the outbound delay blocks
1710
1805
  outBoundDelayBlocks: withdrawQuote.outbound_delay_blocks || 0,
1806
+ // Set the outbound delay seconds
1711
1807
  outBoundDelaySeconds: withdrawQuote.outbound_delay_seconds || 0,
1808
+ // Set the slip basis points
1712
1809
  slipBasisPoints: withdrawQuote.slippage_bps,
1810
+ // Set the errors
1713
1811
  errors,
1714
1812
  };
1813
+ // Return the withdrawal estimation object
1715
1814
  return estimateWithdrawSaver;
1716
1815
  });
1717
1816
  }
1718
1817
  /**
1719
- *
1720
- * @param params - getSaver object > asset, addresss, height?
1721
- * @returns - Savers position object
1818
+ * Retrieve the position of a saver given the asset, address, and height.
1819
+ * @param params - Object containing the asset, address, and height.
1820
+ * @returns - Object representing the saver's position.
1722
1821
  */
1723
1822
  getSaverPosition(params) {
1724
1823
  return __awaiter(this, void 0, void 0, function* () {
1824
+ // Initialize errors array
1725
1825
  const errors = [];
1826
+ // Retrieve inbound details
1726
1827
  const inboundDetails = yield this.thorchainCache.getInboundDetails();
1828
+ // Get the decimals for the asset
1727
1829
  const assetDecimals = yield this.thorchainCache.midgardQuery.getDecimalForAsset(params.asset);
1830
+ // Retrieve block data for the specified asset chain
1728
1831
  const blockData = (yield this.thorchainCache.thornode.getLastBlock()).find((item) => item.chain === params.asset.chain);
1729
- // address comparison is done after conversion to lower case
1832
+ // Retrieve the saver from the Thorchain node API
1730
1833
  const savers = (yield this.thorchainCache.thornode.getSavers(`${params.asset.chain}.${params.asset.symbol}`)).find((item) => item.asset_address.toLowerCase() === params.address.toLowerCase());
1834
+ // Retrieve pool details for the specified asset
1731
1835
  const pool = (yield this.thorchainCache.getPoolForAsset(params.asset)).thornodeDetails;
1836
+ // Push errors if necessary data is not found
1732
1837
  if (!savers)
1733
1838
  errors.push(`Could not find position for ${params.address}`);
1734
1839
  if (!(savers === null || savers === void 0 ? void 0 : savers.last_add_height))
1735
1840
  errors.push(`Could not find position for ${params.address}`);
1736
1841
  if (!(blockData === null || blockData === void 0 ? void 0 : blockData.thorchain))
1737
1842
  errors.push(`Could not get thorchain block height`);
1843
+ // Calculate the outbound fee
1738
1844
  const outboundFee = calcOutboundFee(params.asset, inboundDetails[params.asset.chain]);
1739
1845
  const convertToBaseEight = getBaseAmountWithDiffDecimals(outboundFee, 8);
1740
- // For comparison use 1e8 since asset_redeem_value is returned in 1e8
1846
+ // Push an error if the redeemable value is less than the outbound fee
1741
1847
  if (Number(savers === null || savers === void 0 ? void 0 : savers.asset_redeem_value) < convertToBaseEight.toNumber())
1742
1848
  errors.push(`Unlikely to withdraw balance as outbound fee is greater than redeemable amount`);
1743
- const ownerUnits = Number(savers === null || savers === void 0 ? void 0 : savers.units);
1744
- const lastAdded = Number(savers === null || savers === void 0 ? void 0 : savers.last_add_height);
1745
- const saverUnits = Number(pool.savers_units);
1746
- const assetDepth = Number(pool.savers_depth);
1849
+ // Calculate the redeemable value
1850
+ // Extract necessary data for calculation
1851
+ const ownerUnits = Number(savers === null || savers === void 0 ? void 0 : savers.units); // Number of units owned by the saver
1852
+ const lastAdded = Number(savers === null || savers === void 0 ? void 0 : savers.last_add_height); // Height at which the last addition was made to the pool
1853
+ const saverUnits = Number(pool.savers_units); // Total units in the pool
1854
+ const assetDepth = Number(pool.savers_depth); // Total asset depth in the pool
1855
+ // Calculate the redeemable value of the saver's position based on their ownership in the pool
1747
1856
  const redeemableValue = (ownerUnits / saverUnits) * assetDepth;
1857
+ // Format the deposit amount and redeemable asset amount with appropriate notation and decimals
1748
1858
  const depositAmount = getCryptoAmountWithNotation(new CryptoAmount(baseAmount(savers === null || savers === void 0 ? void 0 : savers.asset_deposit_value), params.asset), assetDecimals);
1749
1859
  const redeemableAssetAmount = getCryptoAmountWithNotation(new CryptoAmount(baseAmount(redeemableValue), params.asset), assetDecimals);
1860
+ // Calculate the age of the saver's position in years and days
1750
1861
  const saversAge = (Number(blockData === null || blockData === void 0 ? void 0 : blockData.thorchain) - lastAdded) / ((365 * 86400) / 6);
1862
+ // Calculate the growth percentage of the saver's position
1751
1863
  const saverGrowth = redeemableAssetAmount.minus(depositAmount).div(depositAmount).times(100);
1864
+ // Create and populate a SaversPosition object with the calculated values
1752
1865
  const saversPos = {
1753
1866
  depositValue: depositAmount,
1754
1867
  redeemableValue: redeemableAssetAmount,
@@ -1757,29 +1870,47 @@ class ThorchainQuery {
1757
1870
  ageInYears: saversAge,
1758
1871
  ageInDays: saversAge * 365,
1759
1872
  asset: params.asset,
1760
- errors,
1873
+ errors, // Array of any errors encountered during the calculation
1761
1874
  };
1875
+ // Return the SaversPosition object representing the saver's position
1762
1876
  return saversPos;
1763
1877
  });
1764
1878
  }
1879
+ /**
1880
+ * Get errors related to estimating the addition of funds to a saver's pool.
1881
+ * @param addAmount - Amount of funds to be added to the saver's pool.
1882
+ * @returns An array of strings representing any errors encountered during the estimation process.
1883
+ */
1765
1884
  getAddSaversEstimateErrors(addAmount) {
1766
1885
  return __awaiter(this, void 0, void 0, function* () {
1767
1886
  const errors = [];
1887
+ // Retrieve all pools
1768
1888
  const pools = yield this.thorchainCache.getPools();
1889
+ // Filter out saver's pools with non-zero depth
1769
1890
  const saversPools = Object.values(pools).filter((i) => i.thornodeDetails.savers_depth !== '0');
1891
+ // Retrieve inbound details
1770
1892
  const inboundDetails = yield this.thorchainCache.getInboundDetails();
1893
+ // Find the saver's pool corresponding to the provided asset
1771
1894
  const saverPool = saversPools.find((i) => assetToString(i.asset) === assetToString(addAmount.asset));
1895
+ // Check if a saver's pool exists for the provided asset
1772
1896
  if (!saverPool)
1773
1897
  errors.push(` ${assetToString(addAmount.asset)} does not have a saver's pool`);
1898
+ // Check if the chain for the provided asset is halted
1774
1899
  if (inboundDetails[addAmount.asset.chain].haltedChain)
1775
1900
  errors.push(`${addAmount.asset.chain} is halted, cannot add`);
1901
+ // Get details of the pool for the provided asset
1776
1902
  const pool = (yield this.thorchainCache.getPoolForAsset(addAmount.asset)).thornodeDetails;
1903
+ // Check if the pool for the provided asset is available
1777
1904
  if (pool.status.toLowerCase() !== 'available')
1778
1905
  errors.push(`Pool is not available for this asset ${assetToString(addAmount.asset)}`);
1779
- const inboundFee = new CryptoAmount(baseAmount(inboundDetails[addAmount.asset.chain].gasRate), addAmount.asset); // only needs to check against inbound fee, not network fee.
1780
- const inboundFeeInAddAmountAsset = yield this.convert(inboundFee, addAmount.asset); // to make sure maths is being done on same assets
1906
+ // Calculate inbound fee for the provided asset
1907
+ const inboundFee = new CryptoAmount(baseAmount(inboundDetails[addAmount.asset.chain].gasRate), addAmount.asset);
1908
+ // Convert inbound fee to the same asset as the addAmount to ensure consistency in calculations
1909
+ const inboundFeeInAddAmountAsset = yield this.convert(inboundFee, addAmount.asset);
1910
+ // Check if the addAmount covers the inbound fees
1781
1911
  if (addAmount.lte(inboundFeeInAddAmountAsset))
1782
1912
  errors.push(`Add amount does not cover fees`);
1913
+ // Return array of errors encountered during estimation
1783
1914
  return errors;
1784
1915
  });
1785
1916
  }
@@ -1856,17 +1987,21 @@ class ThorchainQuery {
1856
1987
  });
1857
1988
  }
1858
1989
  /**
1859
- *
1860
- * @param loanOpenParams - params needed for the end Point
1861
- * @returns
1990
+ * Get a quote for opening a loan.
1991
+ * @param loanOpenParams - Parameters needed for the endpoint.
1992
+ * @returns A Promise resolving to a LoanOpenQuote.
1862
1993
  */
1863
1994
  getLoanQuoteClose({ asset, amount, loanAsset, loanOwner, minOut, height, }) {
1864
1995
  return __awaiter(this, void 0, void 0, function* () {
1865
1996
  const errors = [];
1997
+ // Retrieve loan open response from ThorNode API
1866
1998
  const loanCloseResp = yield this.thorchainCache.thornode.getLoanQuoteClose(`${asset.chain}.${asset.symbol}`, amount.baseAmount.amount().toNumber(), `${loanAsset.chain}.${loanAsset.symbol}`, loanOwner, minOut, height);
1999
+ // Parse loan open response
1867
2000
  const response = JSON.parse(JSON.stringify(loanCloseResp));
2001
+ // Check for errors in response
1868
2002
  if (response.error)
1869
2003
  errors.push(`Thornode request quote failed: ${response.error}`);
2004
+ // If errors exist, return an object with error details
1870
2005
  if (errors.length > 0) {
1871
2006
  return {
1872
2007
  inboundAddress: '',
@@ -1894,6 +2029,7 @@ class ThorchainQuery {
1894
2029
  errors: errors,
1895
2030
  };
1896
2031
  }
2032
+ // Construct loan open quote object
1897
2033
  const loanCloseQuote = {
1898
2034
  inboundAddress: loanCloseResp.inbound_address,
1899
2035
  expectedWaitTime: {
@@ -1923,19 +2059,23 @@ class ThorchainQuery {
1923
2059
  });
1924
2060
  }
1925
2061
  /**
1926
- *
1927
- * @param thorname - input param
1928
- * @returns retrieves details for a thorname
2062
+ * Retrieve details for a THORName.
2063
+ * @param thorname - The THORName to get details for.
2064
+ * @param height - Optional parameter specifying the block height.
2065
+ * @returns A Promise resolving to ThornameDetails.
1929
2066
  */
1930
2067
  getThornameDetails(thorname, height) {
1931
2068
  return __awaiter(this, void 0, void 0, function* () {
1932
2069
  const errors = [];
1933
2070
  try {
2071
+ // Retrieve THORName details from ThorNode API
1934
2072
  const thornameResp = yield this.thorchainCache.thornode.getThornameDetails(thorname, height);
1935
2073
  const response = JSON.parse(JSON.stringify(thornameResp));
2074
+ // Check for errors in response
1936
2075
  if (response.error)
1937
2076
  errors.push(`Thornode request quote failed: ${response.error}`);
1938
2077
  if (errors.length > 0) {
2078
+ // If errors exist, return an object with error details
1939
2079
  const errorResp = {
1940
2080
  name: '',
1941
2081
  expireBlockHeight: 0,
@@ -1947,10 +2087,12 @@ class ThorchainQuery {
1947
2087
  };
1948
2088
  return errorResp;
1949
2089
  }
2090
+ // Map aliases to ThornameAlias objects
1950
2091
  const thornameAliases = thornameResp.aliases.map((alias) => ({
1951
2092
  chain: alias.chain,
1952
2093
  address: alias.address,
1953
2094
  }));
2095
+ // Construct ThornameDetails object
1954
2096
  const thornameDetails = {
1955
2097
  name: thornameResp.name || '',
1956
2098
  expireBlockHeight: thornameResp.expire_block_height || 0,
@@ -1962,6 +2104,7 @@ class ThorchainQuery {
1962
2104
  return thornameDetails;
1963
2105
  }
1964
2106
  catch (e) {
2107
+ // If an error occurs during the process, return an object with error details
1965
2108
  const errorResp = {
1966
2109
  name: '',
1967
2110
  expireBlockHeight: 0,
@@ -1976,31 +2119,32 @@ class ThorchainQuery {
1976
2119
  });
1977
2120
  }
1978
2121
  /**
1979
- * Generate the memo and estimate the cost of register or update a THORName
1980
- * @param thorname - Name to register
1981
- * @param chain - Chain to update / register
1982
- * @param chainAddress - Address to add to chain alias
1983
- * @param owner - Owner address (rune address)
1984
- * @param preferredAsset - referred asset
1985
- * @param expirity - expirity of the domain in MILLISECONDS
1986
- * @param isUpdate - true only if the domain is already register and you want to update its data
1987
- * @returns memo and value of deposit
2122
+ * Generate the memo and estimate the cost of registering or updating a THORName.
2123
+ * @param thorname - The name to register or update.
2124
+ * @param chain - The chain to update/register.
2125
+ * @param chainAddress - The address to add to chain alias.
2126
+ * @param owner - The owner address (rune address).
2127
+ * @param preferredAsset - The preferred asset.
2128
+ * @param expirity - The expiry of the domain in MILLISECONDS.
2129
+ * @param isUpdate - True only if the domain is already registered and you want to update its data.
2130
+ * @returns Memo and value of deposit.
1988
2131
  */
1989
2132
  estimateThorname(params) {
1990
2133
  return __awaiter(this, void 0, void 0, function* () {
1991
- // CHECK IF ALREADY EXISTS
2134
+ // Check if THORName already exists
1992
2135
  const thornameDetails = yield this.getThornameDetails(params.thorname);
1993
2136
  if (thornameDetails.owner !== '' && !params.isUpdate) {
1994
2137
  throw Error('Thorname already registered');
1995
2138
  }
2139
+ // Retrieve block data
1996
2140
  const blockData = yield this.thorchainCache.thornode.getLastBlock();
1997
2141
  const currentThorchainHeight = blockData[0].thorchain;
1998
2142
  const currentHeightForExpirity = params.isUpdate
1999
2143
  ? thornameDetails === null || thornameDetails === void 0 ? void 0 : thornameDetails.expireBlockHeight
2000
2144
  : currentThorchainHeight;
2001
- // DEFAULT EXPIRITY
2145
+ // Default expiry
2002
2146
  let numberOfBlocksToAddToExpirity = params.isUpdate ? 0 : 5259600; // One year by default
2003
- // COMPUTE EXPIRITY HEIGHT
2147
+ // Compute expiry height
2004
2148
  if (params.expirity) {
2005
2149
  const currentTimestamp = Math.floor(Date.now() / 1000);
2006
2150
  const expirityTimestamp = Math.floor(params.expirity.getTime() / 1000);
@@ -2011,7 +2155,7 @@ class ThorchainQuery {
2011
2155
  ? newHeightExpirity - (thornameDetails === null || thornameDetails === void 0 ? void 0 : thornameDetails.expireBlockHeight)
2012
2156
  : numberOfBlocks;
2013
2157
  }
2014
- // COMPUTE VALUE
2158
+ // Compute value
2015
2159
  const constantsDetails = yield this.thorchainCache.thornode.getTcConstants();
2016
2160
  const oneTimeFee = params.isUpdate ? baseAmount(0) : baseAmount(constantsDetails['TNSRegisterFee']);
2017
2161
  const totalFeePerBlock = baseAmount(constantsDetails['TNSFeePerBlock']).times(numberOfBlocksToAddToExpirity > 0 ? numberOfBlocksToAddToExpirity : 0);
@@ -2023,8 +2167,32 @@ class ThorchainQuery {
2023
2167
  };
2024
2168
  });
2025
2169
  }
2170
+ /**
2171
+ * Get inbound addresses details
2172
+ * @returns Inbound details
2173
+ */
2174
+ getInboundDetails() {
2175
+ return __awaiter(this, void 0, void 0, function* () {
2176
+ return this.thorchainCache.getInboundDetails();
2177
+ });
2178
+ }
2179
+ /**
2180
+ * Get chain inbound address details
2181
+ * @returns Inbound details
2182
+ */
2183
+ getChainInboundDetails(chain) {
2184
+ return __awaiter(this, void 0, void 0, function* () {
2185
+ const inboundDetails = yield this.getInboundDetails();
2186
+ if (!inboundDetails[chain])
2187
+ throw Error(`No inbound details known for ${chain} chain`);
2188
+ return inboundDetails[chain];
2189
+ });
2190
+ }
2026
2191
  }
2027
2192
 
2193
+ /**
2194
+ * Enum representing different types of transactions.
2195
+ */
2028
2196
  var TxType;
2029
2197
  (function (TxType) {
2030
2198
  TxType["Swap"] = "Swap";
@@ -2036,12 +2204,18 @@ var TxType;
2036
2204
  TxType["Other"] = "Other";
2037
2205
  TxType["Unknown"] = "Unknown";
2038
2206
  })(TxType || (TxType = {}));
2207
+ /**
2208
+ * Enum representing inbound transaction status.
2209
+ */
2039
2210
  var InboundStatus;
2040
2211
  (function (InboundStatus) {
2041
2212
  InboundStatus["Observed_Consensus"] = "Observed_Consensus";
2042
2213
  InboundStatus["Observed_Incomplete"] = "Observed_Incomplete";
2043
2214
  InboundStatus["Unknown"] = "Unknown";
2044
2215
  })(InboundStatus || (InboundStatus = {}));
2216
+ /**
2217
+ * Enum representing swap transaction status.
2218
+ */
2045
2219
  var SwapStatus;
2046
2220
  (function (SwapStatus) {
2047
2221
  SwapStatus["Complete"] = "Complete";
@@ -2049,6 +2223,9 @@ var SwapStatus;
2049
2223
  SwapStatus["Complete_Below_Dust"] = "Complete_Below_Dust";
2050
2224
  SwapStatus["Incomplete"] = "Incomplete";
2051
2225
  })(SwapStatus || (SwapStatus = {}));
2226
+ /**
2227
+ * Enum representing add liquidity pool transaction status.
2228
+ */
2052
2229
  var AddLpStatus;
2053
2230
  (function (AddLpStatus) {
2054
2231
  AddLpStatus["Complete"] = "Complete";
@@ -2056,18 +2233,27 @@ var AddLpStatus;
2056
2233
  AddLpStatus["Complete_Below_Dust"] = "Complete_Below_Dust";
2057
2234
  AddLpStatus["Incomplete"] = "Incomplete";
2058
2235
  })(AddLpStatus || (AddLpStatus = {}));
2236
+ /**
2237
+ * Enum representing withdraw transaction status.
2238
+ */
2059
2239
  var WithdrawStatus;
2060
2240
  (function (WithdrawStatus) {
2061
2241
  WithdrawStatus["Complete"] = "Complete";
2062
2242
  WithdrawStatus["Incomplete"] = "Incomplete";
2063
2243
  WithdrawStatus["Complete_Refunded"] = "Complete_Refunded";
2064
2244
  })(WithdrawStatus || (WithdrawStatus = {}));
2245
+ /**
2246
+ * Enum representing refund transaction status.
2247
+ */
2065
2248
  var RefundStatus;
2066
2249
  (function (RefundStatus) {
2067
2250
  RefundStatus["Complete"] = "Complete";
2068
2251
  RefundStatus["Incomplete"] = "Incomplete";
2069
2252
  RefundStatus["Complete_Refunded"] = "Complete_Refunded";
2070
2253
  })(RefundStatus || (RefundStatus = {}));
2254
+ /**
2255
+ * Enum representing add saver transaction status.
2256
+ */
2071
2257
  var AddSaverStatus;
2072
2258
  (function (AddSaverStatus) {
2073
2259
  AddSaverStatus["Complete"] = "Complete";
@@ -2075,11 +2261,24 @@ var AddSaverStatus;
2075
2261
  AddSaverStatus["Complete_Below_Dust"] = "Complete_Below_Dust";
2076
2262
  AddSaverStatus["Incomplete"] = "Incomplete";
2077
2263
  })(AddSaverStatus || (AddSaverStatus = {}));
2264
+ /**
2265
+ * Class for managing transaction stages.
2266
+ */
2078
2267
  class TransactionStage {
2268
+ /**
2269
+ * Constructor to create a TransactionStage instance.
2270
+ * @param thorchainCache - ThorchainCache instance.
2271
+ * @param chainAttributes - ChainAttributes object representing default chain attributes.
2272
+ */
2079
2273
  constructor(thorchainCache, chainAttributes = DefaultChainAttributes) {
2080
2274
  this.thorchainCache = thorchainCache;
2081
2275
  this.chainAttributes = chainAttributes;
2082
2276
  }
2277
+ /**
2278
+ * Checks transaction progress.
2279
+ * @param inboundTxHash - Inbound transaction hash.
2280
+ * @returns Promise<TXProgress> - Transaction progress object.
2281
+ */
2083
2282
  checkTxProgress(inboundTxHash) {
2084
2283
  return __awaiter(this, void 0, void 0, function* () {
2085
2284
  let txData;
@@ -2121,29 +2320,37 @@ class TransactionStage {
2121
2320
  return progress;
2122
2321
  });
2123
2322
  }
2323
+ /**
2324
+ * Checks the progress of a swap transaction.
2325
+ * @param txData - Transaction details response.
2326
+ * @param progress - Transaction progress object.
2327
+ */
2124
2328
  checkSwapProgress(txData, progress) {
2125
2329
  var _a, _b, _c, _d;
2126
2330
  return __awaiter(this, void 0, void 0, function* () {
2127
2331
  if (progress.inboundObserved) {
2332
+ // Extract memo fields
2128
2333
  const memo = (_a = txData.tx.tx.memo) !== null && _a !== void 0 ? _a : '';
2129
2334
  const memoFields = this.parseSwapMemo(memo);
2130
2335
  const assetOut = assetFromStringEx(memoFields.asset.toUpperCase());
2131
- //const assetIn = assetFromStringEx(txData.tx.tx.coins?.[0].asset)
2336
+ // Determine swap status
2132
2337
  const swapStatus = ((_b = txData.out_txs[0].memo) === null || _b === void 0 ? void 0 : _b.match('OUT')) ? SwapStatus.Complete : SwapStatus.Complete_Refunded;
2133
- // current height of thorchain, neeed for confirmations
2338
+ // Get current chain height for confirmations
2134
2339
  const chainHeight = yield this.blockHeight(AssetRuneNative);
2135
- // expected outbound height
2340
+ // Expected outbound height and date
2136
2341
  const outboundHeight = Number((_c = txData.outbound_height) !== null && _c !== void 0 ? _c : txData.finalised_height);
2137
2342
  const expectedOutBlock = Number((_d = txData.outbound_height) !== null && _d !== void 0 ? _d : txData.finalised_height);
2138
2343
  const expectedOutDate = yield this.blockToDate(THORChain, txData, outboundHeight); // height held in the scheduled queue
2344
+ // Calculate confirmations
2139
2345
  const confirmations = chainHeight > outboundHeight ? chainHeight - outboundHeight : 0;
2346
+ // Calculate minimum amount out and affiliate fee
2140
2347
  const minimumAmountOut = memoFields.limit
2141
2348
  ? yield this.getCryptoAmount(memoFields.limit, assetOut)
2142
2349
  : yield this.getCryptoAmount('0', assetOut);
2143
2350
  const affliateFee = memoFields.affiliateFee
2144
2351
  ? yield this.getCryptoAmount(memoFields.affiliateFee, assetOut)
2145
2352
  : yield this.getCryptoAmount('0', assetOut);
2146
- // TODO get out tx
2353
+ // Construct swap info object
2147
2354
  const swapInfo = {
2148
2355
  status: swapStatus,
2149
2356
  expectedOutBlock,
@@ -2154,10 +2361,16 @@ class TransactionStage {
2154
2361
  affliateFee,
2155
2362
  toAddress: memoFields.destAddress,
2156
2363
  };
2364
+ // Assign swap info to progress object
2157
2365
  progress.swapInfo = swapInfo;
2158
2366
  }
2159
2367
  });
2160
2368
  }
2369
+ /**
2370
+ * Parses swap memo to extract relevant fields.
2371
+ * @param memo - Transaction memo.
2372
+ * @returns Parsed swap memo fields.
2373
+ */
2161
2374
  parseSwapMemo(memo) {
2162
2375
  //SWAP:ASSET:DESTADDR:LIM:AFFILIATE:FEE
2163
2376
  const parts = memo.split(`:`);
@@ -2169,12 +2382,23 @@ class TransactionStage {
2169
2382
  const affiliateFee = parts.length > 5 && parts[5].length > 0 ? parts[5] : undefined;
2170
2383
  return { action, asset, destAddress, limit, affiliateAddress, affiliateFee };
2171
2384
  }
2385
+ /**
2386
+ * Retrieves a CryptoAmount object.
2387
+ * @param baseAmt - Base amount.
2388
+ * @param asset - Asset object.
2389
+ * @returns Promise<CryptoAmount> - CryptoAmount object.
2390
+ */
2172
2391
  getCryptoAmount(baseAmt, asset) {
2173
2392
  return __awaiter(this, void 0, void 0, function* () {
2174
2393
  const decimals = THORChain === asset.chain ? 8 : Number(yield this.thorchainCache.midgardQuery.getDecimalForAsset(asset));
2175
2394
  return new CryptoAmount(baseAmount(baseAmt, decimals), asset);
2176
2395
  });
2177
2396
  }
2397
+ /**
2398
+ * Determines the observed status of a transaction.
2399
+ * @param txData - Transaction signers response.
2400
+ * @returns Promise<TXProgress> - Transaction progress object.
2401
+ */
2178
2402
  determineObserved(txData) {
2179
2403
  var _a, _b, _c, _d;
2180
2404
  return __awaiter(this, void 0, void 0, function* () {
@@ -2225,14 +2449,21 @@ class TransactionStage {
2225
2449
  return progress;
2226
2450
  });
2227
2451
  }
2452
+ /**
2453
+ * Checks the progress of an add liquidity pool transaction.
2454
+ * @param txData - Transaction details response.
2455
+ * @param progress - Transaction progress object.
2456
+ */
2228
2457
  checkAddLpProgress(txData, progress) {
2229
2458
  var _a;
2230
2459
  return __awaiter(this, void 0, void 0, function* () {
2231
2460
  if (progress.inboundObserved) {
2461
+ // Extract memo fields
2232
2462
  const memo = (_a = txData.tx.tx.memo) !== null && _a !== void 0 ? _a : '';
2233
2463
  const memoFields = this.parseAddLpMemo(memo);
2234
2464
  const asset = assetFromStringEx(memoFields.asset);
2235
2465
  const isSymmetric = memoFields.pairedAddress ? true : false;
2466
+ // Determine if assetTx or runeTx
2236
2467
  const assetTx = !isAssetRuneNative(progress.inboundObserved.amount.asset) ? progress.inboundObserved : undefined;
2237
2468
  const runeTx = isAssetRuneNative(progress.inboundObserved.amount.asset) ? progress.inboundObserved : undefined;
2238
2469
  const pairedAssetExpectedConfirmationDate = assetTx ? yield this.blockToDate(asset.chain, txData) : undefined;
@@ -2250,27 +2481,38 @@ class TransactionStage {
2250
2481
  }
2251
2482
  });
2252
2483
  }
2484
+ /**
2485
+ * Checks the progress of a withdraw liquidity pool transaction.
2486
+ * @param txData - Transaction details response.
2487
+ * @param progress - Transaction progress object.
2488
+ */
2253
2489
  checkWithdrawLpProgress(txData, progress) {
2254
2490
  var _a, _b;
2255
2491
  return __awaiter(this, void 0, void 0, function* () {
2256
2492
  if (progress.inboundObserved) {
2493
+ // Extract memo fields
2257
2494
  const memo = (_a = txData.tx.tx.memo) !== null && _a !== void 0 ? _a : '';
2258
2495
  const memoFields = this.parseWithdrawLpMemo(memo);
2259
2496
  const asset = assetFromStringEx(memoFields.asset);
2497
+ // Get the last block object
2260
2498
  const lastBlockObj = yield this.thorchainCache.thornode.getLastBlock();
2261
2499
  const currentHeight = lastBlockObj.find((obj) => obj);
2262
- // find the date in which the asset should be seen in the wallet
2500
+ // Calculate expected confirmation date
2263
2501
  const outboundHeight = txData.tx.status === 'done' ? txData.finalised_height : Number(`${txData.outbound_height}`);
2264
2502
  const expectedConfirmationDate = yield this.blockToDate(THORChain, txData, outboundHeight); // always pass in thorchain
2265
- // if the TC has process the block that the outbound tx was assigned to then its completed.
2503
+ // Determine transaction status
2266
2504
  const status = txData.tx.status === 'done' ? WithdrawStatus.Complete : WithdrawStatus.Incomplete;
2505
+ // Extract output amount
2267
2506
  const outAmount = status === WithdrawStatus.Complete ? JSON.stringify(txData.out_txs).split(`"amount":"`)[1].split(`"`) : '';
2507
+ // Extract relevant block heights and calculate estimated wait time
2268
2508
  const outboundBlock = Number((_b = txData.outbound_height) !== null && _b !== void 0 ? _b : txData.finalised_height);
2269
2509
  const currentTCHeight = Number(`${currentHeight === null || currentHeight === void 0 ? void 0 : currentHeight.thorchain}`);
2270
2510
  const estimatedWaitTime = outboundBlock > currentTCHeight
2271
2511
  ? (outboundBlock - currentTCHeight) * this.chainAttributes[THORChain].avgBlockTimeInSecs
2272
2512
  : 0;
2513
+ // Get withdrawal amount
2273
2514
  const withdrawalAmount = yield this.getCryptoAmount(outAmount[0], asset);
2515
+ // Construct withdraw liquidity pool info object
2274
2516
  const withdrawLpInfo = {
2275
2517
  status,
2276
2518
  withdrawalAmount,
@@ -2279,38 +2521,58 @@ class TransactionStage {
2279
2521
  outboundHeight: outboundBlock,
2280
2522
  estimatedWaitTime,
2281
2523
  };
2524
+ // Assign withdraw liquidity pool info to progress object
2282
2525
  progress.withdrawLpInfo = withdrawLpInfo;
2283
2526
  }
2284
2527
  });
2285
2528
  }
2529
+ /**
2530
+ * Checks the progress of an add saver transaction.
2531
+ * @param txData - Transaction details response.
2532
+ * @param progress - Transaction progress object.
2533
+ */
2286
2534
  checkAddSaverProgress(txData, progress) {
2287
2535
  return __awaiter(this, void 0, void 0, function* () {
2288
2536
  if (progress.inboundObserved) {
2537
+ // Determine if it's an asset transaction
2289
2538
  const assetTx = !isAssetRuneNative(progress.inboundObserved.amount.asset) ? progress.inboundObserved : undefined;
2539
+ // Check saver vaults
2290
2540
  const checkSaverVaults = yield this.thorchainCache.thornode.getSaver(txData.tx.tx.coins[0].asset, `${assetTx === null || assetTx === void 0 ? void 0 : assetTx.fromAddress}`);
2541
+ // Determine transaction status
2291
2542
  const status = checkSaverVaults ? AddSaverStatus.Complete : AddSaverStatus.Incomplete;
2543
+ // Construct add saver info object
2292
2544
  const addSaverInfo = {
2293
2545
  status: status,
2294
2546
  assetTx,
2295
2547
  saverPos: checkSaverVaults,
2296
2548
  };
2549
+ // Assign add saver info to progress object
2297
2550
  progress.addSaverInfo = addSaverInfo;
2298
2551
  }
2299
2552
  });
2300
2553
  }
2554
+ /**
2555
+ * Checks the progress of a withdraw saver transaction.
2556
+ * @param txData - Transaction details response.
2557
+ * @param progress - Transaction progress object.
2558
+ */
2301
2559
  checkWithdrawSaverProgress(txData, progress) {
2302
2560
  var _a;
2303
2561
  return __awaiter(this, void 0, void 0, function* () {
2304
2562
  if (progress.inboundObserved) {
2563
+ // Extract memo fields
2305
2564
  const memo = (_a = txData.tx.tx.memo) !== null && _a !== void 0 ? _a : '';
2306
2565
  const memoFields = this.parseWithdrawLpMemo(memo);
2307
2566
  const asset = assetFromStringEx(memoFields.asset);
2567
+ // Get the last block object
2308
2568
  const lastBlockObj = yield this.thorchainCache.thornode.getLastBlock();
2309
2569
  const currentHeight = lastBlockObj.find((obj) => obj);
2310
- // find the date in which the asset should be seen in the wallet
2570
+ // Calculate expected confirmation date
2311
2571
  const outboundHeight = txData.tx.status === 'done' ? txData.finalised_height : Number(`${txData.outbound_height}`);
2312
2572
  const expectedConfirmationDate = yield this.blockToDate(THORChain, txData, outboundHeight); // always pass in thorchain
2573
+ // Extract output amount
2313
2574
  const outAmount = txData.out_txs ? JSON.stringify(txData.out_txs).split(`"amount":"`)[1].split(`"`) : '';
2575
+ // Extract relevant block heights and calculate estimated wait time
2314
2576
  const outboundBlock = Number(txData.outbound_height);
2315
2577
  const finalisedHeight = Number(txData.finalised_height);
2316
2578
  const currentTCHeight = Number(`${currentHeight === null || currentHeight === void 0 ? void 0 : currentHeight.thorchain}`);
@@ -2318,9 +2580,11 @@ class TransactionStage {
2318
2580
  ? (outboundBlock - currentTCHeight) * this.chainAttributes[THORChain].avgBlockTimeInSecs +
2319
2581
  this.chainAttributes[asset.chain].avgBlockTimeInSecs
2320
2582
  : 0;
2321
- // if the TC has process the block that the outbound tx was assigned to then its completed.
2583
+ // Determine transaction status
2322
2584
  const status = txData.out_txs ? WithdrawStatus.Complete : WithdrawStatus.Incomplete;
2585
+ // Get withdrawal amount
2323
2586
  const withdrawalAmount = yield this.getCryptoAmount(outAmount[0], asset);
2587
+ // Construct withdraw saver info object
2324
2588
  const withdrawSaverInfo = {
2325
2589
  status,
2326
2590
  withdrawalAmount,
@@ -2330,22 +2594,31 @@ class TransactionStage {
2330
2594
  outboundBlock,
2331
2595
  estimatedWaitTime,
2332
2596
  };
2597
+ // Assign withdraw saver info to progress object
2333
2598
  progress.withdrawSaverInfo = withdrawSaverInfo;
2334
2599
  }
2335
2600
  });
2336
2601
  }
2602
+ /**
2603
+ * Checks the progress of a refund transaction.
2604
+ * @param txData - Transaction details response.
2605
+ * @param progress - Transaction progress object.
2606
+ */
2337
2607
  checkRefund(txData, progress) {
2338
2608
  return __awaiter(this, void 0, void 0, function* () {
2339
2609
  if (progress.inboundObserved) {
2610
+ // Get the last block object
2340
2611
  const lastBlockObj = yield this.thorchainCache.thornode.getLastBlock();
2341
- // find the date in which the asset should be seen in the wallet
2612
+ // Calculate expected confirmation date
2342
2613
  const outboundHeight = txData.tx.status === 'done' ? txData.finalised_height : Number(`${txData.outbound_height}`);
2343
2614
  const expectedConfirmationDate = yield this.blockToDate(THORChain, txData, outboundHeight); // always pass in thorchain
2615
+ // Extract amount and asset
2344
2616
  const amount = txData.tx.tx.coins[0].amount;
2345
2617
  const asset = assetFromStringEx(txData.tx.tx.coins[0].asset);
2346
2618
  const toAddress = `${txData.tx.tx.to_address}`;
2347
2619
  const currentHeight = lastBlockObj.find((obj) => obj.chain === asset.chain);
2348
2620
  console.log(currentHeight);
2621
+ // Extract relevant block heights and calculate estimated wait time
2349
2622
  const outboundBlock = Number(`${currentHeight === null || currentHeight === void 0 ? void 0 : currentHeight.last_observed_in}`);
2350
2623
  const finalisedHeight = Number(txData.finalised_height);
2351
2624
  const currentTCHeight = Number(`${currentHeight === null || currentHeight === void 0 ? void 0 : currentHeight.thorchain}`);
@@ -2370,33 +2643,43 @@ class TransactionStage {
2370
2643
  }
2371
2644
  });
2372
2645
  }
2646
+ /**
2647
+ * Parses the memo of an add liquidity pool transaction.
2648
+ * @param memo - Memo string of the transaction.
2649
+ * @returns Parsed memo fields.
2650
+ */
2373
2651
  parseAddLpMemo(memo) {
2374
- //ADD:POOL:PAIREDADDR:AFFILIATE:FEE
2652
+ // Memo format: ADD:POOL:PAIREDADDR:AFFILIATE:FEE
2375
2653
  const parts = memo.split(`:`);
2376
2654
  const action = parts[0];
2377
2655
  const asset = parts[1];
2378
- //optional fields
2656
+ // Optional fields
2379
2657
  const pairedAddress = parts.length > 2 && parts[2].length > 0 ? parts[2] : undefined;
2380
2658
  const affiliateAddress = parts.length > 3 && parts[3].length > 0 ? parts[3] : undefined;
2381
2659
  const affiliateFee = parts.length > 4 && parts[4].length > 0 ? parts[4] : undefined;
2382
2660
  return { action, asset, pairedAddress, affiliateAddress, affiliateFee };
2383
2661
  }
2662
+ /**
2663
+ * Parses the memo of a withdraw liquidity pool transaction.
2664
+ * @param memo - Memo string of the transaction.
2665
+ * @returns Parsed memo fields.
2666
+ */
2384
2667
  parseWithdrawLpMemo(memo) {
2385
- //ADD:POOL:PAIREDADDR:AFFILIATE:FEE
2668
+ // Memo format: ADD:POOL:PAIREDADDR:AFFILIATE:FEE
2386
2669
  const parts = memo.split(`:`);
2387
2670
  const action = parts[0];
2388
2671
  const asset = parts[1];
2389
- //optional fields
2672
+ // Optional fields
2390
2673
  const pairedAddress = parts.length > 2 && parts[2].length > 0 ? parts[2] : undefined;
2391
2674
  const affiliateAddress = parts.length > 3 && parts[3].length > 0 ? parts[3] : undefined;
2392
2675
  const affiliateFee = parts.length > 4 && parts[4].length > 0 ? parts[4] : undefined;
2393
2676
  return { action, asset, pairedAddress, affiliateAddress, affiliateFee };
2394
2677
  }
2395
2678
  /**
2396
- * Private function to return the date stamp from block height and chain
2397
- * @param chain - input chain
2398
- * @param txData - txResponse
2399
- * @returns date()
2679
+ * Converts block height to date.
2680
+ * @param chain - Input chain.
2681
+ * @param txData - Transaction response data.
2682
+ * @returns Date object.
2400
2683
  */
2401
2684
  blockToDate(chain, txData, outboundBlock) {
2402
2685
  return __awaiter(this, void 0, void 0, function* () {
@@ -2421,7 +2704,7 @@ class TransactionStage {
2421
2704
  return time;
2422
2705
  }
2423
2706
  }
2424
- // find out how long ago it was processed for all chains
2707
+ // Find out how long ago it was processed for all chains
2425
2708
  if (chain == THORChain) {
2426
2709
  const currentHeight = lastBlockObj.find((obj) => obj);
2427
2710
  const thorchainHeight = Number(`${currentHeight === null || currentHeight === void 0 ? void 0 : currentHeight.thorchain}`); // current height of the TC
@@ -2438,9 +2721,9 @@ class TransactionStage {
2438
2721
  });
2439
2722
  }
2440
2723
  /**
2441
- * Returns current block height of an asset's native chain
2442
- * @param chain
2443
- * @returns
2724
+ * Returns the current block height of an asset's native chain.
2725
+ * @param asset - Asset for which block height is needed.
2726
+ * @returns Block height.
2444
2727
  */
2445
2728
  blockHeight(asset) {
2446
2729
  return __awaiter(this, void 0, void 0, function* () {