@xchainjs/xchain-thorchain-query 0.1.0 → 0.1.2

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
@@ -1,7 +1,7 @@
1
1
  import { ObservedTxStatusEnum, TransactionsApi, Configuration as Configuration$1, QueueApi, NetworkApi, PoolsApi, LiquidityProvidersApi } from '@xchainjs/xchain-thornode';
2
- import { assetToBase, formatAssetAmountCurrency, baseToAsset, eqAsset, assetToString, baseAmount as baseAmount$1, AssetRuneNative as AssetRuneNative$1, Chain, AssetAtom, AssetLUNA, AssetAVAX, AssetETH, AssetBNB, AssetDOGE, AssetLTC, AssetBCH, AssetBTC, AvalancheChain, TerraChain, DOGEChain, LTCChain, BCHChain, CosmosChain, THORChain, ETHChain, BTCChain, BNBChain, isAssetRuneNative, assetFromString, assetAmount, assetFromStringEx } from '@xchainjs/xchain-util';
2
+ import { assetToBase, formatAssetAmountCurrency, baseToAsset, eqAsset, assetToString, baseAmount, AssetRuneNative, Chain, AssetAtom, AssetAVAX, AssetETH, AssetBNB, AssetDOGE, AssetLTC, AssetBCH, AssetBTC, AvalancheChain, DOGEChain, LTCChain, BCHChain, CosmosChain, THORChain, ETHChain, BTCChain, BNBChain, isAssetRuneNative, assetFromString, assetAmount, assetFromStringEx } from '@xchainjs/xchain-util';
3
3
  import { BigNumber } from 'bignumber.js';
4
- import { baseAmount, AssetRuneNative } from '@xchainjs/xchain-util/lib';
4
+ import { baseAmount as baseAmount$1, AssetRuneNative as AssetRuneNative$1 } from '@xchainjs/xchain-util/lib';
5
5
  import { Network } from '@xchainjs/xchain-client';
6
6
  import { MidgardApi, Configuration } from '@xchainjs/xchain-midgard';
7
7
  import axios from 'axios';
@@ -61,10 +61,6 @@ const DefaultChainAttributes = {
61
61
  blockReward: 0,
62
62
  avgBlockTimeInSecs: 6,
63
63
  },
64
- TERRA: {
65
- blockReward: 0,
66
- avgBlockTimeInSecs: 0,
67
- },
68
64
  BNB: {
69
65
  blockReward: 0,
70
66
  avgBlockTimeInSecs: 6,
@@ -177,114 +173,14 @@ var TxStage;
177
173
  TxStage[TxStage["OUTBOUND_QUEUED"] = 3] = "OUTBOUND_QUEUED";
178
174
  TxStage[TxStage["OUTBOUND_CHAIN_UNCONFIRMED"] = 4] = "OUTBOUND_CHAIN_UNCONFIRMED";
179
175
  TxStage[TxStage["OUTBOUND_CHAIN_CONFIRMED"] = 5] = "OUTBOUND_CHAIN_CONFIRMED";
180
- })(TxStage || (TxStage = {}));
181
- // export type LiquidityProvider = {
182
- // asset: string
183
- // rune_address: string
184
- // asset_address: string
185
- // last_add_height: number
186
- // last_withdraw_height: number
187
- // units: number
188
- // pending_rune: number
189
- // pending_asset: number
190
- // pending_tx_Id: string
191
- // rune_deposit_value: number
192
- // asset_deposit_value: number
193
- // }
194
-
195
- /**
196
- * https://dev.thorchain.org/thorchain-dev/interface-guide/math#lp-units-add
197
- * @param liquidity - asset amount added
198
- * @param pool - pool depths
199
- * @returns liquidity units - ownership of pool
200
- */
201
- const getLiquidityUnits = (liquidity, pool) => {
202
- const P = new BigNumber(pool.pool.liquidityUnits);
203
- const r = liquidity.rune.amount();
204
- const a = liquidity.asset.amount();
205
- const R = pool.runeBalance.amount();
206
- const A = pool.assetBalance.amount();
207
- const part1 = R.times(a);
208
- const part2 = r.times(A);
209
- const numerator = P.times(part1.plus(part2));
210
- const denominator = R.times(A).times(2);
211
- const result = numerator.div(denominator);
212
- return result;
213
- };
214
- /**
215
- *
216
- * @param unitData - units for both asset and rune
217
- * @param pool - pool that the asset is bound to
218
- * @returns - pool share of both asset and rune in percentage
219
- */
220
- const getPoolShare = (unitData, pool) => {
221
- // formula: (rune * part) / total; (asset * part) / total
222
- const units = unitData.liquidityUnits.amount();
223
- const total = unitData.totalUnits.amount();
224
- const R = pool.runeBalance.amount();
225
- const T = pool.assetBalance.amount();
226
- const asset = T.times(units).div(total);
227
- const rune = R.times(units).div(total);
228
- const poolShareDetail = {
229
- assetShare: new CryptoAmount(baseAmount(asset), pool.asset),
230
- runeShare: new CryptoAmount(baseAmount(rune), AssetRuneNative),
231
- };
232
- return poolShareDetail;
233
- };
234
- /**
235
- *
236
- * @param poolShare - the share of asset and rune added to the pool
237
- * @param pool - Pool that the asset is attached to
238
- * @returns - returns bignumber representing a slip percentage
239
- */
240
- const getSlipOnLiquidity = (stake, pool) => {
241
- // formula: (t * R - T * r)/ (T*r + R*T)
242
- const r = stake.rune.amount();
243
- const t = stake.asset.amount();
244
- const R = pool.runeBalance.amount();
245
- const T = pool.assetBalance.amount();
246
- const numerator = t.times(R).minus(T.times(r));
247
- const denominator = T.times(r).plus(R.times(T));
248
- const result = numerator.div(denominator).abs();
249
- return result;
250
- };
251
- /**
252
- * https://docs.thorchain.org/thorchain-finance/continuous-liquidity-pools#impermanent-loss-protection
253
- * @param poolShare - the share of asset and rune added to the pool
254
- * @param pool - Pool that the asset is attached to
255
- * @param block - blockl object with current, last added and the constant blocksforlossProtection
256
- * @returns
257
- */
258
- // Blocks for full protection 1440000 // 100 days
259
- const getLiquidityProtectionData = (depositValue, poolShare, block) => {
260
- //Coverage formula coverage=((A0∗P1)+R0)−((A1∗P1)+R1)=>((A0∗R1/A1)+R0)−(R1+R1)
261
- //formula: protectionProgress (currentHeight-heightLastAdded)/blocksforfullprotection
262
- const R0 = depositValue.rune.amount(); // rune deposit value
263
- const A0 = depositValue.asset.amount(); // asset deposit value
264
- const R1 = poolShare.runeShare.baseAmount.amount(); // rune amount to redeem
265
- const A1 = poolShare.assetShare.baseAmount.amount(); // asset amount to redeem
266
- const P1 = R1.div(A1); // Pool ratio at withdrawal
267
- const part1 = A0.times(P1).plus(R0).minus(A1.times(P1).plus(R1)); // start position minus end position
268
- const part2 = A0.times(R1.div(A1)).plus(R0).minus(R1.plus(R1)); // different way to check position
269
- const coverage = part1 >= part2 ? part1 : part2; // Coverage represents how much ILP a LP is entitled to
270
- const currentHeight = block.current;
271
- const heightLastAdded = block.lastAdded || 0; //default to zero if undefined
272
- const blocksforfullprotection = block.fullProtection;
273
- const protectionProgress = (currentHeight - heightLastAdded) / blocksforfullprotection; // percentage of entitlement
274
- const result = coverage.times(protectionProgress); // impermanent loss protection result
275
- const ILProtection = {
276
- ILProtection: new CryptoAmount(baseAmount(result), AssetRuneNative),
277
- totalDays: (protectionProgress * 100).toFixed(2),
278
- };
279
- return ILProtection;
280
- };
176
+ })(TxStage || (TxStage = {}));
281
177
 
282
178
  const getBaseAmountWithDiffDecimals = (inputAmount, outDecimals) => {
283
179
  const inDecimals = inputAmount.baseAmount.decimal;
284
180
  let baseAmountOut = inputAmount.baseAmount.amount();
285
181
  const adjustDecimals = outDecimals - inDecimals;
286
182
  baseAmountOut = baseAmountOut.times(Math.pow(10, adjustDecimals));
287
- return baseAmount$1(baseAmountOut, outDecimals).amount();
183
+ return baseAmount(baseAmountOut, outDecimals).amount();
288
184
  };
289
185
  /**
290
186
  *
@@ -299,14 +195,14 @@ const getSwapFee = (inputAmount, pool, toRune) => {
299
195
  const x = getBaseAmountWithDiffDecimals(inputAmount, 8);
300
196
  const X = toRune ? pool.assetBalance.amount() : pool.runeBalance.amount(); // input is asset if toRune
301
197
  const Y = toRune ? pool.runeBalance.amount() : pool.assetBalance.amount(); // output is rune if toRune
302
- const units = toRune ? AssetRuneNative$1 : pool.asset;
198
+ const units = toRune ? AssetRuneNative : pool.asset;
303
199
  const numerator = x.times(x).multipliedBy(Y);
304
200
  const denominator = x.plus(X).pow(2);
305
201
  const result = numerator.div(denominator);
306
- const eightDecimalResult = new CryptoAmount(baseAmount$1(result), units);
202
+ const eightDecimalResult = new CryptoAmount(baseAmount(result), units);
307
203
  const decimals = toRune ? 8 : inputAmount.baseAmount.decimal;
308
204
  const baseOut = getBaseAmountWithDiffDecimals(eightDecimalResult, decimals);
309
- const swapFee = new CryptoAmount(baseAmount$1(baseOut, decimals), units);
205
+ const swapFee = new CryptoAmount(baseAmount(baseOut, decimals), units);
310
206
  //console.log(` swapFee ${swapFee.assetAmountFixedString()} `)
311
207
  return swapFee;
312
208
  };
@@ -337,15 +233,15 @@ const getSwapOutput = (inputAmount, pool, toRune) => {
337
233
  const x = getBaseAmountWithDiffDecimals(inputAmount, 8);
338
234
  const X = toRune ? pool.assetBalance.amount() : pool.runeBalance.amount(); // input is asset if toRune
339
235
  const Y = toRune ? pool.runeBalance.amount() : pool.assetBalance.amount(); // output is rune if toRune
340
- const units = toRune ? AssetRuneNative$1 : pool.asset;
236
+ const units = toRune ? AssetRuneNative : pool.asset;
341
237
  // const decimals = toRune || !pool.decimals ? 8 : pool.decimals
342
238
  const numerator = x.times(X).times(Y);
343
239
  const denominator = x.plus(X).pow(2);
344
240
  const result = numerator.div(denominator);
345
- const eightDecimalResult = new CryptoAmount(baseAmount$1(result), units);
241
+ const eightDecimalResult = new CryptoAmount(baseAmount(result), units);
346
242
  const decimals = toRune ? 8 : inputAmount.baseAmount.decimal;
347
243
  const baseOut = getBaseAmountWithDiffDecimals(eightDecimalResult, decimals);
348
- return new CryptoAmount(baseAmount$1(baseOut, decimals), units);
244
+ return new CryptoAmount(baseAmount(baseOut, decimals), units);
349
245
  };
350
246
  const getDoubleSwapOutput = (inputAmount, pool1, pool2) => {
351
247
  // formula: getSwapOutput(pool1) => getSwapOutput(pool2)
@@ -382,7 +278,7 @@ const getDoubleSwapFee = (inputAmount, pool1, pool2, thorchainCache) => __awaite
382
278
  const fee1InRune = getSwapFee(inputAmount, pool1, true);
383
279
  const swapOutput = getSwapOutput(inputAmount, pool1, true);
384
280
  const fee2InAsset = getSwapFee(swapOutput, pool2, false);
385
- const fee2InRune = yield thorchainCache.convert(fee2InAsset, AssetRuneNative$1);
281
+ const fee2InRune = yield thorchainCache.convert(fee2InAsset, AssetRuneNative);
386
282
  const result = fee1InRune.plus(fee2InRune);
387
283
  return result;
388
284
  });
@@ -415,23 +311,23 @@ const getDoubleSwap = (inputAmount, pool1, pool2, thorchainCache) => __awaiter(v
415
311
  */
416
312
  const calcNetworkFee = (asset, inbound) => {
417
313
  if (asset.synth)
418
- return new CryptoAmount(baseAmount$1(2000000), AssetRuneNative$1);
314
+ return new CryptoAmount(baseAmount(2000000), AssetRuneNative);
419
315
  switch (asset.chain) {
420
316
  case Chain.Bitcoin:
421
- return new CryptoAmount(baseAmount$1(inbound.gasRate.multipliedBy(inbound.outboundTxSize)), AssetBTC);
317
+ return new CryptoAmount(baseAmount(inbound.gasRate.multipliedBy(inbound.outboundTxSize)), AssetBTC);
422
318
  case Chain.BitcoinCash:
423
- return new CryptoAmount(baseAmount$1(inbound.gasRate.multipliedBy(inbound.outboundTxSize)), AssetBCH);
319
+ return new CryptoAmount(baseAmount(inbound.gasRate.multipliedBy(inbound.outboundTxSize)), AssetBCH);
424
320
  case Chain.Litecoin:
425
- return new CryptoAmount(baseAmount$1(inbound.gasRate.multipliedBy(inbound.outboundTxSize)), AssetLTC);
321
+ return new CryptoAmount(baseAmount(inbound.gasRate.multipliedBy(inbound.outboundTxSize)), AssetLTC);
426
322
  case Chain.Doge:
427
323
  // NOTE: UTXO chains estimate fees with a 250 byte size
428
- return new CryptoAmount(baseAmount$1(inbound.gasRate.multipliedBy(inbound.outboundTxSize)), AssetDOGE);
324
+ return new CryptoAmount(baseAmount(inbound.gasRate.multipliedBy(inbound.outboundTxSize)), AssetDOGE);
429
325
  case Chain.Binance:
430
326
  //flat fee
431
- return new CryptoAmount(baseAmount$1(inbound.gasRate), AssetBNB);
327
+ return new CryptoAmount(baseAmount(inbound.gasRate), AssetBNB);
432
328
  case Chain.Ethereum:
433
329
  const gasRateinETHGwei = inbound.gasRate;
434
- const gasRateinETHWei = baseAmount$1(gasRateinETHGwei.multipliedBy(Math.pow(10, 9)), 18);
330
+ const gasRateinETHWei = baseAmount(gasRateinETHGwei.multipliedBy(Math.pow(10, 9)), 18);
435
331
  if (eqAsset(asset, AssetETH)) {
436
332
  return new CryptoAmount(gasRateinETHWei.times(21000), AssetETH);
437
333
  }
@@ -440,19 +336,17 @@ const calcNetworkFee = (asset, inbound) => {
440
336
  }
441
337
  case Chain.Avalanche:
442
338
  const gasRateinAVAXGwei = inbound.gasRate;
443
- const gasRateinAVAXWei = baseAmount$1(gasRateinAVAXGwei.multipliedBy(Math.pow(10, 9)), 18);
339
+ const gasRateinAVAXWei = baseAmount(gasRateinAVAXGwei.multipliedBy(Math.pow(10, 9)), 18);
444
340
  if (eqAsset(asset, AssetAVAX)) {
445
341
  return new CryptoAmount(gasRateinAVAXWei.times(21000), AssetAVAX);
446
342
  }
447
343
  else {
448
344
  return new CryptoAmount(gasRateinAVAXWei.times(70000), AssetAVAX);
449
345
  }
450
- case Chain.Terra:
451
- return new CryptoAmount(baseAmount$1(inbound.gasRate), AssetLUNA);
452
346
  case Chain.Cosmos:
453
- return new CryptoAmount(baseAmount$1(inbound.gasRate), AssetAtom);
347
+ return new CryptoAmount(baseAmount(inbound.gasRate), AssetAtom);
454
348
  case Chain.THORChain:
455
- return new CryptoAmount(baseAmount$1(2000000), AssetRuneNative$1);
349
+ return new CryptoAmount(baseAmount(2000000), AssetRuneNative);
456
350
  }
457
351
  throw new Error(`could not calculate inbound fee for ${asset.chain}`);
458
352
  };
@@ -470,7 +364,7 @@ const getChainAsset = (chain) => {
470
364
  case ETHChain:
471
365
  return AssetETH;
472
366
  case THORChain:
473
- return AssetRuneNative$1;
367
+ return AssetRuneNative;
474
368
  case CosmosChain:
475
369
  return AssetAtom;
476
370
  case BCHChain:
@@ -479,8 +373,6 @@ const getChainAsset = (chain) => {
479
373
  return AssetLTC;
480
374
  case DOGEChain:
481
375
  return AssetDOGE;
482
- case TerraChain:
483
- return AssetLUNA;
484
376
  case AvalancheChain:
485
377
  return AssetAVAX;
486
378
  default:
@@ -510,14 +402,100 @@ const getChain = (chain) => {
510
402
  return LTCChain;
511
403
  case 'DOGE':
512
404
  return DOGEChain;
513
- case 'TERRA':
514
- return TerraChain;
515
405
  default:
516
406
  throw Error('Unknown chain');
517
407
  }
518
408
  };
519
409
 
520
- // import { Network } from '@xchainjs/xchain-client'
410
+ /**
411
+ * https://dev.thorchain.org/thorchain-dev/interface-guide/math#lp-units-add
412
+ * @param liquidity - asset amount added
413
+ * @param pool - pool depths
414
+ * @returns liquidity units - ownership of pool
415
+ */
416
+ const getLiquidityUnits = (liquidity, pool) => {
417
+ const baseAmount8decimals = getBaseAmountWithDiffDecimals(liquidity.asset, 8);
418
+ const P = new BigNumber(pool.pool.liquidityUnits);
419
+ const r = liquidity.rune.baseAmount.amount();
420
+ const a = baseAmount8decimals;
421
+ const R = pool.runeBalance.amount();
422
+ const A = pool.assetBalance.amount();
423
+ const part1 = R.times(a);
424
+ const part2 = r.times(A);
425
+ const numerator = P.times(part1.plus(part2));
426
+ const denominator = R.times(A).times(2);
427
+ const result = numerator.div(denominator);
428
+ return result;
429
+ };
430
+ /**
431
+ *
432
+ * @param unitData - units for both asset and rune
433
+ * @param pool - pool that the asset is bound to
434
+ * @returns - pool share of both asset and rune in percentage
435
+ */
436
+ const getPoolShare = (unitData, pool) => {
437
+ // formula: (rune * part) / total; (asset * part) / total
438
+ const units = unitData.liquidityUnits;
439
+ const total = unitData.totalUnits;
440
+ const R = pool.runeBalance.amount();
441
+ const T = pool.assetBalance.amount();
442
+ const asset = T.times(units).div(total);
443
+ const rune = R.times(units).div(total);
444
+ const poolShareDetail = {
445
+ assetShare: new CryptoAmount(baseAmount$1(asset), pool.asset),
446
+ runeShare: new CryptoAmount(baseAmount$1(rune), AssetRuneNative$1),
447
+ };
448
+ return poolShareDetail;
449
+ };
450
+ /**
451
+ *
452
+ * @param poolShare - the share of asset and rune added to the pool
453
+ * @param pool - Pool that the asset is attached to
454
+ * @returns - returns bignumber representing a slip percentage
455
+ */
456
+ const getSlipOnLiquidity = (stake, pool) => {
457
+ const baseAmount8decimals = getBaseAmountWithDiffDecimals(stake.asset, pool.decimals);
458
+ // formula: (t * R - T * r)/ (T*r + R*T)
459
+ const r = stake.rune.baseAmount.amount();
460
+ const t = baseAmount8decimals;
461
+ const R = pool.runeBalance.amount();
462
+ const T = pool.assetBalance.amount();
463
+ const numerator = t.times(R).minus(T.times(r));
464
+ const denominator = T.times(r).plus(R.times(T));
465
+ const result = numerator.div(denominator).abs();
466
+ return result;
467
+ };
468
+ /**
469
+ * https://docs.thorchain.org/thorchain-finance/continuous-liquidity-pools#impermanent-loss-protection
470
+ * @param poolShare - the share of asset and rune added to the pool
471
+ * @param pool - Pool that the asset is attached to
472
+ * @param block - blockl object with current, last added and the constant blocksforlossProtection
473
+ * @returns
474
+ */
475
+ // Blocks for full protection 1440000 // 100 days
476
+ const getLiquidityProtectionData = (depositValue, poolShare, block) => {
477
+ //Coverage formula coverage=((A0∗P1)+R0)−((A1∗P1)+R1)=>((A0∗R1/A1)+R0)−(R1+R1)
478
+ //formula: protectionProgress (currentHeight-heightLastAdded)/blocksforfullprotection
479
+ const R0 = depositValue.rune.amount(); // rune deposit value
480
+ const A0 = depositValue.asset.amount(); // asset deposit value
481
+ const R1 = poolShare.runeShare.baseAmount.amount(); // rune amount to redeem
482
+ const A1 = poolShare.assetShare.baseAmount.amount(); // asset amount to redeem
483
+ const P1 = R1.div(A1); // Pool ratio at withdrawal
484
+ const part1 = A0.times(P1).plus(R0).minus(A1.times(P1).plus(R1)); // start position minus end position
485
+ const part2 = A0.times(R1.div(A1)).plus(R0).minus(R1.plus(R1)); // different way to check position
486
+ const coverage = part1 >= part2 ? part1 : part2; // Coverage represents how much ILP a LP is entitled to
487
+ const currentHeight = block.current;
488
+ const heightLastAdded = block.lastAdded || 0; //default to zero if undefined
489
+ const blocksforfullprotection = block.fullProtection;
490
+ const protectionProgress = (currentHeight - heightLastAdded) / blocksforfullprotection; // percentage of entitlement
491
+ const result = coverage.times(protectionProgress); // impermanent loss protection result
492
+ const ILProtection = {
493
+ ILProtection: new CryptoAmount(baseAmount$1(result), AssetRuneNative$1),
494
+ totalDays: (protectionProgress * 100).toFixed(2),
495
+ };
496
+ return ILProtection;
497
+ };
498
+
521
499
  const BN_1 = new BigNumber(1);
522
500
  /**
523
501
  * THORChain Class for interacting with THORChain.
@@ -557,9 +535,7 @@ class ThorchainQuery {
557
535
  });
558
536
  const inboundDetails = yield this.thorchainCache.getInboundDetails();
559
537
  const sourceInboundDetails = inboundDetails[input.asset.chain];
560
- // console.log(JSON.stringify(sourceInboundDetails, null, 2))
561
538
  const destinationInboundDetails = inboundDetails[destinationAsset.chain];
562
- // console.log(JSON.stringify(destinationInboundDetails, null, 2))
563
539
  const swapEstimate = yield this.calcSwapEstimate({
564
540
  input,
565
541
  destinationAsset,
@@ -656,13 +632,13 @@ class ThorchainQuery {
656
632
  ? params.input
657
633
  : yield this.thorchainCache.convert(params.input, params.input.asset);
658
634
  // If asset is already rune native, skip the convert
659
- const inputInRune = input.asset === AssetRuneNative$1 ? input : yield this.thorchainCache.convert(input, AssetRuneNative$1);
635
+ const inputInRune = input.asset === AssetRuneNative ? input : yield this.thorchainCache.convert(input, AssetRuneNative);
660
636
  const inboundFeeInAsset = calcNetworkFee(input.asset, sourceInboundDetails);
661
637
  // Retrieve outbound fee from inboundAddressDetails.
662
- const outboundFeeInAsset = new CryptoAmount(baseAmount$1(destinationInboundDetails.outboundFee), params.destinationAsset);
638
+ const outboundFeeInAsset = new CryptoAmount(baseAmount(destinationInboundDetails.outboundFee), params.destinationAsset);
663
639
  // convert fees to rune
664
- const inboundFeeInRune = yield this.thorchainCache.convert(inboundFeeInAsset, AssetRuneNative$1);
665
- let outboundFeeInRune = yield this.thorchainCache.convert(outboundFeeInAsset, AssetRuneNative$1);
640
+ const inboundFeeInRune = yield this.thorchainCache.convert(inboundFeeInAsset, AssetRuneNative);
641
+ let outboundFeeInRune = yield this.thorchainCache.convert(outboundFeeInAsset, AssetRuneNative);
666
642
  // ---------- Remove Fees from inbound before doing the swap -----------
667
643
  // TODO confirm with chris about this change, was there a reason why this was commented out?
668
644
  const inputMinusInboundFeeInRune = inputInRune.minus(inboundFeeInRune);
@@ -678,18 +654,18 @@ class ThorchainQuery {
678
654
  const deepestUSDPOOL = yield this.thorchainCache.getDeepestUSDPool();
679
655
  const usdAsset = deepestUSDPOOL.asset;
680
656
  const networkValues = yield this.thorchainCache.midgard.getNetworkValues();
681
- const usdMinFee = new CryptoAmount(baseAmount$1(networkValues['MINIMUML1OUTBOUNDFEEUSD']), usdAsset);
657
+ const usdMinFee = new CryptoAmount(baseAmount(networkValues['MINIMUML1OUTBOUNDFEEUSD']), usdAsset);
682
658
  // const FeeInUSD = await this.convert(outboundFeeInRune, usdAsset)
683
659
  const checkOutboundFee = (yield this.convert(outboundFeeInRune, usdAsset)).gte(usdMinFee);
684
660
  if (!checkOutboundFee) {
685
661
  const newFee = usdMinFee;
686
- outboundFeeInRune = yield this.convert(newFee, AssetRuneNative$1);
662
+ outboundFeeInRune = yield this.convert(newFee, AssetRuneNative);
687
663
  }
688
664
  }
689
665
  // Now calculate swap output based on inputNetAmount
690
666
  const swapOutput = yield this.thorchainCache.getExpectedSwapOutput(inputNetInAsset, params.destinationAsset);
691
- const swapFeeInRune = yield this.thorchainCache.convert(swapOutput.swapFee, AssetRuneNative$1);
692
- const outputInRune = yield this.thorchainCache.convert(swapOutput.output, AssetRuneNative$1);
667
+ const swapFeeInRune = yield this.thorchainCache.convert(swapOutput.swapFee, AssetRuneNative);
668
+ const outputInRune = yield this.thorchainCache.convert(swapOutput.output, AssetRuneNative);
693
669
  // ---------------- Remove Outbound Fee ---------------------- /
694
670
  const netOutputInRune = outputInRune.minus(outboundFeeInRune);
695
671
  const netOutputInAsset = yield this.thorchainCache.convert(netOutputInRune, params.destinationAsset);
@@ -790,8 +766,8 @@ class ThorchainQuery {
790
766
  checkCoverFees(params, estimate) {
791
767
  return __awaiter(this, void 0, void 0, function* () {
792
768
  let result = undefined;
793
- const inputInRune = yield this.thorchainCache.convert(params.input, AssetRuneNative$1);
794
- const feesInRune = yield this.getFeesIn(estimate.totalFees, AssetRuneNative$1);
769
+ const inputInRune = yield this.thorchainCache.convert(params.input, AssetRuneNative);
770
+ const feesInRune = yield this.getFeesIn(estimate.totalFees, AssetRuneNative);
795
771
  const totalSwapFeesInRune = feesInRune.inboundFee
796
772
  .plus(feesInRune.outboundFee)
797
773
  .plus(feesInRune.swapFee)
@@ -878,15 +854,15 @@ class ThorchainQuery {
878
854
  outboundDelay(outboundAmount) {
879
855
  return __awaiter(this, void 0, void 0, function* () {
880
856
  const networkValues = yield this.thorchainCache.getNetworkValues();
881
- const minTxOutVolumeThreshold = new CryptoAmount(baseAmount$1(networkValues['MINTXOUTVOLUMETHRESHOLD']), AssetRuneNative$1);
857
+ const minTxOutVolumeThreshold = new CryptoAmount(baseAmount(networkValues['MINTXOUTVOLUMETHRESHOLD']), AssetRuneNative);
882
858
  const maxTxOutOffset = networkValues['MAXTXOUTOFFSET'];
883
- let txOutDelayRate = new CryptoAmount(baseAmount$1(networkValues['TXOUTDELAYRATE']), AssetRuneNative$1).assetAmount
859
+ let txOutDelayRate = new CryptoAmount(baseAmount(networkValues['TXOUTDELAYRATE']), AssetRuneNative).assetAmount
884
860
  .amount()
885
861
  .toNumber();
886
862
  const getScheduledOutboundValue = yield this.thorchainCache.midgard.getScheduledOutboundValue();
887
863
  const thorChainblocktime = this.chainAttributes[Chain.THORChain].avgBlockTimeInSecs; // blocks required to confirm tx
888
864
  // If asset is equal to Rune set runeValue as outbound amount else set it to the asset's value in rune
889
- const runeValue = yield this.thorchainCache.convert(outboundAmount, AssetRuneNative$1);
865
+ const runeValue = yield this.thorchainCache.convert(outboundAmount, AssetRuneNative);
890
866
  // Check rune value amount
891
867
  if (runeValue.lt(minTxOutVolumeThreshold)) {
892
868
  return thorChainblocktime;
@@ -1129,18 +1105,18 @@ class ThorchainQuery {
1129
1105
  if (!isAssetRuneNative(params.rune.asset))
1130
1106
  errors.push('params.rune must be THOR.RUNE');
1131
1107
  const assetPool = yield this.thorchainCache.getPoolForAsset(params.asset.asset);
1132
- const lpUnits = getLiquidityUnits({ asset: params.asset.baseAmount, rune: params.rune.baseAmount }, assetPool);
1108
+ const lpUnits = getLiquidityUnits({ asset: params.asset, rune: params.rune }, assetPool);
1133
1109
  const inboundDetails = yield this.thorchainCache.getInboundDetails();
1134
1110
  const unitData = {
1135
- liquidityUnits: baseAmount$1(lpUnits),
1136
- totalUnits: baseAmount$1(assetPool.pool.liquidityUnits),
1111
+ liquidityUnits: lpUnits,
1112
+ totalUnits: new BigNumber(assetPool.pool.liquidityUnits),
1137
1113
  };
1138
1114
  const poolShare = getPoolShare(unitData, assetPool);
1139
1115
  const assetWaitTimeSeconds = yield this.confCounting(params.asset);
1140
1116
  const runeWaitTimeSeconds = yield this.confCounting(params.rune);
1141
1117
  const waitTimeSeconds = assetWaitTimeSeconds > runeWaitTimeSeconds ? assetWaitTimeSeconds : runeWaitTimeSeconds;
1142
- let assetInboundFee = new CryptoAmount(baseAmount$1(0), params.asset.asset);
1143
- let runeInboundFee = new CryptoAmount(baseAmount$1(0), AssetRuneNative$1);
1118
+ let assetInboundFee = new CryptoAmount(baseAmount(0), params.asset.asset);
1119
+ let runeInboundFee = new CryptoAmount(baseAmount(0), AssetRuneNative);
1144
1120
  if (!params.asset.assetAmount.eq(0)) {
1145
1121
  assetInboundFee = calcNetworkFee(params.asset.asset, inboundDetails[params.asset.asset.chain]);
1146
1122
  if (assetInboundFee.assetAmount.amount().times(3).gt(params.asset.assetAmount.amount()))
@@ -1151,12 +1127,13 @@ class ThorchainQuery {
1151
1127
  if (runeInboundFee.assetAmount.amount().times(3).gt(params.rune.assetAmount.amount()))
1152
1128
  errors.push(`Rune amount is less than fees`);
1153
1129
  }
1154
- const totalFees = (yield this.convert(assetInboundFee, AssetRuneNative$1)).plus(runeInboundFee);
1155
- const slip = getSlipOnLiquidity({ asset: params.asset.baseAmount, rune: params.rune.baseAmount }, assetPool);
1130
+ const totalFees = (yield this.convert(assetInboundFee, AssetRuneNative)).plus(runeInboundFee);
1131
+ const slip = getSlipOnLiquidity({ asset: params.asset, rune: params.rune }, assetPool);
1156
1132
  const estimateLP = {
1133
+ assetPool: assetPool.pool.asset,
1157
1134
  slipPercent: slip.times(100),
1158
1135
  poolShare: poolShare,
1159
- lpUnits: baseAmount$1(lpUnits),
1136
+ lpUnits: baseAmount(lpUnits),
1160
1137
  runeToAssetRatio: assetPool.runeToAssetRatio,
1161
1138
  transactionFee: {
1162
1139
  assetFee: assetInboundFee,
@@ -1180,6 +1157,8 @@ class ThorchainQuery {
1180
1157
  const poolAsset = yield this.thorchainCache.getPoolForAsset(asset);
1181
1158
  if (!poolAsset)
1182
1159
  throw Error(`Could not find pool for ${asset}`);
1160
+ if (!assetOrRuneAddress)
1161
+ throw Error(`No address provided ${assetOrRuneAddress}`);
1183
1162
  const liquidityProvider = yield this.thorchainCache.thornode.getLiquidityProvider(poolAsset.assetString, assetOrRuneAddress);
1184
1163
  if (!liquidityProvider)
1185
1164
  throw Error(`Could not find LP for ${assetOrRuneAddress}`);
@@ -1189,8 +1168,8 @@ class ThorchainQuery {
1189
1168
  throw Error(`Could not get block data`);
1190
1169
  // Pools total units & Lp's total units
1191
1170
  const unitData = {
1192
- totalUnits: baseAmount$1(poolAsset.pool.liquidityUnits),
1193
- liquidityUnits: baseAmount$1(liquidityProvider.units),
1171
+ totalUnits: new BigNumber(poolAsset.pool.liquidityUnits),
1172
+ liquidityUnits: new BigNumber(liquidityProvider.units),
1194
1173
  };
1195
1174
  //console.log(`unit data`, unitData.totalUnits.amount().toNumber(), unitData.liquidityUnits.amount().toNumber())
1196
1175
  const networkValues = yield this.thorchainCache.midgard.getNetworkValues();
@@ -1201,8 +1180,8 @@ class ThorchainQuery {
1201
1180
  };
1202
1181
  //
1203
1182
  const currentLP = {
1204
- asset: baseAmount$1(liquidityProvider.asset_deposit_value),
1205
- rune: baseAmount$1(liquidityProvider.rune_deposit_value),
1183
+ asset: baseAmount(liquidityProvider.asset_deposit_value),
1184
+ rune: baseAmount(liquidityProvider.rune_deposit_value),
1206
1185
  };
1207
1186
  const poolShare = getPoolShare(unitData, poolAsset);
1208
1187
  // console.log(poolShare.assetShare.toNumber(), poolShare.runeShare.toNumber())
@@ -1238,22 +1217,21 @@ class ThorchainQuery {
1238
1217
  estimateWithdrawLP(params) {
1239
1218
  return __awaiter(this, void 0, void 0, function* () {
1240
1219
  // Caution Dust Limits: BTC,BCH,LTC chains 10k sats; DOGE 1m Sats; ETH 0 wei; THOR 0 RUNE.
1241
- if (!params.assetAddress)
1242
- throw Error(`can't estimate lp without an asset address`);
1243
- const memberDetail = yield this.checkLiquidityPosition(params.asset, params.assetAddress);
1220
+ const assetOrRuneAddress = params.assetAddress ? params.assetAddress : params.runeAddress;
1221
+ const memberDetail = yield this.checkLiquidityPosition(params.asset, assetOrRuneAddress);
1244
1222
  const dustValues = yield this.getDustValues(params.asset); // returns asset and rune dust values
1245
1223
  const assetPool = yield this.thorchainCache.getPoolForAsset(params.asset);
1246
1224
  // get pool share from unit data
1247
1225
  const poolShare = getPoolShare({
1248
- liquidityUnits: baseAmount$1(memberDetail.position.units),
1249
- totalUnits: baseAmount$1(assetPool.pool.liquidityUnits),
1226
+ liquidityUnits: new BigNumber(memberDetail.position.units),
1227
+ totalUnits: new BigNumber(assetPool.pool.liquidityUnits),
1250
1228
  }, assetPool);
1251
1229
  // calculate total fees
1252
- const totalFees = (yield this.convert(dustValues.asset, AssetRuneNative$1)).plus(dustValues.rune);
1230
+ const totalFees = (yield this.convert(dustValues.asset, AssetRuneNative)).plus(dustValues.rune);
1253
1231
  // get slip on liquidity removal
1254
1232
  const slip = getSlipOnLiquidity({
1255
- asset: poolShare.assetShare.baseAmount,
1256
- rune: poolShare.runeShare.baseAmount,
1233
+ asset: poolShare.assetShare,
1234
+ rune: poolShare.runeShare,
1257
1235
  }, assetPool);
1258
1236
  // TODO make sure we compare wait times for withdrawing both rune and asset OR just rune OR just asset
1259
1237
  const waitTimeSecondsForAsset = yield this.confCounting(poolShare.assetShare.div(params.percentage / 100));
@@ -1269,6 +1247,8 @@ class ThorchainQuery {
1269
1247
  waitTimeSeconds = waitTimeSecondsForRune;
1270
1248
  }
1271
1249
  const estimateLP = {
1250
+ assetAddress: memberDetail.position.asset_address,
1251
+ runeAddress: memberDetail.position.rune_address,
1272
1252
  slipPercent: slip.times(100),
1273
1253
  transactionFee: {
1274
1254
  assetFee: dustValues.asset,
@@ -1279,6 +1259,7 @@ class ThorchainQuery {
1279
1259
  runeAmount: poolShare.runeShare,
1280
1260
  estimatedWaitSeconds: waitTimeSeconds,
1281
1261
  impermanentLossProtection: memberDetail.impermanentLossProtection,
1262
+ assetPool: assetPool.pool.asset,
1282
1263
  };
1283
1264
  return estimateLP;
1284
1265
  });
@@ -1295,42 +1276,42 @@ class ThorchainQuery {
1295
1276
  case 'BNB':
1296
1277
  dustValues = {
1297
1278
  asset: new CryptoAmount(assetToBase(assetAmount(0.000001)), AssetBNB),
1298
- rune: new CryptoAmount(assetToBase(assetAmount(0)), AssetRuneNative$1),
1279
+ rune: new CryptoAmount(assetToBase(assetAmount(0)), AssetRuneNative),
1299
1280
  };
1300
1281
  return dustValues;
1301
1282
  case 'BTC' :
1302
1283
  // 10k sats
1303
1284
  dustValues = {
1304
1285
  asset: new CryptoAmount(assetToBase(assetAmount(0.0001)), asset),
1305
- rune: new CryptoAmount(assetToBase(assetAmount(0)), AssetRuneNative$1),
1286
+ rune: new CryptoAmount(assetToBase(assetAmount(0)), AssetRuneNative),
1306
1287
  };
1307
1288
  return dustValues;
1308
1289
  case 'ETH':
1309
1290
  // 0 wei
1310
1291
  dustValues = {
1311
1292
  asset: new CryptoAmount(assetToBase(assetAmount(0)), asset),
1312
- rune: new CryptoAmount(assetToBase(assetAmount(0)), AssetRuneNative$1),
1293
+ rune: new CryptoAmount(assetToBase(assetAmount(0)), AssetRuneNative),
1313
1294
  };
1314
1295
  return dustValues;
1315
1296
  case 'THOR':
1316
1297
  // 0 Rune
1317
1298
  dustValues = {
1318
1299
  asset: new CryptoAmount(assetToBase(assetAmount(0)), asset),
1319
- rune: new CryptoAmount(assetToBase(assetAmount(0)), AssetRuneNative$1),
1300
+ rune: new CryptoAmount(assetToBase(assetAmount(0)), AssetRuneNative),
1320
1301
  };
1321
1302
  return dustValues;
1322
1303
  case 'GAIA':
1323
1304
  // 0 GAIA
1324
1305
  dustValues = {
1325
1306
  asset: new CryptoAmount(assetToBase(assetAmount(0)), asset),
1326
- rune: new CryptoAmount(assetToBase(assetAmount(0)), AssetRuneNative$1),
1307
+ rune: new CryptoAmount(assetToBase(assetAmount(0)), AssetRuneNative),
1327
1308
  };
1328
1309
  return dustValues;
1329
1310
  case 'DOGE':
1330
1311
  // 1 million sats
1331
1312
  dustValues = {
1332
1313
  asset: new CryptoAmount(assetToBase(assetAmount(0.01)), asset),
1333
- rune: new CryptoAmount(assetToBase(assetAmount(0)), AssetRuneNative$1),
1314
+ rune: new CryptoAmount(assetToBase(assetAmount(0)), AssetRuneNative),
1334
1315
  };
1335
1316
  return dustValues;
1336
1317
  default:
@@ -1352,8 +1333,8 @@ class LiquidityPool {
1352
1333
  this.asset = asset;
1353
1334
  this.decimals = decimals;
1354
1335
  this.assetString = this.pool.asset;
1355
- this.assetBalance = baseAmount$1(this.pool.assetDepth);
1356
- this.runeBalance = baseAmount$1(this.pool.runeDepth);
1336
+ this.assetBalance = baseAmount(this.pool.assetDepth);
1337
+ this.runeBalance = baseAmount(this.pool.runeDepth);
1357
1338
  this.runeToAssetRatio = this.runeBalance.amount().div(this.assetBalance.amount());
1358
1339
  this.assetToRuneRatio = this.assetBalance.amount().div(this.runeBalance.amount());
1359
1340
  }
@@ -1651,7 +1632,7 @@ class ThorchainCache {
1651
1632
  let baseAmountOut = input.baseAmount.times(exchangeRate).amount();
1652
1633
  const adjustDecimals = outDecimals - inDecimals;
1653
1634
  baseAmountOut = baseAmountOut.times(Math.pow(10, adjustDecimals));
1654
- const amt = baseAmount$1(baseAmountOut, outDecimals);
1635
+ const amt = baseAmount(baseAmountOut, outDecimals);
1655
1636
  const result = new CryptoAmount(amt, outAsset);
1656
1637
  // console.log(
1657
1638
  // `${input.formatedAssetString()} ${input.asset.ticker} = ${result.formatedAssetString()} ${outAsset.ticker}`,
@@ -1855,7 +1836,7 @@ class Midgard {
1855
1836
  for (const baseUrl of this.config.midgardBaseUrls) {
1856
1837
  try {
1857
1838
  const { data } = yield axios.get(`${baseUrl}${path}`);
1858
- const value = new CryptoAmount(baseAmount$1(data['scheduled_outbound_value']), AssetRuneNative$1);
1839
+ const value = new CryptoAmount(baseAmount(data['scheduled_outbound_value']), AssetRuneNative);
1859
1840
  return value;
1860
1841
  }
1861
1842
  catch (e) {
package/lib/index.js CHANGED
@@ -70,10 +70,6 @@ const DefaultChainAttributes = {
70
70
  blockReward: 0,
71
71
  avgBlockTimeInSecs: 6,
72
72
  },
73
- TERRA: {
74
- blockReward: 0,
75
- avgBlockTimeInSecs: 0,
76
- },
77
73
  BNB: {
78
74
  blockReward: 0,
79
75
  avgBlockTimeInSecs: 6,
@@ -185,107 +181,7 @@ class CryptoAmount {
185
181
  TxStage[TxStage["OUTBOUND_QUEUED"] = 3] = "OUTBOUND_QUEUED";
186
182
  TxStage[TxStage["OUTBOUND_CHAIN_UNCONFIRMED"] = 4] = "OUTBOUND_CHAIN_UNCONFIRMED";
187
183
  TxStage[TxStage["OUTBOUND_CHAIN_CONFIRMED"] = 5] = "OUTBOUND_CHAIN_CONFIRMED";
188
- })(exports.TxStage || (exports.TxStage = {}));
189
- // export type LiquidityProvider = {
190
- // asset: string
191
- // rune_address: string
192
- // asset_address: string
193
- // last_add_height: number
194
- // last_withdraw_height: number
195
- // units: number
196
- // pending_rune: number
197
- // pending_asset: number
198
- // pending_tx_Id: string
199
- // rune_deposit_value: number
200
- // asset_deposit_value: number
201
- // }
202
-
203
- /**
204
- * https://dev.thorchain.org/thorchain-dev/interface-guide/math#lp-units-add
205
- * @param liquidity - asset amount added
206
- * @param pool - pool depths
207
- * @returns liquidity units - ownership of pool
208
- */
209
- const getLiquidityUnits = (liquidity, pool) => {
210
- const P = new bignumber_js.BigNumber(pool.pool.liquidityUnits);
211
- const r = liquidity.rune.amount();
212
- const a = liquidity.asset.amount();
213
- const R = pool.runeBalance.amount();
214
- const A = pool.assetBalance.amount();
215
- const part1 = R.times(a);
216
- const part2 = r.times(A);
217
- const numerator = P.times(part1.plus(part2));
218
- const denominator = R.times(A).times(2);
219
- const result = numerator.div(denominator);
220
- return result;
221
- };
222
- /**
223
- *
224
- * @param unitData - units for both asset and rune
225
- * @param pool - pool that the asset is bound to
226
- * @returns - pool share of both asset and rune in percentage
227
- */
228
- const getPoolShare = (unitData, pool) => {
229
- // formula: (rune * part) / total; (asset * part) / total
230
- const units = unitData.liquidityUnits.amount();
231
- const total = unitData.totalUnits.amount();
232
- const R = pool.runeBalance.amount();
233
- const T = pool.assetBalance.amount();
234
- const asset = T.times(units).div(total);
235
- const rune = R.times(units).div(total);
236
- const poolShareDetail = {
237
- assetShare: new CryptoAmount(lib.baseAmount(asset), pool.asset),
238
- runeShare: new CryptoAmount(lib.baseAmount(rune), lib.AssetRuneNative),
239
- };
240
- return poolShareDetail;
241
- };
242
- /**
243
- *
244
- * @param poolShare - the share of asset and rune added to the pool
245
- * @param pool - Pool that the asset is attached to
246
- * @returns - returns bignumber representing a slip percentage
247
- */
248
- const getSlipOnLiquidity = (stake, pool) => {
249
- // formula: (t * R - T * r)/ (T*r + R*T)
250
- const r = stake.rune.amount();
251
- const t = stake.asset.amount();
252
- const R = pool.runeBalance.amount();
253
- const T = pool.assetBalance.amount();
254
- const numerator = t.times(R).minus(T.times(r));
255
- const denominator = T.times(r).plus(R.times(T));
256
- const result = numerator.div(denominator).abs();
257
- return result;
258
- };
259
- /**
260
- * https://docs.thorchain.org/thorchain-finance/continuous-liquidity-pools#impermanent-loss-protection
261
- * @param poolShare - the share of asset and rune added to the pool
262
- * @param pool - Pool that the asset is attached to
263
- * @param block - blockl object with current, last added and the constant blocksforlossProtection
264
- * @returns
265
- */
266
- // Blocks for full protection 1440000 // 100 days
267
- const getLiquidityProtectionData = (depositValue, poolShare, block) => {
268
- //Coverage formula coverage=((A0∗P1)+R0)−((A1∗P1)+R1)=>((A0∗R1/A1)+R0)−(R1+R1)
269
- //formula: protectionProgress (currentHeight-heightLastAdded)/blocksforfullprotection
270
- const R0 = depositValue.rune.amount(); // rune deposit value
271
- const A0 = depositValue.asset.amount(); // asset deposit value
272
- const R1 = poolShare.runeShare.baseAmount.amount(); // rune amount to redeem
273
- const A1 = poolShare.assetShare.baseAmount.amount(); // asset amount to redeem
274
- const P1 = R1.div(A1); // Pool ratio at withdrawal
275
- const part1 = A0.times(P1).plus(R0).minus(A1.times(P1).plus(R1)); // start position minus end position
276
- const part2 = A0.times(R1.div(A1)).plus(R0).minus(R1.plus(R1)); // different way to check position
277
- const coverage = part1 >= part2 ? part1 : part2; // Coverage represents how much ILP a LP is entitled to
278
- const currentHeight = block.current;
279
- const heightLastAdded = block.lastAdded || 0; //default to zero if undefined
280
- const blocksforfullprotection = block.fullProtection;
281
- const protectionProgress = (currentHeight - heightLastAdded) / blocksforfullprotection; // percentage of entitlement
282
- const result = coverage.times(protectionProgress); // impermanent loss protection result
283
- const ILProtection = {
284
- ILProtection: new CryptoAmount(lib.baseAmount(result), lib.AssetRuneNative),
285
- totalDays: (protectionProgress * 100).toFixed(2),
286
- };
287
- return ILProtection;
288
- };
184
+ })(exports.TxStage || (exports.TxStage = {}));
289
185
 
290
186
  const getBaseAmountWithDiffDecimals = (inputAmount, outDecimals) => {
291
187
  const inDecimals = inputAmount.baseAmount.decimal;
@@ -455,8 +351,6 @@ const calcNetworkFee = (asset, inbound) => {
455
351
  else {
456
352
  return new CryptoAmount(gasRateinAVAXWei.times(70000), xchainUtil.AssetAVAX);
457
353
  }
458
- case xchainUtil.Chain.Terra:
459
- return new CryptoAmount(xchainUtil.baseAmount(inbound.gasRate), xchainUtil.AssetLUNA);
460
354
  case xchainUtil.Chain.Cosmos:
461
355
  return new CryptoAmount(xchainUtil.baseAmount(inbound.gasRate), xchainUtil.AssetAtom);
462
356
  case xchainUtil.Chain.THORChain:
@@ -487,8 +381,6 @@ const getChainAsset = (chain) => {
487
381
  return xchainUtil.AssetLTC;
488
382
  case xchainUtil.DOGEChain:
489
383
  return xchainUtil.AssetDOGE;
490
- case xchainUtil.TerraChain:
491
- return xchainUtil.AssetLUNA;
492
384
  case xchainUtil.AvalancheChain:
493
385
  return xchainUtil.AssetAVAX;
494
386
  default:
@@ -518,14 +410,100 @@ const getChain = (chain) => {
518
410
  return xchainUtil.LTCChain;
519
411
  case 'DOGE':
520
412
  return xchainUtil.DOGEChain;
521
- case 'TERRA':
522
- return xchainUtil.TerraChain;
523
413
  default:
524
414
  throw Error('Unknown chain');
525
415
  }
526
416
  };
527
417
 
528
- // import { Network } from '@xchainjs/xchain-client'
418
+ /**
419
+ * https://dev.thorchain.org/thorchain-dev/interface-guide/math#lp-units-add
420
+ * @param liquidity - asset amount added
421
+ * @param pool - pool depths
422
+ * @returns liquidity units - ownership of pool
423
+ */
424
+ const getLiquidityUnits = (liquidity, pool) => {
425
+ const baseAmount8decimals = getBaseAmountWithDiffDecimals(liquidity.asset, 8);
426
+ const P = new bignumber_js.BigNumber(pool.pool.liquidityUnits);
427
+ const r = liquidity.rune.baseAmount.amount();
428
+ const a = baseAmount8decimals;
429
+ const R = pool.runeBalance.amount();
430
+ const A = pool.assetBalance.amount();
431
+ const part1 = R.times(a);
432
+ const part2 = r.times(A);
433
+ const numerator = P.times(part1.plus(part2));
434
+ const denominator = R.times(A).times(2);
435
+ const result = numerator.div(denominator);
436
+ return result;
437
+ };
438
+ /**
439
+ *
440
+ * @param unitData - units for both asset and rune
441
+ * @param pool - pool that the asset is bound to
442
+ * @returns - pool share of both asset and rune in percentage
443
+ */
444
+ const getPoolShare = (unitData, pool) => {
445
+ // formula: (rune * part) / total; (asset * part) / total
446
+ const units = unitData.liquidityUnits;
447
+ const total = unitData.totalUnits;
448
+ const R = pool.runeBalance.amount();
449
+ const T = pool.assetBalance.amount();
450
+ const asset = T.times(units).div(total);
451
+ const rune = R.times(units).div(total);
452
+ const poolShareDetail = {
453
+ assetShare: new CryptoAmount(lib.baseAmount(asset), pool.asset),
454
+ runeShare: new CryptoAmount(lib.baseAmount(rune), lib.AssetRuneNative),
455
+ };
456
+ return poolShareDetail;
457
+ };
458
+ /**
459
+ *
460
+ * @param poolShare - the share of asset and rune added to the pool
461
+ * @param pool - Pool that the asset is attached to
462
+ * @returns - returns bignumber representing a slip percentage
463
+ */
464
+ const getSlipOnLiquidity = (stake, pool) => {
465
+ const baseAmount8decimals = getBaseAmountWithDiffDecimals(stake.asset, pool.decimals);
466
+ // formula: (t * R - T * r)/ (T*r + R*T)
467
+ const r = stake.rune.baseAmount.amount();
468
+ const t = baseAmount8decimals;
469
+ const R = pool.runeBalance.amount();
470
+ const T = pool.assetBalance.amount();
471
+ const numerator = t.times(R).minus(T.times(r));
472
+ const denominator = T.times(r).plus(R.times(T));
473
+ const result = numerator.div(denominator).abs();
474
+ return result;
475
+ };
476
+ /**
477
+ * https://docs.thorchain.org/thorchain-finance/continuous-liquidity-pools#impermanent-loss-protection
478
+ * @param poolShare - the share of asset and rune added to the pool
479
+ * @param pool - Pool that the asset is attached to
480
+ * @param block - blockl object with current, last added and the constant blocksforlossProtection
481
+ * @returns
482
+ */
483
+ // Blocks for full protection 1440000 // 100 days
484
+ const getLiquidityProtectionData = (depositValue, poolShare, block) => {
485
+ //Coverage formula coverage=((A0∗P1)+R0)−((A1∗P1)+R1)=>((A0∗R1/A1)+R0)−(R1+R1)
486
+ //formula: protectionProgress (currentHeight-heightLastAdded)/blocksforfullprotection
487
+ const R0 = depositValue.rune.amount(); // rune deposit value
488
+ const A0 = depositValue.asset.amount(); // asset deposit value
489
+ const R1 = poolShare.runeShare.baseAmount.amount(); // rune amount to redeem
490
+ const A1 = poolShare.assetShare.baseAmount.amount(); // asset amount to redeem
491
+ const P1 = R1.div(A1); // Pool ratio at withdrawal
492
+ const part1 = A0.times(P1).plus(R0).minus(A1.times(P1).plus(R1)); // start position minus end position
493
+ const part2 = A0.times(R1.div(A1)).plus(R0).minus(R1.plus(R1)); // different way to check position
494
+ const coverage = part1 >= part2 ? part1 : part2; // Coverage represents how much ILP a LP is entitled to
495
+ const currentHeight = block.current;
496
+ const heightLastAdded = block.lastAdded || 0; //default to zero if undefined
497
+ const blocksforfullprotection = block.fullProtection;
498
+ const protectionProgress = (currentHeight - heightLastAdded) / blocksforfullprotection; // percentage of entitlement
499
+ const result = coverage.times(protectionProgress); // impermanent loss protection result
500
+ const ILProtection = {
501
+ ILProtection: new CryptoAmount(lib.baseAmount(result), lib.AssetRuneNative),
502
+ totalDays: (protectionProgress * 100).toFixed(2),
503
+ };
504
+ return ILProtection;
505
+ };
506
+
529
507
  const BN_1 = new bignumber_js.BigNumber(1);
530
508
  /**
531
509
  * THORChain Class for interacting with THORChain.
@@ -565,9 +543,7 @@ class ThorchainQuery {
565
543
  });
566
544
  const inboundDetails = yield this.thorchainCache.getInboundDetails();
567
545
  const sourceInboundDetails = inboundDetails[input.asset.chain];
568
- // console.log(JSON.stringify(sourceInboundDetails, null, 2))
569
546
  const destinationInboundDetails = inboundDetails[destinationAsset.chain];
570
- // console.log(JSON.stringify(destinationInboundDetails, null, 2))
571
547
  const swapEstimate = yield this.calcSwapEstimate({
572
548
  input,
573
549
  destinationAsset,
@@ -1137,11 +1113,11 @@ class ThorchainQuery {
1137
1113
  if (!xchainUtil.isAssetRuneNative(params.rune.asset))
1138
1114
  errors.push('params.rune must be THOR.RUNE');
1139
1115
  const assetPool = yield this.thorchainCache.getPoolForAsset(params.asset.asset);
1140
- const lpUnits = getLiquidityUnits({ asset: params.asset.baseAmount, rune: params.rune.baseAmount }, assetPool);
1116
+ const lpUnits = getLiquidityUnits({ asset: params.asset, rune: params.rune }, assetPool);
1141
1117
  const inboundDetails = yield this.thorchainCache.getInboundDetails();
1142
1118
  const unitData = {
1143
- liquidityUnits: xchainUtil.baseAmount(lpUnits),
1144
- totalUnits: xchainUtil.baseAmount(assetPool.pool.liquidityUnits),
1119
+ liquidityUnits: lpUnits,
1120
+ totalUnits: new bignumber_js.BigNumber(assetPool.pool.liquidityUnits),
1145
1121
  };
1146
1122
  const poolShare = getPoolShare(unitData, assetPool);
1147
1123
  const assetWaitTimeSeconds = yield this.confCounting(params.asset);
@@ -1160,8 +1136,9 @@ class ThorchainQuery {
1160
1136
  errors.push(`Rune amount is less than fees`);
1161
1137
  }
1162
1138
  const totalFees = (yield this.convert(assetInboundFee, xchainUtil.AssetRuneNative)).plus(runeInboundFee);
1163
- const slip = getSlipOnLiquidity({ asset: params.asset.baseAmount, rune: params.rune.baseAmount }, assetPool);
1139
+ const slip = getSlipOnLiquidity({ asset: params.asset, rune: params.rune }, assetPool);
1164
1140
  const estimateLP = {
1141
+ assetPool: assetPool.pool.asset,
1165
1142
  slipPercent: slip.times(100),
1166
1143
  poolShare: poolShare,
1167
1144
  lpUnits: xchainUtil.baseAmount(lpUnits),
@@ -1188,6 +1165,8 @@ class ThorchainQuery {
1188
1165
  const poolAsset = yield this.thorchainCache.getPoolForAsset(asset);
1189
1166
  if (!poolAsset)
1190
1167
  throw Error(`Could not find pool for ${asset}`);
1168
+ if (!assetOrRuneAddress)
1169
+ throw Error(`No address provided ${assetOrRuneAddress}`);
1191
1170
  const liquidityProvider = yield this.thorchainCache.thornode.getLiquidityProvider(poolAsset.assetString, assetOrRuneAddress);
1192
1171
  if (!liquidityProvider)
1193
1172
  throw Error(`Could not find LP for ${assetOrRuneAddress}`);
@@ -1197,8 +1176,8 @@ class ThorchainQuery {
1197
1176
  throw Error(`Could not get block data`);
1198
1177
  // Pools total units & Lp's total units
1199
1178
  const unitData = {
1200
- totalUnits: xchainUtil.baseAmount(poolAsset.pool.liquidityUnits),
1201
- liquidityUnits: xchainUtil.baseAmount(liquidityProvider.units),
1179
+ totalUnits: new bignumber_js.BigNumber(poolAsset.pool.liquidityUnits),
1180
+ liquidityUnits: new bignumber_js.BigNumber(liquidityProvider.units),
1202
1181
  };
1203
1182
  //console.log(`unit data`, unitData.totalUnits.amount().toNumber(), unitData.liquidityUnits.amount().toNumber())
1204
1183
  const networkValues = yield this.thorchainCache.midgard.getNetworkValues();
@@ -1246,22 +1225,21 @@ class ThorchainQuery {
1246
1225
  estimateWithdrawLP(params) {
1247
1226
  return __awaiter(this, void 0, void 0, function* () {
1248
1227
  // Caution Dust Limits: BTC,BCH,LTC chains 10k sats; DOGE 1m Sats; ETH 0 wei; THOR 0 RUNE.
1249
- if (!params.assetAddress)
1250
- throw Error(`can't estimate lp without an asset address`);
1251
- const memberDetail = yield this.checkLiquidityPosition(params.asset, params.assetAddress);
1228
+ const assetOrRuneAddress = params.assetAddress ? params.assetAddress : params.runeAddress;
1229
+ const memberDetail = yield this.checkLiquidityPosition(params.asset, assetOrRuneAddress);
1252
1230
  const dustValues = yield this.getDustValues(params.asset); // returns asset and rune dust values
1253
1231
  const assetPool = yield this.thorchainCache.getPoolForAsset(params.asset);
1254
1232
  // get pool share from unit data
1255
1233
  const poolShare = getPoolShare({
1256
- liquidityUnits: xchainUtil.baseAmount(memberDetail.position.units),
1257
- totalUnits: xchainUtil.baseAmount(assetPool.pool.liquidityUnits),
1234
+ liquidityUnits: new bignumber_js.BigNumber(memberDetail.position.units),
1235
+ totalUnits: new bignumber_js.BigNumber(assetPool.pool.liquidityUnits),
1258
1236
  }, assetPool);
1259
1237
  // calculate total fees
1260
1238
  const totalFees = (yield this.convert(dustValues.asset, xchainUtil.AssetRuneNative)).plus(dustValues.rune);
1261
1239
  // get slip on liquidity removal
1262
1240
  const slip = getSlipOnLiquidity({
1263
- asset: poolShare.assetShare.baseAmount,
1264
- rune: poolShare.runeShare.baseAmount,
1241
+ asset: poolShare.assetShare,
1242
+ rune: poolShare.runeShare,
1265
1243
  }, assetPool);
1266
1244
  // TODO make sure we compare wait times for withdrawing both rune and asset OR just rune OR just asset
1267
1245
  const waitTimeSecondsForAsset = yield this.confCounting(poolShare.assetShare.div(params.percentage / 100));
@@ -1277,6 +1255,8 @@ class ThorchainQuery {
1277
1255
  waitTimeSeconds = waitTimeSecondsForRune;
1278
1256
  }
1279
1257
  const estimateLP = {
1258
+ assetAddress: memberDetail.position.asset_address,
1259
+ runeAddress: memberDetail.position.rune_address,
1280
1260
  slipPercent: slip.times(100),
1281
1261
  transactionFee: {
1282
1262
  assetFee: dustValues.asset,
@@ -1287,6 +1267,7 @@ class ThorchainQuery {
1287
1267
  runeAmount: poolShare.runeShare,
1288
1268
  estimatedWaitSeconds: waitTimeSeconds,
1289
1269
  impermanentLossProtection: memberDetail.impermanentLossProtection,
1270
+ assetPool: assetPool.pool.asset,
1290
1271
  };
1291
1272
  return estimateLP;
1292
1273
  });
@@ -146,7 +146,7 @@ export declare class ThorchainQuery {
146
146
  * @param address - address used for Lp
147
147
  * @returns - Type Object liquidityPosition
148
148
  */
149
- checkLiquidityPosition(asset: Asset, assetOrRuneAddress: string): Promise<LiquidityPosition>;
149
+ checkLiquidityPosition(asset: Asset, assetOrRuneAddress?: string): Promise<LiquidityPosition>;
150
150
  /**
151
151
  * Do not send assetNativeRune, There is no pool for it.
152
152
  * @param asset - asset required to find the pool
package/lib/types.d.ts CHANGED
@@ -53,8 +53,8 @@ export declare type SwapOutput = {
53
53
  slip: BigNumber;
54
54
  };
55
55
  export declare type UnitData = {
56
- liquidityUnits: BaseAmount;
57
- totalUnits: BaseAmount;
56
+ liquidityUnits: BigNumber;
57
+ totalUnits: BigNumber;
58
58
  };
59
59
  export declare type LiquidityData = {
60
60
  rune: CryptoAmount;
@@ -114,8 +114,8 @@ export declare type TxStatus = {
114
114
  seconds: number;
115
115
  };
116
116
  export declare type LiquidityToAdd = {
117
- asset: BaseAmount;
118
- rune: BaseAmount;
117
+ asset: CryptoAmount;
118
+ rune: CryptoAmount;
119
119
  };
120
120
  export declare type PostionDepositValue = {
121
121
  asset: BaseAmount;
@@ -126,6 +126,7 @@ export declare type PoolShareDetail = {
126
126
  runeShare: CryptoAmount;
127
127
  };
128
128
  export declare type EstimateAddLP = {
129
+ assetPool: string;
129
130
  slipPercent: BigNumber;
130
131
  poolShare: PoolShareDetail;
131
132
  lpUnits: BaseAmount;
@@ -136,12 +137,15 @@ export declare type EstimateAddLP = {
136
137
  canAdd: boolean;
137
138
  };
138
139
  export declare type EstimateWithdrawLP = {
140
+ assetAddress?: string;
141
+ runeAddress?: string;
139
142
  slipPercent: BigNumber;
140
143
  transactionFee: LPFees;
141
144
  assetAmount: CryptoAmount;
142
145
  runeAmount: CryptoAmount;
143
146
  impermanentLossProtection: ILProtectionData;
144
147
  estimatedWaitSeconds: number;
148
+ assetPool: string;
145
149
  };
146
150
  export declare type LPFees = {
147
151
  runeFee: CryptoAmount;
@@ -4,6 +4,7 @@ import { CryptoAmount } from '../crypto-amount';
4
4
  import { LiquidityPool } from '../liquidity-pool';
5
5
  import { ThorchainCache } from '../thorchain-cache';
6
6
  import { InboundDetail, SwapOutput } from '../types';
7
+ export declare const getBaseAmountWithDiffDecimals: (inputAmount: CryptoAmount, outDecimals: number) => BigNumber;
7
8
  /**
8
9
  *
9
10
  * @param inputAmount - amount to swap
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xchainjs/xchain-thorchain-query",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
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.1",
36
+ "@xchainjs/xchain-client": "^0.13.2",
37
37
  "@xchainjs/xchain-midgard": "^0.1.0",
38
38
  "@xchainjs/xchain-thornode": "^0.1.0",
39
- "@xchainjs/xchain-util": "^0.10.0",
39
+ "@xchainjs/xchain-util": "^0.11.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.1",
46
+ "@xchainjs/xchain-client": "^0.13.2",
47
47
  "@xchainjs/xchain-midgard": "^0.1.0",
48
48
  "@xchainjs/xchain-thornode": "^0.1.0",
49
- "@xchainjs/xchain-util": "^0.10.0",
49
+ "@xchainjs/xchain-util": "^0.11.0",
50
50
  "axios": "^0.25.0",
51
51
  "axios-retry": "^3.2.5",
52
52
  "bignumber.js": "^9.0.0",