@xchainjs/xchain-thorchain-query 0.2.2 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.esm.js +292 -243
- package/lib/index.js +442 -370
- package/lib/utils/const.d.ts +24 -0
- package/lib/utils/index.d.ts +1 -0
- package/package.json +5 -23
package/lib/index.esm.js
CHANGED
|
@@ -1,18 +1,9 @@
|
|
|
1
|
-
import { BNBChain, AssetBNB } from '@xchainjs/xchain-binance';
|
|
2
|
-
import { BTCChain, AssetBTC } from '@xchainjs/xchain-bitcoin';
|
|
3
|
-
import { GAIAChain, AssetATOM } from '@xchainjs/xchain-cosmos';
|
|
4
|
-
import { AssetRuneNative, THORChain, isAssetRuneNative } from '@xchainjs/xchain-thorchain';
|
|
5
1
|
import { assetToBase, formatAssetAmountCurrency, baseToAsset, eqAsset, assetToString, assetFromString, baseAmount, assetFromStringEx, assetAmount, getContractAddressFromAsset } from '@xchainjs/xchain-util';
|
|
6
2
|
import { BigNumber } from 'bignumber.js';
|
|
7
3
|
import { Network } from '@xchainjs/xchain-client';
|
|
8
4
|
import { MidgardApi, Configuration } from '@xchainjs/xchain-midgard';
|
|
9
5
|
import axios from 'axios';
|
|
10
6
|
import axiosRetry from 'axios-retry';
|
|
11
|
-
import { AVAXChain, AssetAVAX } from '@xchainjs/xchain-avax';
|
|
12
|
-
import { BCHChain, AssetBCH } from '@xchainjs/xchain-bitcoincash';
|
|
13
|
-
import { DOGEChain, AssetDOGE } from '@xchainjs/xchain-doge';
|
|
14
|
-
import { ETHChain, AssetETH } from '@xchainjs/xchain-ethereum';
|
|
15
|
-
import { LTCChain, AssetLTC } from '@xchainjs/xchain-litecoin';
|
|
16
7
|
import { TransactionsApi, Configuration as Configuration$1, QueueApi, NetworkApi, PoolsApi, LiquidityProvidersApi, SaversApi, QuoteApi, MimirApi } from '@xchainjs/xchain-thornode';
|
|
17
8
|
|
|
18
9
|
/*! *****************************************************************************
|
|
@@ -77,6 +68,14 @@ const DefaultChainAttributes = {
|
|
|
77
68
|
blockReward: 0,
|
|
78
69
|
avgBlockTimeInSecs: 6,
|
|
79
70
|
},
|
|
71
|
+
BSC: {
|
|
72
|
+
blockReward: 0,
|
|
73
|
+
avgBlockTimeInSecs: 3,
|
|
74
|
+
},
|
|
75
|
+
MAYA: {
|
|
76
|
+
blockReward: 0,
|
|
77
|
+
avgBlockTimeInSecs: 6,
|
|
78
|
+
},
|
|
80
79
|
};
|
|
81
80
|
|
|
82
81
|
/**
|
|
@@ -196,148 +195,29 @@ class LiquidityPool {
|
|
|
196
195
|
}
|
|
197
196
|
}
|
|
198
197
|
|
|
199
|
-
const
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
* @returns an array of Pools
|
|
223
|
-
*/
|
|
224
|
-
getPools() {
|
|
225
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
226
|
-
for (const api of this.midgardApis) {
|
|
227
|
-
try {
|
|
228
|
-
return (yield api.getPools()).data;
|
|
229
|
-
}
|
|
230
|
-
catch (e) {
|
|
231
|
-
//console.error(e)
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
throw new Error(`Midgard not responding`);
|
|
235
|
-
});
|
|
236
|
-
}
|
|
237
|
-
/**
|
|
238
|
-
* Gets the latest block using the Health endpoint within Midgard
|
|
239
|
-
*
|
|
240
|
-
* @returns
|
|
241
|
-
*/
|
|
242
|
-
getLatestBlockHeight() {
|
|
243
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
244
|
-
for (const api of this.midgardApis) {
|
|
245
|
-
try {
|
|
246
|
-
const data = (yield api.getHealth()).data;
|
|
247
|
-
return +data.scannerHeight;
|
|
248
|
-
}
|
|
249
|
-
catch (e) {
|
|
250
|
-
//console.error(e)
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
throw Error(`Midgard not responding`);
|
|
254
|
-
});
|
|
255
|
-
}
|
|
256
|
-
/**
|
|
257
|
-
* Gets actions object for any of the parameters
|
|
258
|
-
* @param txHash transaction id
|
|
259
|
-
* @returns Type Action array of objects
|
|
260
|
-
*/
|
|
261
|
-
getActions(address, txid, asset, type, affiliate, limit, offset) {
|
|
262
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
263
|
-
for (const api of this.midgardApis) {
|
|
264
|
-
try {
|
|
265
|
-
const actions = (yield api.getActions(address, txid, asset, type, affiliate, limit, offset)).data.actions;
|
|
266
|
-
return actions;
|
|
267
|
-
}
|
|
268
|
-
catch (e) {
|
|
269
|
-
//console.error(e)
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
throw Error(`Midgard not responding`);
|
|
273
|
-
});
|
|
274
|
-
}
|
|
275
|
-
/**
|
|
276
|
-
* Function to return member details based on valid liquidity position
|
|
277
|
-
* @param address - needed to query for Lp details
|
|
278
|
-
* @returns - object type of Member Detail
|
|
279
|
-
*/
|
|
280
|
-
getMember(address) {
|
|
281
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
282
|
-
for (const api of this.midgardApis) {
|
|
283
|
-
try {
|
|
284
|
-
const memberDetail = (yield api.getMemberDetail(address)).data;
|
|
285
|
-
return memberDetail;
|
|
286
|
-
}
|
|
287
|
-
catch (e) {
|
|
288
|
-
//console.error(e)
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
throw Error(`Midgard not responding`);
|
|
292
|
-
});
|
|
293
|
-
}
|
|
294
|
-
/**
|
|
295
|
-
* Function to return pool statistics for a particular asset
|
|
296
|
-
* @param asset - asset string to query its pool stats
|
|
297
|
-
* @returns - type object poolstatsDetail
|
|
298
|
-
*/
|
|
299
|
-
getPoolStats(asset) {
|
|
300
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
301
|
-
for (const api of this.midgardApis) {
|
|
302
|
-
try {
|
|
303
|
-
const poolDetail = (yield api.getPoolStats(asset)).data;
|
|
304
|
-
return poolDetail;
|
|
305
|
-
}
|
|
306
|
-
catch (e) {
|
|
307
|
-
//console.error(e)
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
throw Error(`Midgard not responding`);
|
|
311
|
-
});
|
|
312
|
-
}
|
|
313
|
-
/**
|
|
314
|
-
* Function to return THORNameDetails for a particular name
|
|
315
|
-
* @param name - thorname string to query
|
|
316
|
-
* @returns - type object THORNameDetails
|
|
317
|
-
*/
|
|
318
|
-
getTHORNameDetails(name) {
|
|
319
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
320
|
-
for (const api of this.midgardApis) {
|
|
321
|
-
try {
|
|
322
|
-
const resp = yield api.getTHORNameDetail(name);
|
|
323
|
-
if (resp.status == 404) {
|
|
324
|
-
return undefined;
|
|
325
|
-
}
|
|
326
|
-
else if (resp.status == 200) {
|
|
327
|
-
return resp.data;
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
catch (e) {
|
|
331
|
-
// if (resp.status == 404) {
|
|
332
|
-
// return undefined
|
|
333
|
-
// }
|
|
334
|
-
//console.error(e)
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
throw Error(`Midgard not responding`);
|
|
338
|
-
});
|
|
339
|
-
}
|
|
340
|
-
}
|
|
198
|
+
const AssetBNB = assetFromStringEx('BNB.BNB');
|
|
199
|
+
const AssetAVAX = assetFromStringEx('AVAX.AVAX');
|
|
200
|
+
const AssetBTC = assetFromStringEx('BTC.BTC');
|
|
201
|
+
const AssetBCH = assetFromStringEx('BCH.BHC');
|
|
202
|
+
const AssetETH = assetFromStringEx('ETH.ETH');
|
|
203
|
+
const AssetDOGE = assetFromStringEx('DOGE.DOGE');
|
|
204
|
+
const AssetLTC = assetFromStringEx('LTC.LTC');
|
|
205
|
+
const AssetATOM = assetFromStringEx('GAIA.ATOM');
|
|
206
|
+
const AssetMAYA = assetFromStringEx('MAYA.CACAO');
|
|
207
|
+
const AssetBSC = assetFromStringEx('BSC.BNB');
|
|
208
|
+
const AssetRuneNative = assetFromStringEx('THOR.RUNE');
|
|
209
|
+
const BNBChain = 'BNB';
|
|
210
|
+
const BTCChain = 'BTC';
|
|
211
|
+
const BCHChain = 'BCH';
|
|
212
|
+
const ETHChain = 'ETH';
|
|
213
|
+
const GAIAChain = 'GAIA';
|
|
214
|
+
const DOGEChain = 'DOGE';
|
|
215
|
+
const LTCChain = 'LTC';
|
|
216
|
+
const AVAXChain = 'AVAX';
|
|
217
|
+
const MAYAChain = 'MAYA';
|
|
218
|
+
const BSCChain = 'BSC';
|
|
219
|
+
const THORChain = 'THOR';
|
|
220
|
+
const isAssetRuneNative = (asset) => assetToString(asset) === assetToString(AssetRuneNative);
|
|
341
221
|
|
|
342
222
|
const getBaseAmountWithDiffDecimals = (inputAmount, outDecimals) => {
|
|
343
223
|
const inDecimals = inputAmount.baseAmount.decimal;
|
|
@@ -491,6 +371,10 @@ const getChainAsset = (chain) => {
|
|
|
491
371
|
return AssetDOGE;
|
|
492
372
|
case AVAXChain:
|
|
493
373
|
return AssetAVAX;
|
|
374
|
+
case BSCChain:
|
|
375
|
+
return AssetBSC;
|
|
376
|
+
case MAYAChain:
|
|
377
|
+
return AssetMAYA;
|
|
494
378
|
default:
|
|
495
379
|
throw Error('Unknown chain');
|
|
496
380
|
}
|
|
@@ -553,6 +437,10 @@ const calcNetworkFee = (asset, inbound) => {
|
|
|
553
437
|
return new CryptoAmount(baseAmount(inbound.gasRate), AssetATOM);
|
|
554
438
|
case THORChain:
|
|
555
439
|
return new CryptoAmount(baseAmount(2000000), AssetRuneNative);
|
|
440
|
+
case BSCChain:
|
|
441
|
+
return new CryptoAmount(baseAmount(inbound.gasRate), AssetBSC);
|
|
442
|
+
case MAYAChain:
|
|
443
|
+
return new CryptoAmount(baseAmount(inbound.gasRate), AssetMAYA);
|
|
556
444
|
}
|
|
557
445
|
throw new Error(`could not calculate inbound fee for ${asset.chain}`);
|
|
558
446
|
};
|
|
@@ -587,12 +475,250 @@ const calcOutboundFee = (asset, inbound) => {
|
|
|
587
475
|
return new CryptoAmount(baseAmount(inbound.outboundFee.multipliedBy(Math.pow(10, 9)), 18), AssetAVAX);
|
|
588
476
|
case GAIAChain:
|
|
589
477
|
return new CryptoAmount(baseAmount(inbound.outboundFee), AssetATOM);
|
|
478
|
+
case BSCChain:
|
|
479
|
+
return new CryptoAmount(baseAmount(inbound.outboundFee), AssetBSC);
|
|
590
480
|
case THORChain:
|
|
591
481
|
return new CryptoAmount(baseAmount(2000000), AssetRuneNative);
|
|
482
|
+
case MAYAChain:
|
|
483
|
+
return new CryptoAmount(baseAmount(2000000), AssetMAYA);
|
|
592
484
|
}
|
|
593
485
|
throw new Error(`could not calculate outbound fee for ${asset.chain}`);
|
|
594
486
|
};
|
|
595
487
|
|
|
488
|
+
/**
|
|
489
|
+
* https://dev.thorchain.org/thorchain-dev/interface-guide/math#lp-units-add
|
|
490
|
+
* @param liquidity - asset amount added
|
|
491
|
+
* @param pool - pool depths
|
|
492
|
+
* @returns liquidity units - ownership of pool
|
|
493
|
+
*/
|
|
494
|
+
const getLiquidityUnits = (liquidity, pool) => {
|
|
495
|
+
const baseAmount8decimals = getBaseAmountWithDiffDecimals(liquidity.asset, 8);
|
|
496
|
+
const P = new BigNumber(pool.pool.liquidityUnits);
|
|
497
|
+
const r = liquidity.rune.baseAmount.amount();
|
|
498
|
+
const a = baseAmount8decimals;
|
|
499
|
+
const R = pool.runeBalance.amount();
|
|
500
|
+
const A = pool.assetBalance.amount();
|
|
501
|
+
const part1 = R.times(a);
|
|
502
|
+
const part2 = r.times(A);
|
|
503
|
+
const numerator = P.times(part1.plus(part2));
|
|
504
|
+
const denominator = R.times(A).times(2);
|
|
505
|
+
const result = numerator.div(denominator);
|
|
506
|
+
return result;
|
|
507
|
+
};
|
|
508
|
+
/**
|
|
509
|
+
*
|
|
510
|
+
* @param unitData - units for both asset and rune
|
|
511
|
+
* @param pool - pool that the asset is bound to
|
|
512
|
+
* @returns - pool share of both asset and rune in percentage
|
|
513
|
+
*/
|
|
514
|
+
const getPoolShare = (unitData, pool) => {
|
|
515
|
+
// formula: (rune * part) / total; (asset * part) / total
|
|
516
|
+
const units = unitData.liquidityUnits;
|
|
517
|
+
const total = unitData.totalUnits;
|
|
518
|
+
const R = pool.runeBalance.amount();
|
|
519
|
+
const T = pool.assetBalance.amount();
|
|
520
|
+
const asset = T.times(units).div(total);
|
|
521
|
+
const rune = R.times(units).div(total);
|
|
522
|
+
const poolShareDetail = {
|
|
523
|
+
assetShare: new CryptoAmount(baseAmount(asset), pool.asset),
|
|
524
|
+
runeShare: new CryptoAmount(baseAmount(rune), AssetRuneNative),
|
|
525
|
+
};
|
|
526
|
+
return poolShareDetail;
|
|
527
|
+
};
|
|
528
|
+
/**
|
|
529
|
+
*
|
|
530
|
+
* @param poolShare - the share of asset and rune added to the pool
|
|
531
|
+
* @param pool - Pool that the asset is attached to
|
|
532
|
+
* @returns - returns bignumber representing a slip percentage
|
|
533
|
+
*/
|
|
534
|
+
const getSlipOnLiquidity = (stake, pool) => {
|
|
535
|
+
const baseAmount8decimals = getBaseAmountWithDiffDecimals(stake.asset, 8);
|
|
536
|
+
// formula: (t * R - T * r)/ (T*r + R*T)
|
|
537
|
+
const r = stake.rune.baseAmount.amount();
|
|
538
|
+
const t = baseAmount8decimals;
|
|
539
|
+
const R = pool.runeBalance.amount();
|
|
540
|
+
const T = pool.assetBalance.amount();
|
|
541
|
+
const numerator = t.times(R).minus(T.times(r));
|
|
542
|
+
const denominator = T.times(r).plus(R.times(T));
|
|
543
|
+
const result = numerator.div(denominator).abs();
|
|
544
|
+
return result;
|
|
545
|
+
};
|
|
546
|
+
/**
|
|
547
|
+
* https://docs.thorchain.org/thorchain-finance/continuous-liquidity-pools#impermanent-loss-protection
|
|
548
|
+
* @param poolShare - the share of asset and rune added to the pool
|
|
549
|
+
* @param pool - Pool that the asset is attached to
|
|
550
|
+
* @param block - blockl object with current, last added and the constant blocksforlossProtection
|
|
551
|
+
* @returns
|
|
552
|
+
*/
|
|
553
|
+
// Blocks for full protection 1440000 // 100 days
|
|
554
|
+
const getLiquidityProtectionData = (depositValue, poolShare, block) => {
|
|
555
|
+
//Coverage formula coverage=((A0∗P1)+R0)−((A1∗P1)+R1)=>((A0∗R1/A1)+R0)−(R1+R1)
|
|
556
|
+
//formula: protectionProgress (currentHeight-heightLastAdded)/blocksforfullprotection
|
|
557
|
+
const R0 = depositValue.rune.amount(); // rune deposit value
|
|
558
|
+
const A0 = depositValue.asset.amount(); // asset deposit value
|
|
559
|
+
const R1 = poolShare.runeShare.baseAmount.amount(); // rune amount to redeem
|
|
560
|
+
const A1 = poolShare.assetShare.baseAmount.amount(); // asset amount to redeem
|
|
561
|
+
const P1 = R1.div(A1); // Pool ratio at withdrawal
|
|
562
|
+
const part1 = A0.times(P1).plus(R0).minus(A1.times(P1).plus(R1)); // start position minus end position
|
|
563
|
+
const part2 = A0.times(R1.div(A1)).plus(R0).minus(R1.plus(R1)); // different way to check position
|
|
564
|
+
const coverage = part1 >= part2 ? part1 : part2; // Coverage represents how much ILP a LP is entitled to
|
|
565
|
+
const currentHeight = block.current;
|
|
566
|
+
const heightLastAdded = block.lastAdded || 0; //default to zero if undefined
|
|
567
|
+
const blocksforfullprotection = block.fullProtection;
|
|
568
|
+
const fractionOfFullILPProtection = (currentHeight - heightLastAdded) / blocksforfullprotection;
|
|
569
|
+
const protectionProgress = Math.min(fractionOfFullILPProtection, 1); // percentage of entitlement, max 100%
|
|
570
|
+
const result = coverage.times(protectionProgress); // impermanent loss protection result
|
|
571
|
+
const maxILP = result.lt(0) ? new BigNumber(0) : result; // max negative ILP to 0
|
|
572
|
+
const ILProtection = {
|
|
573
|
+
ILProtection: new CryptoAmount(baseAmount(maxILP), AssetRuneNative),
|
|
574
|
+
totalDays: (fractionOfFullILPProtection * 100).toFixed(2),
|
|
575
|
+
};
|
|
576
|
+
return ILProtection;
|
|
577
|
+
};
|
|
578
|
+
|
|
579
|
+
const defaultMidgardConfig = {
|
|
580
|
+
mainnet: {
|
|
581
|
+
apiRetries: 3,
|
|
582
|
+
midgardBaseUrls: ['https://midgard.ninerealms.com'],
|
|
583
|
+
},
|
|
584
|
+
stagenet: {
|
|
585
|
+
apiRetries: 3,
|
|
586
|
+
midgardBaseUrls: ['https://stagenet-midgard.ninerealms.com'],
|
|
587
|
+
},
|
|
588
|
+
testnet: {
|
|
589
|
+
apiRetries: 3,
|
|
590
|
+
midgardBaseUrls: ['https://testnet.midgard.thorchain.info'],
|
|
591
|
+
},
|
|
592
|
+
};
|
|
593
|
+
class Midgard {
|
|
594
|
+
constructor(network = Network.Mainnet, config) {
|
|
595
|
+
this.network = network;
|
|
596
|
+
this.config = config !== null && config !== void 0 ? config : defaultMidgardConfig[this.network];
|
|
597
|
+
axiosRetry(axios, { retries: this.config.apiRetries, retryDelay: axiosRetry.exponentialDelay });
|
|
598
|
+
this.midgardApis = this.config.midgardBaseUrls.map((url) => new MidgardApi(new Configuration({ basePath: url })));
|
|
599
|
+
}
|
|
600
|
+
/**
|
|
601
|
+
*
|
|
602
|
+
* @returns an array of Pools
|
|
603
|
+
*/
|
|
604
|
+
getPools() {
|
|
605
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
606
|
+
for (const api of this.midgardApis) {
|
|
607
|
+
try {
|
|
608
|
+
return (yield api.getPools()).data;
|
|
609
|
+
}
|
|
610
|
+
catch (e) {
|
|
611
|
+
//console.error(e)
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
throw new Error(`Midgard not responding`);
|
|
615
|
+
});
|
|
616
|
+
}
|
|
617
|
+
/**
|
|
618
|
+
* Gets the latest block using the Health endpoint within Midgard
|
|
619
|
+
*
|
|
620
|
+
* @returns
|
|
621
|
+
*/
|
|
622
|
+
getLatestBlockHeight() {
|
|
623
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
624
|
+
for (const api of this.midgardApis) {
|
|
625
|
+
try {
|
|
626
|
+
const data = (yield api.getHealth()).data;
|
|
627
|
+
return +data.scannerHeight;
|
|
628
|
+
}
|
|
629
|
+
catch (e) {
|
|
630
|
+
//console.error(e)
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
throw Error(`Midgard not responding`);
|
|
634
|
+
});
|
|
635
|
+
}
|
|
636
|
+
/**
|
|
637
|
+
* Gets actions object for any of the parameters
|
|
638
|
+
* @param txHash transaction id
|
|
639
|
+
* @returns Type Action array of objects
|
|
640
|
+
*/
|
|
641
|
+
getActions(address, txid, asset, type, affiliate, limit, offset) {
|
|
642
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
643
|
+
for (const api of this.midgardApis) {
|
|
644
|
+
try {
|
|
645
|
+
const actions = (yield api.getActions(address, txid, asset, type, affiliate, limit, offset)).data.actions;
|
|
646
|
+
return actions;
|
|
647
|
+
}
|
|
648
|
+
catch (e) {
|
|
649
|
+
//console.error(e)
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
throw Error(`Midgard not responding`);
|
|
653
|
+
});
|
|
654
|
+
}
|
|
655
|
+
/**
|
|
656
|
+
* Function to return member details based on valid liquidity position
|
|
657
|
+
* @param address - needed to query for Lp details
|
|
658
|
+
* @returns - object type of Member Detail
|
|
659
|
+
*/
|
|
660
|
+
getMember(address) {
|
|
661
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
662
|
+
for (const api of this.midgardApis) {
|
|
663
|
+
try {
|
|
664
|
+
const memberDetail = (yield api.getMemberDetail(address)).data;
|
|
665
|
+
return memberDetail;
|
|
666
|
+
}
|
|
667
|
+
catch (e) {
|
|
668
|
+
//console.error(e)
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
throw Error(`Midgard not responding`);
|
|
672
|
+
});
|
|
673
|
+
}
|
|
674
|
+
/**
|
|
675
|
+
* Function to return pool statistics for a particular asset
|
|
676
|
+
* @param asset - asset string to query its pool stats
|
|
677
|
+
* @returns - type object poolstatsDetail
|
|
678
|
+
*/
|
|
679
|
+
getPoolStats(asset) {
|
|
680
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
681
|
+
for (const api of this.midgardApis) {
|
|
682
|
+
try {
|
|
683
|
+
const poolDetail = (yield api.getPoolStats(asset)).data;
|
|
684
|
+
return poolDetail;
|
|
685
|
+
}
|
|
686
|
+
catch (e) {
|
|
687
|
+
//console.error(e)
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
throw Error(`Midgard not responding`);
|
|
691
|
+
});
|
|
692
|
+
}
|
|
693
|
+
/**
|
|
694
|
+
* Function to return THORNameDetails for a particular name
|
|
695
|
+
* @param name - thorname string to query
|
|
696
|
+
* @returns - type object THORNameDetails
|
|
697
|
+
*/
|
|
698
|
+
getTHORNameDetails(name) {
|
|
699
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
700
|
+
for (const api of this.midgardApis) {
|
|
701
|
+
try {
|
|
702
|
+
const resp = yield api.getTHORNameDetail(name);
|
|
703
|
+
if (resp.status == 404) {
|
|
704
|
+
return undefined;
|
|
705
|
+
}
|
|
706
|
+
else if (resp.status == 200) {
|
|
707
|
+
return resp.data;
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
catch (e) {
|
|
711
|
+
// if (resp.status == 404) {
|
|
712
|
+
// return undefined
|
|
713
|
+
// }
|
|
714
|
+
//console.error(e)
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
throw Error(`Midgard not responding`);
|
|
718
|
+
});
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
|
|
596
722
|
const defaultThornodeConfig = {
|
|
597
723
|
mainnet: {
|
|
598
724
|
apiRetries: 3,
|
|
@@ -1356,97 +1482,6 @@ class ThorchainCache {
|
|
|
1356
1482
|
}
|
|
1357
1483
|
}
|
|
1358
1484
|
|
|
1359
|
-
/**
|
|
1360
|
-
* https://dev.thorchain.org/thorchain-dev/interface-guide/math#lp-units-add
|
|
1361
|
-
* @param liquidity - asset amount added
|
|
1362
|
-
* @param pool - pool depths
|
|
1363
|
-
* @returns liquidity units - ownership of pool
|
|
1364
|
-
*/
|
|
1365
|
-
const getLiquidityUnits = (liquidity, pool) => {
|
|
1366
|
-
const baseAmount8decimals = getBaseAmountWithDiffDecimals(liquidity.asset, 8);
|
|
1367
|
-
const P = new BigNumber(pool.pool.liquidityUnits);
|
|
1368
|
-
const r = liquidity.rune.baseAmount.amount();
|
|
1369
|
-
const a = baseAmount8decimals;
|
|
1370
|
-
const R = pool.runeBalance.amount();
|
|
1371
|
-
const A = pool.assetBalance.amount();
|
|
1372
|
-
const part1 = R.times(a);
|
|
1373
|
-
const part2 = r.times(A);
|
|
1374
|
-
const numerator = P.times(part1.plus(part2));
|
|
1375
|
-
const denominator = R.times(A).times(2);
|
|
1376
|
-
const result = numerator.div(denominator);
|
|
1377
|
-
return result;
|
|
1378
|
-
};
|
|
1379
|
-
/**
|
|
1380
|
-
*
|
|
1381
|
-
* @param unitData - units for both asset and rune
|
|
1382
|
-
* @param pool - pool that the asset is bound to
|
|
1383
|
-
* @returns - pool share of both asset and rune in percentage
|
|
1384
|
-
*/
|
|
1385
|
-
const getPoolShare = (unitData, pool) => {
|
|
1386
|
-
// formula: (rune * part) / total; (asset * part) / total
|
|
1387
|
-
const units = unitData.liquidityUnits;
|
|
1388
|
-
const total = unitData.totalUnits;
|
|
1389
|
-
const R = pool.runeBalance.amount();
|
|
1390
|
-
const T = pool.assetBalance.amount();
|
|
1391
|
-
const asset = T.times(units).div(total);
|
|
1392
|
-
const rune = R.times(units).div(total);
|
|
1393
|
-
const poolShareDetail = {
|
|
1394
|
-
assetShare: new CryptoAmount(baseAmount(asset), pool.asset),
|
|
1395
|
-
runeShare: new CryptoAmount(baseAmount(rune), AssetRuneNative),
|
|
1396
|
-
};
|
|
1397
|
-
return poolShareDetail;
|
|
1398
|
-
};
|
|
1399
|
-
/**
|
|
1400
|
-
*
|
|
1401
|
-
* @param poolShare - the share of asset and rune added to the pool
|
|
1402
|
-
* @param pool - Pool that the asset is attached to
|
|
1403
|
-
* @returns - returns bignumber representing a slip percentage
|
|
1404
|
-
*/
|
|
1405
|
-
const getSlipOnLiquidity = (stake, pool) => {
|
|
1406
|
-
const baseAmount8decimals = getBaseAmountWithDiffDecimals(stake.asset, 8);
|
|
1407
|
-
// formula: (t * R - T * r)/ (T*r + R*T)
|
|
1408
|
-
const r = stake.rune.baseAmount.amount();
|
|
1409
|
-
const t = baseAmount8decimals;
|
|
1410
|
-
const R = pool.runeBalance.amount();
|
|
1411
|
-
const T = pool.assetBalance.amount();
|
|
1412
|
-
const numerator = t.times(R).minus(T.times(r));
|
|
1413
|
-
const denominator = T.times(r).plus(R.times(T));
|
|
1414
|
-
const result = numerator.div(denominator).abs();
|
|
1415
|
-
return result;
|
|
1416
|
-
};
|
|
1417
|
-
/**
|
|
1418
|
-
* https://docs.thorchain.org/thorchain-finance/continuous-liquidity-pools#impermanent-loss-protection
|
|
1419
|
-
* @param poolShare - the share of asset and rune added to the pool
|
|
1420
|
-
* @param pool - Pool that the asset is attached to
|
|
1421
|
-
* @param block - blockl object with current, last added and the constant blocksforlossProtection
|
|
1422
|
-
* @returns
|
|
1423
|
-
*/
|
|
1424
|
-
// Blocks for full protection 1440000 // 100 days
|
|
1425
|
-
const getLiquidityProtectionData = (depositValue, poolShare, block) => {
|
|
1426
|
-
//Coverage formula coverage=((A0∗P1)+R0)−((A1∗P1)+R1)=>((A0∗R1/A1)+R0)−(R1+R1)
|
|
1427
|
-
//formula: protectionProgress (currentHeight-heightLastAdded)/blocksforfullprotection
|
|
1428
|
-
const R0 = depositValue.rune.amount(); // rune deposit value
|
|
1429
|
-
const A0 = depositValue.asset.amount(); // asset deposit value
|
|
1430
|
-
const R1 = poolShare.runeShare.baseAmount.amount(); // rune amount to redeem
|
|
1431
|
-
const A1 = poolShare.assetShare.baseAmount.amount(); // asset amount to redeem
|
|
1432
|
-
const P1 = R1.div(A1); // Pool ratio at withdrawal
|
|
1433
|
-
const part1 = A0.times(P1).plus(R0).minus(A1.times(P1).plus(R1)); // start position minus end position
|
|
1434
|
-
const part2 = A0.times(R1.div(A1)).plus(R0).minus(R1.plus(R1)); // different way to check position
|
|
1435
|
-
const coverage = part1 >= part2 ? part1 : part2; // Coverage represents how much ILP a LP is entitled to
|
|
1436
|
-
const currentHeight = block.current;
|
|
1437
|
-
const heightLastAdded = block.lastAdded || 0; //default to zero if undefined
|
|
1438
|
-
const blocksforfullprotection = block.fullProtection;
|
|
1439
|
-
const fractionOfFullILPProtection = (currentHeight - heightLastAdded) / blocksforfullprotection;
|
|
1440
|
-
const protectionProgress = Math.min(fractionOfFullILPProtection, 1); // percentage of entitlement, max 100%
|
|
1441
|
-
const result = coverage.times(protectionProgress); // impermanent loss protection result
|
|
1442
|
-
const maxILP = result.lt(0) ? new BigNumber(0) : result; // max negative ILP to 0
|
|
1443
|
-
const ILProtection = {
|
|
1444
|
-
ILProtection: new CryptoAmount(baseAmount(maxILP), AssetRuneNative),
|
|
1445
|
-
totalDays: (fractionOfFullILPProtection * 100).toFixed(2),
|
|
1446
|
-
};
|
|
1447
|
-
return ILProtection;
|
|
1448
|
-
};
|
|
1449
|
-
|
|
1450
1485
|
const BN_1 = new BigNumber(1);
|
|
1451
1486
|
const defaultCache = new ThorchainCache();
|
|
1452
1487
|
/**
|
|
@@ -2149,6 +2184,20 @@ class ThorchainQuery {
|
|
|
2149
2184
|
rune: new CryptoAmount(assetToBase(assetAmount(0)), AssetRuneNative),
|
|
2150
2185
|
};
|
|
2151
2186
|
return dustValues;
|
|
2187
|
+
case 'BSC':
|
|
2188
|
+
// 0 BSC
|
|
2189
|
+
dustValues = {
|
|
2190
|
+
asset: new CryptoAmount(assetToBase(assetAmount(0)), asset),
|
|
2191
|
+
rune: new CryptoAmount(assetToBase(assetAmount(0)), AssetRuneNative),
|
|
2192
|
+
};
|
|
2193
|
+
return dustValues;
|
|
2194
|
+
case 'MAYA':
|
|
2195
|
+
// 0 MAYA
|
|
2196
|
+
dustValues = {
|
|
2197
|
+
asset: new CryptoAmount(assetToBase(assetAmount(0)), asset),
|
|
2198
|
+
rune: new CryptoAmount(assetToBase(assetAmount(0)), AssetRuneNative),
|
|
2199
|
+
};
|
|
2200
|
+
return dustValues;
|
|
2152
2201
|
default:
|
|
2153
2202
|
throw Error('Unknown chain');
|
|
2154
2203
|
}
|
|
@@ -2740,4 +2789,4 @@ class TransactionStage {
|
|
|
2740
2789
|
}
|
|
2741
2790
|
}
|
|
2742
2791
|
|
|
2743
|
-
export { AddLpStatus, AddSaverStatus, CryptoAmount, InboundStatus, LiquidityPool, Midgard, RefundStatus, SwapStatus, ThorchainCache, ThorchainQuery, Thornode, TransactionStage, TxType, WithdrawStatus, calcNetworkFee, getDoubleSwap, getLiquidityProtectionData, getLiquidityUnits, getPoolShare, getSingleSwap, getSlipOnLiquidity };
|
|
2792
|
+
export { AVAXChain, AddLpStatus, AddSaverStatus, AssetATOM, AssetAVAX, AssetBCH, AssetBNB, AssetBSC, AssetBTC, AssetDOGE, AssetETH, AssetLTC, AssetMAYA, AssetRuneNative, BCHChain, BNBChain, BSCChain, BTCChain, CryptoAmount, DOGEChain, ETHChain, GAIAChain, InboundStatus, LTCChain, LiquidityPool, MAYAChain, Midgard, RefundStatus, SwapStatus, THORChain, ThorchainCache, ThorchainQuery, Thornode, TransactionStage, TxType, WithdrawStatus, calcNetworkFee, getDoubleSwap, getLiquidityProtectionData, getLiquidityUnits, getPoolShare, getSingleSwap, getSlipOnLiquidity, isAssetRuneNative };
|