@shapeshiftoss/swapper 8.7.1 → 9.1.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 (39) hide show
  1. package/dist/api.d.ts +2 -1
  2. package/dist/swappers/cow/CowSwapper.d.ts +2 -1
  3. package/dist/swappers/cow/getCowSwapMinMax/getCowSwapMinMax.d.ts +1 -1
  4. package/dist/swappers/cow/utils/helpers/helpers.d.ts +1 -1
  5. package/dist/swappers/osmosis/OsmosisSwapper.d.ts +1 -1
  6. package/dist/swappers/test/TestSwapper.d.ts +1 -1
  7. package/dist/swappers/thorchain/ThorchainSwapper.d.ts +4 -4
  8. package/dist/swappers/thorchain/ThorchainSwapper.js +47 -19
  9. package/dist/swappers/thorchain/buildThorTrade/buildThorTrade.d.ts +7 -0
  10. package/dist/swappers/thorchain/buildThorTrade/buildThorTrade.js +95 -0
  11. package/dist/swappers/thorchain/getThorTradeQuote/getTradeQuote.js +19 -24
  12. package/dist/swappers/thorchain/thorTradeApprovalNeeded/thorTradeApprovalNeeded.js +2 -6
  13. package/dist/swappers/thorchain/utils/bitcoin/utils/getThorTxData.d.ts +3 -1
  14. package/dist/swappers/thorchain/utils/bitcoin/utils/getThorTxData.js +10 -10
  15. package/dist/swappers/thorchain/utils/constants.d.ts +5 -0
  16. package/dist/swappers/thorchain/utils/constants.js +8 -1
  17. package/dist/swappers/thorchain/utils/estimateTradeFee/estimateTradeFee.d.ts +2 -2
  18. package/dist/swappers/thorchain/utils/estimateTradeFee/estimateTradeFee.js +28 -19
  19. package/dist/swappers/thorchain/utils/ethereum/makeTradeTx.d.ts +4 -2
  20. package/dist/swappers/thorchain/utils/ethereum/makeTradeTx.js +5 -3
  21. package/dist/swappers/thorchain/utils/ethereum/utils/getThorTxData.d.ts +2 -1
  22. package/dist/swappers/thorchain/utils/ethereum/utils/getThorTxData.js +10 -10
  23. package/dist/swappers/thorchain/utils/getTradeRate/getTradeRate.d.ts +1 -1
  24. package/dist/swappers/thorchain/utils/getTradeRate/getTradeRate.js +8 -0
  25. package/dist/swappers/thorchain/utils/getUsdRate/getUsdRate.d.ts +1 -1
  26. package/dist/swappers/thorchain/utils/test-data/setupThorswapDeps.js +19 -1
  27. package/dist/swappers/thorchain/utils/txFeeHelpers/btcTxFees/getBtcTxFees.d.ts +3 -5
  28. package/dist/swappers/thorchain/utils/txFeeHelpers/btcTxFees/getBtcTxFees.js +1 -3
  29. package/dist/swappers/thorchain/utils/txFeeHelpers/ethTxFees/getEthTxFees.d.ts +4 -10
  30. package/dist/swappers/thorchain/utils/txFeeHelpers/ethTxFees/getEthTxFees.js +14 -26
  31. package/dist/swappers/utils/helpers/helpers.d.ts +1 -1
  32. package/dist/swappers/utils/test-data/assets.d.ts +1 -1
  33. package/dist/swappers/utils/test-data/setupDeps.d.ts +1 -1
  34. package/dist/swappers/utils/test-data/setupSwapQuote.d.ts +2 -1
  35. package/dist/swappers/zrx/ZrxSwapper.d.ts +1 -1
  36. package/dist/swappers/zrx/getZrxMinMax/getZrxMinMax.d.ts +1 -1
  37. package/dist/swappers/zrx/utils/helpers/helpers.d.ts +1 -1
  38. package/dist/swappers/zrx/utils/test-data/setupZrxSwapQuote.d.ts +1 -1
  39. package/package.json +5 -5
package/dist/api.d.ts CHANGED
@@ -1,7 +1,8 @@
1
+ import { Asset } from '@shapeshiftoss/asset-service';
1
2
  import { AssetId, ChainId } from '@shapeshiftoss/caip';
2
3
  import { avalanche, cosmos, ethereum, osmosis } from '@shapeshiftoss/chain-adapters';
3
4
  import { HDWallet } from '@shapeshiftoss/hdwallet-core';
4
- import { Asset, BIP44Params, ChainSpecific, KnownChainIds, UtxoAccountType } from '@shapeshiftoss/types';
5
+ import { BIP44Params, ChainSpecific, KnownChainIds, UtxoAccountType } from '@shapeshiftoss/types';
5
6
  export declare const SwapError: {
6
7
  new <V extends {
7
8
  cause?: unknown;
@@ -1,6 +1,7 @@
1
+ import { Asset } from '@shapeshiftoss/asset-service';
1
2
  import { AssetId } from '@shapeshiftoss/caip';
2
3
  import { ethereum } from '@shapeshiftoss/chain-adapters';
3
- import { Asset, KnownChainIds } from '@shapeshiftoss/types';
4
+ import { KnownChainIds } from '@shapeshiftoss/types';
4
5
  import Web3 from 'web3';
5
6
  import { ApprovalNeededInput, ApprovalNeededOutput, ApproveInfiniteInput, BuildTradeInput, BuyAssetBySellIdInput, ExecuteTradeInput, GetTradeQuoteInput, Swapper, SwapperType, TradeQuote, TradeResult, TradeTxs } from '../../api';
6
7
  import { CowTrade } from './types';
@@ -1,4 +1,4 @@
1
- import { Asset } from '@shapeshiftoss/types';
1
+ import { Asset } from '@shapeshiftoss/asset-service';
2
2
  import { MinMaxOutput } from '../../../api';
3
3
  import { CowSwapperDeps } from '../CowSwapper';
4
4
  export declare const getCowSwapMinMax: (deps: CowSwapperDeps, sellAsset: Asset, buyAsset: Asset) => Promise<MinMaxOutput>;
@@ -1,5 +1,5 @@
1
1
  import { TypedDataDomain, TypedDataField } from '@ethersproject/abstract-signer';
2
- import { Asset } from '@shapeshiftoss/types';
2
+ import { Asset } from '@shapeshiftoss/asset-service';
3
3
  import { CowSwapperDeps } from '../../CowSwapper';
4
4
  export declare const ORDER_TYPE_FIELDS: {
5
5
  name: string;
@@ -1,5 +1,5 @@
1
+ import { Asset } from '@shapeshiftoss/asset-service';
1
2
  import { AssetId, ChainId } from '@shapeshiftoss/caip';
2
- import { Asset } from '@shapeshiftoss/types';
3
3
  import { ApprovalNeededOutput, BuildTradeInput, BuyAssetBySellIdInput, ExecuteTradeInput, GetTradeQuoteInput, MinMaxOutput, Swapper, SwapperType, Trade, TradeQuote, TradeResult, TradeTxs } from '../../api';
4
4
  import { OsmoSwapperDeps } from './utils/types';
5
5
  export declare class OsmosisSwapper implements Swapper<ChainId> {
@@ -1,5 +1,5 @@
1
+ import { Asset } from '@shapeshiftoss/asset-service';
1
2
  import { AssetId, ChainId } from '@shapeshiftoss/caip';
2
- import { Asset } from '@shapeshiftoss/types';
3
3
  import { ApprovalNeededOutput, BuyAssetBySellIdInput, Swapper, SwapperType, Trade, TradeQuote, TradeResult, TradeTxs } from '../../api';
4
4
  /**
5
5
  * Playground for testing different scenarios of multiple swappers in the manager.
@@ -1,7 +1,7 @@
1
+ import { Asset } from '@shapeshiftoss/asset-service';
1
2
  import { AssetId, ChainId } from '@shapeshiftoss/caip';
2
- import type { Asset } from '@shapeshiftoss/types';
3
3
  import { KnownChainIds } from '@shapeshiftoss/types';
4
- import { ApprovalNeededInput, ApprovalNeededOutput, ApproveInfiniteInput, BuyAssetBySellIdInput, ExecuteTradeInput, GetTradeQuoteInput, Swapper, SwapperType, Trade, TradeQuote, TradeResult, TradeTxs } from '../../api';
4
+ import { ApprovalNeededInput, ApprovalNeededOutput, ApproveInfiniteInput, BuildTradeInput, BuyAssetBySellIdInput, ExecuteTradeInput, GetTradeQuoteInput, Swapper, SwapperType, Trade, TradeQuote, TradeResult, TradeTxs } from '../../api';
5
5
  import { ThorchainSwapperDeps } from './types';
6
6
  export declare class ThorchainSwapper implements Swapper<ChainId> {
7
7
  readonly name = "Thorchain";
@@ -16,8 +16,8 @@ export declare class ThorchainSwapper implements Swapper<ChainId> {
16
16
  approveInfinite(input: ApproveInfiniteInput<KnownChainIds.EthereumMainnet>): Promise<string>;
17
17
  filterBuyAssetsBySellAssetId(args: BuyAssetBySellIdInput): AssetId[];
18
18
  filterAssetIdsBySellable(): AssetId[];
19
- buildTrade(): Promise<Trade<ChainId>>;
19
+ buildTrade(input: BuildTradeInput): Promise<Trade<ChainId>>;
20
20
  getTradeQuote(input: GetTradeQuoteInput): Promise<TradeQuote<ChainId>>;
21
21
  executeTrade(args: ExecuteTradeInput<ChainId>): Promise<TradeResult>;
22
- getTradeTxs(): Promise<TradeTxs>;
22
+ getTradeTxs(tradeResult: TradeResult): Promise<TradeTxs>;
23
23
  }
@@ -4,6 +4,7 @@ exports.ThorchainSwapper = void 0;
4
4
  const caip_1 = require("@shapeshiftoss/caip");
5
5
  const types_1 = require("@shapeshiftoss/types");
6
6
  const api_1 = require("../../api");
7
+ const buildThorTrade_1 = require("./buildThorTrade/buildThorTrade");
7
8
  const getTradeQuote_1 = require("./getThorTradeQuote/getTradeQuote");
8
9
  const thorTradeApprovalNeeded_1 = require("./thorTradeApprovalNeeded/thorTradeApprovalNeeded");
9
10
  const thorTradeApproveInfinite_1 = require("./thorTradeApproveInfinite/thorTradeApproveInfinite");
@@ -13,8 +14,8 @@ class ThorchainSwapper {
13
14
  constructor(deps) {
14
15
  this.name = 'Thorchain';
15
16
  this.swapSupportedChainIds = {
16
- 'eip155:1': true,
17
- 'bip122:000000000019d6689c085ae165831e93': true
17
+ [types_1.KnownChainIds.EthereumMainnet]: true,
18
+ [types_1.KnownChainIds.BitcoinMainnet]: true
18
19
  };
19
20
  this.supportedAssetIds = [];
20
21
  this.deps = deps;
@@ -59,33 +60,60 @@ class ThorchainSwapper {
59
60
  filterAssetIdsBySellable() {
60
61
  return this.supportedAssetIds;
61
62
  }
62
- async buildTrade() {
63
- throw new Error('ThorchainSwapper: buildTrade unimplemented');
63
+ async buildTrade(input) {
64
+ return (0, buildThorTrade_1.buildTrade)({ deps: this.deps, input });
64
65
  }
65
66
  async getTradeQuote(input) {
66
67
  return (0, getTradeQuote_1.getThorTradeQuote)({ deps: this.deps, input });
67
68
  }
68
69
  async executeTrade(args) {
69
- const { trade, wallet } = args;
70
- const adapter = this.deps.adapterManager.get(trade.sellAsset.chainId);
71
- if (adapter && trade.sellAsset.chainId === types_1.KnownChainIds.EthereumMainnet) {
72
- const thorTradeEth = trade;
73
- const signedTx = await adapter.signTransaction({
74
- txToSign: thorTradeEth.txData,
75
- wallet
76
- });
77
- const txid = await adapter.broadcastTransaction(signedTx);
78
- return { tradeId: txid };
70
+ try {
71
+ const { trade, wallet } = args;
72
+ const adapter = this.deps.adapterManager.get(trade.sellAsset.chainId);
73
+ if (!adapter)
74
+ throw new api_1.SwapError('[executeTrade]: no adapter for sell asset chain id', {
75
+ code: api_1.SwapErrorTypes.SIGN_AND_BROADCAST_FAILED,
76
+ details: { chainId: trade.sellAsset.chainId },
77
+ fn: 'executeTrade'
78
+ });
79
+ if (trade.sellAsset.chainId === types_1.KnownChainIds.EthereumMainnet) {
80
+ const signedTx = await adapter.signTransaction({
81
+ txToSign: trade.txData,
82
+ wallet
83
+ });
84
+ const txid = await adapter.broadcastTransaction(signedTx);
85
+ return { tradeId: txid };
86
+ }
87
+ else if (trade.sellAsset.chainId === types_1.KnownChainIds.BitcoinMainnet) {
88
+ const signedTx = await adapter.signTransaction({
89
+ txToSign: trade.txData,
90
+ wallet
91
+ });
92
+ const txid = await adapter.broadcastTransaction(signedTx);
93
+ return { tradeId: txid };
94
+ }
95
+ else {
96
+ throw new api_1.SwapError('[executeTrade]: unsupported trade', {
97
+ code: api_1.SwapErrorTypes.SIGN_AND_BROADCAST_FAILED,
98
+ fn: 'executeTrade'
99
+ });
100
+ }
79
101
  }
80
- else {
81
- throw new api_1.SwapError('[executeTrade]: unsupported trade', {
102
+ catch (e) {
103
+ if (e instanceof api_1.SwapError)
104
+ throw e;
105
+ throw new api_1.SwapError('[executeTrade]: failed to sign or broadcast', {
82
106
  code: api_1.SwapErrorTypes.SIGN_AND_BROADCAST_FAILED,
83
- fn: 'executeTrade'
107
+ cause: e
84
108
  });
85
109
  }
86
110
  }
87
- async getTradeTxs() {
88
- throw new Error('ThorchainSwapper: executeTrade unimplemented');
111
+ async getTradeTxs(tradeResult) {
112
+ // TODO poll midgard for the correct buyTxid
113
+ return {
114
+ sellTxid: tradeResult.tradeId,
115
+ buyTxid: tradeResult.tradeId
116
+ };
89
117
  }
90
118
  }
91
119
  exports.ThorchainSwapper = ThorchainSwapper;
@@ -0,0 +1,7 @@
1
+ import { ChainId } from '@shapeshiftoss/caip';
2
+ import { BuildTradeInput } from '../../../api';
3
+ import { ThorchainSwapperDeps, ThorTrade } from '../types';
4
+ export declare const buildTrade: ({ deps, input }: {
5
+ deps: ThorchainSwapperDeps;
6
+ input: BuildTradeInput;
7
+ }) => Promise<ThorTrade<ChainId>>;
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildTrade = void 0;
4
+ const types_1 = require("@shapeshiftoss/types");
5
+ const api_1 = require("../../../api");
6
+ const constants_1 = require("../../utils/constants");
7
+ const getTradeQuote_1 = require("../getThorTradeQuote/getTradeQuote");
8
+ const getThorTxData_1 = require("../utils/bitcoin/utils/getThorTxData");
9
+ const makeTradeTx_1 = require("../utils/ethereum/makeTradeTx");
10
+ const buildTrade = async ({ deps, input }) => {
11
+ var _a, _b, _c, _d;
12
+ try {
13
+ const { buyAsset, sellAsset, sellAssetAccountNumber, sellAmount, wallet, slippage: slippageTolerance = constants_1.DEFAULT_SLIPPAGE, receiveAddress: destinationAddress } = input;
14
+ const quote = await (0, getTradeQuote_1.getThorTradeQuote)({ deps, input });
15
+ const sellAdapter = deps.adapterManager.get(sellAsset.chainId);
16
+ if (!sellAdapter)
17
+ throw new api_1.SwapError('[buildTrade]: unsupported sell asset', {
18
+ code: api_1.SwapErrorTypes.BUILD_TRADE_FAILED,
19
+ fn: 'buildTrade',
20
+ details: { sellAsset }
21
+ });
22
+ const sellAssetBip44Params = sellAdapter.buildBIP44Params({
23
+ accountNumber: sellAssetAccountNumber
24
+ });
25
+ if (input.chainId === types_1.KnownChainIds.EthereumMainnet) {
26
+ const ethTradeTx = await (0, makeTradeTx_1.makeTradeTx)({
27
+ wallet,
28
+ slippageTolerance,
29
+ bip44Params: sellAssetBip44Params,
30
+ sellAsset,
31
+ buyAsset,
32
+ adapter: sellAdapter,
33
+ sellAmount,
34
+ destinationAddress,
35
+ deps,
36
+ gasPrice: (_b = (_a = quote.feeData.chainSpecific) === null || _a === void 0 ? void 0 : _a.gasPrice) !== null && _b !== void 0 ? _b : '0',
37
+ gasLimit: (_d = (_c = quote.feeData.chainSpecific) === null || _c === void 0 ? void 0 : _c.estimatedGas) !== null && _d !== void 0 ? _d : '0',
38
+ tradeFee: quote.feeData.tradeFee
39
+ });
40
+ return {
41
+ chainId: types_1.KnownChainIds.EthereumMainnet,
42
+ ...quote,
43
+ receiveAddress: destinationAddress,
44
+ txData: ethTradeTx.txToSign
45
+ };
46
+ }
47
+ else if (input.chainId === types_1.KnownChainIds.BitcoinMainnet) {
48
+ const { vault, opReturnData } = await (0, getThorTxData_1.getThorTxInfo)({
49
+ deps,
50
+ sellAsset,
51
+ buyAsset,
52
+ sellAmount,
53
+ slippageTolerance,
54
+ destinationAddress,
55
+ wallet,
56
+ bip44Params: sellAssetBip44Params,
57
+ accountType: input.accountType,
58
+ tradeFee: quote.feeData.tradeFee
59
+ });
60
+ const buildTxResponse = await sellAdapter.buildSendTransaction({
61
+ value: sellAmount,
62
+ wallet,
63
+ to: vault,
64
+ chainSpecific: {
65
+ accountType: input.accountType,
66
+ satoshiPerByte: quote.feeData.chainSpecific
67
+ .satsPerByte,
68
+ opReturnData
69
+ }
70
+ });
71
+ return {
72
+ chainId: types_1.KnownChainIds.BitcoinMainnet,
73
+ ...quote,
74
+ receiveAddress: destinationAddress,
75
+ txData: buildTxResponse.txToSign
76
+ };
77
+ }
78
+ else {
79
+ throw new api_1.SwapError('[buildTrade]: unsupported chain id', {
80
+ code: api_1.SwapErrorTypes.BUILD_TRADE_FAILED,
81
+ fn: 'buildTrade',
82
+ details: { sellAsset }
83
+ });
84
+ }
85
+ }
86
+ catch (e) {
87
+ if (e instanceof api_1.SwapError)
88
+ throw e;
89
+ throw new api_1.SwapError('[buildTrade]: error building trade', {
90
+ code: api_1.SwapErrorTypes.BUILD_TRADE_FAILED,
91
+ fn: 'buildTrade'
92
+ });
93
+ }
94
+ };
95
+ exports.buildTrade = buildTrade;
@@ -6,18 +6,17 @@ const types_1 = require("@shapeshiftoss/types");
6
6
  const api_1 = require("../../../api");
7
7
  const bignumber_1 = require("../../utils/bignumber");
8
8
  const constants_1 = require("../../utils/constants");
9
- const helpers_1 = require("../../utils/helpers/helpers");
10
9
  const getThorTxData_1 = require("../utils/bitcoin/utils/getThorTxData");
11
10
  const constants_2 = require("../utils/constants");
12
11
  const estimateTradeFee_1 = require("../utils/estimateTradeFee/estimateTradeFee");
13
12
  const getThorTxData_2 = require("../utils/ethereum/utils/getThorTxData");
14
- const getPriceRatio_1 = require("../utils/getPriceRatio/getPriceRatio");
13
+ const getTradeRate_1 = require("../utils/getTradeRate/getTradeRate");
15
14
  const getBtcTxFees_1 = require("../utils/txFeeHelpers/btcTxFees/getBtcTxFees");
16
15
  const getEthTxFees_1 = require("../utils/txFeeHelpers/ethTxFees/getEthTxFees");
17
16
  const getThorTradeQuote = async ({ deps, input }) => {
18
17
  const { sellAsset, buyAsset, sellAmount, sellAssetAccountNumber, wallet, chainId, receiveAddress } = input;
19
18
  if (!wallet)
20
- throw new api_1.SwapError('[getTradeQuote] - wallet is required', {
19
+ throw new api_1.SwapError('[getThorTradeQuote] - wallet is required', {
21
20
  code: api_1.SwapErrorTypes.VALIDATION_FAILED
22
21
  });
23
22
  try {
@@ -28,7 +27,6 @@ const getThorTradeQuote = async ({ deps, input }) => {
28
27
  code: api_1.SwapErrorTypes.UNSUPPORTED_CHAIN,
29
28
  details: { chainId }
30
29
  });
31
- const sellAssetId = sellAsset.assetId;
32
30
  const buyAssetId = buyAsset.assetId;
33
31
  const feeAssetId = (0, caip_1.getFeeAssetIdFromAssetId)(buyAssetId);
34
32
  if (!feeAssetId)
@@ -36,13 +34,14 @@ const getThorTradeQuote = async ({ deps, input }) => {
36
34
  code: api_1.SwapErrorTypes.VALIDATION_FAILED,
37
35
  details: { buyAssetId }
38
36
  });
39
- const priceRatio = await (0, getPriceRatio_1.getPriceRatio)(deps, { sellAssetId, buyAssetId });
40
- const rate = (0, bignumber_1.bnOrZero)(1).div(priceRatio).toString();
41
- const buyAmount = (0, helpers_1.normalizeAmount)((0, bignumber_1.bnOrZero)(sellAmount).times(rate));
42
- const tradeFee = await (0, estimateTradeFee_1.estimateTradeFee)(deps, buyAsset.assetId);
43
- const sellAssetTradeFee = (0, bignumber_1.fromBaseUnit)((0, bignumber_1.bnOrZero)(tradeFee).times((0, bignumber_1.bnOrZero)(priceRatio)), buyAsset.precision);
44
- // padding minimum by 1.5 the trade fee to avoid thorchain "not enough to cover fee" errors.
45
- const minimum = (0, bignumber_1.bnOrZero)(sellAssetTradeFee).times(1.5).toString();
37
+ const tradeRate = await (0, getTradeRate_1.getTradeRate)(sellAsset, buyAsset.assetId, sellAmount, deps);
38
+ const rate = (0, bignumber_1.bnOrZero)(1).div(tradeRate).toString();
39
+ const buyAmount = (0, bignumber_1.toBaseUnit)((0, bignumber_1.bnOrZero)((0, bignumber_1.fromBaseUnit)(sellAmount, sellAsset.precision)).times(tradeRate), buyAsset.precision);
40
+ const tradeFee = await (0, estimateTradeFee_1.estimateTradeFee)(deps, buyAsset);
41
+ const sellAssetTradeFee = (0, bignumber_1.bnOrZero)(tradeFee).times((0, bignumber_1.bnOrZero)(rate));
42
+ // minimum is tradeFee padded by an amount to be sure they get something back
43
+ // usually it will be slightly more than the amount because sellAssetTradeFee is already a high estimate
44
+ const minimum = (0, bignumber_1.bnOrZero)(sellAssetTradeFee).times(constants_2.THOR_MINIMUM_PADDING).toString();
46
45
  const commonQuoteFields = {
47
46
  rate,
48
47
  maximum: constants_2.MAX_THORCHAIN_TRADE,
@@ -57,23 +56,19 @@ const getThorTradeQuote = async ({ deps, input }) => {
57
56
  switch (chainId) {
58
57
  case types_1.KnownChainIds.EthereumMainnet:
59
58
  return (async () => {
60
- const { data, router } = await (0, getThorTxData_2.getThorTxInfo)({
59
+ const { router } = await (0, getThorTxData_2.getThorTxInfo)({
61
60
  deps,
62
61
  sellAsset,
63
62
  buyAsset,
64
63
  sellAmount,
65
64
  slippageTolerance: constants_1.DEFAULT_SLIPPAGE,
66
- destinationAddress: receiveAddress
65
+ destinationAddress: receiveAddress,
66
+ tradeFee
67
67
  });
68
68
  const feeData = await (0, getEthTxFees_1.getEthTxFees)({
69
- deps,
70
- data,
71
- router,
72
- buyAsset,
73
- sellAmount,
74
69
  adapterManager: deps.adapterManager,
75
- receiveAddress,
76
- sellAssetReference: sellAssetErc20Address
70
+ sellAssetReference: sellAssetErc20Address,
71
+ tradeFee
77
72
  });
78
73
  return {
79
74
  ...commonQuoteFields,
@@ -92,16 +87,16 @@ const getThorTradeQuote = async ({ deps, input }) => {
92
87
  destinationAddress: receiveAddress,
93
88
  wallet,
94
89
  bip44Params: input.bip44Params,
95
- accountType: input.accountType
90
+ accountType: input.accountType,
91
+ tradeFee
96
92
  });
97
93
  const feeData = await (0, getBtcTxFees_1.getBtcTxFees)({
98
- deps,
99
- buyAsset,
100
94
  sellAmount,
101
95
  vault,
102
96
  opReturnData,
103
97
  pubkey,
104
- adapterManager: deps.adapterManager
98
+ adapterManager: deps.adapterManager,
99
+ tradeFee
105
100
  });
106
101
  return {
107
102
  ...commonQuoteFields,
@@ -14,12 +14,8 @@ const thorTradeApprovalNeeded = async ({ deps, input }) => {
14
14
  const { adapterManager, web3 } = deps;
15
15
  const { assetReference: sellAssetErc20Address } = (0, caip_1.fromAssetId)(sellAsset.assetId);
16
16
  const { chainNamespace } = (0, caip_1.fromChainId)(sellAsset.chainId);
17
- if (chainNamespace !== 'eip155') {
18
- throw new api_1.SwapError('[thorTradeApprovalNeeded] - sellAsset chain namespace is not supported', {
19
- code: api_1.SwapErrorTypes.UNSUPPORTED_CHAIN,
20
- details: { chainNamespace }
21
- });
22
- }
17
+ if (chainNamespace !== caip_1.CHAIN_NAMESPACE.Ethereum)
18
+ return { approvalNeeded: false };
23
19
  // No approval needed for selling a fee asset
24
20
  if (sellAsset.assetId === (0, caip_1.getFeeAssetIdFromAssetId)(sellAsset.assetId)) {
25
21
  return { approvalNeeded: false };
@@ -1,5 +1,6 @@
1
+ import { Asset } from '@shapeshiftoss/asset-service';
1
2
  import { HDWallet } from '@shapeshiftoss/hdwallet-core';
2
- import { Asset, BIP44Params, UtxoAccountType } from '@shapeshiftoss/types';
3
+ import { BIP44Params, UtxoAccountType } from '@shapeshiftoss/types';
3
4
  import { ThorchainSwapperDeps } from '../../../types';
4
5
  declare type GetBtcThorTxInfoArgs = {
5
6
  deps: ThorchainSwapperDeps;
@@ -11,6 +12,7 @@ declare type GetBtcThorTxInfoArgs = {
11
12
  wallet: HDWallet;
12
13
  bip44Params: BIP44Params;
13
14
  accountType: UtxoAccountType;
15
+ tradeFee: string;
14
16
  };
15
17
  declare type GetBtcThorTxInfoReturn = Promise<{
16
18
  opReturnData: string;
@@ -4,10 +4,11 @@ exports.getThorTxInfo = void 0;
4
4
  const caip_1 = require("@shapeshiftoss/caip");
5
5
  const api_1 = require("../../../../../api");
6
6
  const bignumber_1 = require("../../../../utils/bignumber");
7
- const getPriceRatio_1 = require("../../getPriceRatio/getPriceRatio");
7
+ const constants_1 = require("../../constants");
8
+ const getTradeRate_1 = require("../../getTradeRate/getTradeRate");
8
9
  const makeSwapMemo_1 = require("../../makeSwapMemo/makeSwapMemo");
9
10
  const thorService_1 = require("../../thorService");
10
- const getThorTxInfo = async ({ deps, sellAsset, buyAsset, sellAmount, slippageTolerance, destinationAddress, wallet, bip44Params, accountType }) => {
11
+ const getThorTxInfo = async ({ deps, sellAsset, buyAsset, sellAmount, slippageTolerance, destinationAddress, wallet, bip44Params, accountType, tradeFee }) => {
11
12
  try {
12
13
  const { data: inboundAddresses } = await thorService_1.thorService.get(`${deps.midgardUrl}/thorchain/inbound_addresses`);
13
14
  const btcInboundAddresses = inboundAddresses.find((inbound) => inbound.chain === 'BTC');
@@ -17,19 +18,18 @@ const getThorTxInfo = async ({ deps, sellAsset, buyAsset, sellAmount, slippageTo
17
18
  code: api_1.SwapErrorTypes.RESPONSE_ERROR,
18
19
  details: { inboundAddresses }
19
20
  });
20
- const priceRatio = await (0, getPriceRatio_1.getPriceRatio)(deps, {
21
- buyAssetId: buyAsset.assetId,
22
- sellAssetId: sellAsset.assetId
23
- });
24
- const expectedBuyAmount = (0, bignumber_1.toBaseUnit)((0, bignumber_1.fromBaseUnit)((0, bignumber_1.bnOrZero)(sellAmount).dividedBy(priceRatio), sellAsset.precision), buyAsset.precision);
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);
25
23
  const isValidSlippageRange = (0, bignumber_1.bnOrZero)(slippageTolerance).gte(0) && (0, bignumber_1.bnOrZero)(slippageTolerance).lte(1);
26
- if ((0, bignumber_1.bnOrZero)(expectedBuyAmount).lt(0) || !isValidSlippageRange)
24
+ if ((0, bignumber_1.bnOrZero)(expectedBuyAmountPrecision8).lt(0) || !isValidSlippageRange)
27
25
  throw new api_1.SwapError('[getThorTxInfo]: bad expected buy amount or bad slippage tolerance', {
28
26
  code: api_1.SwapErrorTypes.BUILD_TRADE_FAILED,
29
- details: { expectedBuyAmount, slippageTolerance }
27
+ details: { expectedBuyAmountPrecision8, slippageTolerance }
30
28
  });
31
- const limit = (0, bignumber_1.bnOrZero)(expectedBuyAmount)
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)
32
31
  .times((0, bignumber_1.bn)(1).minus(slippageTolerance))
32
+ .minus((0, bignumber_1.bnOrZero)(tradeFeePrecision8))
33
33
  .decimalPlaces(0)
34
34
  .toString();
35
35
  const memo = (0, makeSwapMemo_1.makeSwapMemo)({
@@ -1,2 +1,7 @@
1
1
  export declare const MAX_THORCHAIN_TRADE = "100000000000000000000000000";
2
2
  export declare const MAX_ALLOWANCE = "100000000000000000000000000";
3
+ export declare const THOR_MINIMUM_PADDING = 1.2;
4
+ export declare const THOR_ETH_GAS_LIMIT = "100000";
5
+ export declare const THORCHAIN_FIXED_PRECISION = 8;
6
+ export declare const THOR_TRADE_FEE_BTC_SIZE = 1000;
7
+ export declare const THOR_TRADE_FEE_ETH_GAS = 120000;
@@ -1,5 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MAX_ALLOWANCE = exports.MAX_THORCHAIN_TRADE = void 0;
3
+ exports.THOR_TRADE_FEE_ETH_GAS = exports.THOR_TRADE_FEE_BTC_SIZE = exports.THORCHAIN_FIXED_PRECISION = exports.THOR_ETH_GAS_LIMIT = exports.THOR_MINIMUM_PADDING = exports.MAX_ALLOWANCE = exports.MAX_THORCHAIN_TRADE = void 0;
4
4
  exports.MAX_THORCHAIN_TRADE = '100000000000000000000000000';
5
5
  exports.MAX_ALLOWANCE = '100000000000000000000000000';
6
+ exports.THOR_MINIMUM_PADDING = 1.2;
7
+ exports.THOR_ETH_GAS_LIMIT = '100000'; // for sends of eth / erc20 into thorchain router
8
+ exports.THORCHAIN_FIXED_PRECISION = 8; // limit values are precision 8 regardless of the chain
9
+ // These are different from THOR_ETH_GAS_LIMIT
10
+ // Used to estimate the fee thorchain will take out of the buyAsset
11
+ exports.THOR_TRADE_FEE_BTC_SIZE = 1000; // used for estimating thorchain side fees
12
+ exports.THOR_TRADE_FEE_ETH_GAS = 120000; // used for estimating thorchain side fees
@@ -1,3 +1,3 @@
1
- import { AssetId } from '@shapeshiftoss/caip';
1
+ import { Asset } from '@shapeshiftoss/asset-service';
2
2
  import { ThorchainSwapperDeps } from '../../types';
3
- export declare const estimateTradeFee: (deps: ThorchainSwapperDeps, buyAssetId: AssetId) => Promise<string>;
3
+ export declare const estimateTradeFee: (deps: ThorchainSwapperDeps, buyAsset: Asset) => Promise<string>;
@@ -4,23 +4,32 @@ exports.estimateTradeFee = void 0;
4
4
  const caip_1 = require("@shapeshiftoss/caip");
5
5
  const api_1 = require("../../../../api");
6
6
  const bignumber_1 = require("../../../utils/bignumber");
7
+ const constants_1 = require("../constants");
7
8
  const getPriceRatio_1 = require("../getPriceRatio/getPriceRatio");
8
9
  const thorService_1 = require("../thorService");
9
10
  const gweiGasPrecision = 9;
10
- // https://docs.thorchain.org/how-it-works/fees#outbound-fee
11
- // estimatedTradeFee = `3 * estimatedFeeOutboundFee`
12
- // eth txs from thorchain use approx 38383 gas
13
- const ethEstimate = (gasRate) => (0, bignumber_1.bnOrZero)(gasRate).times(38383).times(3).times((0, bignumber_1.bn)(10).exponentiatedBy(gweiGasPrecision)).toString();
14
- // erc20 txs from thorchain use approx 70996 gas
15
- const erc20Estimate = (gasRate) => (0, bignumber_1.bnOrZero)(gasRate).times(70996).times(3).times((0, bignumber_1.bn)(10).exponentiatedBy(gweiGasPrecision)).toString();
16
- // BTC utxo transactions from thorchain are approx 303 bytes long
17
- const btcEstimate = (gasRate) => (0, bignumber_1.bnOrZero)(gasRate).times(303).times(3).toString();
18
- const estimateTradeFee = async (deps, buyAssetId) => {
19
- const thorId = caip_1.adapters.assetIdToPoolAssetId({ assetId: buyAssetId });
11
+ // Official docs on fees are incorrect
12
+ // https://discord.com/channels/838986635756044328/997675038675316776/998552541170253834
13
+ // This is still not "perfect" and tends to overestimate by a randomish amount
14
+ // TODO figure out if its possible to accurately estimate the outbound fee.
15
+ // Neither the discord nor official docs are correct
16
+ const ethEstimate = (gasRate) => (0, bignumber_1.bnOrZero)(gasRate)
17
+ .times(constants_1.THOR_TRADE_FEE_ETH_GAS)
18
+ .times(2)
19
+ .times((0, bignumber_1.bn)(10).exponentiatedBy(gweiGasPrecision))
20
+ .toString();
21
+ const erc20Estimate = (gasRate) => (0, bignumber_1.bnOrZero)(gasRate)
22
+ .times(constants_1.THOR_TRADE_FEE_ETH_GAS)
23
+ .times(2)
24
+ .times((0, bignumber_1.bn)(10).exponentiatedBy(gweiGasPrecision))
25
+ .toString();
26
+ const btcEstimate = (gasRate) => (0, bignumber_1.bnOrZero)(gasRate).times(constants_1.THOR_TRADE_FEE_BTC_SIZE).times(2).toString();
27
+ const estimateTradeFee = async (deps, buyAsset) => {
28
+ const thorId = caip_1.adapters.assetIdToPoolAssetId({ assetId: buyAsset.assetId });
20
29
  if (!thorId)
21
30
  throw new api_1.SwapError('[estimateTradeFee] - undefined thorId for given buyAssetId', {
22
31
  code: api_1.SwapErrorTypes.VALIDATION_FAILED,
23
- details: { buyAssetId }
32
+ details: { buyAssetId: buyAsset.assetId }
24
33
  });
25
34
  const thorPoolChainId = thorId.slice(0, thorId.indexOf('.'));
26
35
  const { data: inboundAddresses } = await thorService_1.thorService.get(`${deps.midgardUrl}/thorchain/inbound_addresses`);
@@ -31,28 +40,28 @@ const estimateTradeFee = async (deps, buyAssetId) => {
31
40
  details: { thorPoolChainId }
32
41
  });
33
42
  const gasRate = inboundInfo.gas_rate;
34
- const { chainId, assetNamespace } = (0, caip_1.fromAssetId)(buyAssetId);
35
- const feeAssetId = (0, caip_1.getFeeAssetIdFromAssetId)(buyAssetId);
43
+ const { chainId, assetNamespace } = (0, caip_1.fromAssetId)(buyAsset.assetId);
44
+ const feeAssetId = (0, caip_1.getFeeAssetIdFromAssetId)(buyAsset.assetId);
36
45
  if (!feeAssetId)
37
46
  throw new api_1.SwapError('[estimateTradeFee] - no fee assetId', {
38
47
  code: api_1.SwapErrorTypes.VALIDATION_FAILED,
39
- details: { buyAssetId }
48
+ details: { buyAssetId: buyAsset.assetId }
40
49
  });
41
- const feeAssetRatio = buyAssetId !== feeAssetId
50
+ const feeAssetRatio = buyAsset.assetId !== feeAssetId
42
51
  ? await (0, getPriceRatio_1.getPriceRatio)(deps, {
43
- sellAssetId: buyAssetId,
52
+ sellAssetId: buyAsset.assetId,
44
53
  buyAssetId: feeAssetId
45
54
  })
46
55
  : '1';
47
56
  switch (chainId) {
48
57
  case 'bip122:000000000019d6689c085ae165831e93':
49
- return (0, bignumber_1.bnOrZero)(btcEstimate(gasRate)).times(feeAssetRatio).dp(0).toString();
58
+ return (0, bignumber_1.fromBaseUnit)((0, bignumber_1.bnOrZero)(btcEstimate(gasRate)).times(feeAssetRatio).dp(0), buyAsset.precision);
50
59
  case 'eip155:1':
51
60
  switch (assetNamespace) {
52
61
  case 'slip44':
53
- return (0, bignumber_1.bnOrZero)(ethEstimate(gasRate)).times(feeAssetRatio).dp(0).toString();
62
+ return (0, bignumber_1.fromBaseUnit)((0, bignumber_1.bnOrZero)(ethEstimate(gasRate)).times(feeAssetRatio).dp(0), buyAsset.precision);
54
63
  case 'erc20':
55
- return (0, bignumber_1.bnOrZero)(erc20Estimate(gasRate)).times(feeAssetRatio).dp(0).toString();
64
+ return (0, bignumber_1.fromBaseUnit)((0, bignumber_1.bnOrZero)(erc20Estimate(gasRate)).times(feeAssetRatio).dp(0), buyAsset.precision);
56
65
  default:
57
66
  throw new api_1.SwapError('[estimateTradeFee] - unsupported asset namespace', {
58
67
  code: api_1.SwapErrorTypes.VALIDATION_FAILED,
@@ -1,8 +1,9 @@
1
+ import { Asset } from '@shapeshiftoss/asset-service';
1
2
  import { ethereum } from '@shapeshiftoss/chain-adapters';
2
3
  import { ETHSignTx, HDWallet } from '@shapeshiftoss/hdwallet-core';
3
- import { Asset, BIP44Params } from '@shapeshiftoss/types';
4
+ import { BIP44Params } from '@shapeshiftoss/types';
4
5
  import { ThorchainSwapperDeps } from '../../types';
5
- export declare const makeTradeTx: ({ wallet, bip44Params, sellAmount, buyAsset, sellAsset, destinationAddress, adapter, maxFeePerGas, maxPriorityFeePerGas, gasPrice, slippageTolerance, deps, gasLimit }: {
6
+ export declare const makeTradeTx: ({ wallet, bip44Params, sellAmount, buyAsset, sellAsset, destinationAddress, adapter, maxFeePerGas, maxPriorityFeePerGas, gasPrice, slippageTolerance, deps, gasLimit, tradeFee }: {
6
7
  wallet: HDWallet;
7
8
  bip44Params: BIP44Params;
8
9
  sellAmount: string;
@@ -13,6 +14,7 @@ export declare const makeTradeTx: ({ wallet, bip44Params, sellAmount, buyAsset,
13
14
  slippageTolerance: string;
14
15
  deps: ThorchainSwapperDeps;
15
16
  gasLimit: string;
17
+ tradeFee: string;
16
18
  } & ({
17
19
  gasPrice: string;
18
20
  maxFeePerGas?: undefined;
@@ -2,9 +2,10 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.makeTradeTx = void 0;
4
4
  const caip_1 = require("@shapeshiftoss/caip");
5
+ const web3_utils_1 = require("web3-utils");
5
6
  const api_1 = require("../../../../api");
6
7
  const getThorTxData_1 = require("../ethereum/utils/getThorTxData");
7
- const makeTradeTx = async ({ wallet, bip44Params, sellAmount, buyAsset, sellAsset, destinationAddress, adapter, maxFeePerGas, maxPriorityFeePerGas, gasPrice, slippageTolerance, deps, gasLimit }) => {
8
+ const makeTradeTx = async ({ wallet, bip44Params, sellAmount, buyAsset, sellAsset, destinationAddress, adapter, maxFeePerGas, maxPriorityFeePerGas, gasPrice, slippageTolerance, deps, gasLimit, tradeFee }) => {
8
9
  try {
9
10
  const { assetNamespace } = (0, caip_1.fromAssetId)(sellAsset.assetId);
10
11
  const isErc20Trade = assetNamespace === 'erc20';
@@ -14,7 +15,8 @@ const makeTradeTx = async ({ wallet, bip44Params, sellAmount, buyAsset, sellAsse
14
15
  buyAsset,
15
16
  sellAmount,
16
17
  slippageTolerance,
17
- destinationAddress
18
+ destinationAddress,
19
+ tradeFee
18
20
  });
19
21
  return adapter.buildCustomTx({
20
22
  wallet,
@@ -29,7 +31,7 @@ const makeTradeTx = async ({ wallet, bip44Params, sellAmount, buyAsset, sellAsse
29
31
  maxFeePerGas,
30
32
  maxPriorityFeePerGas
31
33
  }),
32
- value: isErc20Trade ? '0' : sellAmount,
34
+ value: isErc20Trade ? '0x0' : (0, web3_utils_1.numberToHex)(sellAmount),
33
35
  data
34
36
  });
35
37
  }
@@ -1,4 +1,4 @@
1
- import { Asset } from '@shapeshiftoss/types';
1
+ import { Asset } from '@shapeshiftoss/asset-service';
2
2
  import { ThorchainSwapperDeps } from '../../../types';
3
3
  declare type GetBtcThorTxInfoArgs = {
4
4
  deps: ThorchainSwapperDeps;
@@ -7,6 +7,7 @@ declare type GetBtcThorTxInfoArgs = {
7
7
  sellAmount: string;
8
8
  slippageTolerance: string;
9
9
  destinationAddress: string;
10
+ tradeFee: string;
10
11
  };
11
12
  declare type GetBtcThorTxInfoReturn = Promise<{
12
13
  data: string;
@@ -4,11 +4,12 @@ exports.getThorTxInfo = void 0;
4
4
  const caip_1 = require("@shapeshiftoss/caip");
5
5
  const api_1 = require("../../../../../api");
6
6
  const bignumber_1 = require("../../../../utils/bignumber");
7
- const getPriceRatio_1 = require("../../getPriceRatio/getPriceRatio");
7
+ const getTradeRate_1 = require("../../../utils/getTradeRate/getTradeRate");
8
+ const constants_1 = require("../../constants");
8
9
  const makeSwapMemo_1 = require("../../makeSwapMemo/makeSwapMemo");
9
10
  const thorService_1 = require("../../thorService");
10
11
  const routerCalldata_1 = require("../routerCalldata");
11
- const getThorTxInfo = async ({ deps, sellAsset, buyAsset, sellAmount, slippageTolerance, destinationAddress }) => {
12
+ const getThorTxInfo = async ({ deps, sellAsset, buyAsset, sellAmount, slippageTolerance, destinationAddress, tradeFee }) => {
12
13
  try {
13
14
  const { assetReference, assetNamespace } = (0, caip_1.fromAssetId)(sellAsset.assetId);
14
15
  const isErc20Trade = assetNamespace === 'erc20';
@@ -21,19 +22,18 @@ const getThorTxInfo = async ({ deps, sellAsset, buyAsset, sellAmount, slippageTo
21
22
  code: api_1.SwapErrorTypes.RESPONSE_ERROR,
22
23
  details: { inboundAddresses }
23
24
  });
24
- const priceRatio = await (0, getPriceRatio_1.getPriceRatio)(deps, {
25
- buyAssetId: buyAsset.assetId,
26
- sellAssetId: sellAsset.assetId
27
- });
28
- const expectedBuyAmount = (0, bignumber_1.toBaseUnit)((0, bignumber_1.fromBaseUnit)((0, bignumber_1.bnOrZero)(sellAmount).dividedBy(priceRatio), sellAsset.precision), buyAsset.precision);
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);
29
28
  const isValidSlippageRange = (0, bignumber_1.bnOrZero)(slippageTolerance).gte(0) && (0, bignumber_1.bnOrZero)(slippageTolerance).lte(1);
30
- if ((0, bignumber_1.bnOrZero)(expectedBuyAmount).lt(0) || !isValidSlippageRange)
29
+ if ((0, bignumber_1.bnOrZero)(expectedBuyAmountPrecision8).lt(0) || !isValidSlippageRange)
31
30
  throw new api_1.SwapError('[makeTradeTx]: bad expected buy amount or bad slippage tolerance', {
32
31
  code: api_1.SwapErrorTypes.BUILD_TRADE_FAILED,
33
- details: { expectedBuyAmount, slippageTolerance }
32
+ details: { expectedBuyAmountPrecision8, slippageTolerance }
34
33
  });
35
- const limit = (0, bignumber_1.bnOrZero)(expectedBuyAmount)
34
+ const limit = (0, bignumber_1.bnOrZero)(expectedBuyAmountPrecision8)
36
35
  .times((0, bignumber_1.bn)(1).minus(slippageTolerance))
36
+ .minus((0, bignumber_1.bnOrZero)(tradeFeePrecision8))
37
37
  .decimalPlaces(0)
38
38
  .toString();
39
39
  const memo = (0, makeSwapMemo_1.makeSwapMemo)({
@@ -1,4 +1,4 @@
1
+ import { Asset } from '@shapeshiftoss/asset-service';
1
2
  import { AssetId } from '@shapeshiftoss/caip';
2
- import { Asset } from '@shapeshiftoss/types';
3
3
  import { ThorchainSwapperDeps } from '../../types';
4
4
  export declare const getTradeRate: (sellAsset: Asset, buyAssetId: AssetId, sellAmount: string, deps: ThorchainSwapperDeps) => Promise<string>;
@@ -5,6 +5,7 @@ const caip_1 = require("@shapeshiftoss/caip");
5
5
  const api_1 = require("../../../../api");
6
6
  const bignumber_1 = require("../../../utils/bignumber");
7
7
  const bignumber_2 = require("../../../utils/bignumber");
8
+ const getPriceRatio_1 = require("../getPriceRatio/getPriceRatio");
8
9
  const thorService_1 = require("../thorService");
9
10
  const THOR_PRECISION = 8;
10
11
  const getSwapOutput = (inputAmount, poolData, toRune) => {
@@ -23,6 +24,13 @@ const getDoubleSwapOutput = (input, inputPool, outputPool) => {
23
24
  // TODO this does not support swaps between native "RUNE"
24
25
  // Rune swaps use a different calculation because its 1 hop between pools instead of 2
25
26
  const getTradeRate = async (sellAsset, buyAssetId, sellAmount, deps) => {
27
+ // we can't get a quote for a zero amount so use getPriceRatio between pools instead
28
+ if ((0, bignumber_1.bnOrZero)(sellAmount).eq(0)) {
29
+ return (0, getPriceRatio_1.getPriceRatio)(deps, {
30
+ sellAssetId: sellAsset.assetId,
31
+ buyAssetId
32
+ });
33
+ }
26
34
  const buyPoolId = caip_1.adapters.assetIdToPoolAssetId({ assetId: buyAssetId });
27
35
  const sellPoolId = caip_1.adapters.assetIdToPoolAssetId({ assetId: sellAsset.assetId });
28
36
  if (!buyPoolId || !sellPoolId)
@@ -1,4 +1,4 @@
1
- import { Asset } from '@shapeshiftoss/types';
1
+ import { Asset } from '@shapeshiftoss/asset-service';
2
2
  import { ThorchainSwapperDeps } from '../../types';
3
3
  export declare const getUsdRate: ({ deps, input }: {
4
4
  deps: ThorchainSwapperDeps;
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.setupThorswapDeps = void 0;
7
+ const chain_adapters_1 = require("@shapeshiftoss/chain-adapters");
7
8
  const web3_1 = __importDefault(require("web3"));
8
9
  jest.mock('web3');
9
10
  const setupThorswapDeps = () => {
@@ -20,7 +21,24 @@ const setupThorswapDeps = () => {
20
21
  {
21
22
  buildBIP44Params: jest.fn(() => ({ purpose: 44, coinType: 60, accountNumber: 0 })),
22
23
  getAddress: jest.fn(() => Promise.resolve('0xthisIsMyAddress')),
23
- getFeeData: jest.fn(() => feeData)
24
+ getFeeData: jest.fn(() => feeData),
25
+ getGasFeeData: jest.fn(() => ({
26
+ [chain_adapters_1.FeeDataKey.Slow]: {
27
+ gasPrice: '1',
28
+ maxFeePerGas: '2',
29
+ maxPriorityFeePerGas: '3'
30
+ },
31
+ [chain_adapters_1.FeeDataKey.Average]: {
32
+ gasPrice: '4',
33
+ maxFeePerGas: '5',
34
+ maxPriorityFeePerGas: '6'
35
+ },
36
+ [chain_adapters_1.FeeDataKey.Fast]: {
37
+ gasPrice: '7',
38
+ maxFeePerGas: '8',
39
+ maxPriorityFeePerGas: '9'
40
+ }
41
+ }))
24
42
  }
25
43
  ]
26
44
  ]);
@@ -1,13 +1,11 @@
1
1
  import { ChainAdapterManager } from '@shapeshiftoss/chain-adapters';
2
- import { Asset, KnownChainIds } from '@shapeshiftoss/types';
2
+ import { KnownChainIds } from '@shapeshiftoss/types';
3
3
  import { QuoteFeeData } from '../../../../../api';
4
- import { ThorchainSwapperDeps } from '../../../types';
5
- export declare const getBtcTxFees: ({ deps, opReturnData, vault, buyAsset, sellAmount, adapterManager, pubkey }: {
6
- deps: ThorchainSwapperDeps;
4
+ export declare const getBtcTxFees: ({ opReturnData, vault, sellAmount, adapterManager, pubkey, tradeFee }: {
7
5
  opReturnData: string;
8
6
  vault: string;
9
- buyAsset: Asset;
10
7
  sellAmount: string;
11
8
  adapterManager: ChainAdapterManager;
12
9
  pubkey: string;
10
+ tradeFee: string;
13
11
  }) => Promise<QuoteFeeData<KnownChainIds.BitcoinMainnet>>;
@@ -3,8 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getBtcTxFees = void 0;
4
4
  const api_1 = require("../../../../../api");
5
5
  const bignumber_1 = require("../../../../utils/bignumber");
6
- const estimateTradeFee_1 = require("../../estimateTradeFee/estimateTradeFee");
7
- const getBtcTxFees = async ({ deps, opReturnData, vault, buyAsset, sellAmount, adapterManager, pubkey }) => {
6
+ const getBtcTxFees = async ({ opReturnData, vault, sellAmount, adapterManager, pubkey, tradeFee }) => {
8
7
  try {
9
8
  const adapter = adapterManager.get('bip122:000000000019d6689c085ae165831e93');
10
9
  if (!adapter)
@@ -18,7 +17,6 @@ const getBtcTxFees = async ({ deps, opReturnData, vault, buyAsset, sellAmount, a
18
17
  chainSpecific: { pubkey, opReturnData }
19
18
  });
20
19
  const feeData = feeDataOptions['fast'];
21
- const tradeFee = await (0, estimateTradeFee_1.estimateTradeFee)(deps, buyAsset.assetId);
22
20
  return {
23
21
  fee: feeData.txFee,
24
22
  tradeFee,
@@ -1,15 +1,9 @@
1
1
  import { AssetReference } from '@shapeshiftoss/caip';
2
2
  import { ChainAdapterManager } from '@shapeshiftoss/chain-adapters';
3
- import { Asset, KnownChainIds } from '@shapeshiftoss/types';
3
+ import { KnownChainIds } from '@shapeshiftoss/types';
4
4
  import { QuoteFeeData } from '../../../../../api';
5
- import { ThorchainSwapperDeps } from '../../../types';
6
- export declare const getEthTxFees: ({ deps, data, router, buyAsset, sellAmount, adapterManager, receiveAddress, sellAssetReference }: {
7
- deps: ThorchainSwapperDeps;
8
- data: string;
9
- router: string;
10
- buyAsset: Asset;
11
- sellAmount: string;
12
- sellAssetReference: AssetReference | string;
5
+ export declare const getEthTxFees: ({ adapterManager, sellAssetReference, tradeFee }: {
13
6
  adapterManager: ChainAdapterManager;
14
- receiveAddress: string;
7
+ sellAssetReference: AssetReference | string;
8
+ tradeFee: string;
15
9
  }) => Promise<QuoteFeeData<KnownChainIds.EthereumMainnet>>;
@@ -6,8 +6,8 @@ const types_1 = require("@shapeshiftoss/types");
6
6
  const api_1 = require("../../../../../api");
7
7
  const bignumber_1 = require("../../../../utils/bignumber");
8
8
  const constants_1 = require("../../../../utils/constants");
9
- const estimateTradeFee_1 = require("../../estimateTradeFee/estimateTradeFee");
10
- const getEthTxFees = async ({ deps, data, router, buyAsset, sellAmount, adapterManager, receiveAddress, sellAssetReference }) => {
9
+ const constants_2 = require("../../constants");
10
+ const getEthTxFees = async ({ adapterManager, sellAssetReference, tradeFee }) => {
11
11
  try {
12
12
  const adapter = adapterManager.get(types_1.KnownChainIds.EthereumMainnet);
13
13
  if (!adapter) {
@@ -16,32 +16,20 @@ const getEthTxFees = async ({ deps, data, router, buyAsset, sellAmount, adapterM
16
16
  details: { chainId: types_1.KnownChainIds.EthereumMainnet }
17
17
  });
18
18
  }
19
- let feeDataOptions;
20
- try {
21
- feeDataOptions = await adapter.getFeeData({
22
- to: router,
23
- value: sellAmount,
24
- chainSpecific: { from: receiveAddress, contractData: data }
25
- });
26
- }
27
- catch (e) {
28
- // Fallback to fixed fee amount in case of failure so that quote will not fail
29
- // eslint-disable-next-line no-console
30
- console.debug('[ThorSwapper:getEthTxFees] precise gas estimate failed, falling back on hard coded limit');
31
- const gasFeeData = await adapter.getGasFeeData();
32
- const gasLimit = '100000'; // good value to cover all thortrades out of eth/erc20
33
- feeDataOptions = {
34
- fast: {
35
- txFee: (0, bignumber_1.bn)(gasLimit).times(gasFeeData[chain_adapters_1.FeeDataKey.Fast].gasPrice).toString(),
36
- chainSpecific: {
37
- gasPrice: gasFeeData[chain_adapters_1.FeeDataKey.Fast].gasPrice,
38
- gasLimit
39
- }
19
+ const gasFeeData = await adapter.getGasFeeData();
20
+ // this is a good value to cover all thortrades out of eth/erc20
21
+ // in the future we may want to look at doing this more precisely and in a future-proof way
22
+ const gasLimit = constants_2.THOR_ETH_GAS_LIMIT;
23
+ const feeDataOptions = {
24
+ fast: {
25
+ txFee: (0, bignumber_1.bn)(gasLimit).times(gasFeeData[chain_adapters_1.FeeDataKey.Fast].gasPrice).toString(),
26
+ chainSpecific: {
27
+ gasPrice: gasFeeData[chain_adapters_1.FeeDataKey.Fast].gasPrice,
28
+ gasLimit
40
29
  }
41
- };
42
- }
30
+ }
31
+ };
43
32
  const feeData = feeDataOptions['fast'];
44
- const tradeFee = await (0, estimateTradeFee_1.estimateTradeFee)(deps, buyAsset.assetId);
45
33
  return {
46
34
  fee: feeData.txFee,
47
35
  chainSpecific: {
@@ -1,5 +1,5 @@
1
+ import { Asset } from '@shapeshiftoss/asset-service';
1
2
  import { HDWallet } from '@shapeshiftoss/hdwallet-core';
2
- import { Asset } from '@shapeshiftoss/types';
3
3
  import BigNumber from 'bignumber.js';
4
4
  import Web3 from 'web3';
5
5
  import { AbiItem } from 'web3-utils';
@@ -1,4 +1,4 @@
1
- import { Asset } from '@shapeshiftoss/types';
1
+ import { Asset } from '@shapeshiftoss/asset-service';
2
2
  export declare const BTC: Asset;
3
3
  export declare const WETH: Asset;
4
4
  export declare const FOX: Asset;
@@ -3,5 +3,5 @@ import Web3 from 'web3';
3
3
  export declare const setupDeps: () => {
4
4
  web3: Web3;
5
5
  adapter: ethereum.ChainAdapter;
6
- feeAsset: import("@shapeshiftoss/types").Asset;
6
+ feeAsset: import("@shapeshiftoss/asset-service").Asset;
7
7
  };
@@ -1,5 +1,6 @@
1
+ import { Asset } from '@shapeshiftoss/asset-service';
1
2
  import { HDWallet } from '@shapeshiftoss/hdwallet-core';
2
- import { Asset, KnownChainIds } from '@shapeshiftoss/types';
3
+ import { KnownChainIds } from '@shapeshiftoss/types';
3
4
  import { TradeQuote } from '../../../api';
4
5
  export declare const setupQuote: () => {
5
6
  quoteInput: import("../../../api").GetEvmTradeQuoteInput;
@@ -1,5 +1,5 @@
1
+ import { Asset } from '@shapeshiftoss/asset-service';
1
2
  import { AssetId, ChainId } from '@shapeshiftoss/caip';
2
- import { Asset } from '@shapeshiftoss/types';
3
3
  import { ApprovalNeededInput, ApprovalNeededOutput, ApproveInfiniteInput, BuildTradeInput, BuyAssetBySellIdInput, EvmSupportedChainIds, GetEvmTradeQuoteInput, Swapper, SwapperType, TradeQuote, TradeResult, TradeTxs } from '../../api';
4
4
  import { ZrxExecuteTradeInput, ZrxSwapperDeps, ZrxTrade } from './types';
5
5
  export declare class ZrxSwapper<T extends EvmSupportedChainIds> implements Swapper<T> {
@@ -1,3 +1,3 @@
1
- import { Asset } from '@shapeshiftoss/types';
1
+ import { Asset } from '@shapeshiftoss/asset-service';
2
2
  import { MinMaxOutput } from '../../../api';
3
3
  export declare const getZrxMinMax: (sellAsset: Asset, buyAsset: Asset) => Promise<MinMaxOutput>;
@@ -1,5 +1,5 @@
1
+ import { Asset } from '@shapeshiftoss/asset-service';
1
2
  import { AssetId } from '@shapeshiftoss/caip';
2
- import { Asset } from '@shapeshiftoss/types';
3
3
  export declare const baseUrlFromChainId: (chainId: string) => string;
4
4
  export declare const usdcContractFromChainId: (chainId: string) => string;
5
5
  export declare const isNativeEvmAsset: (assetId: AssetId) => boolean;
@@ -1,4 +1,4 @@
1
- import { Asset } from '@shapeshiftoss/types';
1
+ import { Asset } from '@shapeshiftoss/asset-service';
2
2
  import { ZrxQuoteResponse } from '../../types';
3
3
  export declare const setupZrxTradeQuoteResponse: () => {
4
4
  quoteResponse: ZrxQuoteResponse;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shapeshiftoss/swapper",
3
- "version": "8.7.1",
3
+ "version": "9.1.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",
@@ -30,20 +30,20 @@
30
30
  "web3": "1.7.4"
31
31
  },
32
32
  "peerDependencies": {
33
- "@shapeshiftoss/asset-service": "^6.2.1",
33
+ "@shapeshiftoss/asset-service": "^7.0.0",
34
34
  "@shapeshiftoss/caip": "^6.2.0",
35
35
  "@shapeshiftoss/chain-adapters": "^7.2.0",
36
36
  "@shapeshiftoss/errors": "^1.1.2",
37
37
  "@shapeshiftoss/hdwallet-core": "^1.27.0",
38
- "@shapeshiftoss/types": "^7.0.0"
38
+ "@shapeshiftoss/types": "^8.0.0"
39
39
  },
40
40
  "devDependencies": {
41
- "@shapeshiftoss/asset-service": "^6.2.1",
41
+ "@shapeshiftoss/asset-service": "^7.0.0",
42
42
  "@shapeshiftoss/caip": "^6.2.0",
43
43
  "@shapeshiftoss/chain-adapters": "^7.2.0",
44
44
  "@shapeshiftoss/errors": "^1.1.2",
45
45
  "@shapeshiftoss/hdwallet-core": "^1.27.0",
46
- "@shapeshiftoss/types": "^7.0.0",
46
+ "@shapeshiftoss/types": "^8.0.0",
47
47
  "@types/readline-sync": "^1.4.4",
48
48
  "readline-sync": "^1.4.10",
49
49
  "web3-utils": "1.7.4",