@shapeshiftoss/swapper 8.0.1 → 8.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.
Files changed (35) hide show
  1. package/dist/api.d.ts +4 -1
  2. package/dist/swappercli.js +5 -2
  3. package/dist/swappers/cow/CowSwapper.d.ts +1 -1
  4. package/dist/swappers/cow/CowSwapper.js +3 -3
  5. package/dist/swappers/cow/cowApprovalNeeded/cowApprovalNeeded.js +2 -2
  6. package/dist/swappers/cow/cowBuildTrade/cowBuildTrade.d.ts +4 -0
  7. package/dist/swappers/cow/cowBuildTrade/cowBuildTrade.js +124 -0
  8. package/dist/swappers/cow/getCowSwapTradeQuote/getCowSwapTradeQuote.d.ts +0 -11
  9. package/dist/swappers/cow/getCowSwapTradeQuote/getCowSwapTradeQuote.js +34 -25
  10. package/dist/swappers/cow/utils/constants.d.ts +0 -1
  11. package/dist/swappers/cow/utils/constants.js +5 -6
  12. package/dist/swappers/cow/utils/helpers/helpers.d.ts +12 -0
  13. package/dist/swappers/cow/utils/helpers/helpers.js +10 -1
  14. package/dist/swappers/test/TestSwapper.d.ts +1 -0
  15. package/dist/swappers/test/TestSwapper.js +1 -0
  16. package/dist/swappers/thorchain/ThorchainSwapper.d.ts +1 -0
  17. package/dist/swappers/thorchain/ThorchainSwapper.js +1 -0
  18. package/dist/swappers/thorchain/getThorTradeQuote/getTradeQuote.d.ts +6 -2
  19. package/dist/swappers/thorchain/getThorTradeQuote/getTradeQuote.js +76 -45
  20. package/dist/swappers/thorchain/utils/bitcoin/utils/getThorTxData.d.ts +22 -0
  21. package/dist/swappers/thorchain/utils/bitcoin/utils/getThorTxData.js +54 -0
  22. package/dist/swappers/thorchain/utils/ethereum/makeTradeTx.js +1 -2
  23. package/dist/swappers/thorchain/utils/ethereum/utils/getThorTxData.d.ts +7 -4
  24. package/dist/swappers/thorchain/utils/ethereum/utils/getThorTxData.js +7 -5
  25. package/dist/swappers/utils/helpers/helpers.d.ts +6 -0
  26. package/dist/swappers/utils/helpers/helpers.js +8 -1
  27. package/dist/swappers/utils/test-data/assets.d.ts +1 -0
  28. package/dist/swappers/utils/test-data/assets.js +13 -1
  29. package/dist/swappers/utils/test-data/setupSwapQuote.d.ts +20 -0
  30. package/dist/swappers/utils/test-data/setupSwapQuote.js +21 -2
  31. package/dist/swappers/zrx/ZrxSwapper.d.ts +1 -1
  32. package/dist/swappers/zrx/ZrxSwapper.js +1 -1
  33. package/dist/swappers/zrx/utils/test-data/setupZrxSwapQuote.d.ts +0 -19
  34. package/dist/swappers/zrx/utils/test-data/setupZrxSwapQuote.js +1 -18
  35. package/package.json +1 -1
package/dist/api.d.ts CHANGED
@@ -63,7 +63,8 @@ declare type CommonTradeInput = {
63
63
  sellAmount: string;
64
64
  sendMax: boolean;
65
65
  sellAssetAccountNumber: number;
66
- wallet?: HDWallet;
66
+ wallet: HDWallet;
67
+ receiveAddress: string;
67
68
  };
68
69
  export declare type EvmSupportedChainIds = KnownChainIds.EthereumMainnet | KnownChainIds.AvalancheMainnet;
69
70
  export declare type EvmSupportedChainAdapters = ethereum.ChainAdapter | avalanche.ChainAdapter;
@@ -160,6 +161,8 @@ export declare enum SwapErrorTypes {
160
161
  POOL_NOT_FOUND = "POOL_NOT_FOUND"
161
162
  }
162
163
  export interface Swapper<T extends ChainId> {
164
+ /** Human readable swapper name */
165
+ readonly name: string;
163
166
  /** perform any necessary async initialization */
164
167
  initialize?(): Promise<void>;
165
168
  /** Returns the swapper type */
@@ -114,7 +114,9 @@ const main = async () => {
114
114
  buyAsset,
115
115
  sellAmount: sellAmountBase,
116
116
  sellAssetAccountNumber: 0,
117
- sendMax: false
117
+ sendMax: false,
118
+ receiveAddress: '0xc770eefad204b5180df6a14ee197d99d808ee52d',
119
+ wallet
118
120
  });
119
121
  }
120
122
  catch (e) {
@@ -135,7 +137,8 @@ const main = async () => {
135
137
  sellAmount: sellAmountBase,
136
138
  sellAsset,
137
139
  sellAssetAccountNumber: 0,
138
- buyAssetAccountNumber: 0
140
+ buyAssetAccountNumber: 0,
141
+ receiveAddress: '0xc770eefad204b5180df6a14ee197d99d808ee52d'
139
142
  });
140
143
  const txid = await swapper.executeTrade({ trade, wallet });
141
144
  console.info('broadcast tx with id: ', txid);
@@ -14,7 +14,7 @@ export declare type CowSwapperDeps = {
14
14
  feeAsset: Asset;
15
15
  };
16
16
  export declare class CowSwapper implements Swapper<KnownChainIds.EthereumMainnet> {
17
- static swapperName: string;
17
+ readonly name = "CowSwap";
18
18
  deps: CowSwapperDeps;
19
19
  constructor(deps: CowSwapperDeps);
20
20
  getType(): SwapperType;
@@ -4,19 +4,20 @@ exports.CowSwapper = void 0;
4
4
  const api_1 = require("../../api");
5
5
  const cowApprovalNeeded_1 = require("./cowApprovalNeeded/cowApprovalNeeded");
6
6
  const cowApproveInfinite_1 = require("./cowApproveInfinite/cowApproveInfinite");
7
+ const cowBuildTrade_1 = require("./cowBuildTrade/cowBuildTrade");
7
8
  const getCowSwapTradeQuote_1 = require("./getCowSwapTradeQuote/getCowSwapTradeQuote");
8
9
  const blacklist_1 = require("./utils/blacklist");
9
10
  const helpers_1 = require("./utils/helpers/helpers");
10
11
  class CowSwapper {
11
12
  constructor(deps) {
13
+ this.name = 'CowSwap';
12
14
  this.deps = deps;
13
15
  }
14
16
  getType() {
15
17
  return api_1.SwapperType.CowSwap;
16
18
  }
17
19
  async buildTrade(args) {
18
- console.info(args);
19
- throw new Error('CowSwapper: buildTrade unimplemented');
20
+ return (0, cowBuildTrade_1.cowBuildTrade)(this.deps, args);
20
21
  }
21
22
  async getTradeQuote(input) {
22
23
  return (0, getCowSwapTradeQuote_1.getCowSwapTradeQuote)(this.deps, input);
@@ -51,4 +52,3 @@ class CowSwapper {
51
52
  }
52
53
  }
53
54
  exports.CowSwapper = CowSwapper;
54
- CowSwapper.swapperName = 'CowSwapper';
@@ -6,7 +6,7 @@ const api_1 = require("../../../api");
6
6
  const erc20Allowance_abi_1 = require("../../utils/abi/erc20Allowance-abi");
7
7
  const bignumber_1 = require("../../utils/bignumber");
8
8
  const helpers_1 = require("../../utils/helpers/helpers");
9
- const COW_SWAP_VAULT_RELAYER_ADDRESS = '0xc92e8bdf79f0507f65a392b0ab4667716bfe0110';
9
+ const constants_1 = require("../utils/constants");
10
10
  async function cowApprovalNeeded({ adapter, web3 }, { quote, wallet }) {
11
11
  const { sellAsset } = quote;
12
12
  const { assetReference: sellAssetErc20Address, assetNamespace } = (0, caip_1.fromAssetId)(sellAsset.assetId);
@@ -22,7 +22,7 @@ async function cowApprovalNeeded({ adapter, web3 }, { quote, wallet }) {
22
22
  web3,
23
23
  erc20AllowanceAbi: erc20Allowance_abi_1.erc20AllowanceAbi,
24
24
  sellAssetErc20Address,
25
- spenderAddress: COW_SWAP_VAULT_RELAYER_ADDRESS,
25
+ spenderAddress: constants_1.COW_SWAP_VAULT_RELAYER_ADDRESS,
26
26
  ownerAddress: receiveAddress
27
27
  });
28
28
  const allowanceOnChain = (0, bignumber_1.bnOrZero)(allowanceResult);
@@ -0,0 +1,4 @@
1
+ import { KnownChainIds } from '@shapeshiftoss/types';
2
+ import { BuildTradeInput, Trade } from '../../../api';
3
+ import { CowSwapperDeps } from '../CowSwapper';
4
+ export declare function cowBuildTrade(deps: CowSwapperDeps, input: BuildTradeInput): Promise<Trade<KnownChainIds.EthereumMainnet>>;
@@ -0,0 +1,124 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.cowBuildTrade = void 0;
4
+ const caip_1 = require("@shapeshiftoss/caip");
5
+ const api_1 = require("../../../api");
6
+ const erc20Allowance_abi_1 = require("../../utils/abi/erc20Allowance-abi");
7
+ const bignumber_1 = require("../../utils/bignumber");
8
+ const helpers_1 = require("../../utils/helpers/helpers");
9
+ const constants_1 = require("../utils/constants");
10
+ const cowService_1 = require("../utils/cowService");
11
+ const helpers_2 = require("../utils/helpers/helpers");
12
+ async function cowBuildTrade(deps, input) {
13
+ try {
14
+ const { sellAsset, buyAsset, sellAmount, sellAssetAccountNumber, wallet } = input;
15
+ const { adapter, feeAsset, web3 } = deps;
16
+ 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', {
20
+ code: api_1.SwapErrorTypes.UNSUPPORTED_PAIR,
21
+ details: { buyAssetNamespace, sellAssetNamespace }
22
+ });
23
+ }
24
+ const receiveAddress = await adapter.getAddress({ wallet });
25
+ const normalizedSellAmount = (0, helpers_1.normalizeAmount)(sellAmount);
26
+ /**
27
+ * /v1/quote
28
+ * params: {
29
+ * sellToken: contract address of token to sell
30
+ * buyToken: contractAddress of token to buy
31
+ * receiver: receiver address can be defaulted to "0x0000000000000000000000000000000000000000"
32
+ * validTo: time duration during which quote is valid (eg : 1654851610 as timestamp)
33
+ * appData: appData for the CowSwap quote that can be used later, can be defaulted to "0x0000000000000000000000000000000000000000000000000000000000000000"
34
+ * partiallyFillable: false
35
+ * from: sender address can be defaulted to "0x0000000000000000000000000000000000000000"
36
+ * kind: "sell" or "buy"
37
+ * sellAmountBeforeFee / buyAmountAfterFee: amount in base unit
38
+ * }
39
+ */
40
+ const quoteResponse = await cowService_1.cowService.post(`${deps.apiUrl}/v1/quote/`, {
41
+ sellToken: sellAssetErc20Address,
42
+ buyToken: buyAssetErc20Address,
43
+ receiver: receiveAddress,
44
+ validTo: (0, helpers_2.getNowPlusThirtyMinutesTimestamp)(),
45
+ appData: constants_1.DEFAULT_APP_DATA,
46
+ partiallyFillable: false,
47
+ from: receiveAddress,
48
+ kind: constants_1.ORDER_KIND_SELL,
49
+ sellAmountBeforeFee: normalizedSellAmount
50
+ });
51
+ const { data: { quote } } = quoteResponse;
52
+ const buyCryptoAmount = (0, bignumber_1.bn)(quote.buyAmount).div((0, bignumber_1.bn)(10).exponentiatedBy(buyAsset.precision));
53
+ const sellCryptoAmount = (0, bignumber_1.bn)(quote.sellAmount).div((0, bignumber_1.bn)(10).exponentiatedBy(sellAsset.precision));
54
+ const rate = buyCryptoAmount.div(sellCryptoAmount).toString();
55
+ const data = (0, helpers_1.getApproveContractData)({
56
+ web3,
57
+ spenderAddress: constants_1.COW_SWAP_VAULT_RELAYER_ADDRESS,
58
+ contractAddress: sellAssetErc20Address
59
+ });
60
+ const [feeDataOptions, feeAssetUsdRate, sellAssetUsdRate] = await Promise.all([
61
+ adapter.getFeeData({
62
+ to: sellAssetErc20Address,
63
+ value: '0',
64
+ chainSpecific: { from: receiveAddress, contractData: data }
65
+ }),
66
+ (0, helpers_2.getUsdRate)(deps, feeAsset),
67
+ (0, helpers_2.getUsdRate)(deps, sellAsset)
68
+ ]);
69
+ const feeData = feeDataOptions['fast'];
70
+ // quote.feeAmount is expressed in sellAsset token
71
+ // We need fee to be expressed in feeAsset token
72
+ // feeInFeeAsset * feeAssetUsdRate = feeInSellAsset * sellAssetUsdRate
73
+ // hence feeInFeeAsset = feeInSellAsset * sellAssetUsdRate / feeAssetUsdRate
74
+ const feeInSellAsset = (0, bignumber_1.bnOrZero)(quote.feeAmount).div((0, bignumber_1.bn)(10).exponentiatedBy(sellAsset.precision));
75
+ // feeInFeeAsset = feeInSellAsset * sellAssetUsdRate / feeAssetUsdRate
76
+ const feeInFeeAsset = feeInSellAsset
77
+ .multipliedBy((0, bignumber_1.bnOrZero)(sellAssetUsdRate))
78
+ .div((0, bignumber_1.bnOrZero)(feeAssetUsdRate));
79
+ // taking precision into account
80
+ const fee = feeInFeeAsset.multipliedBy((0, bignumber_1.bn)(10).exponentiatedBy(feeAsset.precision)).toString();
81
+ const trade = {
82
+ rate,
83
+ feeData: {
84
+ fee,
85
+ chainSpecific: {
86
+ estimatedGas: feeData.chainSpecific.gasLimit,
87
+ gasPrice: feeData.chainSpecific.gasPrice
88
+ },
89
+ tradeFee: '0'
90
+ },
91
+ sellAmount: normalizedSellAmount,
92
+ buyAmount: quote.buyAmount,
93
+ sources: constants_1.DEFAULT_SOURCE,
94
+ buyAsset,
95
+ sellAsset,
96
+ sellAssetAccountNumber,
97
+ receiveAddress
98
+ };
99
+ const allowanceRequired = await (0, helpers_1.getAllowanceRequired)({
100
+ adapter,
101
+ sellAsset,
102
+ allowanceContract: constants_1.COW_SWAP_VAULT_RELAYER_ADDRESS,
103
+ receiveAddress,
104
+ sellAmount: quote.sellAmount,
105
+ web3: deps.web3,
106
+ erc20AllowanceAbi: erc20Allowance_abi_1.erc20AllowanceAbi
107
+ });
108
+ if (!allowanceRequired.isZero()) {
109
+ trade.feeData.chainSpecific.approvalFee = (0, bignumber_1.bnOrZero)(feeData.chainSpecific.gasLimit)
110
+ .multipliedBy((0, bignumber_1.bnOrZero)(feeData.chainSpecific.gasPrice))
111
+ .toString();
112
+ }
113
+ return trade;
114
+ }
115
+ catch (e) {
116
+ if (e instanceof api_1.SwapError)
117
+ throw e;
118
+ throw new api_1.SwapError('[cowBuildTrade]', {
119
+ cause: e,
120
+ code: api_1.SwapErrorTypes.TRADE_QUOTE_FAILED
121
+ });
122
+ }
123
+ }
124
+ exports.cowBuildTrade = cowBuildTrade;
@@ -1,15 +1,4 @@
1
1
  import { KnownChainIds } from '@shapeshiftoss/types';
2
2
  import { GetTradeQuoteInput, TradeQuote } from '../../../api';
3
3
  import { CowSwapperDeps } from '../CowSwapper';
4
- export declare type CowSwapQuoteApiInput = {
5
- appData: string;
6
- buyToken: string;
7
- from: string;
8
- kind: string;
9
- partiallyFillable: boolean;
10
- receiver: string;
11
- sellAmountBeforeFee: string;
12
- sellToken: string;
13
- validTo: number;
14
- };
15
4
  export declare function getCowSwapTradeQuote(deps: CowSwapperDeps, input: GetTradeQuoteInput): Promise<TradeQuote<KnownChainIds.EthereumMainnet>>;
@@ -4,16 +4,15 @@ exports.getCowSwapTradeQuote = 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("../../utils/constants");
8
7
  const helpers_1 = require("../../utils/helpers/helpers");
9
8
  const getCowSwapMinMax_1 = require("../getCowSwapMinMax/getCowSwapMinMax");
10
- const constants_2 = require("../utils/constants");
9
+ const constants_1 = require("../utils/constants");
11
10
  const cowService_1 = require("../utils/cowService");
12
11
  const helpers_2 = require("../utils/helpers/helpers");
13
12
  async function getCowSwapTradeQuote(deps, input) {
14
13
  try {
15
14
  const { sellAsset, buyAsset, sellAmount, sellAssetAccountNumber, wallet } = input;
16
- const { adapter, feeAsset } = deps;
15
+ const { adapter, feeAsset, web3 } = deps;
17
16
  const { assetReference: sellAssetErc20Address, assetNamespace: sellAssetNamespace } = (0, caip_1.fromAssetId)(sellAsset.assetId);
18
17
  const { assetReference: buyAssetErc20Address, assetNamespace: buyAssetNamespace } = (0, caip_1.fromAssetId)(buyAsset.assetId);
19
18
  if (buyAssetNamespace !== 'erc20' || sellAssetNamespace !== 'erc20') {
@@ -29,12 +28,12 @@ async function getCowSwapTradeQuote(deps, input) {
29
28
  const apiInput = {
30
29
  sellToken: sellAssetErc20Address,
31
30
  buyToken: buyAssetErc20Address,
32
- receiver: constants_2.DEFAULT_ADDRESS,
33
- validTo: constants_2.DEFAULT_VALIDTO_TIMESTAMP,
34
- appData: constants_2.DEFAULT_APP_DATA,
31
+ receiver: constants_1.DEFAULT_ADDRESS,
32
+ validTo: (0, helpers_2.getNowPlusThirtyMinutesTimestamp)(),
33
+ appData: constants_1.DEFAULT_APP_DATA,
35
34
  partiallyFillable: false,
36
- from: constants_2.DEFAULT_ADDRESS,
37
- kind: constants_2.ORDER_KIND_SELL,
35
+ from: constants_1.DEFAULT_ADDRESS,
36
+ kind: constants_1.ORDER_KIND_SELL,
38
37
  sellAmountBeforeFee: normalizedSellAmount
39
38
  };
40
39
  /**
@@ -53,26 +52,36 @@ async function getCowSwapTradeQuote(deps, input) {
53
52
  */
54
53
  const quoteResponse = await cowService_1.cowService.post(`${deps.apiUrl}/v1/quote/`, apiInput);
55
54
  const { data: { quote } } = quoteResponse;
56
- const rate = (0, bignumber_1.bn)(quote.buyAmount)
57
- .div(quote.sellAmount)
58
- .times((0, bignumber_1.bn)(10).exponentiatedBy(sellAsset.precision - buyAsset.precision))
59
- .toString();
60
- const receiveAddress = wallet ? await adapter.getAddress({ wallet }) : constants_2.DEFAULT_ADDRESS;
61
- const [feeDataOptions, wethUsdRate, usdRateSellAsset] = await Promise.all([
55
+ const buyCryptoAmount = (0, bignumber_1.bn)(quote.buyAmount).div((0, bignumber_1.bn)(10).exponentiatedBy(buyAsset.precision));
56
+ const sellCryptoAmount = (0, bignumber_1.bn)(quote.sellAmount).div((0, bignumber_1.bn)(10).exponentiatedBy(sellAsset.precision));
57
+ const rate = buyCryptoAmount.div(sellCryptoAmount).toString();
58
+ const receiveAddress = wallet ? await adapter.getAddress({ wallet }) : constants_1.DEFAULT_ADDRESS;
59
+ const data = (0, helpers_1.getApproveContractData)({
60
+ web3,
61
+ spenderAddress: constants_1.COW_SWAP_VAULT_RELAYER_ADDRESS,
62
+ contractAddress: sellAssetErc20Address
63
+ });
64
+ const [feeDataOptions, feeAssetUsdRate, sellAssetUsdRate] = await Promise.all([
62
65
  adapter.getFeeData({
63
- to: constants_2.COW_SWAP_VAULT_RELAYER_ADDRESS,
66
+ to: sellAssetErc20Address,
64
67
  value: '0',
65
- chainSpecific: { from: receiveAddress, contractAddress: sellAssetErc20Address }
68
+ chainSpecific: { from: receiveAddress, contractData: data }
66
69
  }),
67
70
  (0, helpers_2.getUsdRate)(deps, feeAsset),
68
71
  (0, helpers_2.getUsdRate)(deps, sellAsset)
69
72
  ]);
70
73
  const feeData = feeDataOptions['fast'];
71
- const fee = (0, bignumber_1.bnOrZero)(quote.feeAmount)
72
- .multipliedBy((0, bignumber_1.bnOrZero)(usdRateSellAsset))
73
- .div((0, bignumber_1.bnOrZero)(wethUsdRate))
74
- .div((0, bignumber_1.bn)(10).exponentiatedBy(sellAsset.precision - feeAsset.precision))
75
- .toString();
74
+ // quote.feeAmount is expressed in sellAsset token
75
+ // We need fee to be expressed in feeAsset token
76
+ // feeInFeeAsset * feeAssetUsdRate = feeInSellAsset * sellAssetUsdRate
77
+ // hence feeInFeeAsset = feeInSellAsset * sellAssetUsdRate / feeAssetUsdRate
78
+ const feeInSellAsset = (0, bignumber_1.bnOrZero)(quote.feeAmount).div((0, bignumber_1.bn)(10).exponentiatedBy(sellAsset.precision));
79
+ // feeInFeeAsset = feeInSellAsset * sellAssetUsdRate / feeAssetUsdRate
80
+ const feeInFeeAsset = feeInSellAsset
81
+ .multipliedBy((0, bignumber_1.bnOrZero)(sellAssetUsdRate))
82
+ .div((0, bignumber_1.bnOrZero)(feeAssetUsdRate));
83
+ // taking precision into account
84
+ const fee = feeInFeeAsset.multipliedBy((0, bignumber_1.bn)(10).exponentiatedBy(feeAsset.precision)).toString();
76
85
  return {
77
86
  rate,
78
87
  minimum,
@@ -82,16 +91,16 @@ async function getCowSwapTradeQuote(deps, input) {
82
91
  chainSpecific: {
83
92
  estimatedGas: feeData.chainSpecific.gasLimit,
84
93
  gasPrice: feeData.chainSpecific.gasPrice,
85
- approvalFee: (0, bignumber_1.bnOrZero)(constants_1.APPROVAL_GAS_LIMIT)
94
+ approvalFee: (0, bignumber_1.bnOrZero)(feeData.chainSpecific.gasLimit)
86
95
  .multipliedBy((0, bignumber_1.bnOrZero)(feeData.chainSpecific.gasPrice))
87
96
  .toString()
88
97
  },
89
98
  tradeFee: '0'
90
99
  },
91
- sellAmount: quote.sellAmount,
100
+ sellAmount: normalizedSellAmount,
92
101
  buyAmount: quote.buyAmount,
93
- sources: constants_2.DEFAULT_SOURCE,
94
- allowanceContract: '',
102
+ sources: constants_1.DEFAULT_SOURCE,
103
+ allowanceContract: constants_1.COW_SWAP_VAULT_RELAYER_ADDRESS,
95
104
  buyAsset,
96
105
  sellAsset,
97
106
  sellAssetAccountNumber
@@ -8,5 +8,4 @@ export declare const DEFAULT_SOURCE: {
8
8
  export declare const DEFAULT_ADDRESS = "0x0000000000000000000000000000000000000000";
9
9
  export declare const DEFAULT_APP_DATA = "0x0000000000000000000000000000000000000000000000000000000000000000";
10
10
  export declare const COW_SWAP_VAULT_RELAYER_ADDRESS = "0xc92e8bdf79f0507f65a392b0ab4667716bfe0110";
11
- export declare const DEFAULT_VALIDTO_TIMESTAMP = 4294967295;
12
11
  export declare const ORDER_KIND_SELL = "sell";
@@ -1,13 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ORDER_KIND_SELL = exports.DEFAULT_VALIDTO_TIMESTAMP = 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 = void 0;
3
+ exports.ORDER_KIND_SELL = 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
+ const constants_1 = require("@ethersproject/constants");
5
+ exports.MAX_ALLOWANCE = '100000000000000000000000000';
4
6
  exports.MAX_COWSWAP_TRADE = '100000000000000000000000000';
5
7
  exports.MIN_COWSWAP_VALUE_USD = 10;
6
8
  exports.DEFAULT_SOURCE = [{ name: 'CowSwap', proportion: '1' }];
7
- exports.DEFAULT_ADDRESS = '0x0000000000000000000000000000000000000000';
8
- exports.DEFAULT_APP_DATA = '0x0000000000000000000000000000000000000000000000000000000000000000';
9
+ exports.DEFAULT_ADDRESS = constants_1.AddressZero;
10
+ exports.DEFAULT_APP_DATA = constants_1.HashZero;
9
11
  exports.COW_SWAP_VAULT_RELAYER_ADDRESS = '0xc92e8bdf79f0507f65a392b0ab4667716bfe0110';
10
- // CowSwap API requires validTo field which specifies a limit date for the order to be valid
11
- // This is the default value being used by CowSwap exchange, corresponding to a date in year 2106
12
- exports.DEFAULT_VALIDTO_TIMESTAMP = 4294967295;
13
12
  exports.ORDER_KIND_SELL = 'sell';
@@ -1,3 +1,15 @@
1
1
  import { Asset } from '@shapeshiftoss/types';
2
2
  import { CowSwapperDeps } from '../../CowSwapper';
3
+ export declare type CowSwapQuoteApiInput = {
4
+ appData: string;
5
+ buyToken: string;
6
+ from: string;
7
+ kind: string;
8
+ partiallyFillable: boolean;
9
+ receiver: string;
10
+ sellAmountBeforeFee: string;
11
+ sellToken: string;
12
+ validTo: number;
13
+ };
3
14
  export declare const getUsdRate: ({ apiUrl, feeAsset }: CowSwapperDeps, input: Asset) => Promise<string>;
15
+ export declare const getNowPlusThirtyMinutesTimestamp: () => number;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getUsdRate = void 0;
3
+ exports.getNowPlusThirtyMinutesTimestamp = exports.getUsdRate = 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");
@@ -17,6 +17,9 @@ const getUsdRate = async ({ apiUrl, feeAsset }, input) => {
17
17
  details: { assetNamespace }
18
18
  });
19
19
  }
20
+ if (erc20Address === USDC_CONTRACT_ADDRESS) {
21
+ return '1';
22
+ }
20
23
  const buyAmountInDollars = 1000;
21
24
  const buyAmount = (0, bignumber_1.bn)(buyAmountInDollars).times((0, bignumber_1.bn)(10).exponentiatedBy(USDC_ASSET_PRECISION));
22
25
  try {
@@ -42,3 +45,9 @@ const getUsdRate = async ({ apiUrl, feeAsset }, input) => {
42
45
  }
43
46
  };
44
47
  exports.getUsdRate = getUsdRate;
48
+ const getNowPlusThirtyMinutesTimestamp = () => {
49
+ const ts = new Date();
50
+ ts.setMinutes(ts.getMinutes() + 30);
51
+ return Math.round(ts.getTime() / 1000);
52
+ };
53
+ exports.getNowPlusThirtyMinutesTimestamp = getNowPlusThirtyMinutesTimestamp;
@@ -6,6 +6,7 @@ import { ApprovalNeededOutput, BuyAssetBySellIdInput, Swapper, SwapperType, Trad
6
6
  * Meant for local testing only
7
7
  */
8
8
  export declare class TestSwapper implements Swapper<ChainId> {
9
+ readonly name = "Test";
9
10
  supportAssets: string[];
10
11
  initialize(): Promise<void>;
11
12
  getType(): SwapperType;
@@ -8,6 +8,7 @@ const api_1 = require("../../api");
8
8
  */
9
9
  class TestSwapper {
10
10
  constructor() {
11
+ this.name = 'Test';
11
12
  this.supportAssets = [
12
13
  'bip122:000000000019d6689c085ae165831e93/slip44:0',
13
14
  'cosmos:cosmoshub-4/slip44:118',
@@ -4,6 +4,7 @@ import { KnownChainIds } from '@shapeshiftoss/types';
4
4
  import { ApprovalNeededInput, ApprovalNeededOutput, ApproveInfiniteInput, 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
+ readonly name = "Thorchain";
7
8
  private swapSupportedChainIds;
8
9
  private supportedAssetIds;
9
10
  deps: ThorchainSwapperDeps;
@@ -11,6 +11,7 @@ const getUsdRate_1 = require("./utils/getUsdRate/getUsdRate");
11
11
  const thorService_1 = require("./utils/thorService");
12
12
  class ThorchainSwapper {
13
13
  constructor(deps) {
14
+ this.name = 'Thorchain';
14
15
  this.swapSupportedChainIds = {
15
16
  'eip155:1': true,
16
17
  'bip122:000000000019d6689c085ae165831e93': true
@@ -1,7 +1,11 @@
1
1
  import { ChainId } from '@shapeshiftoss/caip';
2
2
  import { GetTradeQuoteInput, TradeQuote } from '../../../api';
3
3
  import { ThorchainSwapperDeps } from '../types';
4
- export declare const getThorTradeQuote: ({ deps, input }: {
4
+ declare type GetThorTradeQuoteInput = {
5
5
  deps: ThorchainSwapperDeps;
6
6
  input: GetTradeQuoteInput;
7
- }) => Promise<TradeQuote<ChainId>>;
7
+ };
8
+ declare type GetThorTradeQuoteReturn = Promise<TradeQuote<ChainId>>;
9
+ declare type GetThorTradeQuote = (args: GetThorTradeQuoteInput) => GetThorTradeQuoteReturn;
10
+ export declare const getThorTradeQuote: GetThorTradeQuote;
11
+ export {};
@@ -2,61 +2,32 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getThorTradeQuote = 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 constants_1 = require("../../utils/constants");
8
9
  const helpers_1 = require("../../utils/helpers/helpers");
10
+ const getThorTxData_1 = require("../utils/bitcoin/utils/getThorTxData");
9
11
  const constants_2 = require("../utils/constants");
10
- const getThorTxData_1 = require("../utils/ethereum/utils/getThorTxData");
12
+ const estimateTradeFee_1 = require("../utils/estimateTradeFee/estimateTradeFee");
13
+ const getThorTxData_2 = require("../utils/ethereum/utils/getThorTxData");
11
14
  const getPriceRatio_1 = require("../utils/getPriceRatio/getPriceRatio");
15
+ const getBtcTxFees_1 = require("../utils/txFeeHelpers/btcTxFees/getBtcTxFees");
12
16
  const getEthTxFees_1 = require("../utils/txFeeHelpers/ethTxFees/getEthTxFees");
13
17
  const getThorTradeQuote = async ({ deps, input }) => {
14
- const { sellAsset, buyAsset, sellAmount, sellAssetAccountNumber, wallet } = input;
18
+ const { sellAsset, buyAsset, sellAmount, sellAssetAccountNumber, wallet, chainId, receiveAddress } = input;
15
19
  if (!wallet)
16
20
  throw new api_1.SwapError('[getTradeQuote] - wallet is required', {
17
21
  code: api_1.SwapErrorTypes.VALIDATION_FAILED
18
22
  });
19
23
  try {
20
- const { assetReference: sellAssetErc20Address, chainReference, chainNamespace } = (0, caip_1.fromAssetId)(sellAsset.assetId);
21
- const isErc20Trade = sellAssetErc20Address.startsWith('0x');
22
- const sellAssetChainId = (0, caip_1.toChainId)({ chainReference, chainNamespace });
23
- const adapter = deps.adapterManager.get(sellAssetChainId);
24
+ const { assetReference: sellAssetErc20Address } = (0, caip_1.fromAssetId)(sellAsset.assetId);
25
+ const adapter = deps.adapterManager.get(chainId);
24
26
  if (!adapter)
25
- throw new api_1.SwapError(`[getThorTradeQuote] - No chain adapter found for ${sellAssetChainId}.`, {
27
+ throw new api_1.SwapError(`[getThorTradeQuote] - No chain adapter found for ${chainId}.`, {
26
28
  code: api_1.SwapErrorTypes.UNSUPPORTED_CHAIN,
27
- details: { sellAssetChainId }
29
+ details: { chainId }
28
30
  });
29
- const bip44Params = adapter.buildBIP44Params({ accountNumber: Number(sellAssetAccountNumber) });
30
- const receiveAddress = await adapter.getAddress({ wallet, bip44Params });
31
- const { data, router } = await (0, getThorTxData_1.getThorTxInfo)({
32
- deps,
33
- sellAsset,
34
- buyAsset,
35
- sellAmount,
36
- slippageTolerance: constants_1.DEFAULT_SLIPPAGE,
37
- destinationAddress: receiveAddress,
38
- isErc20Trade
39
- });
40
- const feeData = await (async () => {
41
- switch (sellAssetChainId) {
42
- case 'eip155:1':
43
- return await (0, getEthTxFees_1.getEthTxFees)({
44
- deps,
45
- data,
46
- router,
47
- buyAsset,
48
- sellAmount,
49
- adapterManager: deps.adapterManager,
50
- receiveAddress,
51
- sellAssetReference: sellAssetErc20Address
52
- });
53
- default:
54
- throw new api_1.SwapError('[getThorTradeQuote] - Asset chainId is not supported.', {
55
- code: api_1.SwapErrorTypes.UNSUPPORTED_CHAIN,
56
- details: { sellAssetChainId }
57
- });
58
- }
59
- })();
60
31
  const sellAssetId = sellAsset.assetId;
61
32
  const buyAssetId = buyAsset.assetId;
62
33
  const feeAssetId = (0, caip_1.getFeeAssetIdFromAssetId)(buyAssetId);
@@ -69,22 +40,82 @@ const getThorTradeQuote = async ({ deps, input }) => {
69
40
  const priceRatio = await (0, getPriceRatio_1.getPriceRatio)(deps, { sellAssetId, buyAssetId });
70
41
  const rate = (0, bignumber_1.bnOrZero)(1).div(priceRatio).toString();
71
42
  const buyAmount = (0, helpers_1.normalizeAmount)((0, bignumber_1.bnOrZero)(sellAmount).times(rate));
72
- const sellAssetTradeFee = (0, bignumber_1.bnOrZero)(feeData.tradeFee).times((0, bignumber_1.bnOrZero)(feeAssetRatio));
43
+ const tradeFee = await (0, estimateTradeFee_1.estimateTradeFee)(deps, buyAsset.assetId);
44
+ const sellAssetTradeFee = (0, bignumber_1.bnOrZero)(tradeFee).times((0, bignumber_1.bnOrZero)(feeAssetRatio));
73
45
  // padding minimum by 1.5 the trade fee to avoid thorchain "not enough to cover fee" errors.
74
46
  const minimum = (0, bignumber_1.fromBaseUnit)(sellAssetTradeFee.times(1.5).toString(), sellAsset.precision);
75
- return {
47
+ const commonQuoteFields = {
76
48
  rate,
77
- minimum,
78
49
  maximum: constants_2.MAX_THORCHAIN_TRADE,
79
- feeData,
80
50
  sellAmount,
81
51
  buyAmount,
82
52
  sources: [{ name: 'thorchain', proportion: '1' }],
83
- allowanceContract: router,
84
53
  buyAsset,
85
54
  sellAsset,
86
- sellAssetAccountNumber
55
+ sellAssetAccountNumber,
56
+ minimum
87
57
  };
58
+ switch (chainId) {
59
+ case types_1.KnownChainIds.EthereumMainnet:
60
+ return (async () => {
61
+ const { data, router } = await (0, getThorTxData_2.getThorTxInfo)({
62
+ deps,
63
+ sellAsset,
64
+ buyAsset,
65
+ sellAmount,
66
+ slippageTolerance: constants_1.DEFAULT_SLIPPAGE,
67
+ destinationAddress: receiveAddress
68
+ });
69
+ const feeData = await (0, getEthTxFees_1.getEthTxFees)({
70
+ deps,
71
+ data,
72
+ router,
73
+ buyAsset,
74
+ sellAmount,
75
+ adapterManager: deps.adapterManager,
76
+ receiveAddress,
77
+ sellAssetReference: sellAssetErc20Address
78
+ });
79
+ return {
80
+ ...commonQuoteFields,
81
+ allowanceContract: router,
82
+ feeData
83
+ };
84
+ })();
85
+ case types_1.KnownChainIds.BitcoinMainnet:
86
+ return (async () => {
87
+ const { vault, opReturnData, pubkey } = await (0, getThorTxData_1.getThorTxInfo)({
88
+ deps,
89
+ sellAsset,
90
+ buyAsset,
91
+ sellAmount,
92
+ slippageTolerance: constants_1.DEFAULT_SLIPPAGE,
93
+ destinationAddress: receiveAddress,
94
+ wallet,
95
+ bip44Params: input.bip44Params,
96
+ accountType: input.accountType
97
+ });
98
+ const feeData = await (0, getBtcTxFees_1.getBtcTxFees)({
99
+ deps,
100
+ buyAsset,
101
+ sellAmount,
102
+ vault,
103
+ opReturnData,
104
+ pubkey,
105
+ adapterManager: deps.adapterManager
106
+ });
107
+ return {
108
+ ...commonQuoteFields,
109
+ allowanceContract: '0x0',
110
+ feeData
111
+ };
112
+ })();
113
+ default:
114
+ throw new api_1.SwapError('[getThorTradeQuote] - Asset chainId is not supported.', {
115
+ code: api_1.SwapErrorTypes.UNSUPPORTED_CHAIN,
116
+ details: { chainId }
117
+ });
118
+ }
88
119
  }
89
120
  catch (e) {
90
121
  if (e instanceof api_1.SwapError)
@@ -0,0 +1,22 @@
1
+ import { HDWallet } from '@shapeshiftoss/hdwallet-core';
2
+ import { Asset, BIP44Params, UtxoAccountType } from '@shapeshiftoss/types';
3
+ import { ThorchainSwapperDeps } from '../../../types';
4
+ declare type GetBtcThorTxInfoArgs = {
5
+ deps: ThorchainSwapperDeps;
6
+ sellAsset: Asset;
7
+ buyAsset: Asset;
8
+ sellAmount: string;
9
+ slippageTolerance: string;
10
+ destinationAddress: string;
11
+ wallet: HDWallet;
12
+ bip44Params: BIP44Params;
13
+ accountType: UtxoAccountType;
14
+ };
15
+ declare type GetBtcThorTxInfoReturn = Promise<{
16
+ opReturnData: string;
17
+ vault: string;
18
+ pubkey: string;
19
+ }>;
20
+ declare type GetBtcThorTxInfo = (args: GetBtcThorTxInfoArgs) => GetBtcThorTxInfoReturn;
21
+ export declare const getThorTxInfo: GetBtcThorTxInfo;
22
+ export {};
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getThorTxInfo = void 0;
4
+ const caip_1 = require("@shapeshiftoss/caip");
5
+ const api_1 = require("../../../../../api");
6
+ const bignumber_1 = require("../../../../utils/bignumber");
7
+ const getPriceRatio_1 = require("../../getPriceRatio/getPriceRatio");
8
+ const makeSwapMemo_1 = require("../../makeSwapMemo/makeSwapMemo");
9
+ const thorService_1 = require("../../thorService");
10
+ const getThorTxInfo = async ({ deps, sellAsset, buyAsset, sellAmount, slippageTolerance, destinationAddress, wallet, bip44Params, accountType }) => {
11
+ try {
12
+ const { data: inboundAddresses } = await thorService_1.thorService.get(`${deps.midgardUrl}/thorchain/inbound_addresses`);
13
+ const btcInboundAddresses = inboundAddresses.find((inbound) => inbound.chain === 'BTC');
14
+ const vault = btcInboundAddresses === null || btcInboundAddresses === void 0 ? void 0 : btcInboundAddresses.address;
15
+ if (!vault)
16
+ throw new api_1.SwapError(`[getThorTxInfo]: vault not found for BTC`, {
17
+ code: api_1.SwapErrorTypes.RESPONSE_ERROR,
18
+ details: { inboundAddresses }
19
+ });
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);
25
+ 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)
27
+ throw new api_1.SwapError('[getThorTxInfo]: bad expected buy amount or bad slippage tolerance', {
28
+ code: api_1.SwapErrorTypes.BUILD_TRADE_FAILED,
29
+ details: { expectedBuyAmount, slippageTolerance }
30
+ });
31
+ const limit = (0, bignumber_1.bnOrZero)(expectedBuyAmount)
32
+ .times((0, bignumber_1.bn)(1).minus(slippageTolerance))
33
+ .decimalPlaces(0)
34
+ .toString();
35
+ const memo = (0, makeSwapMemo_1.makeSwapMemo)({
36
+ buyAssetId: buyAsset.assetId,
37
+ destinationAddress,
38
+ limit
39
+ });
40
+ const adapter = deps.adapterManager.get(caip_1.btcChainId);
41
+ const pubkey = await adapter.getPublicKey(wallet, bip44Params, accountType);
42
+ return {
43
+ opReturnData: memo,
44
+ vault,
45
+ pubkey: pubkey.xpub
46
+ };
47
+ }
48
+ catch (e) {
49
+ if (e instanceof api_1.SwapError)
50
+ throw e;
51
+ throw new api_1.SwapError('[getThorTxInfo]', { cause: e, code: api_1.SwapErrorTypes.TRADE_QUOTE_FAILED });
52
+ }
53
+ };
54
+ exports.getThorTxInfo = getThorTxInfo;
@@ -14,8 +14,7 @@ const makeTradeTx = async ({ wallet, bip44Params, sellAmount, buyAsset, sellAsse
14
14
  buyAsset,
15
15
  sellAmount,
16
16
  slippageTolerance,
17
- destinationAddress,
18
- isErc20Trade
17
+ destinationAddress
19
18
  });
20
19
  return adapter.buildCustomTx({
21
20
  wallet,
@@ -1,15 +1,18 @@
1
1
  import { Asset } from '@shapeshiftoss/types';
2
2
  import { ThorchainSwapperDeps } from '../../../types';
3
- export declare const getThorTxInfo: ({ deps, sellAsset, buyAsset, sellAmount, slippageTolerance, destinationAddress, isErc20Trade }: {
3
+ declare type GetBtcThorTxInfoArgs = {
4
4
  deps: ThorchainSwapperDeps;
5
5
  sellAsset: Asset;
6
6
  buyAsset: Asset;
7
7
  sellAmount: string;
8
8
  slippageTolerance: string;
9
9
  destinationAddress: string;
10
- isErc20Trade: boolean;
11
- }) => Promise<{
12
- data: any;
10
+ };
11
+ declare type GetBtcThorTxInfoReturn = Promise<{
12
+ data: string;
13
13
  memo: string;
14
14
  router: string;
15
15
  }>;
16
+ declare type GetBtcThorTxInfo = (args: GetBtcThorTxInfoArgs) => GetBtcThorTxInfoReturn;
17
+ export declare const getThorTxInfo: GetBtcThorTxInfo;
18
+ export {};
@@ -8,9 +8,10 @@ const getPriceRatio_1 = require("../../getPriceRatio/getPriceRatio");
8
8
  const makeSwapMemo_1 = require("../../makeSwapMemo/makeSwapMemo");
9
9
  const thorService_1 = require("../../thorService");
10
10
  const routerCalldata_1 = require("../routerCalldata");
11
- const getThorTxInfo = async ({ deps, sellAsset, buyAsset, sellAmount, slippageTolerance, destinationAddress, isErc20Trade }) => {
11
+ const getThorTxInfo = async ({ deps, sellAsset, buyAsset, sellAmount, slippageTolerance, destinationAddress }) => {
12
12
  try {
13
- const { assetReference } = (0, caip_1.fromAssetId)(sellAsset.assetId);
13
+ const { assetReference, assetNamespace } = (0, caip_1.fromAssetId)(sellAsset.assetId);
14
+ const isErc20Trade = assetNamespace === 'erc20';
14
15
  const { data: inboundAddresses } = await thorService_1.thorService.get(`${deps.midgardUrl}/thorchain/inbound_addresses`);
15
16
  const ethInboundAddresses = inboundAddresses.find((inbound) => inbound.chain === 'ETH');
16
17
  const vault = ethInboundAddresses === null || ethInboundAddresses === void 0 ? void 0 : ethInboundAddresses.address;
@@ -25,10 +26,11 @@ const getThorTxInfo = async ({ deps, sellAsset, buyAsset, sellAmount, slippageTo
25
26
  sellAssetId: sellAsset.assetId
26
27
  });
27
28
  const expectedBuyAmount = (0, bignumber_1.toBaseUnit)((0, bignumber_1.fromBaseUnit)((0, bignumber_1.bnOrZero)(sellAmount).dividedBy(priceRatio), sellAsset.precision), buyAsset.precision);
28
- if (!(0, bignumber_1.bnOrZero)(expectedBuyAmount).gte(0) ||
29
- !((0, bignumber_1.bnOrZero)(slippageTolerance).gte(0) && (0, bignumber_1.bnOrZero)(slippageTolerance).lte(1)))
29
+ 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)
30
31
  throw new api_1.SwapError('[makeTradeTx]: bad expected buy amount or bad slippage tolerance', {
31
- code: api_1.SwapErrorTypes.BUILD_TRADE_FAILED
32
+ code: api_1.SwapErrorTypes.BUILD_TRADE_FAILED,
33
+ details: { expectedBuyAmount, slippageTolerance }
32
34
  });
33
35
  const limit = (0, bignumber_1.bnOrZero)(expectedBuyAmount)
34
36
  .times((0, bignumber_1.bn)(1).minus(slippageTolerance))
@@ -21,6 +21,11 @@ export declare type GetERC20AllowanceArgs = {
21
21
  ownerAddress: string;
22
22
  spenderAddress: string;
23
23
  };
24
+ export declare type GetApproveContractDataArgs = {
25
+ web3: Web3;
26
+ spenderAddress: string;
27
+ contractAddress: string;
28
+ };
24
29
  declare type GrantAllowanceArgs<T extends EvmSupportedChainIds> = {
25
30
  quote: TradeQuote<T>;
26
31
  wallet: HDWallet;
@@ -38,4 +43,5 @@ export declare const grantAllowance: <T extends EvmSupportedChainIds>({ quote, w
38
43
  */
39
44
  export declare const normalizeAmount: (amount: string | number | BN) => string;
40
45
  export declare const normalizeIntegerAmount: (amount: string | number | BN) => string;
46
+ export declare const getApproveContractData: ({ web3, spenderAddress, contractAddress }: GetApproveContractDataArgs) => string;
41
47
  export {};
@@ -1,9 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.normalizeIntegerAmount = exports.normalizeAmount = exports.grantAllowance = exports.getAllowanceRequired = exports.getERC20Allowance = void 0;
3
+ exports.getApproveContractData = exports.normalizeIntegerAmount = exports.normalizeAmount = exports.grantAllowance = exports.getAllowanceRequired = exports.getERC20Allowance = void 0;
4
4
  const caip_1 = require("@shapeshiftoss/caip");
5
5
  const web3_utils_1 = require("web3-utils");
6
6
  const api_1 = require("../../../api");
7
+ const constants_1 = require("../../cow/utils/constants");
8
+ const erc20_abi_1 = require("../abi/erc20-abi");
7
9
  const bignumber_1 = require("../bignumber");
8
10
  const getERC20Allowance = async ({ erc20AllowanceAbi, web3, sellAssetErc20Address, ownerAddress, spenderAddress }) => {
9
11
  const erc20Contract = new web3.eth.Contract(erc20AllowanceAbi, sellAssetErc20Address);
@@ -115,3 +117,8 @@ const normalizeIntegerAmount = (amount) => {
115
117
  .toLocaleString('fullwide', { useGrouping: false });
116
118
  };
117
119
  exports.normalizeIntegerAmount = normalizeIntegerAmount;
120
+ const getApproveContractData = ({ web3, spenderAddress, contractAddress }) => {
121
+ const contract = new web3.eth.Contract(erc20_abi_1.erc20Abi, contractAddress);
122
+ return contract.methods.approve(spenderAddress, constants_1.MAX_ALLOWANCE).encodeABI();
123
+ };
124
+ exports.getApproveContractData = getApproveContractData;
@@ -5,3 +5,4 @@ export declare const FOX: Asset;
5
5
  export declare const WBTC: Asset;
6
6
  export declare const ETH: Asset;
7
7
  export declare const UNSUPPORTED: Asset;
8
+ export declare const USDC: Asset;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.UNSUPPORTED = exports.ETH = exports.WBTC = exports.FOX = exports.WETH = exports.BTC = void 0;
3
+ exports.USDC = exports.UNSUPPORTED = exports.ETH = exports.WBTC = exports.FOX = exports.WETH = exports.BTC = void 0;
4
4
  exports.BTC = {
5
5
  assetId: 'bip122:000000000019d6689c085ae165831e93/slip44:0',
6
6
  chainId: 'bip122:000000000019d6689c085ae165831e93',
@@ -73,3 +73,15 @@ exports.UNSUPPORTED = {
73
73
  explorerTxLink: 'https://etherscan.io/tx/',
74
74
  explorerAddressLink: 'https://etherscan.io/address/'
75
75
  };
76
+ exports.USDC = {
77
+ assetId: 'eip155:1/erc20:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
78
+ chainId: 'eip155:1',
79
+ symbol: 'USDC',
80
+ name: 'USD Coin',
81
+ precision: 6,
82
+ color: '#2373CB',
83
+ icon: 'https://rawcdn.githack.com/trustwallet/assets/master/blockchains/ethereum/assets/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48/logo.png',
84
+ explorer: 'https://etherscan.io',
85
+ explorerAddressLink: 'https://etherscan.io/address/',
86
+ explorerTxLink: 'https://etherscan.io/tx/'
87
+ };
@@ -1,3 +1,4 @@
1
+ import { HDWallet } from '@shapeshiftoss/hdwallet-core';
1
2
  import { Asset, KnownChainIds } from '@shapeshiftoss/types';
2
3
  import { TradeQuote } from '../../../api';
3
4
  export declare const setupQuote: () => {
@@ -6,3 +7,22 @@ export declare const setupQuote: () => {
6
7
  buyAsset: Asset;
7
8
  sellAsset: Asset;
8
9
  };
10
+ export declare const setupBuildTrade: () => {
11
+ buildTradeInput: {
12
+ sellAsset: Asset;
13
+ buyAsset: Asset;
14
+ sellAmount: string;
15
+ sendMax: boolean;
16
+ sellAssetAccountNumber: number;
17
+ wallet: HDWallet;
18
+ receiveAddress: string;
19
+ } & {
20
+ chainId: import("../../../api").EvmSupportedChainIds;
21
+ } & {
22
+ buyAssetAccountNumber: number;
23
+ slippage?: string | undefined;
24
+ wallet: HDWallet;
25
+ };
26
+ buyAsset: Asset;
27
+ sellAsset: Asset;
28
+ };
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.setupQuote = void 0;
3
+ exports.setupBuildTrade = exports.setupQuote = void 0;
4
4
  const types_1 = require("@shapeshiftoss/types");
5
5
  const assets_1 = require("./assets");
6
6
  const setupQuote = () => {
@@ -25,8 +25,27 @@ const setupQuote = () => {
25
25
  sellAsset,
26
26
  buyAsset,
27
27
  sellAssetAccountNumber: 0,
28
- sendMax: false
28
+ sendMax: false,
29
+ receiveAddress: '0xc770eefad204b5180df6a14ee197d99d808ee52d',
30
+ wallet: {}
29
31
  };
30
32
  return { quoteInput, tradeQuote, buyAsset, sellAsset };
31
33
  };
32
34
  exports.setupQuote = setupQuote;
35
+ const setupBuildTrade = () => {
36
+ const sellAsset = { ...assets_1.FOX };
37
+ const buyAsset = { ...assets_1.WETH };
38
+ const buildTradeInput = {
39
+ chainId: types_1.KnownChainIds.EthereumMainnet,
40
+ sellAmount: '1000000000000000000',
41
+ buyAsset,
42
+ sendMax: false,
43
+ sellAssetAccountNumber: 0,
44
+ buyAssetAccountNumber: 0,
45
+ sellAsset,
46
+ wallet: {},
47
+ receiveAddress: ''
48
+ };
49
+ return { buildTradeInput, buyAsset, sellAsset };
50
+ };
51
+ exports.setupBuildTrade = setupBuildTrade;
@@ -3,7 +3,7 @@ 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> {
6
- static swapperName: string;
6
+ readonly name = "0x";
7
7
  deps: ZrxSwapperDeps;
8
8
  chainId: ChainId;
9
9
  constructor(deps: ZrxSwapperDeps);
@@ -12,6 +12,7 @@ const zrxBuildTrade_1 = require("./zrxBuildTrade/zrxBuildTrade");
12
12
  const zrxExecuteTrade_1 = require("./zrxExecuteTrade/zrxExecuteTrade");
13
13
  class ZrxSwapper {
14
14
  constructor(deps) {
15
+ this.name = '0x';
15
16
  this.deps = deps;
16
17
  this.chainId = deps.adapter.getChainId();
17
18
  }
@@ -62,4 +63,3 @@ class ZrxSwapper {
62
63
  }
63
64
  }
64
65
  exports.ZrxSwapper = ZrxSwapper;
65
- ZrxSwapper.swapperName = 'ZrxSwapper';
@@ -1,4 +1,3 @@
1
- import { HDWallet } from '@shapeshiftoss/hdwallet-core';
2
1
  import { Asset } from '@shapeshiftoss/types';
3
2
  import { ZrxQuoteResponse } from '../../types';
4
3
  export declare const setupZrxTradeQuoteResponse: () => {
@@ -6,24 +5,6 @@ export declare const setupZrxTradeQuoteResponse: () => {
6
5
  buyAsset: Asset;
7
6
  sellAsset: Asset;
8
7
  };
9
- export declare const setupBuildTrade: () => {
10
- buildTradeInput: {
11
- sellAsset: Asset;
12
- buyAsset: Asset;
13
- sellAmount: string;
14
- sendMax: boolean;
15
- sellAssetAccountNumber: number;
16
- wallet?: HDWallet | undefined;
17
- } & {
18
- chainId: import("../../../../api").EvmSupportedChainIds;
19
- } & {
20
- buyAssetAccountNumber: number;
21
- slippage?: string | undefined;
22
- wallet: HDWallet;
23
- };
24
- buyAsset: Asset;
25
- sellAsset: Asset;
26
- };
27
8
  export declare const setupExecuteTrade: () => {
28
9
  executeTradeInput: {
29
10
  sellAmount: string;
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.setupExecuteTrade = exports.setupBuildTrade = exports.setupZrxTradeQuoteResponse = void 0;
4
- const types_1 = require("@shapeshiftoss/types");
3
+ exports.setupExecuteTrade = exports.setupZrxTradeQuoteResponse = void 0;
5
4
  const assets_1 = require("../../../utils/test-data/assets");
6
5
  const setupZrxTradeQuoteResponse = () => {
7
6
  const sellAsset = { ...assets_1.FOX };
@@ -20,22 +19,6 @@ const setupZrxTradeQuoteResponse = () => {
20
19
  return { quoteResponse, buyAsset, sellAsset };
21
20
  };
22
21
  exports.setupZrxTradeQuoteResponse = setupZrxTradeQuoteResponse;
23
- const setupBuildTrade = () => {
24
- const sellAsset = { ...assets_1.FOX };
25
- const buyAsset = { ...assets_1.WETH };
26
- const buildTradeInput = {
27
- chainId: types_1.KnownChainIds.EthereumMainnet,
28
- sellAmount: '1000000000000000000',
29
- buyAsset,
30
- sendMax: false,
31
- sellAssetAccountNumber: 0,
32
- buyAssetAccountNumber: 0,
33
- sellAsset,
34
- wallet: {}
35
- };
36
- return { buildTradeInput, buyAsset, sellAsset };
37
- };
38
- exports.setupBuildTrade = setupBuildTrade;
39
22
  const setupExecuteTrade = () => {
40
23
  const sellAsset = { ...assets_1.FOX };
41
24
  const buyAsset = { ...assets_1.WETH };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shapeshiftoss/swapper",
3
- "version": "8.0.1",
3
+ "version": "8.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",