@shapeshiftoss/swapper 9.3.1 → 9.5.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.
Files changed (24) hide show
  1. package/dist/api.d.ts +3 -0
  2. package/dist/swappers/cow/CowSwapper.d.ts +0 -4
  3. package/dist/swappers/cow/CowSwapper.js +5 -3
  4. package/dist/swappers/cow/cowBuildTrade/cowBuildTrade.js +13 -5
  5. package/dist/swappers/cow/cowExecuteTrade/cowExecuteTrade.js +13 -5
  6. package/dist/swappers/cow/getCowSwapMinMax/getCowSwapMinMax.js +5 -2
  7. package/dist/swappers/cow/getCowSwapTradeQuote/getCowSwapTradeQuote.js +13 -5
  8. package/dist/swappers/cow/utils/constants.d.ts +1 -0
  9. package/dist/swappers/cow/utils/constants.js +4 -1
  10. package/dist/swappers/thorchain/ThorchainSwapper.d.ts +4 -2
  11. package/dist/swappers/thorchain/ThorchainSwapper.js +32 -9
  12. package/dist/swappers/thorchain/buildThorTrade/buildThorTrade.js +21 -0
  13. package/dist/swappers/thorchain/getThorTradeQuote/getTradeQuote.js +15 -2
  14. package/dist/swappers/thorchain/types.d.ts +6 -2
  15. package/dist/swappers/thorchain/utils/bitcoin/utils/getThorTxData.js +11 -17
  16. package/dist/swappers/thorchain/utils/constants.d.ts +3 -2
  17. package/dist/swappers/thorchain/utils/constants.js +15 -4
  18. package/dist/swappers/thorchain/utils/cosmos/cosmosTxData.d.ts +19 -0
  19. package/dist/swappers/thorchain/utils/cosmos/cosmosTxData.js +46 -0
  20. package/dist/swappers/thorchain/utils/estimateTradeFee/estimateTradeFee.js +8 -43
  21. package/dist/swappers/thorchain/utils/ethereum/utils/getThorTxData.js +11 -17
  22. package/dist/swappers/thorchain/utils/getLimit/getLimit.d.ts +12 -0
  23. package/dist/swappers/thorchain/utils/getLimit/getLimit.js +24 -0
  24. package/package.json +1 -1
package/dist/api.d.ts CHANGED
@@ -42,6 +42,9 @@ declare type ChainSpecificQuoteFeeData<T extends ChainId> = ChainSpecific<T, {
42
42
  byteCount: string;
43
43
  satsPerByte: string;
44
44
  };
45
+ [KnownChainIds.CosmosMainnet]: {
46
+ estimatedGas: string;
47
+ };
45
48
  }>;
46
49
  export declare type QuoteFeeData<T extends ChainId> = {
47
50
  fee: string;
@@ -5,10 +5,6 @@ import { KnownChainIds } from '@shapeshiftoss/types';
5
5
  import Web3 from 'web3';
6
6
  import { ApprovalNeededInput, ApprovalNeededOutput, ApproveInfiniteInput, BuildTradeInput, BuyAssetBySellIdInput, ExecuteTradeInput, GetTradeQuoteInput, Swapper, SwapperType, TradeQuote, TradeResult, TradeTxs } from '../../api';
7
7
  import { CowTrade } from './types';
8
- /**
9
- * CowSwap only supports ERC-20 swaps, hence ETH is not supported
10
- * In order to get rates correctly, we need WETH asset to be passed as feeAsset
11
- */
12
8
  export declare type CowSwapperDeps = {
13
9
  apiUrl: string;
14
10
  adapter: ethereum.ChainAdapter;
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.CowSwapper = void 0;
4
+ const caip_1 = require("@shapeshiftoss/caip");
5
+ const types_1 = require("@shapeshiftoss/types");
4
6
  const api_1 = require("../../api");
5
7
  const cowApprovalNeeded_1 = require("./cowApprovalNeeded/cowApprovalNeeded");
6
8
  const cowApproveInfinite_1 = require("./cowApproveInfinite/cowApproveInfinite");
@@ -38,15 +40,15 @@ class CowSwapper {
38
40
  }
39
41
  filterBuyAssetsBySellAssetId(args) {
40
42
  const { assetIds = [], sellAssetId } = args;
41
- if (!(sellAssetId === null || sellAssetId === void 0 ? void 0 : sellAssetId.startsWith('eip155:1/erc20')) ||
43
+ if ((0, caip_1.fromAssetId)(sellAssetId).assetNamespace !== 'erc20' ||
42
44
  blacklist_1.COWSWAP_UNSUPPORTED_ASSETS.includes(sellAssetId))
43
45
  return [];
44
46
  return assetIds.filter((id) => id !== sellAssetId &&
45
- id.startsWith('eip155:1/erc20') &&
47
+ (0, caip_1.fromAssetId)(id).chainId === types_1.KnownChainIds.EthereumMainnet &&
46
48
  !blacklist_1.COWSWAP_UNSUPPORTED_ASSETS.includes(id));
47
49
  }
48
50
  filterAssetIdsBySellable(assetIds) {
49
- return assetIds.filter((id) => id.startsWith('eip155:1/erc20') && !blacklist_1.COWSWAP_UNSUPPORTED_ASSETS.includes(id));
51
+ return assetIds.filter((id) => (0, caip_1.fromAssetId)(id).assetNamespace === 'erc20' && !blacklist_1.COWSWAP_UNSUPPORTED_ASSETS.includes(id));
50
52
  }
51
53
  async getTradeTxs(args) {
52
54
  return (0, cowGetTradeTxs_1.cowGetTradeTxs)(this.deps, args);
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.cowBuildTrade = void 0;
4
4
  const caip_1 = require("@shapeshiftoss/caip");
5
+ const types_1 = require("@shapeshiftoss/types");
5
6
  const api_1 = require("../../../api");
6
7
  const erc20Allowance_abi_1 = require("../../utils/abi/erc20Allowance-abi");
7
8
  const bignumber_1 = require("../../utils/bignumber");
@@ -14,13 +15,20 @@ async function cowBuildTrade(deps, input) {
14
15
  const { sellAsset, buyAsset, sellAmount, sellAssetAccountNumber, wallet } = input;
15
16
  const { adapter, web3 } = deps;
16
17
  const { assetReference: sellAssetErc20Address, assetNamespace: sellAssetNamespace } = (0, caip_1.fromAssetId)(sellAsset.assetId);
17
- const { assetReference: buyAssetErc20Address, assetNamespace: buyAssetNamespace } = (0, caip_1.fromAssetId)(buyAsset.assetId);
18
- if (buyAssetNamespace !== 'erc20' || sellAssetNamespace !== 'erc20') {
19
- throw new api_1.SwapError('[cowBuildTrade] - Both assets need to be ERC-20 to use CowSwap', {
18
+ const { assetReference: buyAssetErc20Address, chainId: buyAssetChainId } = (0, caip_1.fromAssetId)(buyAsset.assetId);
19
+ if (sellAssetNamespace !== 'erc20') {
20
+ throw new api_1.SwapError('[cowBuildTrade] - Sell asset needs to be ERC-20 to use CowSwap', {
20
21
  code: api_1.SwapErrorTypes.UNSUPPORTED_PAIR,
21
- details: { buyAssetNamespace, sellAssetNamespace }
22
+ details: { sellAssetNamespace }
22
23
  });
23
24
  }
25
+ if (buyAssetChainId !== types_1.KnownChainIds.EthereumMainnet) {
26
+ throw new api_1.SwapError('[cowBuildTrade] - Buy asset needs to be on ETH mainnet to use CowSwap', {
27
+ code: api_1.SwapErrorTypes.UNSUPPORTED_PAIR,
28
+ details: { buyAssetChainId }
29
+ });
30
+ }
31
+ const buyToken = buyAsset.assetId !== caip_1.ethAssetId ? buyAssetErc20Address : constants_1.COW_SWAP_ETH_MARKER_ADDRESS;
24
32
  const receiveAddress = await adapter.getAddress({ wallet });
25
33
  const normalizedSellAmount = (0, helpers_1.normalizeAmount)(sellAmount);
26
34
  /**
@@ -39,7 +47,7 @@ async function cowBuildTrade(deps, input) {
39
47
  */
40
48
  const quoteResponse = await cowService_1.cowService.post(`${deps.apiUrl}/v1/quote/`, {
41
49
  sellToken: sellAssetErc20Address,
42
- buyToken: buyAssetErc20Address,
50
+ buyToken,
43
51
  receiver: receiveAddress,
44
52
  validTo: (0, helpers_2.getNowPlusThirtyMinutesTimestamp)(),
45
53
  appData: constants_1.DEFAULT_APP_DATA,
@@ -4,6 +4,7 @@ exports.cowExecuteTrade = void 0;
4
4
  const caip_1 = require("@shapeshiftoss/caip");
5
5
  const chain_adapters_1 = require("@shapeshiftoss/chain-adapters");
6
6
  const hdwallet_core_1 = require("@shapeshiftoss/hdwallet-core");
7
+ const types_1 = require("@shapeshiftoss/types");
7
8
  const ethers_1 = require("ethers");
8
9
  const api_1 = require("../../../api");
9
10
  const constants_1 = require("../utils/constants");
@@ -13,17 +14,24 @@ async function cowExecuteTrade({ apiUrl, adapter }, { trade, wallet }) {
13
14
  const cowTrade = trade;
14
15
  const { sellAsset, buyAsset, feeAmountInSellToken, sellAmountWithoutFee } = cowTrade;
15
16
  const { assetReference: sellAssetErc20Address, assetNamespace: sellAssetNamespace } = (0, caip_1.fromAssetId)(sellAsset.assetId);
16
- const { assetReference: buyAssetErc20Address, assetNamespace: buyAssetNamespace } = (0, caip_1.fromAssetId)(buyAsset.assetId);
17
- if (buyAssetNamespace !== 'erc20' || sellAssetNamespace !== 'erc20') {
18
- throw new api_1.SwapError('[cowExecuteTrade] - Both assets need to be ERC-20 to use CowSwap', {
17
+ const { assetReference: buyAssetErc20Address, chainId: buyAssetChainId } = (0, caip_1.fromAssetId)(buyAsset.assetId);
18
+ if (sellAssetNamespace !== 'erc20') {
19
+ throw new api_1.SwapError('[cowExecuteTrade] - Sell asset needs to be ERC-20 to use CowSwap', {
19
20
  code: api_1.SwapErrorTypes.UNSUPPORTED_PAIR,
20
- details: { buyAssetNamespace, sellAssetNamespace }
21
+ details: { sellAssetNamespace }
21
22
  });
22
23
  }
24
+ if (buyAssetChainId !== types_1.KnownChainIds.EthereumMainnet) {
25
+ throw new api_1.SwapError('[cowExecuteTrade] - Buy asset needs to be on ETH mainnet to use CowSwap', {
26
+ code: api_1.SwapErrorTypes.UNSUPPORTED_PAIR,
27
+ details: { buyAssetChainId }
28
+ });
29
+ }
30
+ const buyToken = buyAsset.assetId !== caip_1.ethAssetId ? buyAssetErc20Address : constants_1.COW_SWAP_ETH_MARKER_ADDRESS;
23
31
  try {
24
32
  const orderToSign = {
25
33
  sellToken: sellAssetErc20Address,
26
- buyToken: buyAssetErc20Address,
34
+ buyToken,
27
35
  sellAmount: sellAmountWithoutFee,
28
36
  buyAmount: trade.buyAmount,
29
37
  validTo: (0, helpers_1.getNowPlusThirtyMinutesTimestamp)(),
@@ -1,14 +1,17 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getCowSwapMinMax = void 0;
4
+ const caip_1 = require("@shapeshiftoss/caip");
5
+ const types_1 = require("@shapeshiftoss/types");
4
6
  const api_1 = require("../../../api");
5
7
  const bignumber_1 = require("../../utils/bignumber");
6
8
  const constants_1 = require("../utils/constants");
7
9
  const helpers_1 = require("../utils/helpers/helpers");
8
10
  const getCowSwapMinMax = async (deps, sellAsset, buyAsset) => {
9
11
  try {
10
- if (!sellAsset.assetId.startsWith('eip155:1/erc20') ||
11
- !buyAsset.assetId.startsWith('eip155:1/erc20')) {
12
+ const { assetNamespace: sellAssetNamespace } = (0, caip_1.fromAssetId)(sellAsset.assetId);
13
+ const { chainId: buyAssetChainId } = (0, caip_1.fromAssetId)(buyAsset.assetId);
14
+ if (sellAssetNamespace !== 'erc20' || buyAssetChainId !== types_1.KnownChainIds.EthereumMainnet) {
12
15
  throw new api_1.SwapError('[getCowSwapMinMax]', { code: api_1.SwapErrorTypes.UNSUPPORTED_PAIR });
13
16
  }
14
17
  const usdRate = await (0, helpers_1.getUsdRate)(deps, sellAsset);
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getCowSwapTradeQuote = void 0;
4
4
  const caip_1 = require("@shapeshiftoss/caip");
5
+ const types_1 = require("@shapeshiftoss/types");
5
6
  const api_1 = require("../../../api");
6
7
  const bignumber_1 = require("../../utils/bignumber");
7
8
  const helpers_1 = require("../../utils/helpers/helpers");
@@ -14,20 +15,27 @@ async function getCowSwapTradeQuote(deps, input) {
14
15
  const { sellAsset, buyAsset, sellAmount, sellAssetAccountNumber, wallet } = input;
15
16
  const { adapter, web3 } = deps;
16
17
  const { assetReference: sellAssetErc20Address, assetNamespace: sellAssetNamespace } = (0, caip_1.fromAssetId)(sellAsset.assetId);
17
- const { assetReference: buyAssetErc20Address, assetNamespace: buyAssetNamespace } = (0, caip_1.fromAssetId)(buyAsset.assetId);
18
- if (buyAssetNamespace !== 'erc20' || sellAssetNamespace !== 'erc20') {
19
- throw new api_1.SwapError('[getCowSwapTradeQuote] - Both assets need to be ERC-20 to use CowSwap', {
18
+ const { assetReference: buyAssetErc20Address, chainId: buyAssetChainId } = (0, caip_1.fromAssetId)(buyAsset.assetId);
19
+ if (sellAssetNamespace !== 'erc20') {
20
+ throw new api_1.SwapError('[getCowSwapTradeQuote] - Sell asset needs to be ERC-20 to use CowSwap', {
20
21
  code: api_1.SwapErrorTypes.UNSUPPORTED_PAIR,
21
- details: { buyAssetNamespace, sellAssetNamespace }
22
+ details: { sellAssetNamespace }
22
23
  });
23
24
  }
25
+ if (buyAssetChainId !== types_1.KnownChainIds.EthereumMainnet) {
26
+ throw new api_1.SwapError('[getCowSwapTradeQuote] - Buy asset needs to be on ETH mainnet to use CowSwap', {
27
+ code: api_1.SwapErrorTypes.UNSUPPORTED_PAIR,
28
+ details: { buyAssetChainId }
29
+ });
30
+ }
31
+ const buyToken = buyAsset.assetId !== caip_1.ethAssetId ? buyAssetErc20Address : constants_1.COW_SWAP_ETH_MARKER_ADDRESS;
24
32
  const { minimum, maximum } = await (0, getCowSwapMinMax_1.getCowSwapMinMax)(deps, sellAsset, buyAsset);
25
33
  const minQuoteSellAmount = (0, bignumber_1.bnOrZero)(minimum).times((0, bignumber_1.bn)(10).exponentiatedBy(sellAsset.precision));
26
34
  // making sure we do not have decimals for cowswap api (can happen at least from minQuoteSellAmount)
27
35
  const normalizedSellAmount = (0, helpers_1.normalizeIntegerAmount)((0, bignumber_1.bnOrZero)(sellAmount).lt(minQuoteSellAmount) ? minQuoteSellAmount : sellAmount);
28
36
  const apiInput = {
29
37
  sellToken: sellAssetErc20Address,
30
- buyToken: buyAssetErc20Address,
38
+ buyToken,
31
39
  receiver: constants_1.DEFAULT_ADDRESS,
32
40
  validTo: (0, helpers_2.getNowPlusThirtyMinutesTimestamp)(),
33
41
  appData: constants_1.DEFAULT_APP_DATA,
@@ -15,3 +15,4 @@ export declare const ORDER_KIND_BUY = "buy";
15
15
  export declare const SIGNING_SCHEME = "ethsign";
16
16
  export declare const ERC20_TOKEN_BALANCE = "erc20";
17
17
  export declare const ORDER_STATUS_FULFILLED = "fulfilled";
18
+ export declare const COW_SWAP_ETH_MARKER_ADDRESS = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ORDER_STATUS_FULFILLED = exports.ERC20_TOKEN_BALANCE = exports.SIGNING_SCHEME = exports.ORDER_KIND_BUY = exports.ORDER_KIND_SELL = exports.WETH_ASSET_ID = exports.COW_SWAP_SETTLEMENT_ADDRESS = exports.COW_SWAP_VAULT_RELAYER_ADDRESS = exports.DEFAULT_APP_DATA = exports.DEFAULT_ADDRESS = exports.DEFAULT_SOURCE = exports.MIN_COWSWAP_VALUE_USD = exports.MAX_COWSWAP_TRADE = exports.MAX_ALLOWANCE = void 0;
3
+ exports.COW_SWAP_ETH_MARKER_ADDRESS = exports.ORDER_STATUS_FULFILLED = exports.ERC20_TOKEN_BALANCE = exports.SIGNING_SCHEME = exports.ORDER_KIND_BUY = exports.ORDER_KIND_SELL = exports.WETH_ASSET_ID = exports.COW_SWAP_SETTLEMENT_ADDRESS = exports.COW_SWAP_VAULT_RELAYER_ADDRESS = exports.DEFAULT_APP_DATA = exports.DEFAULT_ADDRESS = exports.DEFAULT_SOURCE = exports.MIN_COWSWAP_VALUE_USD = exports.MAX_COWSWAP_TRADE = exports.MAX_ALLOWANCE = void 0;
4
4
  const constants_1 = require("@ethersproject/constants");
5
5
  exports.MAX_ALLOWANCE = '100000000000000000000000000';
6
6
  exports.MAX_COWSWAP_TRADE = '100000000000000000000000000';
@@ -16,3 +16,6 @@ exports.ORDER_KIND_BUY = 'buy';
16
16
  exports.SIGNING_SCHEME = 'ethsign';
17
17
  exports.ERC20_TOKEN_BALANCE = 'erc20';
18
18
  exports.ORDER_STATUS_FULFILLED = 'fulfilled';
19
+ // Address used by CowSwap to buy ETH
20
+ // See https://github.com/gnosis/gp-v2-contracts/commit/821b5a8da213297b0f7f1d8b17c893c5627020af#diff-12bbbe13cd5cf42d639e34a39d8795021ba40d3ee1e1a8282df652eb161a11d6R13
21
+ exports.COW_SWAP_ETH_MARKER_ADDRESS = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE';
@@ -5,8 +5,10 @@ import { ApprovalNeededInput, ApprovalNeededOutput, ApproveInfiniteInput, BuildT
5
5
  import { ThorchainSwapperDeps } from './types';
6
6
  export declare class ThorchainSwapper implements Swapper<ChainId> {
7
7
  readonly name = "Thorchain";
8
- private swapSupportedChainIds;
9
- private supportedAssetIds;
8
+ private sellSupportedChainIds;
9
+ private buySupportedChainIds;
10
+ private supportedSellAssetIds;
11
+ private supportedBuyAssetIds;
10
12
  deps: ThorchainSwapperDeps;
11
13
  constructor(deps: ThorchainSwapperDeps);
12
14
  initialize(): Promise<void>;
@@ -13,24 +13,39 @@ const thorService_1 = require("./utils/thorService");
13
13
  class ThorchainSwapper {
14
14
  constructor(deps) {
15
15
  this.name = 'Thorchain';
16
- this.swapSupportedChainIds = {
16
+ this.sellSupportedChainIds = {
17
17
  [types_1.KnownChainIds.EthereumMainnet]: true,
18
- [types_1.KnownChainIds.BitcoinMainnet]: true
18
+ [types_1.KnownChainIds.BitcoinMainnet]: true,
19
+ [types_1.KnownChainIds.CosmosMainnet]: true
19
20
  };
20
- this.supportedAssetIds = [];
21
+ this.buySupportedChainIds = {
22
+ [types_1.KnownChainIds.EthereumMainnet]: true,
23
+ [types_1.KnownChainIds.BitcoinMainnet]: true,
24
+ [types_1.KnownChainIds.DogecoinMainnet]: true,
25
+ [types_1.KnownChainIds.LitecoinMainnet]: true,
26
+ [types_1.KnownChainIds.CosmosMainnet]: true
27
+ };
28
+ this.supportedSellAssetIds = [];
29
+ this.supportedBuyAssetIds = [];
21
30
  this.deps = deps;
22
31
  }
23
32
  async initialize() {
24
33
  try {
25
34
  const { data: responseData } = await thorService_1.thorService.get(`${this.deps.midgardUrl}/pools`);
26
- const supportedAssetIds = responseData.reduce((acc, midgardPool) => {
35
+ this.supportedSellAssetIds = responseData.reduce((acc, midgardPool) => {
36
+ const assetId = caip_1.adapters.poolAssetIdToAssetId(midgardPool.asset);
37
+ if (!assetId || !this.sellSupportedChainIds[(0, caip_1.fromAssetId)(assetId).chainId])
38
+ return acc;
39
+ acc.push(assetId);
40
+ return acc;
41
+ }, []);
42
+ this.supportedBuyAssetIds = responseData.reduce((acc, midgardPool) => {
27
43
  const assetId = caip_1.adapters.poolAssetIdToAssetId(midgardPool.asset);
28
- if (!assetId || !this.swapSupportedChainIds[(0, caip_1.fromAssetId)(assetId).chainId])
44
+ if (!assetId || !this.buySupportedChainIds[(0, caip_1.fromAssetId)(assetId).chainId])
29
45
  return acc;
30
46
  acc.push(assetId);
31
47
  return acc;
32
48
  }, []);
33
- this.supportedAssetIds = supportedAssetIds;
34
49
  }
35
50
  catch (e) {
36
51
  throw new api_1.SwapError('[thorchainInitialize]: initialize failed to set supportedAssetIds', {
@@ -53,12 +68,12 @@ class ThorchainSwapper {
53
68
  }
54
69
  filterBuyAssetsBySellAssetId(args) {
55
70
  const { assetIds = [], sellAssetId } = args;
56
- if (!this.supportedAssetIds.includes(sellAssetId))
71
+ if (!this.supportedSellAssetIds.includes(sellAssetId))
57
72
  return [];
58
- return assetIds.filter((assetId) => this.supportedAssetIds.includes(assetId) && assetId !== sellAssetId);
73
+ return assetIds.filter((assetId) => this.supportedBuyAssetIds.includes(assetId) && assetId !== sellAssetId);
59
74
  }
60
75
  filterAssetIdsBySellable() {
61
- return this.supportedAssetIds;
76
+ return this.supportedSellAssetIds;
62
77
  }
63
78
  async buildTrade(input) {
64
79
  return (0, buildThorTrade_1.buildTrade)({ deps: this.deps, input });
@@ -92,6 +107,14 @@ class ThorchainSwapper {
92
107
  const txid = await adapter.broadcastTransaction(signedTx);
93
108
  return { tradeId: txid };
94
109
  }
110
+ else if (trade.sellAsset.chainId === types_1.KnownChainIds.CosmosMainnet) {
111
+ const signedTx = await adapter.signTransaction({
112
+ txToSign: trade.txData,
113
+ wallet
114
+ });
115
+ const txid = await adapter.broadcastTransaction(signedTx);
116
+ return { tradeId: txid };
117
+ }
95
118
  else {
96
119
  throw new api_1.SwapError('[executeTrade]: unsupported trade', {
97
120
  code: api_1.SwapErrorTypes.SIGN_AND_BROADCAST_FAILED,
@@ -6,6 +6,7 @@ const api_1 = require("../../../api");
6
6
  const constants_1 = require("../../utils/constants");
7
7
  const getTradeQuote_1 = require("../getThorTradeQuote/getTradeQuote");
8
8
  const getThorTxData_1 = require("../utils/bitcoin/utils/getThorTxData");
9
+ const cosmosTxData_1 = require("../utils/cosmos/cosmosTxData");
9
10
  const makeTradeTx_1 = require("../utils/ethereum/makeTradeTx");
10
11
  const buildTrade = async ({ deps, input }) => {
11
12
  var _a, _b, _c, _d;
@@ -75,6 +76,26 @@ const buildTrade = async ({ deps, input }) => {
75
76
  txData: buildTxResponse.txToSign
76
77
  };
77
78
  }
79
+ else if (input.chainId === types_1.KnownChainIds.CosmosMainnet) {
80
+ const txData = await (0, cosmosTxData_1.cosmosTxData)({
81
+ deps,
82
+ sellAdapter: sellAdapter,
83
+ sellAmount,
84
+ sellAsset,
85
+ slippageTolerance,
86
+ chainId: input.chainId,
87
+ buyAsset,
88
+ wallet,
89
+ destinationAddress,
90
+ quote: quote
91
+ });
92
+ return {
93
+ chainId: types_1.KnownChainIds.CosmosMainnet,
94
+ ...quote,
95
+ receiveAddress: destinationAddress,
96
+ txData
97
+ };
98
+ }
78
99
  else {
79
100
  throw new api_1.SwapError('[buildTrade]: unsupported chain id', {
80
101
  code: api_1.SwapErrorTypes.BUILD_TRADE_FAILED,
@@ -21,8 +21,8 @@ const getThorTradeQuote = async ({ deps, input }) => {
21
21
  });
22
22
  try {
23
23
  const { assetReference: sellAssetErc20Address } = (0, caip_1.fromAssetId)(sellAsset.assetId);
24
- const adapter = deps.adapterManager.get(chainId);
25
- if (!adapter)
24
+ const sellAdapter = deps.adapterManager.get(chainId);
25
+ if (!sellAdapter)
26
26
  throw new api_1.SwapError(`[getThorTradeQuote] - No chain adapter found for ${chainId}.`, {
27
27
  code: api_1.SwapErrorTypes.UNSUPPORTED_CHAIN,
28
28
  details: { chainId }
@@ -97,6 +97,19 @@ const getThorTradeQuote = async ({ deps, input }) => {
97
97
  feeData
98
98
  };
99
99
  })();
100
+ case types_1.KnownChainIds.CosmosMainnet:
101
+ return (async () => {
102
+ const feeData = await sellAdapter.getFeeData({});
103
+ return {
104
+ ...commonQuoteFields,
105
+ allowanceContract: '0x0',
106
+ feeData: {
107
+ fee: feeData.fast.txFee,
108
+ tradeFee,
109
+ chainSpecific: { estimatedGas: feeData.fast.chainSpecific.gasLimit }
110
+ }
111
+ };
112
+ })();
100
113
  default:
101
114
  throw new api_1.SwapError('[getThorTradeQuote] - Asset chainId is not supported.', {
102
115
  code: api_1.SwapErrorTypes.UNSUPPORTED_CHAIN,
@@ -1,6 +1,6 @@
1
1
  import { ChainId } from '@shapeshiftoss/caip';
2
2
  import { ChainAdapterManager } from '@shapeshiftoss/chain-adapters';
3
- import { BTCSignTx, ETHSignTx } from '@shapeshiftoss/hdwallet-core';
3
+ import { BTCSignTx, CosmosSignTx, ETHSignTx } from '@shapeshiftoss/hdwallet-core';
4
4
  import { KnownChainIds } from '@shapeshiftoss/types';
5
5
  import type Web3 from 'web3';
6
6
  import { Trade } from '../../api';
@@ -39,4 +39,8 @@ export interface EthThorTrade<C extends ChainId> extends Trade<C> {
39
39
  chainId: KnownChainIds.EthereumMainnet;
40
40
  txData: ETHSignTx;
41
41
  }
42
- export declare type ThorTrade<C extends ChainId> = BtcThorTrade<C> | EthThorTrade<C>;
42
+ export interface CosmosThorTrade<C extends ChainId> extends Trade<C> {
43
+ chainId: KnownChainIds.CosmosMainnet;
44
+ txData: CosmosSignTx;
45
+ }
46
+ export declare type ThorTrade<C extends ChainId> = BtcThorTrade<C> | EthThorTrade<C> | CosmosThorTrade<C>;
@@ -3,9 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getThorTxInfo = void 0;
4
4
  const caip_1 = require("@shapeshiftoss/caip");
5
5
  const api_1 = require("../../../../../api");
6
- const bignumber_1 = require("../../../../utils/bignumber");
7
- const constants_1 = require("../../constants");
8
- const getTradeRate_1 = require("../../getTradeRate/getTradeRate");
6
+ const getLimit_1 = require("../../getLimit/getLimit");
9
7
  const makeSwapMemo_1 = require("../../makeSwapMemo/makeSwapMemo");
10
8
  const thorService_1 = require("../../thorService");
11
9
  const getThorTxInfo = async ({ deps, sellAsset, buyAsset, sellAmount, slippageTolerance, destinationAddress, wallet, bip44Params, accountType, tradeFee }) => {
@@ -18,20 +16,16 @@ const getThorTxInfo = async ({ deps, sellAsset, buyAsset, sellAmount, slippageTo
18
16
  code: api_1.SwapErrorTypes.RESPONSE_ERROR,
19
17
  details: { inboundAddresses }
20
18
  });
21
- const tradeRate = await (0, getTradeRate_1.getTradeRate)(sellAsset, buyAsset.assetId, sellAmount, deps);
22
- const expectedBuyAmountPrecision8 = (0, bignumber_1.toBaseUnit)((0, bignumber_1.fromBaseUnit)((0, bignumber_1.bnOrZero)(sellAmount).times(tradeRate), sellAsset.precision), constants_1.THORCHAIN_FIXED_PRECISION);
23
- const isValidSlippageRange = (0, bignumber_1.bnOrZero)(slippageTolerance).gte(0) && (0, bignumber_1.bnOrZero)(slippageTolerance).lte(1);
24
- if ((0, bignumber_1.bnOrZero)(expectedBuyAmountPrecision8).lt(0) || !isValidSlippageRange)
25
- throw new api_1.SwapError('[getThorTxInfo]: bad expected buy amount or bad slippage tolerance', {
26
- code: api_1.SwapErrorTypes.BUILD_TRADE_FAILED,
27
- details: { expectedBuyAmountPrecision8, slippageTolerance }
28
- });
29
- const tradeFeePrecision8 = (0, bignumber_1.toBaseUnit)((0, bignumber_1.bnOrZero)(tradeFee), constants_1.THORCHAIN_FIXED_PRECISION);
30
- const limit = (0, bignumber_1.bnOrZero)(expectedBuyAmountPrecision8)
31
- .times((0, bignumber_1.bn)(1).minus(slippageTolerance))
32
- .minus((0, bignumber_1.bnOrZero)(tradeFeePrecision8))
33
- .decimalPlaces(0)
34
- .toString();
19
+ const limit = await (0, getLimit_1.getLimit)({
20
+ buyAssetId: buyAsset.assetId,
21
+ destinationAddress,
22
+ sellAmount,
23
+ sellAsset,
24
+ buyAsset,
25
+ slippageTolerance,
26
+ deps,
27
+ tradeFee
28
+ });
35
29
  const memo = (0, makeSwapMemo_1.makeSwapMemo)({
36
30
  buyAssetId: buyAsset.assetId,
37
31
  destinationAddress,
@@ -1,3 +1,5 @@
1
+ import { ChainId } from '@shapeshiftoss/caip';
2
+ import BigNumber from 'bignumber.js';
1
3
  export declare const MAX_THORCHAIN_TRADE = "100000000000000000000000000";
2
4
  export declare const MAX_ALLOWANCE = "100000000000000000000000000";
3
5
  export declare const THOR_MINIMUM_PADDING = 1.2;
@@ -5,5 +7,4 @@ export declare const THOR_ETH_GAS_LIMIT = "100000";
5
7
  export declare const THORCHAIN_FIXED_PRECISION = 8;
6
8
  export declare const THORCHAIN_AFFILIATE_NAME = "ss";
7
9
  export declare const THORCHAIN_AFFILIATE_BIPS = "0";
8
- export declare const THOR_TRADE_FEE_BTC_SIZE = 1000;
9
- export declare const THOR_TRADE_FEE_ETH_GAS = 120000;
10
+ export declare const THOR_TRADE_FEE_MULTIPLIERS: Record<ChainId, BigNumber>;
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.THOR_TRADE_FEE_ETH_GAS = exports.THOR_TRADE_FEE_BTC_SIZE = exports.THORCHAIN_AFFILIATE_BIPS = exports.THORCHAIN_AFFILIATE_NAME = exports.THORCHAIN_FIXED_PRECISION = exports.THOR_ETH_GAS_LIMIT = exports.THOR_MINIMUM_PADDING = exports.MAX_ALLOWANCE = exports.MAX_THORCHAIN_TRADE = void 0;
3
+ exports.THOR_TRADE_FEE_MULTIPLIERS = exports.THORCHAIN_AFFILIATE_BIPS = exports.THORCHAIN_AFFILIATE_NAME = exports.THORCHAIN_FIXED_PRECISION = exports.THOR_ETH_GAS_LIMIT = exports.THOR_MINIMUM_PADDING = exports.MAX_ALLOWANCE = exports.MAX_THORCHAIN_TRADE = void 0;
4
+ const types_1 = require("@shapeshiftoss/types");
5
+ const bignumber_1 = require("../../utils/bignumber");
4
6
  exports.MAX_THORCHAIN_TRADE = '100000000000000000000000000';
5
7
  exports.MAX_ALLOWANCE = '100000000000000000000000000';
6
8
  exports.THOR_MINIMUM_PADDING = 1.2;
@@ -8,7 +10,16 @@ exports.THOR_ETH_GAS_LIMIT = '100000'; // for sends of eth / erc20 into thorchai
8
10
  exports.THORCHAIN_FIXED_PRECISION = 8; // limit values are precision 8 regardless of the chain
9
11
  exports.THORCHAIN_AFFILIATE_NAME = 'ss';
10
12
  exports.THORCHAIN_AFFILIATE_BIPS = '0'; // affiliate fee in basis points (100 = 1%)
11
- // These are different from THOR_ETH_GAS_LIMIT
12
13
  // Used to estimate the fee thorchain will take out of the buyAsset
13
- exports.THOR_TRADE_FEE_BTC_SIZE = 1000; // used for estimating thorchain side fees
14
- exports.THOR_TRADE_FEE_ETH_GAS = 120000; // used for estimating thorchain side fees
14
+ // Official docs on fees are incorrect
15
+ // https://discord.com/channels/838986635756044328/997675038675316776/998552541170253834
16
+ // This is still not "perfect" and tends to overestimate by a small randomish amount
17
+ // TODO figure out if its possible to accurately estimate the outbound fee.
18
+ // Neither the discord nor official docs are correct
19
+ exports.THOR_TRADE_FEE_MULTIPLIERS = {
20
+ [types_1.KnownChainIds.BitcoinMainnet]: (0, bignumber_1.bn)(0.00002),
21
+ [types_1.KnownChainIds.DogecoinMainnet]: (0, bignumber_1.bn)(0.00002),
22
+ [types_1.KnownChainIds.LitecoinMainnet]: (0, bignumber_1.bn)(0.000005),
23
+ [types_1.KnownChainIds.CosmosMainnet]: (0, bignumber_1.bn)(0.00000002),
24
+ [types_1.KnownChainIds.EthereumMainnet]: (0, bignumber_1.bn)(0.00024) // A value that "works". Discord recommended value (80,000 gas * 2 or 160k) is often too low
25
+ };
@@ -0,0 +1,19 @@
1
+ import { Asset } from '@shapeshiftoss/asset-service';
2
+ import { ChainId } from '@shapeshiftoss/caip';
3
+ import { ChainAdapter } from '@shapeshiftoss/chain-adapters';
4
+ import { HDWallet } from '@shapeshiftoss/hdwallet-core';
5
+ import { KnownChainIds } from '@shapeshiftoss/types';
6
+ import { TradeQuote } from '../../../../api';
7
+ import { ThorchainSwapperDeps } from '../../types';
8
+ export declare const cosmosTxData: (input: {
9
+ destinationAddress: string;
10
+ deps: ThorchainSwapperDeps;
11
+ sellAmount: string;
12
+ sellAsset: Asset;
13
+ buyAsset: Asset;
14
+ slippageTolerance: string;
15
+ wallet: HDWallet;
16
+ quote: TradeQuote<KnownChainIds.CosmosMainnet>;
17
+ chainId: ChainId;
18
+ sellAdapter: ChainAdapter<KnownChainIds.CosmosMainnet>;
19
+ }) => Promise<import("@shapeshiftoss/hdwallet-core").CosmosSignTx>;
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.cosmosTxData = void 0;
4
+ const api_1 = require("../../../../api");
5
+ const getLimit_1 = require("../getLimit/getLimit");
6
+ const makeSwapMemo_1 = require("../makeSwapMemo/makeSwapMemo");
7
+ const thorService_1 = require("../thorService");
8
+ const cosmosTxData = async (input) => {
9
+ const { deps, destinationAddress, sellAmount, sellAsset, buyAsset, slippageTolerance, quote, wallet, sellAdapter } = input;
10
+ const { data: inboundAddresses } = await thorService_1.thorService.get(`${deps.midgardUrl}/thorchain/inbound_addresses`);
11
+ const atomInboundAddresses = inboundAddresses.find((inbound) => inbound.chain === 'GAIA');
12
+ const vault = atomInboundAddresses === null || atomInboundAddresses === void 0 ? void 0 : atomInboundAddresses.address;
13
+ if (!vault)
14
+ throw new api_1.SwapError('[buildTrade]: no vault for chain', {
15
+ code: api_1.SwapErrorTypes.BUILD_TRADE_FAILED,
16
+ fn: 'buildTrade',
17
+ details: { chainId: input.chainId }
18
+ });
19
+ const limit = await (0, getLimit_1.getLimit)({
20
+ buyAssetId: buyAsset.assetId,
21
+ destinationAddress,
22
+ sellAmount,
23
+ sellAsset,
24
+ buyAsset,
25
+ slippageTolerance,
26
+ deps,
27
+ tradeFee: quote.feeData.tradeFee
28
+ });
29
+ const memo = (0, makeSwapMemo_1.makeSwapMemo)({
30
+ buyAssetId: buyAsset.assetId,
31
+ destinationAddress,
32
+ limit
33
+ });
34
+ const buildTxResponse = await sellAdapter.buildSendTransaction({
35
+ value: sellAmount,
36
+ wallet,
37
+ to: vault,
38
+ memo,
39
+ chainSpecific: {
40
+ gas: quote.feeData.chainSpecific.estimatedGas,
41
+ fee: quote.feeData.fee
42
+ }
43
+ });
44
+ return buildTxResponse.txToSign;
45
+ };
46
+ exports.cosmosTxData = cosmosTxData;
@@ -1,30 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.estimateTradeFee = void 0;
4
- const asset_service_1 = require("@shapeshiftoss/asset-service");
5
4
  const caip_1 = require("@shapeshiftoss/caip");
6
5
  const api_1 = require("../../../../api");
7
- const bignumber_1 = require("../../../utils/bignumber");
8
6
  const constants_1 = require("../constants");
9
7
  const getPriceRatio_1 = require("../getPriceRatio/getPriceRatio");
10
8
  const thorService_1 = require("../thorService");
11
- const gweiGasPrecision = 9;
12
- // Official docs on fees are incorrect
13
- // https://discord.com/channels/838986635756044328/997675038675316776/998552541170253834
14
- // This is still not "perfect" and tends to overestimate by a randomish amount
15
- // TODO figure out if its possible to accurately estimate the outbound fee.
16
- // Neither the discord nor official docs are correct
17
- const ethEstimate = (gasRate) => (0, bignumber_1.bnOrZero)(gasRate)
18
- .times(constants_1.THOR_TRADE_FEE_ETH_GAS)
19
- .times(2)
20
- .times((0, bignumber_1.bn)(10).exponentiatedBy(gweiGasPrecision))
21
- .toString();
22
- const erc20Estimate = (gasRate) => (0, bignumber_1.bnOrZero)(gasRate)
23
- .times(constants_1.THOR_TRADE_FEE_ETH_GAS)
24
- .times(2)
25
- .times((0, bignumber_1.bn)(10).exponentiatedBy(gweiGasPrecision))
26
- .toString();
27
- const btcEstimate = (gasRate) => (0, bignumber_1.bnOrZero)(gasRate).times(constants_1.THOR_TRADE_FEE_BTC_SIZE).times(2).toString();
28
9
  const estimateTradeFee = async (deps, buyAsset) => {
29
10
  const thorId = caip_1.adapters.assetIdToPoolAssetId({ assetId: buyAsset.assetId });
30
11
  if (!thorId)
@@ -41,7 +22,7 @@ const estimateTradeFee = async (deps, buyAsset) => {
41
22
  details: { thorPoolChainId }
42
23
  });
43
24
  const gasRate = inboundInfo.gas_rate;
44
- const { chainId: buyChainId, assetNamespace } = (0, caip_1.fromAssetId)(buyAsset.assetId);
25
+ const { chainId: buyChainId } = (0, caip_1.fromAssetId)(buyAsset.assetId);
45
26
  const buyAdapter = deps.adapterManager.get(buyChainId);
46
27
  if (!buyAdapter)
47
28
  throw new api_1.SwapError('[estimateTradeFee] - unable to get buy asset adapter', {
@@ -54,33 +35,17 @@ const estimateTradeFee = async (deps, buyAsset) => {
54
35
  code: api_1.SwapErrorTypes.VALIDATION_FAILED,
55
36
  details: { buyAssetId: buyAsset.assetId }
56
37
  });
57
- const feeAssetRatio = buyAsset.assetId !== buyFeeAssetId
38
+ const buyFeeAssetRatio = buyAsset.assetId !== buyFeeAssetId
58
39
  ? await (0, getPriceRatio_1.getPriceRatio)(deps, {
59
40
  sellAssetId: buyAsset.assetId,
60
41
  buyAssetId: buyFeeAssetId
61
42
  })
62
43
  : '1';
63
- const buyFeeAsset = new asset_service_1.AssetService().getAll()[buyFeeAssetId];
64
- switch (buyChainId) {
65
- case 'bip122:000000000019d6689c085ae165831e93':
66
- return (0, bignumber_1.fromBaseUnit)((0, bignumber_1.bnOrZero)(btcEstimate(gasRate)).times(feeAssetRatio).dp(0), buyFeeAsset.precision);
67
- case 'eip155:1':
68
- switch (assetNamespace) {
69
- case 'slip44':
70
- return (0, bignumber_1.fromBaseUnit)((0, bignumber_1.bnOrZero)(ethEstimate(gasRate)).times(feeAssetRatio).dp(0), buyFeeAsset.precision);
71
- case 'erc20':
72
- return (0, bignumber_1.fromBaseUnit)((0, bignumber_1.bnOrZero)(erc20Estimate(gasRate)).times(feeAssetRatio).dp(0), buyFeeAsset.precision);
73
- default:
74
- throw new api_1.SwapError('[estimateTradeFee] - unsupported asset namespace', {
75
- code: api_1.SwapErrorTypes.VALIDATION_FAILED,
76
- details: { assetNamespace }
77
- });
78
- }
79
- default:
80
- throw new api_1.SwapError('[estimateTradeFee] - unsupported chain id', {
81
- code: api_1.SwapErrorTypes.VALIDATION_FAILED,
82
- details: { chainId: buyChainId }
83
- });
84
- }
44
+ if (!constants_1.THOR_TRADE_FEE_MULTIPLIERS[buyChainId])
45
+ throw new api_1.SwapError('[estimateTradeFee] - no trade fee multiplier', {
46
+ code: api_1.SwapErrorTypes.VALIDATION_FAILED,
47
+ details: { buyChainId }
48
+ });
49
+ return constants_1.THOR_TRADE_FEE_MULTIPLIERS[buyChainId].times(buyFeeAssetRatio).times(gasRate).toString();
85
50
  };
86
51
  exports.estimateTradeFee = estimateTradeFee;
@@ -3,9 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getThorTxInfo = void 0;
4
4
  const caip_1 = require("@shapeshiftoss/caip");
5
5
  const api_1 = require("../../../../../api");
6
- const bignumber_1 = require("../../../../utils/bignumber");
7
- const getTradeRate_1 = require("../../../utils/getTradeRate/getTradeRate");
8
- const constants_1 = require("../../constants");
6
+ const getLimit_1 = require("../../getLimit/getLimit");
9
7
  const makeSwapMemo_1 = require("../../makeSwapMemo/makeSwapMemo");
10
8
  const thorService_1 = require("../../thorService");
11
9
  const routerCalldata_1 = require("../routerCalldata");
@@ -22,20 +20,16 @@ const getThorTxInfo = async ({ deps, sellAsset, buyAsset, sellAmount, slippageTo
22
20
  code: api_1.SwapErrorTypes.RESPONSE_ERROR,
23
21
  details: { inboundAddresses }
24
22
  });
25
- const tradeRate = await (0, getTradeRate_1.getTradeRate)(sellAsset, buyAsset.assetId, sellAmount, deps);
26
- const expectedBuyAmountPrecision8 = (0, bignumber_1.toBaseUnit)((0, bignumber_1.fromBaseUnit)((0, bignumber_1.bnOrZero)(sellAmount).times(tradeRate), sellAsset.precision), constants_1.THORCHAIN_FIXED_PRECISION);
27
- const tradeFeePrecision8 = (0, bignumber_1.toBaseUnit)((0, bignumber_1.bnOrZero)(tradeFee), constants_1.THORCHAIN_FIXED_PRECISION);
28
- const isValidSlippageRange = (0, bignumber_1.bnOrZero)(slippageTolerance).gte(0) && (0, bignumber_1.bnOrZero)(slippageTolerance).lte(1);
29
- if ((0, bignumber_1.bnOrZero)(expectedBuyAmountPrecision8).lt(0) || !isValidSlippageRange)
30
- throw new api_1.SwapError('[makeTradeTx]: bad expected buy amount or bad slippage tolerance', {
31
- code: api_1.SwapErrorTypes.BUILD_TRADE_FAILED,
32
- details: { expectedBuyAmountPrecision8, slippageTolerance }
33
- });
34
- const limit = (0, bignumber_1.bnOrZero)(expectedBuyAmountPrecision8)
35
- .times((0, bignumber_1.bn)(1).minus(slippageTolerance))
36
- .minus((0, bignumber_1.bnOrZero)(tradeFeePrecision8))
37
- .decimalPlaces(0)
38
- .toString();
23
+ const limit = await (0, getLimit_1.getLimit)({
24
+ buyAssetId: buyAsset.assetId,
25
+ destinationAddress,
26
+ sellAmount,
27
+ sellAsset,
28
+ buyAsset,
29
+ slippageTolerance,
30
+ deps,
31
+ tradeFee
32
+ });
39
33
  const memo = (0, makeSwapMemo_1.makeSwapMemo)({
40
34
  buyAssetId: buyAsset.assetId,
41
35
  destinationAddress,
@@ -0,0 +1,12 @@
1
+ import { Asset } from '@shapeshiftoss/asset-service';
2
+ import { ThorchainSwapperDeps } from '../../types';
3
+ export declare const getLimit: ({ sellAsset, buyAsset, sellAmount, deps, slippageTolerance, tradeFee }: {
4
+ buyAssetId: string;
5
+ destinationAddress: string;
6
+ sellAsset: Asset;
7
+ buyAsset: Asset;
8
+ sellAmount: string;
9
+ deps: ThorchainSwapperDeps;
10
+ slippageTolerance: string;
11
+ tradeFee: string;
12
+ }) => Promise<string>;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getLimit = void 0;
4
+ const api_1 = require("../../../../api");
5
+ const bignumber_1 = require("../../../utils/bignumber");
6
+ const constants_1 = require("../constants");
7
+ const getTradeRate_1 = require("../getTradeRate/getTradeRate");
8
+ const getLimit = async ({ sellAsset, buyAsset, sellAmount, deps, slippageTolerance, tradeFee }) => {
9
+ const tradeRate = await (0, getTradeRate_1.getTradeRate)(sellAsset, buyAsset.assetId, sellAmount, deps);
10
+ const expectedBuyAmountPrecision8 = (0, bignumber_1.toBaseUnit)((0, bignumber_1.fromBaseUnit)((0, bignumber_1.bnOrZero)(sellAmount).times(tradeRate), sellAsset.precision), constants_1.THORCHAIN_FIXED_PRECISION);
11
+ const isValidSlippageRange = (0, bignumber_1.bnOrZero)(slippageTolerance).gte(0) && (0, bignumber_1.bnOrZero)(slippageTolerance).lte(1);
12
+ if ((0, bignumber_1.bnOrZero)(expectedBuyAmountPrecision8).lt(0) || !isValidSlippageRange)
13
+ throw new api_1.SwapError('[getThorTxInfo]: bad expected buy amount or bad slippage tolerance', {
14
+ code: api_1.SwapErrorTypes.BUILD_TRADE_FAILED,
15
+ details: { expectedBuyAmountPrecision8, slippageTolerance }
16
+ });
17
+ const tradeFeePrecision8 = (0, bignumber_1.toBaseUnit)((0, bignumber_1.bnOrZero)(tradeFee), constants_1.THORCHAIN_FIXED_PRECISION);
18
+ return (0, bignumber_1.bnOrZero)(expectedBuyAmountPrecision8)
19
+ .times((0, bignumber_1.bn)(1).minus(slippageTolerance))
20
+ .minus((0, bignumber_1.bnOrZero)(tradeFeePrecision8))
21
+ .decimalPlaces(0)
22
+ .toString();
23
+ };
24
+ exports.getLimit = getLimit;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shapeshiftoss/swapper",
3
- "version": "9.3.1",
3
+ "version": "9.5.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",