@xchainjs/xchain-thorchain-query 0.1.0-beta → 0.1.0-beta2
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 +471 -135
- package/lib/index.js +434 -98
- package/lib/thorchain-cache.d.ts +12 -0
- package/lib/thorchain-query.d.ts +31 -2
- package/lib/types.d.ts +67 -7
- package/lib/utils/liquidity.d.ts +24 -17
- package/lib/utils/midgard.d.ts +19 -3
- package/lib/utils/thornode.d.ts +24 -1
- package/package.json +5 -5
package/lib/index.esm.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { ObservedTxStatusEnum, TransactionsApi, Configuration as Configuration$1, QueueApi, NetworkApi, PoolsApi } from '@xchainjs/xchain-thornode';
|
|
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 } from '@xchainjs/xchain-util';
|
|
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';
|
|
3
3
|
import BigNumber$1, { BigNumber } from 'bignumber.js';
|
|
4
|
+
import { baseAmount, AssetRuneNative } from '@xchainjs/xchain-util/lib';
|
|
4
5
|
import { Network } from '@xchainjs/xchain-client';
|
|
5
6
|
import { MidgardApi, Configuration } from '@xchainjs/xchain-midgard';
|
|
6
7
|
import axios from 'axios';
|
|
@@ -176,14 +177,114 @@ var TxStage;
|
|
|
176
177
|
TxStage[TxStage["OUTBOUND_QUEUED"] = 3] = "OUTBOUND_QUEUED";
|
|
177
178
|
TxStage[TxStage["OUTBOUND_CHAIN_UNCONFIRMED"] = 4] = "OUTBOUND_CHAIN_UNCONFIRMED";
|
|
178
179
|
TxStage[TxStage["OUTBOUND_CHAIN_CONFIRMED"] = 5] = "OUTBOUND_CHAIN_CONFIRMED";
|
|
179
|
-
})(TxStage || (TxStage = {}));
|
|
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
|
+
};
|
|
180
281
|
|
|
181
282
|
const getBaseAmountWithDiffDecimals = (inputAmount, outDecimals) => {
|
|
182
283
|
const inDecimals = inputAmount.baseAmount.decimal;
|
|
183
284
|
let baseAmountOut = inputAmount.baseAmount.amount();
|
|
184
285
|
const adjustDecimals = outDecimals - inDecimals;
|
|
185
286
|
baseAmountOut = baseAmountOut.times(Math.pow(10, adjustDecimals));
|
|
186
|
-
return baseAmount(baseAmountOut, outDecimals).amount();
|
|
287
|
+
return baseAmount$1(baseAmountOut, outDecimals).amount();
|
|
187
288
|
};
|
|
188
289
|
/**
|
|
189
290
|
*
|
|
@@ -198,14 +299,14 @@ const getSwapFee = (inputAmount, pool, toRune) => {
|
|
|
198
299
|
const x = getBaseAmountWithDiffDecimals(inputAmount, 8);
|
|
199
300
|
const X = toRune ? pool.assetBalance.amount() : pool.runeBalance.amount(); // input is asset if toRune
|
|
200
301
|
const Y = toRune ? pool.runeBalance.amount() : pool.assetBalance.amount(); // output is rune if toRune
|
|
201
|
-
const units = toRune ? AssetRuneNative : pool.asset;
|
|
302
|
+
const units = toRune ? AssetRuneNative$1 : pool.asset;
|
|
202
303
|
const numerator = x.times(x).multipliedBy(Y);
|
|
203
304
|
const denominator = x.plus(X).pow(2);
|
|
204
305
|
const result = numerator.div(denominator);
|
|
205
|
-
const eightDecimalResult = new CryptoAmount(baseAmount(result), units);
|
|
306
|
+
const eightDecimalResult = new CryptoAmount(baseAmount$1(result), units);
|
|
206
307
|
const decimals = toRune ? 8 : inputAmount.baseAmount.decimal;
|
|
207
308
|
const baseOut = getBaseAmountWithDiffDecimals(eightDecimalResult, decimals);
|
|
208
|
-
const swapFee = new CryptoAmount(baseAmount(baseOut, decimals), units);
|
|
309
|
+
const swapFee = new CryptoAmount(baseAmount$1(baseOut, decimals), units);
|
|
209
310
|
//console.log(` swapFee ${swapFee.assetAmountFixedString()} `)
|
|
210
311
|
return swapFee;
|
|
211
312
|
};
|
|
@@ -236,15 +337,15 @@ const getSwapOutput = (inputAmount, pool, toRune) => {
|
|
|
236
337
|
const x = getBaseAmountWithDiffDecimals(inputAmount, 8);
|
|
237
338
|
const X = toRune ? pool.assetBalance.amount() : pool.runeBalance.amount(); // input is asset if toRune
|
|
238
339
|
const Y = toRune ? pool.runeBalance.amount() : pool.assetBalance.amount(); // output is rune if toRune
|
|
239
|
-
const units = toRune ? AssetRuneNative : pool.asset;
|
|
340
|
+
const units = toRune ? AssetRuneNative$1 : pool.asset;
|
|
240
341
|
// const decimals = toRune || !pool.decimals ? 8 : pool.decimals
|
|
241
342
|
const numerator = x.times(X).times(Y);
|
|
242
343
|
const denominator = x.plus(X).pow(2);
|
|
243
344
|
const result = numerator.div(denominator);
|
|
244
|
-
const eightDecimalResult = new CryptoAmount(baseAmount(result), units);
|
|
345
|
+
const eightDecimalResult = new CryptoAmount(baseAmount$1(result), units);
|
|
245
346
|
const decimals = toRune ? 8 : inputAmount.baseAmount.decimal;
|
|
246
347
|
const baseOut = getBaseAmountWithDiffDecimals(eightDecimalResult, decimals);
|
|
247
|
-
return new CryptoAmount(baseAmount(baseOut, decimals), units);
|
|
348
|
+
return new CryptoAmount(baseAmount$1(baseOut, decimals), units);
|
|
248
349
|
};
|
|
249
350
|
const getDoubleSwapOutput = (inputAmount, pool1, pool2) => {
|
|
250
351
|
// formula: getSwapOutput(pool1) => getSwapOutput(pool2)
|
|
@@ -281,7 +382,7 @@ const getDoubleSwapFee = (inputAmount, pool1, pool2, thorchainCache) => __awaite
|
|
|
281
382
|
const fee1InRune = getSwapFee(inputAmount, pool1, true);
|
|
282
383
|
const swapOutput = getSwapOutput(inputAmount, pool1, true);
|
|
283
384
|
const fee2InAsset = getSwapFee(swapOutput, pool2, false);
|
|
284
|
-
const fee2InRune = yield thorchainCache.convert(fee2InAsset, AssetRuneNative);
|
|
385
|
+
const fee2InRune = yield thorchainCache.convert(fee2InAsset, AssetRuneNative$1);
|
|
285
386
|
const result = fee1InRune.plus(fee2InRune);
|
|
286
387
|
return result;
|
|
287
388
|
});
|
|
@@ -314,23 +415,23 @@ const getDoubleSwap = (inputAmount, pool1, pool2, thorchainCache) => __awaiter(v
|
|
|
314
415
|
*/
|
|
315
416
|
const calcNetworkFee = (asset, gasRate) => {
|
|
316
417
|
if (asset.synth)
|
|
317
|
-
return new CryptoAmount(baseAmount(2000000), AssetRuneNative);
|
|
418
|
+
return new CryptoAmount(baseAmount$1(2000000), AssetRuneNative$1);
|
|
318
419
|
switch (asset.chain) {
|
|
319
420
|
case Chain.Bitcoin:
|
|
320
|
-
return new CryptoAmount(baseAmount(gasRate.multipliedBy(1000)), AssetBTC);
|
|
421
|
+
return new CryptoAmount(baseAmount$1(gasRate.multipliedBy(1000)), AssetBTC);
|
|
321
422
|
case Chain.BitcoinCash:
|
|
322
|
-
return new CryptoAmount(baseAmount(gasRate.multipliedBy(1500)), AssetBCH);
|
|
423
|
+
return new CryptoAmount(baseAmount$1(gasRate.multipliedBy(1500)), AssetBCH);
|
|
323
424
|
case Chain.Litecoin:
|
|
324
|
-
return new CryptoAmount(baseAmount(gasRate.multipliedBy(250)), AssetLTC);
|
|
425
|
+
return new CryptoAmount(baseAmount$1(gasRate.multipliedBy(250)), AssetLTC);
|
|
325
426
|
case Chain.Doge:
|
|
326
427
|
// NOTE: UTXO chains estimate fees with a 250 byte size
|
|
327
|
-
return new CryptoAmount(baseAmount(gasRate.multipliedBy(1000)), AssetDOGE);
|
|
428
|
+
return new CryptoAmount(baseAmount$1(gasRate.multipliedBy(1000)), AssetDOGE);
|
|
328
429
|
case Chain.Binance:
|
|
329
430
|
//flat fee
|
|
330
|
-
return new CryptoAmount(baseAmount(gasRate), AssetBNB);
|
|
431
|
+
return new CryptoAmount(baseAmount$1(gasRate), AssetBNB);
|
|
331
432
|
case Chain.Ethereum:
|
|
332
433
|
const gasRateinETHGwei = gasRate;
|
|
333
|
-
const gasRateinETHWei = baseAmount(gasRateinETHGwei.multipliedBy(Math.pow(10, 9)), 18);
|
|
434
|
+
const gasRateinETHWei = baseAmount$1(gasRateinETHGwei.multipliedBy(Math.pow(10, 9)), 18);
|
|
334
435
|
if (eqAsset(asset, AssetETH)) {
|
|
335
436
|
return new CryptoAmount(gasRateinETHWei.times(21000), AssetETH);
|
|
336
437
|
}
|
|
@@ -339,7 +440,7 @@ const calcNetworkFee = (asset, gasRate) => {
|
|
|
339
440
|
}
|
|
340
441
|
case Chain.Avalanche:
|
|
341
442
|
const gasRateinAVAXGwei = gasRate;
|
|
342
|
-
const gasRateinAVAXWei = baseAmount(gasRateinAVAXGwei.multipliedBy(Math.pow(10, 9)), 18);
|
|
443
|
+
const gasRateinAVAXWei = baseAmount$1(gasRateinAVAXGwei.multipliedBy(Math.pow(10, 9)), 18);
|
|
343
444
|
if (eqAsset(asset, AssetAVAX)) {
|
|
344
445
|
return new CryptoAmount(gasRateinAVAXWei.times(21000), AssetAVAX);
|
|
345
446
|
}
|
|
@@ -347,11 +448,11 @@ const calcNetworkFee = (asset, gasRate) => {
|
|
|
347
448
|
return new CryptoAmount(gasRateinAVAXWei.times(70000), AssetAVAX);
|
|
348
449
|
}
|
|
349
450
|
case Chain.Terra:
|
|
350
|
-
return new CryptoAmount(baseAmount(gasRate), AssetLUNA);
|
|
451
|
+
return new CryptoAmount(baseAmount$1(gasRate), AssetLUNA);
|
|
351
452
|
case Chain.Cosmos:
|
|
352
|
-
return new CryptoAmount(baseAmount(gasRate), AssetAtom);
|
|
453
|
+
return new CryptoAmount(baseAmount$1(gasRate), AssetAtom);
|
|
353
454
|
case Chain.THORChain:
|
|
354
|
-
return new CryptoAmount(baseAmount(2000000), AssetRuneNative);
|
|
455
|
+
return new CryptoAmount(baseAmount$1(2000000), AssetRuneNative$1);
|
|
355
456
|
}
|
|
356
457
|
throw new Error(`could not calculate inbound fee for ${asset.chain}`);
|
|
357
458
|
};
|
|
@@ -369,7 +470,7 @@ const getChainAsset = (chain) => {
|
|
|
369
470
|
case ETHChain:
|
|
370
471
|
return AssetETH;
|
|
371
472
|
case THORChain:
|
|
372
|
-
return AssetRuneNative;
|
|
473
|
+
return AssetRuneNative$1;
|
|
373
474
|
case CosmosChain:
|
|
374
475
|
return AssetAtom;
|
|
375
476
|
case BCHChain:
|
|
@@ -555,13 +656,13 @@ class ThorchainQuery {
|
|
|
555
656
|
? params.input
|
|
556
657
|
: yield this.thorchainCache.convert(params.input, params.input.asset);
|
|
557
658
|
// If asset is already rune native, skip the convert
|
|
558
|
-
const inputInRune = input.asset === AssetRuneNative ? input : yield this.thorchainCache.convert(input, AssetRuneNative);
|
|
659
|
+
const inputInRune = input.asset === AssetRuneNative$1 ? input : yield this.thorchainCache.convert(input, AssetRuneNative$1);
|
|
559
660
|
const inboundFeeInAsset = calcNetworkFee(input.asset, sourceInboundDetails.gas_rate);
|
|
560
661
|
let outboundFeeInAsset = calcNetworkFee(params.destinationAsset, destinationInboundDetails.gas_rate);
|
|
561
662
|
outboundFeeInAsset = outboundFeeInAsset.times(3);
|
|
562
663
|
// convert fees to rune
|
|
563
|
-
const inboundFeeInRune = yield this.thorchainCache.convert(inboundFeeInAsset, AssetRuneNative);
|
|
564
|
-
let outboundFeeInRune = yield this.thorchainCache.convert(outboundFeeInAsset, AssetRuneNative);
|
|
664
|
+
const inboundFeeInRune = yield this.thorchainCache.convert(inboundFeeInAsset, AssetRuneNative$1);
|
|
665
|
+
let outboundFeeInRune = yield this.thorchainCache.convert(outboundFeeInAsset, AssetRuneNative$1);
|
|
565
666
|
// ---------- Remove Fees from inbound before doing the swap -----------
|
|
566
667
|
// TODO confirm with chris about this change, was there a reason why this was commented out?
|
|
567
668
|
const inputMinusInboundFeeInRune = inputInRune.minus(inboundFeeInRune);
|
|
@@ -577,18 +678,18 @@ class ThorchainQuery {
|
|
|
577
678
|
const deepestUSDPOOL = yield this.thorchainCache.getDeepestUSDPool();
|
|
578
679
|
const usdAsset = deepestUSDPOOL.asset;
|
|
579
680
|
const networkValues = yield this.thorchainCache.midgard.getNetworkValues();
|
|
580
|
-
const usdMinFee = new CryptoAmount(baseAmount(networkValues['MINIMUML1OUTBOUNDFEEUSD']), usdAsset);
|
|
681
|
+
const usdMinFee = new CryptoAmount(baseAmount$1(networkValues['MINIMUML1OUTBOUNDFEEUSD']), usdAsset);
|
|
581
682
|
// const FeeInUSD = await this.convert(outboundFeeInRune, usdAsset)
|
|
582
683
|
const checkOutboundFee = (yield this.convert(outboundFeeInRune, usdAsset)).gte(usdMinFee);
|
|
583
684
|
if (!checkOutboundFee) {
|
|
584
685
|
const newFee = usdMinFee;
|
|
585
|
-
outboundFeeInRune = yield this.convert(newFee, AssetRuneNative);
|
|
686
|
+
outboundFeeInRune = yield this.convert(newFee, AssetRuneNative$1);
|
|
586
687
|
}
|
|
587
688
|
}
|
|
588
689
|
// Now calculate swap output based on inputNetAmount
|
|
589
690
|
const swapOutput = yield this.thorchainCache.getExpectedSwapOutput(inputNetInAsset, params.destinationAsset);
|
|
590
|
-
const swapFeeInRune = yield this.thorchainCache.convert(swapOutput.swapFee, AssetRuneNative);
|
|
591
|
-
const outputInRune = yield this.thorchainCache.convert(swapOutput.output, AssetRuneNative);
|
|
691
|
+
const swapFeeInRune = yield this.thorchainCache.convert(swapOutput.swapFee, AssetRuneNative$1);
|
|
692
|
+
const outputInRune = yield this.thorchainCache.convert(swapOutput.output, AssetRuneNative$1);
|
|
592
693
|
// ---------------- Remove Outbound Fee ---------------------- /
|
|
593
694
|
const netOutputInRune = outputInRune.minus(outboundFeeInRune);
|
|
594
695
|
const netOutputInAsset = yield this.thorchainCache.convert(netOutputInRune, params.destinationAsset);
|
|
@@ -689,8 +790,8 @@ class ThorchainQuery {
|
|
|
689
790
|
checkCoverFees(params, estimate) {
|
|
690
791
|
return __awaiter(this, void 0, void 0, function* () {
|
|
691
792
|
let result = undefined;
|
|
692
|
-
const inputInRune = yield this.thorchainCache.convert(params.input, AssetRuneNative);
|
|
693
|
-
const feesInRune = yield this.getFeesIn(estimate.totalFees, AssetRuneNative);
|
|
793
|
+
const inputInRune = yield this.thorchainCache.convert(params.input, AssetRuneNative$1);
|
|
794
|
+
const feesInRune = yield this.getFeesIn(estimate.totalFees, AssetRuneNative$1);
|
|
694
795
|
const totalSwapFeesInRune = feesInRune.inboundFee
|
|
695
796
|
.plus(feesInRune.outboundFee)
|
|
696
797
|
.plus(feesInRune.swapFee)
|
|
@@ -777,13 +878,15 @@ class ThorchainQuery {
|
|
|
777
878
|
outboundDelay(outboundAmount) {
|
|
778
879
|
return __awaiter(this, void 0, void 0, function* () {
|
|
779
880
|
const networkValues = yield this.thorchainCache.getNetworkValues();
|
|
780
|
-
const minTxOutVolumeThreshold = new CryptoAmount(baseAmount(networkValues['MINTXOUTVOLUMETHRESHOLD']), AssetRuneNative);
|
|
881
|
+
const minTxOutVolumeThreshold = new CryptoAmount(baseAmount$1(networkValues['MINTXOUTVOLUMETHRESHOLD']), AssetRuneNative$1);
|
|
781
882
|
const maxTxOutOffset = networkValues['MAXTXOUTOFFSET'];
|
|
782
|
-
let txOutDelayRate = new CryptoAmount(baseAmount(networkValues['TXOUTDELAYRATE']), AssetRuneNative)
|
|
883
|
+
let txOutDelayRate = new CryptoAmount(baseAmount$1(networkValues['TXOUTDELAYRATE']), AssetRuneNative$1).assetAmount
|
|
884
|
+
.amount()
|
|
885
|
+
.toNumber();
|
|
783
886
|
const getScheduledOutboundValue = yield this.thorchainCache.midgard.getScheduledOutboundValue();
|
|
784
887
|
const thorChainblocktime = this.chainAttributes[Chain.THORChain].avgBlockTimeInSecs; // blocks required to confirm tx
|
|
785
888
|
// If asset is equal to Rune set runeValue as outbound amount else set it to the asset's value in rune
|
|
786
|
-
const runeValue = yield this.thorchainCache.convert(outboundAmount, AssetRuneNative);
|
|
889
|
+
const runeValue = yield this.thorchainCache.convert(outboundAmount, AssetRuneNative$1);
|
|
787
890
|
// Check rune value amount
|
|
788
891
|
if (runeValue.lt(minTxOutVolumeThreshold)) {
|
|
789
892
|
return thorChainblocktime;
|
|
@@ -797,11 +900,9 @@ class ThorchainQuery {
|
|
|
797
900
|
// calculate the if outboundAmountTotal is over the volume threshold
|
|
798
901
|
const volumeThreshold = outboundAmountTotal.div(minTxOutVolumeThreshold);
|
|
799
902
|
// check delay rate
|
|
800
|
-
txOutDelayRate = txOutDelayRate
|
|
801
|
-
? new CryptoAmount(baseAmount(1), AssetRuneNative)
|
|
802
|
-
: txOutDelayRate;
|
|
903
|
+
txOutDelayRate = txOutDelayRate - volumeThreshold.assetAmount.amount().toNumber() <= 1 ? 1 : txOutDelayRate;
|
|
803
904
|
// calculate the minimum number of blocks in the future the txn has to be
|
|
804
|
-
let minBlocks = runeValue.
|
|
905
|
+
let minBlocks = runeValue.assetAmount.amount().toNumber() / txOutDelayRate;
|
|
805
906
|
minBlocks = minBlocks > maxTxOutOffset ? maxTxOutOffset : minBlocks;
|
|
806
907
|
return minBlocks * thorChainblocktime;
|
|
807
908
|
});
|
|
@@ -836,10 +937,12 @@ class ThorchainQuery {
|
|
|
836
937
|
if (!pool)
|
|
837
938
|
throw Error(`No pool found from memo`);
|
|
838
939
|
const getAsset = assetFromString(pool[1].toUpperCase());
|
|
940
|
+
if (!getAsset)
|
|
941
|
+
throw Error(`Invalid pool asset`);
|
|
839
942
|
// Retrieve thorchain blockHeight for the tx
|
|
840
943
|
if (!((_b = txData.observed_tx.tx) === null || _b === void 0 ? void 0 : _b.id))
|
|
841
944
|
throw Error('No action observed');
|
|
842
|
-
const recordedAction = yield this.thorchainCache.midgard.getActions(txData.observed_tx.tx.id);
|
|
945
|
+
const recordedAction = yield this.thorchainCache.midgard.getActions('', txData.observed_tx.tx.id);
|
|
843
946
|
const recordedTCBlock = recordedAction.find((block) => {
|
|
844
947
|
return block;
|
|
845
948
|
});
|
|
@@ -1013,6 +1116,228 @@ class ThorchainQuery {
|
|
|
1013
1116
|
return txStatus;
|
|
1014
1117
|
});
|
|
1015
1118
|
}
|
|
1119
|
+
/**
|
|
1120
|
+
* Estimates a liquidity position for given crypto amount value, both asymmetrical and symetrical
|
|
1121
|
+
* @param params - parameters needed for a estimated liquidity position
|
|
1122
|
+
* @returns - type object EstimateLP
|
|
1123
|
+
*/
|
|
1124
|
+
estimateAddLP(params) {
|
|
1125
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1126
|
+
const errors = [];
|
|
1127
|
+
if (params.asset.asset.synth || params.rune.asset.synth)
|
|
1128
|
+
errors.push('you cannot add liquidity with a synth');
|
|
1129
|
+
if (!isAssetRuneNative(params.rune.asset))
|
|
1130
|
+
errors.push('params.rune must be THOR.RUNE');
|
|
1131
|
+
const assetPool = yield this.thorchainCache.getPoolForAsset(params.asset.asset);
|
|
1132
|
+
const lpUnits = getLiquidityUnits({ asset: params.asset.baseAmount, rune: params.rune.baseAmount }, assetPool);
|
|
1133
|
+
const inboundDetails = yield this.thorchainCache.midgard.getInboundDetails();
|
|
1134
|
+
const unitData = {
|
|
1135
|
+
liquidityUnits: baseAmount$1(lpUnits),
|
|
1136
|
+
totalUnits: baseAmount$1(assetPool.pool.liquidityUnits),
|
|
1137
|
+
};
|
|
1138
|
+
const poolShare = getPoolShare(unitData, assetPool);
|
|
1139
|
+
const assetWaitTimeSeconds = yield this.confCounting(params.asset);
|
|
1140
|
+
const runeWaitTimeSeconds = yield this.confCounting(params.rune);
|
|
1141
|
+
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);
|
|
1144
|
+
if (!params.asset.assetAmount.eq(0)) {
|
|
1145
|
+
assetInboundFee = calcNetworkFee(params.asset.asset, inboundDetails[params.asset.asset.chain].gas_rate);
|
|
1146
|
+
if (assetInboundFee.assetAmount.amount().times(3).gt(params.asset.assetAmount.amount()))
|
|
1147
|
+
errors.push(`Asset amount is less than fees`);
|
|
1148
|
+
}
|
|
1149
|
+
if (!params.rune.assetAmount.eq(0)) {
|
|
1150
|
+
runeInboundFee = calcNetworkFee(params.rune.asset, inboundDetails[params.rune.asset.chain].gas_rate);
|
|
1151
|
+
if (runeInboundFee.assetAmount.amount().times(3).gt(params.rune.assetAmount.amount()))
|
|
1152
|
+
errors.push(`Rune amount is less than fees`);
|
|
1153
|
+
}
|
|
1154
|
+
const totalFees = (yield this.convert(assetInboundFee, AssetRuneNative$1)).plus(runeInboundFee);
|
|
1155
|
+
const slip = getSlipOnLiquidity({ asset: params.asset.baseAmount, rune: params.rune.baseAmount }, assetPool);
|
|
1156
|
+
const estimateLP = {
|
|
1157
|
+
slipPercent: slip.times(100),
|
|
1158
|
+
poolShare: poolShare,
|
|
1159
|
+
lpUnits: baseAmount$1(lpUnits),
|
|
1160
|
+
runeToAssetRatio: assetPool.runeToAssetRatio,
|
|
1161
|
+
transactionFee: {
|
|
1162
|
+
assetFee: assetInboundFee,
|
|
1163
|
+
runeFee: runeInboundFee,
|
|
1164
|
+
totalFees: totalFees,
|
|
1165
|
+
},
|
|
1166
|
+
estimatedWaitSeconds: waitTimeSeconds,
|
|
1167
|
+
errors,
|
|
1168
|
+
canAdd: errors.length > 0 ? false : true,
|
|
1169
|
+
};
|
|
1170
|
+
return estimateLP;
|
|
1171
|
+
});
|
|
1172
|
+
}
|
|
1173
|
+
/**
|
|
1174
|
+
* @param - Asset for lp
|
|
1175
|
+
* @param address - address used for Lp
|
|
1176
|
+
* @returns - Type Object liquidityPosition
|
|
1177
|
+
*/
|
|
1178
|
+
checkLiquidityPosition(asset, assetOrRuneAddress) {
|
|
1179
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1180
|
+
const poolAsset = yield this.thorchainCache.getPoolForAsset(asset);
|
|
1181
|
+
if (!poolAsset)
|
|
1182
|
+
throw Error(`Could not find pool for ${asset}`);
|
|
1183
|
+
const liquidityProvider = yield this.thorchainCache.thornode.getLiquidityProvider(poolAsset.assetString, assetOrRuneAddress);
|
|
1184
|
+
if (!liquidityProvider)
|
|
1185
|
+
throw Error(`Could not find LP for ${assetOrRuneAddress}`);
|
|
1186
|
+
// Current block number for that chain
|
|
1187
|
+
const blockData = (yield this.thorchainCache.thornode.getLastBlock()).find((item) => item.chain === asset.chain);
|
|
1188
|
+
if (!blockData)
|
|
1189
|
+
throw Error(`Could not get block data`);
|
|
1190
|
+
// Pools total units & Lp's total units
|
|
1191
|
+
const unitData = {
|
|
1192
|
+
totalUnits: baseAmount$1(poolAsset.pool.liquidityUnits),
|
|
1193
|
+
liquidityUnits: baseAmount$1(liquidityProvider.units),
|
|
1194
|
+
};
|
|
1195
|
+
//console.log(`unit data`, unitData.totalUnits.amount().toNumber(), unitData.liquidityUnits.amount().toNumber())
|
|
1196
|
+
const networkValues = yield this.thorchainCache.midgard.getNetworkValues();
|
|
1197
|
+
const block = {
|
|
1198
|
+
current: blockData.thorchain,
|
|
1199
|
+
lastAdded: liquidityProvider.last_add_height,
|
|
1200
|
+
fullProtection: networkValues['FULLIMPLOSSPROTECTIONBLOCKS'],
|
|
1201
|
+
};
|
|
1202
|
+
//
|
|
1203
|
+
const currentLP = {
|
|
1204
|
+
asset: baseAmount$1(liquidityProvider.asset_deposit_value),
|
|
1205
|
+
rune: baseAmount$1(liquidityProvider.rune_deposit_value),
|
|
1206
|
+
};
|
|
1207
|
+
const poolShare = getPoolShare(unitData, poolAsset);
|
|
1208
|
+
// console.log(poolShare.assetShare.toNumber(), poolShare.runeShare.toNumber())
|
|
1209
|
+
// console.log(poolAsset.pool.liquidityUnits)
|
|
1210
|
+
const impermanentLossProtection = getLiquidityProtectionData(currentLP, poolShare, block);
|
|
1211
|
+
const lpPosition = {
|
|
1212
|
+
poolShare,
|
|
1213
|
+
position: liquidityProvider,
|
|
1214
|
+
impermanentLossProtection: impermanentLossProtection,
|
|
1215
|
+
};
|
|
1216
|
+
return lpPosition;
|
|
1217
|
+
});
|
|
1218
|
+
}
|
|
1219
|
+
/**
|
|
1220
|
+
* Do not send assetNativeRune, There is no pool for it.
|
|
1221
|
+
* @param asset - asset required to find the pool
|
|
1222
|
+
* @returns - object type ratios
|
|
1223
|
+
*/
|
|
1224
|
+
getPoolRatios(asset) {
|
|
1225
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1226
|
+
const assetPool = yield this.thorchainCache.getPoolForAsset(asset);
|
|
1227
|
+
const poolRatio = {
|
|
1228
|
+
assetToRune: assetPool.assetToRuneRatio,
|
|
1229
|
+
runeToAsset: assetPool.runeToAssetRatio,
|
|
1230
|
+
};
|
|
1231
|
+
return poolRatio;
|
|
1232
|
+
});
|
|
1233
|
+
}
|
|
1234
|
+
/**
|
|
1235
|
+
*
|
|
1236
|
+
* @param params
|
|
1237
|
+
*/
|
|
1238
|
+
estimateWithdrawLP(params) {
|
|
1239
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1240
|
+
// 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);
|
|
1244
|
+
const dustValues = yield this.getDustValues(params.asset); // returns asset and rune dust values
|
|
1245
|
+
const assetPool = yield this.thorchainCache.getPoolForAsset(params.asset);
|
|
1246
|
+
// get pool share from unit data
|
|
1247
|
+
const poolShare = getPoolShare({
|
|
1248
|
+
liquidityUnits: baseAmount$1(memberDetail.position.units),
|
|
1249
|
+
totalUnits: baseAmount$1(assetPool.pool.liquidityUnits),
|
|
1250
|
+
}, assetPool);
|
|
1251
|
+
// calculate total fees
|
|
1252
|
+
const totalFees = (yield this.convert(dustValues.asset, AssetRuneNative$1)).plus(dustValues.rune);
|
|
1253
|
+
// get slip on liquidity removal
|
|
1254
|
+
const slip = getSlipOnLiquidity({
|
|
1255
|
+
asset: poolShare.assetShare.baseAmount,
|
|
1256
|
+
rune: poolShare.runeShare.baseAmount,
|
|
1257
|
+
}, assetPool);
|
|
1258
|
+
// TODO make sure we compare wait times for withdrawing both rune and asset OR just rune OR just asset
|
|
1259
|
+
const waitTimeSecondsForAsset = yield this.confCounting(poolShare.assetShare.div(params.percentage / 100));
|
|
1260
|
+
const waitTimeSecondsForRune = yield this.confCounting(poolShare.runeShare.div(params.percentage / 100));
|
|
1261
|
+
let waitTimeSeconds = 0;
|
|
1262
|
+
if (params.assetAddress && params.runeAddress) {
|
|
1263
|
+
waitTimeSeconds = waitTimeSecondsForAsset + waitTimeSecondsForRune;
|
|
1264
|
+
}
|
|
1265
|
+
else if (params.assetAddress) {
|
|
1266
|
+
waitTimeSeconds = waitTimeSecondsForAsset;
|
|
1267
|
+
}
|
|
1268
|
+
else {
|
|
1269
|
+
waitTimeSeconds = waitTimeSecondsForRune;
|
|
1270
|
+
}
|
|
1271
|
+
const estimateLP = {
|
|
1272
|
+
slipPercent: slip.times(100),
|
|
1273
|
+
transactionFee: {
|
|
1274
|
+
assetFee: dustValues.asset,
|
|
1275
|
+
runeFee: dustValues.rune,
|
|
1276
|
+
totalFees: totalFees,
|
|
1277
|
+
},
|
|
1278
|
+
assetAmount: poolShare.assetShare,
|
|
1279
|
+
runeAmount: poolShare.runeShare,
|
|
1280
|
+
estimatedWaitSeconds: waitTimeSeconds,
|
|
1281
|
+
impermanentLossProtection: memberDetail.impermanentLossProtection,
|
|
1282
|
+
};
|
|
1283
|
+
return estimateLP;
|
|
1284
|
+
});
|
|
1285
|
+
}
|
|
1286
|
+
/**
|
|
1287
|
+
* // can this become a quried constant? added to inbound_addresses or something
|
|
1288
|
+
* @param asset - asset needed to retrieve dust values
|
|
1289
|
+
* @returns - object type dust values
|
|
1290
|
+
*/
|
|
1291
|
+
getDustValues(asset) {
|
|
1292
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1293
|
+
let dustValues;
|
|
1294
|
+
switch (asset.chain) {
|
|
1295
|
+
case 'BNB':
|
|
1296
|
+
dustValues = {
|
|
1297
|
+
asset: new CryptoAmount(assetToBase(assetAmount(0.000001)), AssetBNB),
|
|
1298
|
+
rune: new CryptoAmount(assetToBase(assetAmount(0)), AssetRuneNative$1),
|
|
1299
|
+
};
|
|
1300
|
+
return dustValues;
|
|
1301
|
+
case 'BTC' :
|
|
1302
|
+
// 10k sats
|
|
1303
|
+
dustValues = {
|
|
1304
|
+
asset: new CryptoAmount(assetToBase(assetAmount(0.0001)), asset),
|
|
1305
|
+
rune: new CryptoAmount(assetToBase(assetAmount(0)), AssetRuneNative$1),
|
|
1306
|
+
};
|
|
1307
|
+
return dustValues;
|
|
1308
|
+
case 'ETH':
|
|
1309
|
+
// 0 wei
|
|
1310
|
+
dustValues = {
|
|
1311
|
+
asset: new CryptoAmount(assetToBase(assetAmount(0)), asset),
|
|
1312
|
+
rune: new CryptoAmount(assetToBase(assetAmount(0)), AssetRuneNative$1),
|
|
1313
|
+
};
|
|
1314
|
+
return dustValues;
|
|
1315
|
+
case 'THOR':
|
|
1316
|
+
// 0 Rune
|
|
1317
|
+
dustValues = {
|
|
1318
|
+
asset: new CryptoAmount(assetToBase(assetAmount(0)), asset),
|
|
1319
|
+
rune: new CryptoAmount(assetToBase(assetAmount(0)), AssetRuneNative$1),
|
|
1320
|
+
};
|
|
1321
|
+
return dustValues;
|
|
1322
|
+
case 'GAIA':
|
|
1323
|
+
// 0 GAIA
|
|
1324
|
+
dustValues = {
|
|
1325
|
+
asset: new CryptoAmount(assetToBase(assetAmount(0)), asset),
|
|
1326
|
+
rune: new CryptoAmount(assetToBase(assetAmount(0)), AssetRuneNative$1),
|
|
1327
|
+
};
|
|
1328
|
+
return dustValues;
|
|
1329
|
+
case 'DOGE':
|
|
1330
|
+
// 1 million sats
|
|
1331
|
+
dustValues = {
|
|
1332
|
+
asset: new CryptoAmount(assetToBase(assetAmount(0.01)), asset),
|
|
1333
|
+
rune: new CryptoAmount(assetToBase(assetAmount(0)), AssetRuneNative$1),
|
|
1334
|
+
};
|
|
1335
|
+
return dustValues;
|
|
1336
|
+
default:
|
|
1337
|
+
throw Error('Unknown chain');
|
|
1338
|
+
}
|
|
1339
|
+
});
|
|
1340
|
+
}
|
|
1016
1341
|
}
|
|
1017
1342
|
|
|
1018
1343
|
/**
|
|
@@ -1027,8 +1352,8 @@ class LiquidityPool {
|
|
|
1027
1352
|
this.asset = asset;
|
|
1028
1353
|
this.decimals = decimals;
|
|
1029
1354
|
this.assetString = this.pool.asset;
|
|
1030
|
-
this.assetBalance = baseAmount(this.pool.assetDepth);
|
|
1031
|
-
this.runeBalance = baseAmount(this.pool.runeDepth);
|
|
1355
|
+
this.assetBalance = baseAmount$1(this.pool.assetDepth);
|
|
1356
|
+
this.runeBalance = baseAmount$1(this.pool.runeDepth);
|
|
1032
1357
|
this.runeToAssetRatio = this.runeBalance.amount().div(this.assetBalance.amount());
|
|
1033
1358
|
this.assetToRuneRatio = this.assetBalance.amount().div(this.runeBalance.amount());
|
|
1034
1359
|
}
|
|
@@ -1042,12 +1367,15 @@ const TEN_MINUTES = 10 * 60 * 1000;
|
|
|
1042
1367
|
const DEFAULT_THORCHAIN_DECIMALS = 8;
|
|
1043
1368
|
const USD_ASSETS = {
|
|
1044
1369
|
mainnet: [
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1370
|
+
assetFromStringEx('BNB.BUSD-BD1'),
|
|
1371
|
+
assetFromStringEx('ETH.USDC-0XA0B86991C6218B36C1D19D4A2E9EB0CE3606EB48'),
|
|
1372
|
+
assetFromStringEx('ETH.USDT-0XDAC17F958D2EE523A2206206994597C13D831EC7'),
|
|
1373
|
+
],
|
|
1374
|
+
stagenet: [assetFromStringEx('ETH.USDT-0XDAC17F958D2EE523A2206206994597C13D831EC7')],
|
|
1375
|
+
testnet: [
|
|
1376
|
+
assetFromStringEx('BNB.BUSD-74E'),
|
|
1377
|
+
assetFromStringEx('ETH.USDT-0XA3910454BF2CB59B8B3A401589A3BACC5CA42306'),
|
|
1048
1378
|
],
|
|
1049
|
-
stagenet: [assetFromString('ETH.USDT-0XDAC17F958D2EE523A2206206994597C13D831EC7')],
|
|
1050
|
-
testnet: [assetFromString('BNB.BUSD-74E'), assetFromString('ETH.USDT-0XA3910454BF2CB59B8B3A401589A3BACC5CA42306')],
|
|
1051
1379
|
};
|
|
1052
1380
|
/**
|
|
1053
1381
|
* This class manages retrieving information from up to date Thorchain
|
|
@@ -1279,7 +1607,7 @@ class ThorchainCache {
|
|
|
1279
1607
|
let baseAmountOut = input.baseAmount.times(exchangeRate).amount();
|
|
1280
1608
|
const adjustDecimals = outDecimals - inDecimals;
|
|
1281
1609
|
baseAmountOut = baseAmountOut.times(Math.pow(10, adjustDecimals));
|
|
1282
|
-
const amt = baseAmount(baseAmountOut, outDecimals);
|
|
1610
|
+
const amt = baseAmount$1(baseAmountOut, outDecimals);
|
|
1283
1611
|
const result = new CryptoAmount(amt, outAsset);
|
|
1284
1612
|
// console.log(
|
|
1285
1613
|
// `${input.formatedAssetString()} ${input.asset.ticker} = ${result.formatedAssetString()} ${outAsset.ticker}`,
|
|
@@ -1306,6 +1634,10 @@ class ThorchainCache {
|
|
|
1306
1634
|
return inboundAsgard === null || inboundAsgard === void 0 ? void 0 : inboundAsgard.router;
|
|
1307
1635
|
});
|
|
1308
1636
|
}
|
|
1637
|
+
/**
|
|
1638
|
+
*
|
|
1639
|
+
* @returns - inbound adresses item
|
|
1640
|
+
*/
|
|
1309
1641
|
getInboundAddressesItems() {
|
|
1310
1642
|
var _a;
|
|
1311
1643
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -1326,6 +1658,10 @@ class ThorchainCache {
|
|
|
1326
1658
|
}
|
|
1327
1659
|
});
|
|
1328
1660
|
}
|
|
1661
|
+
/**
|
|
1662
|
+
*
|
|
1663
|
+
* @returns - inbound details
|
|
1664
|
+
*/
|
|
1329
1665
|
getInboundDetails() {
|
|
1330
1666
|
var _a;
|
|
1331
1667
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -1346,6 +1682,10 @@ class ThorchainCache {
|
|
|
1346
1682
|
}
|
|
1347
1683
|
});
|
|
1348
1684
|
}
|
|
1685
|
+
/**
|
|
1686
|
+
*
|
|
1687
|
+
* @returns - network values
|
|
1688
|
+
*/
|
|
1349
1689
|
getNetworkValues() {
|
|
1350
1690
|
var _a;
|
|
1351
1691
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -1385,95 +1725,13 @@ class ThorchainCache {
|
|
|
1385
1725
|
}
|
|
1386
1726
|
}
|
|
1387
1727
|
|
|
1388
|
-
/**
|
|
1389
|
-
*
|
|
1390
|
-
* @param liquidity - asset amount added
|
|
1391
|
-
* @param pool - pool depths
|
|
1392
|
-
* @returns liquidity units
|
|
1393
|
-
*/
|
|
1394
|
-
const getLiquidityUnits = (liquidity, pool) => {
|
|
1395
|
-
// formula: ((R + T) (r T + R t))/(4 R T)
|
|
1396
|
-
// part1 * (part2 + part3) / denominator
|
|
1397
|
-
const r = liquidity.rune;
|
|
1398
|
-
const t = liquidity.asset;
|
|
1399
|
-
const R = pool.runeBalance.amount().plus(r); // Must add r first
|
|
1400
|
-
const T = pool.assetBalance.amount().plus(t); // Must add t first
|
|
1401
|
-
const part1 = R.plus(T);
|
|
1402
|
-
const part2 = r.times(T);
|
|
1403
|
-
const part3 = R.times(t);
|
|
1404
|
-
const numerator = part1.times(part2.plus(part3));
|
|
1405
|
-
const denominator = R.times(T).times(4);
|
|
1406
|
-
const result = numerator.div(denominator);
|
|
1407
|
-
return result;
|
|
1408
|
-
};
|
|
1409
|
-
/**
|
|
1410
|
-
*
|
|
1411
|
-
* @param unitData
|
|
1412
|
-
* @param pool
|
|
1413
|
-
* @returns
|
|
1414
|
-
*/
|
|
1415
|
-
const getPoolShare = (unitData, pool) => {
|
|
1416
|
-
// formula: (rune * part) / total; (asset * part) / total
|
|
1417
|
-
const units = unitData.liquidityUnits;
|
|
1418
|
-
const total = unitData.totalUnits;
|
|
1419
|
-
const R = pool.runeBalance.amount();
|
|
1420
|
-
const T = pool.assetBalance.amount();
|
|
1421
|
-
const asset = T.times(units).div(total);
|
|
1422
|
-
const rune = R.times(units).div(total);
|
|
1423
|
-
const liquidityData = {
|
|
1424
|
-
asset: asset,
|
|
1425
|
-
rune: rune,
|
|
1426
|
-
};
|
|
1427
|
-
return liquidityData;
|
|
1428
|
-
};
|
|
1429
|
-
/**
|
|
1430
|
-
*
|
|
1431
|
-
* @param liquidity
|
|
1432
|
-
* @param pool
|
|
1433
|
-
* @returns
|
|
1434
|
-
*/
|
|
1435
|
-
const getSlipOnLiquidity = (liquidity, pool) => {
|
|
1436
|
-
// formula: (t * R - T * r)/ (T*r + R*T)
|
|
1437
|
-
const r = liquidity.rune;
|
|
1438
|
-
const t = liquidity.asset;
|
|
1439
|
-
const R = pool.runeBalance.amount();
|
|
1440
|
-
const T = pool.assetBalance.amount();
|
|
1441
|
-
const numerator = t.times(R).minus(T.times(r));
|
|
1442
|
-
const denominator = T.times(r).plus(R.times(T));
|
|
1443
|
-
const result = numerator.div(denominator).abs();
|
|
1444
|
-
return result;
|
|
1445
|
-
};
|
|
1446
|
-
/**
|
|
1447
|
-
*
|
|
1448
|
-
* @param liquidity
|
|
1449
|
-
* @param pool
|
|
1450
|
-
* @param block
|
|
1451
|
-
* @returns
|
|
1452
|
-
*/
|
|
1453
|
-
// Blocks for full protection 144000 // 100 days
|
|
1454
|
-
const getLiquidityProtectionData = (liquidity, pool, block) => {
|
|
1455
|
-
//formula: protectionProgress (currentHeight-heightLastAdded)/blocksforfullprotection
|
|
1456
|
-
const R0 = liquidity.rune; // symetrical value of rune deposit
|
|
1457
|
-
const A0 = liquidity.asset; // symetrical value of asset deposit
|
|
1458
|
-
const R1 = pool.runeBalance.amount(); // rune to redeem
|
|
1459
|
-
const A1 = pool.assetBalance.amount(); // asset to redeem
|
|
1460
|
-
const P1 = R1.div(A1); // Pool ratio at withdrawal
|
|
1461
|
-
const coverage = A0.times(P1).plus(R0).minus(A1.times(P1).plus(R1));
|
|
1462
|
-
const currentHeight = block.current;
|
|
1463
|
-
const heightLastAdded = block.lastAdded;
|
|
1464
|
-
const blocksforfullprotection = block.fullProtection;
|
|
1465
|
-
const protectionProgress = (currentHeight - heightLastAdded) / blocksforfullprotection;
|
|
1466
|
-
const result = protectionProgress * coverage.toNumber(); // impermanent loss protection result
|
|
1467
|
-
return result;
|
|
1468
|
-
};
|
|
1469
|
-
|
|
1470
1728
|
const defaultMidgardConfig = {
|
|
1471
1729
|
mainnet: {
|
|
1472
1730
|
apiRetries: 3,
|
|
1473
1731
|
midgardBaseUrls: [
|
|
1732
|
+
'https://midgard.ninerealms.com',
|
|
1474
1733
|
'https://midgard.thorchain.info',
|
|
1475
1734
|
'https://midgard.thorswap.net',
|
|
1476
|
-
'https://midgard.ninerealms.com',
|
|
1477
1735
|
],
|
|
1478
1736
|
},
|
|
1479
1737
|
stagenet: {
|
|
@@ -1570,6 +1828,10 @@ class Midgard {
|
|
|
1570
1828
|
return inboundDetails;
|
|
1571
1829
|
});
|
|
1572
1830
|
}
|
|
1831
|
+
/**
|
|
1832
|
+
*
|
|
1833
|
+
* @returns - constants
|
|
1834
|
+
*/
|
|
1573
1835
|
getConstantsDetails() {
|
|
1574
1836
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1575
1837
|
const path = '/v2/thorchain/constants';
|
|
@@ -1595,7 +1857,7 @@ class Midgard {
|
|
|
1595
1857
|
for (const baseUrl of this.config.midgardBaseUrls) {
|
|
1596
1858
|
try {
|
|
1597
1859
|
const { data } = yield axios.get(`${baseUrl}${path}`);
|
|
1598
|
-
const value = new CryptoAmount(baseAmount(data['scheduled_outbound_value']), AssetRuneNative);
|
|
1860
|
+
const value = new CryptoAmount(baseAmount$1(data['scheduled_outbound_value']), AssetRuneNative$1);
|
|
1599
1861
|
return value;
|
|
1600
1862
|
}
|
|
1601
1863
|
catch (e) {
|
|
@@ -1647,15 +1909,15 @@ class Midgard {
|
|
|
1647
1909
|
});
|
|
1648
1910
|
}
|
|
1649
1911
|
/**
|
|
1650
|
-
* Gets actions
|
|
1912
|
+
* Gets actions object for any of the parameters
|
|
1651
1913
|
* @param txHash transaction id
|
|
1652
1914
|
* @returns Type Action array of objects
|
|
1653
1915
|
*/
|
|
1654
|
-
getActions(
|
|
1916
|
+
getActions(address, txid, asset, type, affiliate, limit, offset) {
|
|
1655
1917
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1656
1918
|
for (const api of this.midgardApis) {
|
|
1657
1919
|
try {
|
|
1658
|
-
const actions = (yield api.getActions(
|
|
1920
|
+
const actions = (yield api.getActions(address, txid, asset, type, affiliate, limit, offset)).data.actions;
|
|
1659
1921
|
return actions;
|
|
1660
1922
|
}
|
|
1661
1923
|
catch (e) {
|
|
@@ -1665,6 +1927,44 @@ class Midgard {
|
|
|
1665
1927
|
throw Error(`Midgard not responding`);
|
|
1666
1928
|
});
|
|
1667
1929
|
}
|
|
1930
|
+
/**
|
|
1931
|
+
* Function to return member details based on valid liquidity position
|
|
1932
|
+
* @param address - needed to query for Lp details
|
|
1933
|
+
* @returns - object type of Member Detail
|
|
1934
|
+
*/
|
|
1935
|
+
getMember(address) {
|
|
1936
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1937
|
+
for (const api of this.midgardApis) {
|
|
1938
|
+
try {
|
|
1939
|
+
const memberDetail = (yield api.getMemberDetail(address)).data;
|
|
1940
|
+
return memberDetail;
|
|
1941
|
+
}
|
|
1942
|
+
catch (e) {
|
|
1943
|
+
console.error(e);
|
|
1944
|
+
}
|
|
1945
|
+
}
|
|
1946
|
+
throw Error(`Midgard not responding`);
|
|
1947
|
+
});
|
|
1948
|
+
}
|
|
1949
|
+
/**
|
|
1950
|
+
* Function to return pool statistics for a particular asset
|
|
1951
|
+
* @param asset - asset string to query its pool stats
|
|
1952
|
+
* @returns - type object poolstatsDetail
|
|
1953
|
+
*/
|
|
1954
|
+
getPoolStats(asset) {
|
|
1955
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1956
|
+
for (const api of this.midgardApis) {
|
|
1957
|
+
try {
|
|
1958
|
+
const poolDetail = (yield api.getPoolStats(asset)).data;
|
|
1959
|
+
return poolDetail;
|
|
1960
|
+
}
|
|
1961
|
+
catch (e) {
|
|
1962
|
+
console.error(e);
|
|
1963
|
+
}
|
|
1964
|
+
}
|
|
1965
|
+
throw Error(`Midgard not responding`);
|
|
1966
|
+
});
|
|
1967
|
+
}
|
|
1668
1968
|
}
|
|
1669
1969
|
|
|
1670
1970
|
const defaultThornodeConfig = {
|
|
@@ -1694,6 +1994,7 @@ class Thornode {
|
|
|
1694
1994
|
this.queueApi = this.config.thornodeBaseUrls.map((url) => new QueueApi(new Configuration$1({ basePath: url })));
|
|
1695
1995
|
this.networkApi = this.config.thornodeBaseUrls.map((url) => new NetworkApi(new Configuration$1({ basePath: url })));
|
|
1696
1996
|
this.poolsApi = this.config.thornodeBaseUrls.map((url) => new PoolsApi(new Configuration$1({ basePath: url })));
|
|
1997
|
+
this.liquidityProvidersApi = this.config.thornodeBaseUrls.map((url) => new LiquidityProvidersApi(new Configuration$1({ basePath: url })));
|
|
1697
1998
|
}
|
|
1698
1999
|
/**
|
|
1699
2000
|
* Returns the oubound transactions held by THORChain due to outbound delay
|
|
@@ -1717,6 +2018,11 @@ class Thornode {
|
|
|
1717
2018
|
throw Error(`THORNode not responding`);
|
|
1718
2019
|
});
|
|
1719
2020
|
}
|
|
2021
|
+
/**
|
|
2022
|
+
*
|
|
2023
|
+
* @param txHash - transaction hash
|
|
2024
|
+
* @returns - transaction object
|
|
2025
|
+
*/
|
|
1720
2026
|
getTxData(txHash) {
|
|
1721
2027
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1722
2028
|
for (const api of this.transactionsApi) {
|
|
@@ -1735,6 +2041,11 @@ class Thornode {
|
|
|
1735
2041
|
throw new Error(`THORNode not responding`);
|
|
1736
2042
|
});
|
|
1737
2043
|
}
|
|
2044
|
+
/**
|
|
2045
|
+
*
|
|
2046
|
+
* @param height - optional thorchain height only
|
|
2047
|
+
* @returns - last block data || or block data pertaining to that height number
|
|
2048
|
+
*/
|
|
1738
2049
|
getLastBlock(height) {
|
|
1739
2050
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1740
2051
|
for (const api of this.networkApi) {
|
|
@@ -1749,6 +2060,10 @@ class Thornode {
|
|
|
1749
2060
|
throw new Error(`THORNode not responding`);
|
|
1750
2061
|
});
|
|
1751
2062
|
}
|
|
2063
|
+
/**
|
|
2064
|
+
*
|
|
2065
|
+
* @returns - thorchain pool
|
|
2066
|
+
*/
|
|
1752
2067
|
getPools() {
|
|
1753
2068
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1754
2069
|
for (const api of this.poolsApi) {
|
|
@@ -1764,6 +2079,27 @@ class Thornode {
|
|
|
1764
2079
|
throw new Error(`THORNode not responding`);
|
|
1765
2080
|
});
|
|
1766
2081
|
}
|
|
2082
|
+
/**
|
|
2083
|
+
*
|
|
2084
|
+
* @param asset - asset string
|
|
2085
|
+
* @param address - address
|
|
2086
|
+
* @param height - optional block height, defaults to current tip
|
|
2087
|
+
* @returns
|
|
2088
|
+
*/
|
|
2089
|
+
getLiquidityProvider(asset, address, height) {
|
|
2090
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2091
|
+
for (const api of this.liquidityProvidersApi) {
|
|
2092
|
+
try {
|
|
2093
|
+
const lps = (yield api.liquidityProviders(asset, height)).data;
|
|
2094
|
+
return lps.find((lp) => lp.asset_address === address || lp.rune_address === address);
|
|
2095
|
+
}
|
|
2096
|
+
catch (e) {
|
|
2097
|
+
console.error(e);
|
|
2098
|
+
}
|
|
2099
|
+
}
|
|
2100
|
+
throw new Error(`THORNode not responding`);
|
|
2101
|
+
});
|
|
2102
|
+
}
|
|
1767
2103
|
}
|
|
1768
2104
|
|
|
1769
2105
|
export { CryptoAmount, LiquidityPool, Midgard, ThorchainCache, ThorchainQuery, Thornode, TxStage, calcNetworkFee, getDoubleSwap, getLiquidityProtectionData, getLiquidityUnits, getPoolShare, getSingleSwap, getSlipOnLiquidity };
|