@xchainjs/xchain-thorchain-query 0.1.0-alpha1 → 0.1.0-beta1

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.
@@ -25,8 +25,8 @@ export declare class CryptoAmount {
25
25
  * This guard protects against trying to perform math with different assets
26
26
  *
27
27
  * Example.
28
- * const x = new CryptoAmount(baseAmount(1),AssetBTC)
29
- * const y = new CryptoAmount(baseAmount(1),AssetETH)
28
+ * const x = new CryptoAmount(assetAmount(1),AssetBTC)
29
+ * const y = new CryptoAmount(assetAmount(1),AssetETH)
30
30
  *
31
31
  * x.plus(y) <- will throw error "cannot perform math on 2 diff assets BTC.BTC ETH.ETH
32
32
  *
package/lib/index.esm.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { ObservedTxStatusEnum, TransactionsApi, Configuration as Configuration$1, QueueApi, NetworkApi, PoolsApi } from '@xchainjs/xchain-thornode';
2
- import { formatAssetAmountCurrency, baseToAsset, eqAsset, assetToString, baseAmount, AssetRuneNative, Chain, AssetAtom, AssetLUNA, AssetAVAX, AssetETH, AssetBNB, AssetDOGE, AssetLTC, AssetBCH, AssetBTC, AvalancheChain, TerraChain, DOGEChain, LTCChain, BCHChain, CosmosChain, THORChain, ETHChain, BTCChain, BNBChain, isAssetRuneNative, assetFromString, assetAmount, assetToBase } from '@xchainjs/xchain-util';
2
+ import { assetToBase, formatAssetAmountCurrency, baseToAsset, eqAsset, assetToString, baseAmount, AssetRuneNative, Chain, AssetAtom, AssetLUNA, AssetAVAX, AssetETH, AssetBNB, AssetDOGE, AssetLTC, AssetBCH, AssetBTC, AvalancheChain, TerraChain, DOGEChain, LTCChain, BCHChain, CosmosChain, THORChain, ETHChain, BTCChain, BNBChain, isAssetRuneNative, assetFromString, assetFromStringEx } from '@xchainjs/xchain-util';
3
3
  import BigNumber$1, { BigNumber } from 'bignumber.js';
4
4
  import { Network } from '@xchainjs/xchain-client';
5
5
  import { MidgardApi, Configuration } from '@xchainjs/xchain-midgard';
@@ -85,55 +85,55 @@ class CryptoAmount {
85
85
  }
86
86
  plus(v) {
87
87
  this.check(v);
88
- const baseAmountResult = this.baseAmount.plus(v.baseAmount);
89
- return new CryptoAmount(baseAmountResult, this.asset);
88
+ const assetAmountResult = assetToBase(this.assetAmount.plus(v.assetAmount));
89
+ return new CryptoAmount(assetAmountResult, this.asset);
90
90
  }
91
91
  minus(v) {
92
92
  this.check(v);
93
- const baseAmountResult = this.baseAmount.minus(v.baseAmount);
94
- return new CryptoAmount(baseAmountResult, this.asset);
93
+ const assetAmountResult = assetToBase(this.assetAmount.minus(v.assetAmount));
94
+ return new CryptoAmount(assetAmountResult, this.asset);
95
95
  }
96
96
  times(v) {
97
97
  this.check(v);
98
98
  if (v instanceof CryptoAmount) {
99
- const baseAmountResult = this.baseAmount.times(v.baseAmount);
100
- return new CryptoAmount(baseAmountResult, this.asset);
99
+ const assetAmountResult = assetToBase(this.assetAmount.times(v.assetAmount));
100
+ return new CryptoAmount(assetAmountResult, this.asset);
101
101
  }
102
102
  else {
103
- const baseAmountResult = this.baseAmount.times(v);
104
- return new CryptoAmount(baseAmountResult, this.asset);
103
+ const assetAmountResult = assetToBase(this.assetAmount.times(v));
104
+ return new CryptoAmount(assetAmountResult, this.asset);
105
105
  }
106
106
  }
107
107
  div(v) {
108
108
  this.check(v);
109
109
  if (v instanceof CryptoAmount) {
110
- const baseAmountResult = this.baseAmount.div(v.baseAmount);
111
- return new CryptoAmount(baseAmountResult, this.asset);
110
+ const assetAmountResult = assetToBase(this.assetAmount.div(v.assetAmount));
111
+ return new CryptoAmount(assetAmountResult, this.asset);
112
112
  }
113
113
  else {
114
- const baseAmountResult = this.baseAmount.div(v);
115
- return new CryptoAmount(baseAmountResult, this.asset);
114
+ const assetAmountResult = assetToBase(this.assetAmount.div(v));
115
+ return new CryptoAmount(assetAmountResult, this.asset);
116
116
  }
117
117
  }
118
118
  lt(v) {
119
119
  this.check(v);
120
- return this.baseAmount.lt(v.baseAmount);
120
+ return this.assetAmount.lt(v.assetAmount);
121
121
  }
122
122
  lte(v) {
123
123
  this.check(v);
124
- return this.baseAmount.lte(v.baseAmount);
124
+ return this.assetAmount.lte(v.assetAmount);
125
125
  }
126
126
  gt(v) {
127
127
  this.check(v);
128
- return this.baseAmount.gt(v.baseAmount);
128
+ return this.assetAmount.gt(v.assetAmount);
129
129
  }
130
130
  gte(v) {
131
131
  this.check(v);
132
- return this.baseAmount.gte(v.baseAmount);
132
+ return this.assetAmount.gte(v.assetAmount);
133
133
  }
134
134
  eq(v) {
135
135
  this.check(v);
136
- return this.baseAmount.eq(v.baseAmount);
136
+ return this.assetAmount.eq(v.assetAmount);
137
137
  }
138
138
  formatedAssetString() {
139
139
  return formatAssetAmountCurrency({
@@ -152,8 +152,8 @@ class CryptoAmount {
152
152
  * This guard protects against trying to perform math with different assets
153
153
  *
154
154
  * Example.
155
- * const x = new CryptoAmount(baseAmount(1),AssetBTC)
156
- * const y = new CryptoAmount(baseAmount(1),AssetETH)
155
+ * const x = new CryptoAmount(assetAmount(1),AssetBTC)
156
+ * const y = new CryptoAmount(assetAmount(1),AssetETH)
157
157
  *
158
158
  * x.plus(y) <- will throw error "cannot perform math on 2 diff assets BTC.BTC ETH.ETH
159
159
  *
@@ -178,6 +178,13 @@ var TxStage;
178
178
  TxStage[TxStage["OUTBOUND_CHAIN_CONFIRMED"] = 5] = "OUTBOUND_CHAIN_CONFIRMED";
179
179
  })(TxStage || (TxStage = {}));
180
180
 
181
+ const getBaseAmountWithDiffDecimals = (inputAmount, outDecimals) => {
182
+ const inDecimals = inputAmount.baseAmount.decimal;
183
+ let baseAmountOut = inputAmount.baseAmount.amount();
184
+ const adjustDecimals = outDecimals - inDecimals;
185
+ baseAmountOut = baseAmountOut.times(Math.pow(10, adjustDecimals));
186
+ return baseAmount(baseAmountOut, outDecimals).amount();
187
+ };
181
188
  /**
182
189
  *
183
190
  * @param inputAmount - amount to swap
@@ -188,16 +195,18 @@ var TxStage;
188
195
  const getSwapFee = (inputAmount, pool, toRune) => {
189
196
  // formula: (x * x * Y) / (x + X) ^ 2
190
197
  // const isInputRune = isAssetRuneNative(inputAmount.asset)
191
- const x = inputAmount.baseAmount.amount();
198
+ const x = getBaseAmountWithDiffDecimals(inputAmount, 8);
192
199
  const X = toRune ? pool.assetBalance.amount() : pool.runeBalance.amount(); // input is asset if toRune
193
200
  const Y = toRune ? pool.runeBalance.amount() : pool.assetBalance.amount(); // output is rune if toRune
194
201
  const units = toRune ? AssetRuneNative : pool.asset;
195
- const decimals = toRune || !pool.decimals ? 8 : pool.decimals;
196
202
  const numerator = x.times(x).multipliedBy(Y);
197
203
  const denominator = x.plus(X).pow(2);
198
204
  const result = numerator.div(denominator);
199
- const swapFee = new CryptoAmount(baseAmount(result, decimals), units);
200
- // console.log(` swapFee ${swapFee.assetAmountFixedString()} ${assetToString(units)}`)
205
+ const eightDecimalResult = new CryptoAmount(baseAmount(result), units);
206
+ const decimals = toRune ? 8 : inputAmount.baseAmount.decimal;
207
+ const baseOut = getBaseAmountWithDiffDecimals(eightDecimalResult, decimals);
208
+ const swapFee = new CryptoAmount(baseAmount(baseOut, decimals), units);
209
+ //console.log(` swapFee ${swapFee.assetAmountFixedString()} `)
201
210
  return swapFee;
202
211
  };
203
212
  /**
@@ -210,7 +219,7 @@ const getSwapFee = (inputAmount, pool, toRune) => {
210
219
  */
211
220
  const getSwapSlip = (inputAmount, pool, toRune) => {
212
221
  // formula: (x) / (x + X)
213
- const x = inputAmount.baseAmount.amount();
222
+ const x = getBaseAmountWithDiffDecimals(inputAmount, 8);
214
223
  const X = toRune ? pool.assetBalance.amount() : pool.runeBalance.amount(); // input is asset if toRune
215
224
  const result = x.div(x.plus(X));
216
225
  return new BigNumber(result);
@@ -224,15 +233,18 @@ const getSwapSlip = (inputAmount, pool, toRune) => {
224
233
  */
225
234
  const getSwapOutput = (inputAmount, pool, toRune) => {
226
235
  // formula: (x * X * Y) / (x + X) ^ 2
227
- const x = inputAmount.baseAmount.amount();
236
+ const x = getBaseAmountWithDiffDecimals(inputAmount, 8);
228
237
  const X = toRune ? pool.assetBalance.amount() : pool.runeBalance.amount(); // input is asset if toRune
229
238
  const Y = toRune ? pool.runeBalance.amount() : pool.assetBalance.amount(); // output is rune if toRune
230
239
  const units = toRune ? AssetRuneNative : pool.asset;
231
- const decimals = toRune || !pool.decimals ? 8 : pool.decimals;
240
+ // const decimals = toRune || !pool.decimals ? 8 : pool.decimals
232
241
  const numerator = x.times(X).times(Y);
233
242
  const denominator = x.plus(X).pow(2);
234
243
  const result = numerator.div(denominator);
235
- return new CryptoAmount(baseAmount(result, decimals), units);
244
+ const eightDecimalResult = new CryptoAmount(baseAmount(result), units);
245
+ const decimals = toRune ? 8 : inputAmount.baseAmount.decimal;
246
+ const baseOut = getBaseAmountWithDiffDecimals(eightDecimalResult, decimals);
247
+ return new CryptoAmount(baseAmount(baseOut, decimals), units);
236
248
  };
237
249
  const getDoubleSwapOutput = (inputAmount, pool1, pool2) => {
238
250
  // formula: getSwapOutput(pool1) => getSwapOutput(pool2)
@@ -329,10 +341,10 @@ const calcNetworkFee = (asset, gasRate) => {
329
341
  const gasRateinAVAXGwei = gasRate;
330
342
  const gasRateinAVAXWei = baseAmount(gasRateinAVAXGwei.multipliedBy(Math.pow(10, 9)), 18);
331
343
  if (eqAsset(asset, AssetAVAX)) {
332
- return new CryptoAmount(gasRateinAVAXWei.times(21000), AssetETH);
344
+ return new CryptoAmount(gasRateinAVAXWei.times(21000), AssetAVAX);
333
345
  }
334
346
  else {
335
- return new CryptoAmount(gasRateinAVAXWei.times(70000), AssetETH);
347
+ return new CryptoAmount(gasRateinAVAXWei.times(70000), AssetAVAX);
336
348
  }
337
349
  case Chain.Terra:
338
350
  return new CryptoAmount(baseAmount(gasRate), AssetLUNA);
@@ -536,18 +548,24 @@ class ThorchainQuery {
536
548
  */
537
549
  calcSwapEstimate(params, sourceInboundDetails, destinationInboundDetails) {
538
550
  return __awaiter(this, void 0, void 0, function* () {
539
- //NOTE need to convert the asset to 8 decimals places for all calcs
540
- const input = yield this.thorchainCache.convert(params.input, params.input.asset);
541
- const inputInRune = yield this.thorchainCache.convert(input, AssetRuneNative);
551
+ // NOTE need to convert the asset to 8 decimals places for all calcs
552
+ const DEFAULT_THORCHAIN_DECIMALS = 8;
553
+ // If input is already in 8 decimals skip the convert
554
+ const input = params.input.baseAmount.decimal === DEFAULT_THORCHAIN_DECIMALS
555
+ ? params.input
556
+ : yield this.thorchainCache.convert(params.input, params.input.asset);
557
+ // If asset is already rune native, skip the convert
558
+ const inputInRune = input.asset === AssetRuneNative ? input : yield this.thorchainCache.convert(input, AssetRuneNative);
542
559
  const inboundFeeInAsset = calcNetworkFee(input.asset, sourceInboundDetails.gas_rate);
543
560
  let outboundFeeInAsset = calcNetworkFee(params.destinationAsset, destinationInboundDetails.gas_rate);
544
561
  outboundFeeInAsset = outboundFeeInAsset.times(3);
562
+ // convert fees to rune
545
563
  const inboundFeeInRune = yield this.thorchainCache.convert(inboundFeeInAsset, AssetRuneNative);
546
564
  let outboundFeeInRune = yield this.thorchainCache.convert(outboundFeeInAsset, AssetRuneNative);
547
565
  // ---------- Remove Fees from inbound before doing the swap -----------
548
- // TODO confirm with chris about this change
549
- // const inputMinusInboundFeeInRune = inputInRune.minus(inboundFeeInRune)
550
- const inputMinusInboundFeeInRune = inputInRune;
566
+ // TODO confirm with chris about this change, was there a reason why this was commented out?
567
+ const inputMinusInboundFeeInRune = inputInRune.minus(inboundFeeInRune);
568
+ //>//const inputMinusInboundFeeInRune = inputInRune
551
569
  // remove any affiliateFee. netInput * affiliateFee (%age) of the destination asset type
552
570
  const affiliateFeeInRune = inputMinusInboundFeeInRune.times(params.affiliateFeePercent || 0);
553
571
  // remove the affiliate fee from the input.
@@ -567,7 +585,7 @@ class ThorchainQuery {
567
585
  outboundFeeInRune = yield this.convert(newFee, AssetRuneNative);
568
586
  }
569
587
  }
570
- // Now calculate swapfee based on inputNetAmount
588
+ // Now calculate swap output based on inputNetAmount
571
589
  const swapOutput = yield this.thorchainCache.getExpectedSwapOutput(inputNetInAsset, params.destinationAsset);
572
590
  const swapFeeInRune = yield this.thorchainCache.convert(swapOutput.swapFee, AssetRuneNative);
573
591
  const outputInRune = yield this.thorchainCache.convert(swapOutput.output, AssetRuneNative);
@@ -818,6 +836,8 @@ class ThorchainQuery {
818
836
  if (!pool)
819
837
  throw Error(`No pool found from memo`);
820
838
  const getAsset = assetFromString(pool[1].toUpperCase());
839
+ if (!getAsset)
840
+ throw Error(`Invalid pool asset`);
821
841
  // Retrieve thorchain blockHeight for the tx
822
842
  if (!((_b = txData.observed_tx.tx) === null || _b === void 0 ? void 0 : _b.id))
823
843
  throw Error('No action observed');
@@ -1024,12 +1044,15 @@ const TEN_MINUTES = 10 * 60 * 1000;
1024
1044
  const DEFAULT_THORCHAIN_DECIMALS = 8;
1025
1045
  const USD_ASSETS = {
1026
1046
  mainnet: [
1027
- assetFromString('BNB.BUSD-BD1'),
1028
- assetFromString('ETH.USDC-0XA0B86991C6218B36C1D19D4A2E9EB0CE3606EB48'),
1029
- assetFromString('ETH.USDT-0XDAC17F958D2EE523A2206206994597C13D831EC7'),
1047
+ assetFromStringEx('BNB.BUSD-BD1'),
1048
+ assetFromStringEx('ETH.USDC-0XA0B86991C6218B36C1D19D4A2E9EB0CE3606EB48'),
1049
+ assetFromStringEx('ETH.USDT-0XDAC17F958D2EE523A2206206994597C13D831EC7'),
1050
+ ],
1051
+ stagenet: [assetFromStringEx('ETH.USDT-0XDAC17F958D2EE523A2206206994597C13D831EC7')],
1052
+ testnet: [
1053
+ assetFromStringEx('BNB.BUSD-74E'),
1054
+ assetFromStringEx('ETH.USDT-0XA3910454BF2CB59B8B3A401589A3BACC5CA42306'),
1030
1055
  ],
1031
- stagenet: [assetFromString('ETH.USDT-0XDAC17F958D2EE523A2206206994597C13D831EC7')],
1032
- testnet: [assetFromString('BNB.BUSD-74E'), assetFromString('ETH.USDT-0XA3910454BF2CB59B8B3A401589A3BACC5CA42306')],
1033
1056
  };
1034
1057
  /**
1035
1058
  * This class manages retrieving information from up to date Thorchain
@@ -1250,23 +1273,35 @@ class ThorchainCache {
1250
1273
  * Ex. convert(input:100 BUSD, outAsset: BTC) -> 0.0001234 BTC
1251
1274
  *
1252
1275
  * @param input - amount/asset to convert to outAsset
1253
- * @param ouAsset - the Asset you want to convert to
1276
+ * @param outAsset - the Asset you want to convert to
1254
1277
  * @returns CryptoAmount of input
1255
1278
  */
1256
1279
  convert(input, outAsset) {
1257
- var _a;
1258
1280
  return __awaiter(this, void 0, void 0, function* () {
1259
1281
  const exchangeRate = yield this.getExchangeRate(input.asset, outAsset);
1260
- let decimals = DEFAULT_THORCHAIN_DECIMALS;
1261
- if (!isAssetRuneNative(outAsset)) {
1262
- const pool = yield this.getPoolForAsset(outAsset);
1263
- decimals = (_a = pool.decimals) !== null && _a !== void 0 ? _a : DEFAULT_THORCHAIN_DECIMALS;
1264
- }
1265
- const amt = assetAmount(input.assetAmount.times(exchangeRate).amount().toFixed(), decimals);
1266
- const result = new CryptoAmount(assetToBase(amt), outAsset);
1282
+ const outDecimals = yield this.getDecimalForAsset(outAsset);
1283
+ const inDecimals = input.baseAmount.decimal;
1284
+ let baseAmountOut = input.baseAmount.times(exchangeRate).amount();
1285
+ const adjustDecimals = outDecimals - inDecimals;
1286
+ baseAmountOut = baseAmountOut.times(Math.pow(10, adjustDecimals));
1287
+ const amt = baseAmount(baseAmountOut, outDecimals);
1288
+ const result = new CryptoAmount(amt, outAsset);
1289
+ // console.log(
1290
+ // `${input.formatedAssetString()} ${input.asset.ticker} = ${result.formatedAssetString()} ${outAsset.ticker}`,
1291
+ // )
1267
1292
  return result;
1268
1293
  });
1269
1294
  }
1295
+ getDecimalForAsset(asset) {
1296
+ var _a;
1297
+ return __awaiter(this, void 0, void 0, function* () {
1298
+ if (!isAssetRuneNative(asset)) {
1299
+ const pool = yield this.getPoolForAsset(asset);
1300
+ return (_a = pool.decimals) !== null && _a !== void 0 ? _a : DEFAULT_THORCHAIN_DECIMALS;
1301
+ }
1302
+ return DEFAULT_THORCHAIN_DECIMALS;
1303
+ });
1304
+ }
1270
1305
  getRouterAddressForChain(chain) {
1271
1306
  return __awaiter(this, void 0, void 0, function* () {
1272
1307
  const inboundAsgard = (yield this.getInboundAddressesItems())[chain];
@@ -1723,6 +1758,7 @@ class Thornode {
1723
1758
  return __awaiter(this, void 0, void 0, function* () {
1724
1759
  for (const api of this.poolsApi) {
1725
1760
  try {
1761
+ // console.log(console.log(JSON.stringify(api, null, 2)))
1726
1762
  const pools = yield api.pools();
1727
1763
  return pools.data;
1728
1764
  }
package/lib/index.js CHANGED
@@ -95,55 +95,55 @@ class CryptoAmount {
95
95
  }
96
96
  plus(v) {
97
97
  this.check(v);
98
- const baseAmountResult = this.baseAmount.plus(v.baseAmount);
99
- return new CryptoAmount(baseAmountResult, this.asset);
98
+ const assetAmountResult = xchainUtil.assetToBase(this.assetAmount.plus(v.assetAmount));
99
+ return new CryptoAmount(assetAmountResult, this.asset);
100
100
  }
101
101
  minus(v) {
102
102
  this.check(v);
103
- const baseAmountResult = this.baseAmount.minus(v.baseAmount);
104
- return new CryptoAmount(baseAmountResult, this.asset);
103
+ const assetAmountResult = xchainUtil.assetToBase(this.assetAmount.minus(v.assetAmount));
104
+ return new CryptoAmount(assetAmountResult, this.asset);
105
105
  }
106
106
  times(v) {
107
107
  this.check(v);
108
108
  if (v instanceof CryptoAmount) {
109
- const baseAmountResult = this.baseAmount.times(v.baseAmount);
110
- return new CryptoAmount(baseAmountResult, this.asset);
109
+ const assetAmountResult = xchainUtil.assetToBase(this.assetAmount.times(v.assetAmount));
110
+ return new CryptoAmount(assetAmountResult, this.asset);
111
111
  }
112
112
  else {
113
- const baseAmountResult = this.baseAmount.times(v);
114
- return new CryptoAmount(baseAmountResult, this.asset);
113
+ const assetAmountResult = xchainUtil.assetToBase(this.assetAmount.times(v));
114
+ return new CryptoAmount(assetAmountResult, this.asset);
115
115
  }
116
116
  }
117
117
  div(v) {
118
118
  this.check(v);
119
119
  if (v instanceof CryptoAmount) {
120
- const baseAmountResult = this.baseAmount.div(v.baseAmount);
121
- return new CryptoAmount(baseAmountResult, this.asset);
120
+ const assetAmountResult = xchainUtil.assetToBase(this.assetAmount.div(v.assetAmount));
121
+ return new CryptoAmount(assetAmountResult, this.asset);
122
122
  }
123
123
  else {
124
- const baseAmountResult = this.baseAmount.div(v);
125
- return new CryptoAmount(baseAmountResult, this.asset);
124
+ const assetAmountResult = xchainUtil.assetToBase(this.assetAmount.div(v));
125
+ return new CryptoAmount(assetAmountResult, this.asset);
126
126
  }
127
127
  }
128
128
  lt(v) {
129
129
  this.check(v);
130
- return this.baseAmount.lt(v.baseAmount);
130
+ return this.assetAmount.lt(v.assetAmount);
131
131
  }
132
132
  lte(v) {
133
133
  this.check(v);
134
- return this.baseAmount.lte(v.baseAmount);
134
+ return this.assetAmount.lte(v.assetAmount);
135
135
  }
136
136
  gt(v) {
137
137
  this.check(v);
138
- return this.baseAmount.gt(v.baseAmount);
138
+ return this.assetAmount.gt(v.assetAmount);
139
139
  }
140
140
  gte(v) {
141
141
  this.check(v);
142
- return this.baseAmount.gte(v.baseAmount);
142
+ return this.assetAmount.gte(v.assetAmount);
143
143
  }
144
144
  eq(v) {
145
145
  this.check(v);
146
- return this.baseAmount.eq(v.baseAmount);
146
+ return this.assetAmount.eq(v.assetAmount);
147
147
  }
148
148
  formatedAssetString() {
149
149
  return xchainUtil.formatAssetAmountCurrency({
@@ -162,8 +162,8 @@ class CryptoAmount {
162
162
  * This guard protects against trying to perform math with different assets
163
163
  *
164
164
  * Example.
165
- * const x = new CryptoAmount(baseAmount(1),AssetBTC)
166
- * const y = new CryptoAmount(baseAmount(1),AssetETH)
165
+ * const x = new CryptoAmount(assetAmount(1),AssetBTC)
166
+ * const y = new CryptoAmount(assetAmount(1),AssetETH)
167
167
  *
168
168
  * x.plus(y) <- will throw error "cannot perform math on 2 diff assets BTC.BTC ETH.ETH
169
169
  *
@@ -187,6 +187,13 @@ class CryptoAmount {
187
187
  TxStage[TxStage["OUTBOUND_CHAIN_CONFIRMED"] = 5] = "OUTBOUND_CHAIN_CONFIRMED";
188
188
  })(exports.TxStage || (exports.TxStage = {}));
189
189
 
190
+ const getBaseAmountWithDiffDecimals = (inputAmount, outDecimals) => {
191
+ const inDecimals = inputAmount.baseAmount.decimal;
192
+ let baseAmountOut = inputAmount.baseAmount.amount();
193
+ const adjustDecimals = outDecimals - inDecimals;
194
+ baseAmountOut = baseAmountOut.times(Math.pow(10, adjustDecimals));
195
+ return xchainUtil.baseAmount(baseAmountOut, outDecimals).amount();
196
+ };
190
197
  /**
191
198
  *
192
199
  * @param inputAmount - amount to swap
@@ -197,16 +204,18 @@ class CryptoAmount {
197
204
  const getSwapFee = (inputAmount, pool, toRune) => {
198
205
  // formula: (x * x * Y) / (x + X) ^ 2
199
206
  // const isInputRune = isAssetRuneNative(inputAmount.asset)
200
- const x = inputAmount.baseAmount.amount();
207
+ const x = getBaseAmountWithDiffDecimals(inputAmount, 8);
201
208
  const X = toRune ? pool.assetBalance.amount() : pool.runeBalance.amount(); // input is asset if toRune
202
209
  const Y = toRune ? pool.runeBalance.amount() : pool.assetBalance.amount(); // output is rune if toRune
203
210
  const units = toRune ? xchainUtil.AssetRuneNative : pool.asset;
204
- const decimals = toRune || !pool.decimals ? 8 : pool.decimals;
205
211
  const numerator = x.times(x).multipliedBy(Y);
206
212
  const denominator = x.plus(X).pow(2);
207
213
  const result = numerator.div(denominator);
208
- const swapFee = new CryptoAmount(xchainUtil.baseAmount(result, decimals), units);
209
- // console.log(` swapFee ${swapFee.assetAmountFixedString()} ${assetToString(units)}`)
214
+ const eightDecimalResult = new CryptoAmount(xchainUtil.baseAmount(result), units);
215
+ const decimals = toRune ? 8 : inputAmount.baseAmount.decimal;
216
+ const baseOut = getBaseAmountWithDiffDecimals(eightDecimalResult, decimals);
217
+ const swapFee = new CryptoAmount(xchainUtil.baseAmount(baseOut, decimals), units);
218
+ //console.log(` swapFee ${swapFee.assetAmountFixedString()} `)
210
219
  return swapFee;
211
220
  };
212
221
  /**
@@ -219,7 +228,7 @@ const getSwapFee = (inputAmount, pool, toRune) => {
219
228
  */
220
229
  const getSwapSlip = (inputAmount, pool, toRune) => {
221
230
  // formula: (x) / (x + X)
222
- const x = inputAmount.baseAmount.amount();
231
+ const x = getBaseAmountWithDiffDecimals(inputAmount, 8);
223
232
  const X = toRune ? pool.assetBalance.amount() : pool.runeBalance.amount(); // input is asset if toRune
224
233
  const result = x.div(x.plus(X));
225
234
  return new BigNumber.BigNumber(result);
@@ -233,15 +242,18 @@ const getSwapSlip = (inputAmount, pool, toRune) => {
233
242
  */
234
243
  const getSwapOutput = (inputAmount, pool, toRune) => {
235
244
  // formula: (x * X * Y) / (x + X) ^ 2
236
- const x = inputAmount.baseAmount.amount();
245
+ const x = getBaseAmountWithDiffDecimals(inputAmount, 8);
237
246
  const X = toRune ? pool.assetBalance.amount() : pool.runeBalance.amount(); // input is asset if toRune
238
247
  const Y = toRune ? pool.runeBalance.amount() : pool.assetBalance.amount(); // output is rune if toRune
239
248
  const units = toRune ? xchainUtil.AssetRuneNative : pool.asset;
240
- const decimals = toRune || !pool.decimals ? 8 : pool.decimals;
249
+ // const decimals = toRune || !pool.decimals ? 8 : pool.decimals
241
250
  const numerator = x.times(X).times(Y);
242
251
  const denominator = x.plus(X).pow(2);
243
252
  const result = numerator.div(denominator);
244
- return new CryptoAmount(xchainUtil.baseAmount(result, decimals), units);
253
+ const eightDecimalResult = new CryptoAmount(xchainUtil.baseAmount(result), units);
254
+ const decimals = toRune ? 8 : inputAmount.baseAmount.decimal;
255
+ const baseOut = getBaseAmountWithDiffDecimals(eightDecimalResult, decimals);
256
+ return new CryptoAmount(xchainUtil.baseAmount(baseOut, decimals), units);
245
257
  };
246
258
  const getDoubleSwapOutput = (inputAmount, pool1, pool2) => {
247
259
  // formula: getSwapOutput(pool1) => getSwapOutput(pool2)
@@ -338,10 +350,10 @@ const calcNetworkFee = (asset, gasRate) => {
338
350
  const gasRateinAVAXGwei = gasRate;
339
351
  const gasRateinAVAXWei = xchainUtil.baseAmount(gasRateinAVAXGwei.multipliedBy(Math.pow(10, 9)), 18);
340
352
  if (xchainUtil.eqAsset(asset, xchainUtil.AssetAVAX)) {
341
- return new CryptoAmount(gasRateinAVAXWei.times(21000), xchainUtil.AssetETH);
353
+ return new CryptoAmount(gasRateinAVAXWei.times(21000), xchainUtil.AssetAVAX);
342
354
  }
343
355
  else {
344
- return new CryptoAmount(gasRateinAVAXWei.times(70000), xchainUtil.AssetETH);
356
+ return new CryptoAmount(gasRateinAVAXWei.times(70000), xchainUtil.AssetAVAX);
345
357
  }
346
358
  case xchainUtil.Chain.Terra:
347
359
  return new CryptoAmount(xchainUtil.baseAmount(gasRate), xchainUtil.AssetLUNA);
@@ -545,18 +557,24 @@ class ThorchainQuery {
545
557
  */
546
558
  calcSwapEstimate(params, sourceInboundDetails, destinationInboundDetails) {
547
559
  return __awaiter(this, void 0, void 0, function* () {
548
- //NOTE need to convert the asset to 8 decimals places for all calcs
549
- const input = yield this.thorchainCache.convert(params.input, params.input.asset);
550
- const inputInRune = yield this.thorchainCache.convert(input, xchainUtil.AssetRuneNative);
560
+ // NOTE need to convert the asset to 8 decimals places for all calcs
561
+ const DEFAULT_THORCHAIN_DECIMALS = 8;
562
+ // If input is already in 8 decimals skip the convert
563
+ const input = params.input.baseAmount.decimal === DEFAULT_THORCHAIN_DECIMALS
564
+ ? params.input
565
+ : yield this.thorchainCache.convert(params.input, params.input.asset);
566
+ // If asset is already rune native, skip the convert
567
+ const inputInRune = input.asset === xchainUtil.AssetRuneNative ? input : yield this.thorchainCache.convert(input, xchainUtil.AssetRuneNative);
551
568
  const inboundFeeInAsset = calcNetworkFee(input.asset, sourceInboundDetails.gas_rate);
552
569
  let outboundFeeInAsset = calcNetworkFee(params.destinationAsset, destinationInboundDetails.gas_rate);
553
570
  outboundFeeInAsset = outboundFeeInAsset.times(3);
571
+ // convert fees to rune
554
572
  const inboundFeeInRune = yield this.thorchainCache.convert(inboundFeeInAsset, xchainUtil.AssetRuneNative);
555
573
  let outboundFeeInRune = yield this.thorchainCache.convert(outboundFeeInAsset, xchainUtil.AssetRuneNative);
556
574
  // ---------- Remove Fees from inbound before doing the swap -----------
557
- // TODO confirm with chris about this change
558
- // const inputMinusInboundFeeInRune = inputInRune.minus(inboundFeeInRune)
559
- const inputMinusInboundFeeInRune = inputInRune;
575
+ // TODO confirm with chris about this change, was there a reason why this was commented out?
576
+ const inputMinusInboundFeeInRune = inputInRune.minus(inboundFeeInRune);
577
+ //>//const inputMinusInboundFeeInRune = inputInRune
560
578
  // remove any affiliateFee. netInput * affiliateFee (%age) of the destination asset type
561
579
  const affiliateFeeInRune = inputMinusInboundFeeInRune.times(params.affiliateFeePercent || 0);
562
580
  // remove the affiliate fee from the input.
@@ -576,7 +594,7 @@ class ThorchainQuery {
576
594
  outboundFeeInRune = yield this.convert(newFee, xchainUtil.AssetRuneNative);
577
595
  }
578
596
  }
579
- // Now calculate swapfee based on inputNetAmount
597
+ // Now calculate swap output based on inputNetAmount
580
598
  const swapOutput = yield this.thorchainCache.getExpectedSwapOutput(inputNetInAsset, params.destinationAsset);
581
599
  const swapFeeInRune = yield this.thorchainCache.convert(swapOutput.swapFee, xchainUtil.AssetRuneNative);
582
600
  const outputInRune = yield this.thorchainCache.convert(swapOutput.output, xchainUtil.AssetRuneNative);
@@ -827,6 +845,8 @@ class ThorchainQuery {
827
845
  if (!pool)
828
846
  throw Error(`No pool found from memo`);
829
847
  const getAsset = xchainUtil.assetFromString(pool[1].toUpperCase());
848
+ if (!getAsset)
849
+ throw Error(`Invalid pool asset`);
830
850
  // Retrieve thorchain blockHeight for the tx
831
851
  if (!((_b = txData.observed_tx.tx) === null || _b === void 0 ? void 0 : _b.id))
832
852
  throw Error('No action observed');
@@ -1033,12 +1053,15 @@ const TEN_MINUTES = 10 * 60 * 1000;
1033
1053
  const DEFAULT_THORCHAIN_DECIMALS = 8;
1034
1054
  const USD_ASSETS = {
1035
1055
  mainnet: [
1036
- xchainUtil.assetFromString('BNB.BUSD-BD1'),
1037
- xchainUtil.assetFromString('ETH.USDC-0XA0B86991C6218B36C1D19D4A2E9EB0CE3606EB48'),
1038
- xchainUtil.assetFromString('ETH.USDT-0XDAC17F958D2EE523A2206206994597C13D831EC7'),
1056
+ xchainUtil.assetFromStringEx('BNB.BUSD-BD1'),
1057
+ xchainUtil.assetFromStringEx('ETH.USDC-0XA0B86991C6218B36C1D19D4A2E9EB0CE3606EB48'),
1058
+ xchainUtil.assetFromStringEx('ETH.USDT-0XDAC17F958D2EE523A2206206994597C13D831EC7'),
1059
+ ],
1060
+ stagenet: [xchainUtil.assetFromStringEx('ETH.USDT-0XDAC17F958D2EE523A2206206994597C13D831EC7')],
1061
+ testnet: [
1062
+ xchainUtil.assetFromStringEx('BNB.BUSD-74E'),
1063
+ xchainUtil.assetFromStringEx('ETH.USDT-0XA3910454BF2CB59B8B3A401589A3BACC5CA42306'),
1039
1064
  ],
1040
- stagenet: [xchainUtil.assetFromString('ETH.USDT-0XDAC17F958D2EE523A2206206994597C13D831EC7')],
1041
- testnet: [xchainUtil.assetFromString('BNB.BUSD-74E'), xchainUtil.assetFromString('ETH.USDT-0XA3910454BF2CB59B8B3A401589A3BACC5CA42306')],
1042
1065
  };
1043
1066
  /**
1044
1067
  * This class manages retrieving information from up to date Thorchain
@@ -1259,23 +1282,35 @@ class ThorchainCache {
1259
1282
  * Ex. convert(input:100 BUSD, outAsset: BTC) -> 0.0001234 BTC
1260
1283
  *
1261
1284
  * @param input - amount/asset to convert to outAsset
1262
- * @param ouAsset - the Asset you want to convert to
1285
+ * @param outAsset - the Asset you want to convert to
1263
1286
  * @returns CryptoAmount of input
1264
1287
  */
1265
1288
  convert(input, outAsset) {
1266
- var _a;
1267
1289
  return __awaiter(this, void 0, void 0, function* () {
1268
1290
  const exchangeRate = yield this.getExchangeRate(input.asset, outAsset);
1269
- let decimals = DEFAULT_THORCHAIN_DECIMALS;
1270
- if (!xchainUtil.isAssetRuneNative(outAsset)) {
1271
- const pool = yield this.getPoolForAsset(outAsset);
1272
- decimals = (_a = pool.decimals) !== null && _a !== void 0 ? _a : DEFAULT_THORCHAIN_DECIMALS;
1273
- }
1274
- const amt = xchainUtil.assetAmount(input.assetAmount.times(exchangeRate).amount().toFixed(), decimals);
1275
- const result = new CryptoAmount(xchainUtil.assetToBase(amt), outAsset);
1291
+ const outDecimals = yield this.getDecimalForAsset(outAsset);
1292
+ const inDecimals = input.baseAmount.decimal;
1293
+ let baseAmountOut = input.baseAmount.times(exchangeRate).amount();
1294
+ const adjustDecimals = outDecimals - inDecimals;
1295
+ baseAmountOut = baseAmountOut.times(Math.pow(10, adjustDecimals));
1296
+ const amt = xchainUtil.baseAmount(baseAmountOut, outDecimals);
1297
+ const result = new CryptoAmount(amt, outAsset);
1298
+ // console.log(
1299
+ // `${input.formatedAssetString()} ${input.asset.ticker} = ${result.formatedAssetString()} ${outAsset.ticker}`,
1300
+ // )
1276
1301
  return result;
1277
1302
  });
1278
1303
  }
1304
+ getDecimalForAsset(asset) {
1305
+ var _a;
1306
+ return __awaiter(this, void 0, void 0, function* () {
1307
+ if (!xchainUtil.isAssetRuneNative(asset)) {
1308
+ const pool = yield this.getPoolForAsset(asset);
1309
+ return (_a = pool.decimals) !== null && _a !== void 0 ? _a : DEFAULT_THORCHAIN_DECIMALS;
1310
+ }
1311
+ return DEFAULT_THORCHAIN_DECIMALS;
1312
+ });
1313
+ }
1279
1314
  getRouterAddressForChain(chain) {
1280
1315
  return __awaiter(this, void 0, void 0, function* () {
1281
1316
  const inboundAsgard = (yield this.getInboundAddressesItems())[chain];
@@ -1732,6 +1767,7 @@ class Thornode {
1732
1767
  return __awaiter(this, void 0, void 0, function* () {
1733
1768
  for (const api of this.poolsApi) {
1734
1769
  try {
1770
+ // console.log(console.log(JSON.stringify(api, null, 2)))
1735
1771
  const pools = yield api.pools();
1736
1772
  return pools.data;
1737
1773
  }
@@ -99,10 +99,11 @@ export declare class ThorchainCache {
99
99
  * Ex. convert(input:100 BUSD, outAsset: BTC) -> 0.0001234 BTC
100
100
  *
101
101
  * @param input - amount/asset to convert to outAsset
102
- * @param ouAsset - the Asset you want to convert to
102
+ * @param outAsset - the Asset you want to convert to
103
103
  * @returns CryptoAmount of input
104
104
  */
105
105
  convert(input: CryptoAmount, outAsset: Asset): Promise<CryptoAmount>;
106
+ private getDecimalForAsset;
106
107
  getRouterAddressForChain(chain: Chain): Promise<Address>;
107
108
  getInboundAddressesItems(): Promise<Record<string, InboundAddressesItem>>;
108
109
  getInboundDetails(): Promise<Record<string, InboundDetail>>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xchainjs/xchain-thorchain-query",
3
- "version": "0.1.0-alpha1",
3
+ "version": "0.1.0-beta1",
4
4
  "license": "MIT",
5
5
  "description": "Thorchain query module that is resposible for estimating swap calculations and add/remove liquidity for thorchain ",
6
6
  "keywords": [
@@ -33,20 +33,20 @@
33
33
  "postversion": "git push --follow-tags"
34
34
  },
35
35
  "devDependencies": {
36
- "@xchainjs/xchain-client": "^0.13.0",
36
+ "@xchainjs/xchain-client": "^0.13.1",
37
37
  "@xchainjs/xchain-midgard": "^0.1.0-alpha2",
38
38
  "@xchainjs/xchain-thornode": "^0.1.0-alpha4",
39
- "@xchainjs/xchain-util": "^0.9.0",
39
+ "@xchainjs/xchain-util": "^0.10.0",
40
40
  "axios": "^0.25.0",
41
41
  "axios-retry": "^3.2.5",
42
42
  "bignumber.js": "^9.0.0",
43
43
  "rimraf": "~3.0.2"
44
44
  },
45
45
  "peerDependencies": {
46
- "@xchainjs/xchain-client": "^0.13.0",
46
+ "@xchainjs/xchain-client": "^0.13.1",
47
47
  "@xchainjs/xchain-midgard": "^0.1.0-alpha2",
48
48
  "@xchainjs/xchain-thornode": "^0.1.0-alpha4",
49
- "@xchainjs/xchain-util": "^0.9.0",
49
+ "@xchainjs/xchain-util": "^0.10.0",
50
50
  "axios": "^0.25.0",
51
51
  "axios-retry": "^3.2.5",
52
52
  "bignumber.js": "^9.0.0",