@shapeshiftoss/swapper 14.2.3 → 14.3.0

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.
@@ -1,6 +1,8 @@
1
1
  import { Asset } from '@shapeshiftoss/asset-service';
2
2
  import { AssetId, ChainId } from '@shapeshiftoss/caip';
3
+ import { ChainAdapterManager } from '@shapeshiftoss/chain-adapters';
3
4
  import { KnownChainIds } from '@shapeshiftoss/types';
5
+ import Web3 from 'web3';
4
6
  import type { ApprovalNeededInput, ApprovalNeededOutput, ApproveInfiniteInput, BuildTradeInput, BuyAssetBySellIdInput, ExecuteTradeInput, GetTradeQuoteInput, Swapper, Trade, TradeQuote, TradeResult, TradeTxs } from '../../api';
5
7
  import { SwapperName, SwapperType } from '../../api';
6
8
  import { ThorchainSwapperDeps } from './types';
@@ -12,10 +14,14 @@ export declare class ThorchainSwapper implements Swapper<ChainId> {
12
14
  private supportedSellAssetIds;
13
15
  private supportedBuyAssetIds;
14
16
  deps: ThorchainSwapperDeps;
17
+ daemonUrl: string;
18
+ midgardUrl: string;
19
+ adapterManager: ChainAdapterManager;
20
+ web3: Web3;
15
21
  constructor(deps: ThorchainSwapperDeps);
16
22
  initialize(): Promise<void>;
17
23
  getType(): SwapperType;
18
- getUsdRate(input: Pick<Asset, 'symbol' | 'assetId'>): Promise<string>;
24
+ getUsdRate({ assetId }: Pick<Asset, 'assetId'>): Promise<string>;
19
25
  approvalNeeded(input: ApprovalNeededInput<KnownChainIds.EthereumMainnet>): Promise<ApprovalNeededOutput>;
20
26
  approveInfinite(input: ApproveInfiniteInput<KnownChainIds.EthereumMainnet>): Promise<string>;
21
27
  approveAmount(): Promise<string>;
@@ -46,30 +46,26 @@ class ThorchainSwapper {
46
46
  [types_1.KnownChainIds.CosmosMainnet]: true,
47
47
  [types_1.KnownChainIds.ThorchainMainnet]: true,
48
48
  };
49
- this.supportedSellAssetIds = [];
50
- this.supportedBuyAssetIds = [];
49
+ this.supportedSellAssetIds = [caip_1.thorchainAssetId];
50
+ this.supportedBuyAssetIds = [caip_1.thorchainAssetId];
51
51
  this.deps = deps;
52
+ this.daemonUrl = deps.daemonUrl;
53
+ this.midgardUrl = deps.midgardUrl;
54
+ this.adapterManager = deps.adapterManager;
55
+ this.web3 = deps.web3;
52
56
  }
53
57
  async initialize() {
54
58
  try {
55
59
  const { data: allPools } = await thorService_1.thorService.get(`${this.deps.daemonUrl}/lcd/thorchain/pools`);
56
60
  const availablePools = allPools.filter((pool) => pool.status === 'Available');
57
- this.supportedSellAssetIds = availablePools.reduce((acc, pool) => {
61
+ availablePools.forEach((pool) => {
58
62
  const assetId = caip_1.adapters.poolAssetIdToAssetId(pool.asset);
59
- if (!assetId || !this.sellSupportedChainIds[(0, caip_1.fromAssetId)(assetId).chainId])
60
- return acc;
61
- acc.push(assetId);
62
- return acc;
63
- }, []);
64
- this.supportedSellAssetIds.push(caip_1.thorchainAssetId);
65
- this.supportedBuyAssetIds = availablePools.reduce((acc, pool) => {
66
- const assetId = caip_1.adapters.poolAssetIdToAssetId(pool.asset);
67
- if (!assetId || !this.buySupportedChainIds[(0, caip_1.fromAssetId)(assetId).chainId])
68
- return acc;
69
- acc.push(assetId);
70
- return acc;
71
- }, []);
72
- this.supportedBuyAssetIds.push(caip_1.thorchainAssetId);
63
+ if (!assetId)
64
+ return;
65
+ const { chainId } = (0, caip_1.fromAssetId)(assetId);
66
+ this.sellSupportedChainIds[chainId] && this.supportedSellAssetIds.push(assetId);
67
+ this.buySupportedChainIds[chainId] && this.supportedBuyAssetIds.push(assetId);
68
+ });
73
69
  }
74
70
  catch (e) {
75
71
  throw new api_1.SwapError('[thorchainInitialize]: initialize failed to set supportedAssetIds', {
@@ -81,8 +77,8 @@ class ThorchainSwapper {
81
77
  getType() {
82
78
  return api_1.SwapperType.Thorchain;
83
79
  }
84
- getUsdRate(input) {
85
- return (0, getUsdRate_1.getUsdRate)({ deps: this.deps, input });
80
+ async getUsdRate({ assetId }) {
81
+ return (0, getUsdRate_1.getUsdRate)(this.daemonUrl, assetId);
86
82
  }
87
83
  async approvalNeeded(input) {
88
84
  return (0, thorTradeApprovalNeeded_1.thorTradeApprovalNeeded)({ deps: this.deps, input });
@@ -36,11 +36,8 @@ const getThorTradeQuote = async ({ deps, input }) => {
36
36
  ? constants_2.RUNE_OUTBOUND_TRANSACTION_FEE_CRYPTO_HUMAN.toString()
37
37
  : (0, bignumber_1.fromBaseUnit)((0, bignumber_1.bnOrZero)(buyAssetAddressData === null || buyAssetAddressData === void 0 ? void 0 : buyAssetAddressData.outbound_fee), constants_3.THORCHAIN_FIXED_PRECISION);
38
38
  const buyAssetChainFeeAssetId = buyAdapter.getFeeAssetId();
39
- const sellAssetUsdRate = await (0, getUsdRate_1.getUsdRate)({ deps, input: { assetId: sellAsset.assetId } });
40
- const buyFeeAssetUsdRate = await (0, getUsdRate_1.getUsdRate)({
41
- deps,
42
- input: { assetId: buyAssetChainFeeAssetId },
43
- });
39
+ const sellAssetUsdRate = await (0, getUsdRate_1.getUsdRate)(deps.daemonUrl, sellAsset.assetId);
40
+ const buyFeeAssetUsdRate = await (0, getUsdRate_1.getUsdRate)(deps.daemonUrl, buyAssetChainFeeAssetId);
44
41
  const buyAssetTradeFeeUsd = (0, bignumber_1.bn)(buyFeeAssetUsdRate)
45
42
  .times(estimatedBuyAssetTradeFeeFeeAssetCryptoHuman)
46
43
  .toString();
@@ -4,20 +4,6 @@ import type { BTCSignTx, CosmosSignTx, ETHSignTx } from '@shapeshiftoss/hdwallet
4
4
  import { KnownChainIds } from '@shapeshiftoss/types';
5
5
  import type Web3 from 'web3';
6
6
  import type { Trade, UtxoSupportedChainIds } from '../../api';
7
- export declare type MidgardPoolResponse = {
8
- asset: string;
9
- assetDepth: string;
10
- assetPrice: string;
11
- assetPriceUSD: string;
12
- liquidityUnits: string;
13
- poolAPY: string;
14
- runeDepth: string;
15
- status: string;
16
- synthSupply: string;
17
- synthUnits: string;
18
- units: string;
19
- volume24h: string;
20
- };
21
7
  export declare type ThornodePoolResponse = {
22
8
  LP_units: string;
23
9
  asset: string;
@@ -26,11 +26,8 @@ const getLimit = async ({ sellAsset, buyAssetId, sellAmountCryptoPrecision, deps
26
26
  details: { sellAssetChainFeeAssetId, buyAssetChainFeeAssetId },
27
27
  });
28
28
  }
29
- const sellFeeAssetUsdRate = await (0, getUsdRate_1.getUsdRate)({
30
- deps,
31
- input: { assetId: sellAssetChainFeeAssetId },
32
- });
33
- const buyAssetUsdRate = await (0, getUsdRate_1.getUsdRate)({ deps, input: { assetId: buyAssetId } });
29
+ const sellFeeAssetUsdRate = await (0, getUsdRate_1.getUsdRate)(deps.daemonUrl, sellAssetChainFeeAssetId);
30
+ const buyAssetUsdRate = await (0, getUsdRate_1.getUsdRate)(deps.daemonUrl, buyAssetId);
34
31
  const expectedBuyAmountCryptoPrecision8 = (0, bignumber_1.toBaseUnit)((0, bignumber_1.fromBaseUnit)((0, bignumber_1.bnOrZero)(sellAmountCryptoPrecision).times(tradeRate), sellAsset.precision), constants_2.THORCHAIN_FIXED_PRECISION);
35
32
  const isValidSlippageRange = (0, bignumber_1.bnOrZero)(slippageTolerance).gte(0) && (0, bignumber_1.bnOrZero)(slippageTolerance).lte(1);
36
33
  if ((0, bignumber_1.bnOrZero)(expectedBuyAmountCryptoPrecision8).lt(0) || !isValidSlippageRange)
@@ -1,6 +1,2 @@
1
- import { Asset } from '@shapeshiftoss/asset-service';
2
- import { ThorchainSwapperDeps } from '../../types';
3
- export declare const getUsdRate: ({ deps, input, }: {
4
- deps: ThorchainSwapperDeps;
5
- input: Pick<Asset, 'assetId'>;
6
- }) => Promise<string>;
1
+ import { AssetId } from '@shapeshiftoss/caip';
2
+ export declare const getUsdRate: (daemonUrl: string, assetId: AssetId) => Promise<string>;
@@ -6,42 +6,66 @@ const api_1 = require("../../../../api");
6
6
  const bignumber_1 = require("../../../utils/bignumber");
7
7
  const isRune_1 = require("../isRune/isRune");
8
8
  const thorService_1 = require("../thorService");
9
- const THOR_PRECISION = 8;
10
- // not sure what to do for rune usd rate - inverting USDC pool rate for now
11
- const usdcPool = 'ETH.USDC-0XA0B86991C6218B36C1D19D4A2E9EB0CE3606EB48';
12
- const getUsdRate = async ({ deps, input, }) => {
13
- const { assetId } = input;
9
+ const PRECISION = 18;
10
+ const USD_POOLS = Object.freeze([
11
+ 'AVAX.USDC-0XB97EF9EF8734C71904D8002F8B6BC66DD9C48A6E',
12
+ 'BNB.BUSD-BD1',
13
+ 'ETH.USDC-0XA0B86991C6218B36C1D19D4A2E9EB0CE3606EB48',
14
+ 'ETH.USDT-0XDAC17F958D2EE523A2206206994597C13D831EC7',
15
+ ]);
16
+ // calculate rune usd price from a usd pool (ex. USDC_POOL)
17
+ const getRuneUsdPrice = async (daemonUrl) => {
18
+ const { data } = await thorService_1.thorService.get(`${daemonUrl}/lcd/thorchain/pools`);
19
+ const availableUsdPools = data.filter((pool) => pool.status === 'Available' && USD_POOLS.includes(pool.asset));
20
+ const { aggregatedRuneUsdPrice, numPools } = availableUsdPools.reduce((prev, pool) => {
21
+ const usdBalance = (0, bignumber_1.bnOrZero)(pool.balance_asset);
22
+ const runeBalance = (0, bignumber_1.bnOrZero)(pool.balance_rune);
23
+ if (usdBalance.isZero() || runeBalance.isZero())
24
+ return prev;
25
+ // usdBalance / runeBalance = runeUsdPrice
26
+ const runeUsdPrice = usdBalance.div(runeBalance);
27
+ prev.aggregatedRuneUsdPrice = prev.aggregatedRuneUsdPrice.plus(runeUsdPrice);
28
+ prev.numPools++;
29
+ return prev;
30
+ }, { aggregatedRuneUsdPrice: (0, bignumber_1.bn)(0), numPools: 0 });
31
+ if (!numPools) {
32
+ throw new api_1.SwapError('[getUsdRate]: no available usd pools', {
33
+ code: api_1.SwapErrorTypes.USD_RATE_FAILED,
34
+ });
35
+ }
36
+ // aggregatedRuneUsdPrice / numPools = averageRuneUsdPrice
37
+ return aggregatedRuneUsdPrice.div(numPools);
38
+ };
39
+ const getUsdRate = async (daemonUrl, assetId) => {
14
40
  try {
15
- const thorchainPoolId = (() => {
16
- if ((0, isRune_1.isRune)(assetId)) {
17
- return usdcPool;
18
- }
19
- return caip_1.adapters.assetIdToPoolAssetId({ assetId });
20
- })();
21
- if (!thorchainPoolId) {
22
- throw new api_1.SwapError(`[getUsdRate]: No thorchainPoolId found for assetId: ${assetId}`, {
41
+ if ((0, isRune_1.isRune)(assetId)) {
42
+ const runeUsdPrice = await getRuneUsdPrice(daemonUrl);
43
+ return runeUsdPrice.toFixed(PRECISION);
44
+ }
45
+ const poolId = caip_1.adapters.assetIdToPoolAssetId({ assetId });
46
+ if (!poolId) {
47
+ throw new api_1.SwapError(`[getUsdRate]: no pool found for assetId: ${assetId}`, {
23
48
  code: api_1.SwapErrorTypes.USD_RATE_FAILED,
24
49
  });
25
50
  }
26
- const { data: responseData } = await thorService_1.thorService.get(`${deps.midgardUrl}/pool/${thorchainPoolId}`);
27
- const rate = (() => {
28
- if ((0, isRune_1.isRune)(assetId)) {
29
- const bnRate = (0, bignumber_1.bnOrZero)(responseData === null || responseData === void 0 ? void 0 : responseData.assetPrice);
30
- if (bnRate.isZero()) {
31
- throw new api_1.SwapError('[getUsdRate]: cannot invert rate zero', {
32
- code: api_1.SwapErrorTypes.USD_RATE_FAILED,
33
- });
34
- }
35
- const inverseRate = (0, bignumber_1.bn)(1).div(bnRate);
36
- return inverseRate.toFixed(THOR_PRECISION);
37
- }
38
- return responseData === null || responseData === void 0 ? void 0 : responseData.assetPriceUSD;
39
- })();
40
- if (!rate)
41
- throw new api_1.SwapError(`[getUsdRate]: No rate for ${assetId}`, {
51
+ const { data } = await thorService_1.thorService.get(`${daemonUrl}/lcd/thorchain/pool/${poolId}`);
52
+ if (data.status !== 'Available') {
53
+ throw new api_1.SwapError('[getUsdRate]: pool is no longer available', {
42
54
  code: api_1.SwapErrorTypes.USD_RATE_FAILED,
43
55
  });
44
- return rate;
56
+ }
57
+ const assetBalance = (0, bignumber_1.bnOrZero)(data.balance_asset);
58
+ const runeBalance = (0, bignumber_1.bnOrZero)(data.balance_rune);
59
+ if (assetBalance.isZero() || runeBalance.isZero()) {
60
+ throw new api_1.SwapError('[getUsdRate]: pool has a zero balance', {
61
+ code: api_1.SwapErrorTypes.USD_RATE_FAILED,
62
+ });
63
+ }
64
+ const runeUsdPrice = await getRuneUsdPrice(daemonUrl);
65
+ // runeBalance / assetBalance = assetPriceInRune
66
+ const assetPriceInRune = runeBalance.div(assetBalance);
67
+ // runeUsdPrice * assetPriceInRune = assetUsdPrice
68
+ return runeUsdPrice.times(assetPriceInRune).toFixed(PRECISION);
45
69
  }
46
70
  catch (e) {
47
71
  if (e instanceof api_1.SwapError)
@@ -1,8 +1,6 @@
1
- import { InboundAddressResponse, MidgardPoolResponse, ThornodePoolResponse } from '../../types';
2
- export declare const btcMidgardPool: MidgardPoolResponse;
1
+ import { InboundAddressResponse, ThornodePoolResponse } from '../../types';
3
2
  export declare const btcThornodePool: ThornodePoolResponse;
4
- export declare const ethMidgardPool: MidgardPoolResponse;
5
3
  export declare const ethThornodePool: ThornodePoolResponse;
6
- export declare const foxMidgardPool: MidgardPoolResponse;
7
4
  export declare const foxThornodePool: ThornodePoolResponse;
5
+ export declare const usdcThornodePool: ThornodePoolResponse;
8
6
  export declare const mockInboundAddresses: InboundAddressResponse[];
@@ -1,20 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.mockInboundAddresses = exports.foxThornodePool = exports.foxMidgardPool = exports.ethThornodePool = exports.ethMidgardPool = exports.btcThornodePool = exports.btcMidgardPool = void 0;
4
- exports.btcMidgardPool = {
5
- asset: 'BTC.BTC',
6
- assetDepth: '91027798705',
7
- assetPrice: '10280.68095465986',
8
- assetPriceUSD: '29850.505131750208',
9
- liquidityUnits: '536055974608843',
10
- poolAPY: '0.09305294391574037',
11
- runeDepth: '935827756491105',
12
- status: 'available',
13
- synthSupply: '3281284823',
14
- synthUnits: '9838954536080',
15
- units: '545894929144923',
16
- volume24h: '15031085906495',
17
- };
3
+ exports.mockInboundAddresses = exports.usdcThornodePool = exports.foxThornodePool = exports.ethThornodePool = exports.btcThornodePool = void 0;
18
4
  exports.btcThornodePool = {
19
5
  LP_units: '536055974608843',
20
6
  asset: 'BTC.BTC',
@@ -27,20 +13,6 @@ exports.btcThornodePool = {
27
13
  synth_supply: '3281284823',
28
14
  synth_units: '9838954536080',
29
15
  };
30
- exports.ethMidgardPool = {
31
- asset: 'ETH.ETH',
32
- assetDepth: '915018987646',
33
- assetPrice: '676.2118757936507',
34
- assetPriceUSD: '1595',
35
- liquidityUnits: '273709963437801',
36
- poolAPY: '0.10532151323548256',
37
- runeDepth: '618746706022909',
38
- status: 'available',
39
- synthSupply: '3572065751',
40
- synthUnits: '535301524652',
41
- units: '274245264962453',
42
- volume24h: '9890096673763',
43
- };
44
16
  exports.ethThornodePool = {
45
17
  LP_units: '273709963437801',
46
18
  asset: 'ETH.ETH',
@@ -53,20 +25,6 @@ exports.ethThornodePool = {
53
25
  synth_supply: '3572065751',
54
26
  synth_units: '535301524652',
55
27
  };
56
- exports.foxMidgardPool = {
57
- asset: 'ETH.FOX-0XC770EEFAD204B5180DF6A14EE197D99D808EE52D',
58
- assetDepth: '166650912393467',
59
- assetPrice: '0.05303710198887871',
60
- assetPriceUSD: '0.15399605260336216',
61
- liquidityUnits: '10015457121887',
62
- poolAPY: '0.2597568967423438',
63
- runeDepth: '8838681437152',
64
- status: 'available',
65
- synthSupply: '17428372569375',
66
- synthUnits: '552604585625',
67
- units: '10568061707512',
68
- volume24h: '251596933033',
69
- };
70
28
  exports.foxThornodePool = {
71
29
  LP_units: '10015457121887',
72
30
  asset: 'ETH.FOX-0XC770EEFAD204B5180DF6A14EE197D99D808EE52D',
@@ -79,6 +37,18 @@ exports.foxThornodePool = {
79
37
  synth_supply: '17428372569375',
80
38
  synth_units: '552604585625',
81
39
  };
40
+ exports.usdcThornodePool = {
41
+ LP_units: '30018075345020',
42
+ asset: 'ETH.USDC-0XA0B86991C6218B36C1D19D4A2E9EB0CE3606EB48',
43
+ balance_asset: '290355330190652994811',
44
+ balance_rune: '100000000000000000000',
45
+ pending_inbound_asset: '22020062300',
46
+ pending_inbound_rune: '0',
47
+ pool_units: '31954495292990',
48
+ status: 'Available',
49
+ synth_supply: '25598723155460',
50
+ synth_units: '1936419947970',
51
+ };
82
52
  exports.mockInboundAddresses = [
83
53
  {
84
54
  chain: 'BCH',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shapeshiftoss/swapper",
3
- "version": "14.2.3",
3
+ "version": "14.3.0",
4
4
  "description": "An interface and implementations to trade coins via various protocols",
5
5
  "repository": "https://github.com/shapeshift/lib",
6
6
  "license": "MIT",