@shapeshiftoss/swapper 3.0.5 → 3.0.6

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 (26) hide show
  1. package/dist/api.d.ts +71 -1
  2. package/dist/swappers/test/TestSwapper.d.ts +4 -1
  3. package/dist/swappers/test/TestSwapper.js +9 -0
  4. package/dist/swappers/thorchain/ThorchainSwapper.d.ts +4 -1
  5. package/dist/swappers/thorchain/ThorchainSwapper.js +9 -0
  6. package/dist/swappers/zrx/ZrxApprovalNeeded/ZrxApprovalNeeded.d.ts +2 -1
  7. package/dist/swappers/zrx/ZrxApprovalNeeded/ZrxApprovalNeeded.js +3 -3
  8. package/dist/swappers/zrx/ZrxApproveInfinite/ZrxApproveInfinite.d.ts +2 -1
  9. package/dist/swappers/zrx/ZrxBuildQuoteTx/ZrxBuildQuoteTx.js +14 -14
  10. package/dist/swappers/zrx/ZrxSwapper.d.ts +5 -2
  11. package/dist/swappers/zrx/ZrxSwapper.js +12 -0
  12. package/dist/swappers/zrx/getZrxMinMax/getZrxMinMax.js +2 -5
  13. package/dist/swappers/zrx/getZrxQuote/getZrxQuote.js +4 -12
  14. package/dist/swappers/zrx/getZrxTradeQuote/getZrxTradeQuote.d.ts +3 -0
  15. package/dist/swappers/zrx/getZrxTradeQuote/getZrxTradeQuote.js +107 -0
  16. package/dist/swappers/zrx/types.d.ts +17 -0
  17. package/dist/swappers/zrx/types.js +2 -0
  18. package/dist/swappers/zrx/utils/helpers/helpers.d.ts +5 -2
  19. package/dist/swappers/zrx/utils/helpers/helpers.js +14 -17
  20. package/dist/swappers/zrx/utils/test-data/setupSwapQuote.d.ts +6 -0
  21. package/dist/swappers/zrx/utils/test-data/setupSwapQuote.js +18 -1
  22. package/dist/swappers/zrx/zrxBuildTrade/zrxBuildTrade.d.ts +4 -0
  23. package/dist/swappers/zrx/zrxBuildTrade/zrxBuildTrade.js +169 -0
  24. package/dist/swappers/zrx/zrxExecuteTrade/zrxExecuteTrade.d.ts +4 -0
  25. package/dist/swappers/zrx/zrxExecuteTrade/zrxExecuteTrade.js +76 -0
  26. package/package.json +1 -1
package/dist/api.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { CAIP19 } from '@shapeshiftoss/caip';
2
2
  import { HDWallet } from '@shapeshiftoss/hdwallet-core';
3
- import { ApprovalNeededInput, ApprovalNeededOutput, ApproveInfiniteInput, Asset, BuildQuoteTxInput, ChainTypes, ExecQuoteInput, ExecQuoteOutput, GetQuoteInput, MinMaxOutput, Quote, SwapperType } from '@shapeshiftoss/types';
3
+ import { ApprovalNeededOutput, Asset, BuildQuoteTxInput, chainAdapters, ChainTypes, ExecQuoteInput, ExecQuoteOutput, GetQuoteInput, MinMaxOutput, Quote, SwapperType } from '@shapeshiftoss/types';
4
4
  export declare type SupportedAssetInput = {
5
5
  assetIds: CAIP19[];
6
6
  };
@@ -15,17 +15,82 @@ export declare type BuyAssetBySellIdInput = {
15
15
  export declare type SupportedSellAssetsInput = {
16
16
  assetIds: CAIP19[];
17
17
  };
18
+ export declare type CommonTradeInput = {
19
+ sellAsset: Asset;
20
+ buyAsset: Asset;
21
+ sellAmount?: string;
22
+ buyAmount?: string;
23
+ sendMax: boolean;
24
+ sellAssetAccountId: string;
25
+ };
26
+ export declare type GetTradeQuoteInput = CommonTradeInput;
27
+ export declare type BuildTradeInput = CommonTradeInput & {
28
+ buyAssetAccountId: string;
29
+ slippage?: string;
30
+ wallet: HDWallet;
31
+ };
32
+ interface TradeBase<C extends ChainTypes> {
33
+ success: boolean;
34
+ statusReason: string;
35
+ buyAmount: string;
36
+ sellAmount: string;
37
+ feeData: chainAdapters.QuoteFeeData<C>;
38
+ rate: string;
39
+ allowanceContract: string;
40
+ sources: Array<SwapSource>;
41
+ buyAsset: Asset;
42
+ sellAsset: Asset;
43
+ sellAssetAccountId: string;
44
+ }
45
+ export interface TradeQuote<C extends ChainTypes> extends TradeBase<C> {
46
+ minimum: string;
47
+ maximum: string;
48
+ }
49
+ export interface Trade<C extends ChainTypes> extends TradeBase<C> {
50
+ txData: string;
51
+ depositAddress: string;
52
+ receiveAddress: string;
53
+ }
54
+ export declare type ExecuteTradeInput<C extends ChainTypes> = {
55
+ trade: Trade<C>;
56
+ wallet: HDWallet;
57
+ };
58
+ export declare type TradeResult = {
59
+ txid: string;
60
+ };
61
+ export declare type SwapSource = {
62
+ name: string;
63
+ proportion: string;
64
+ };
65
+ export declare type ApproveInfiniteInput<C extends ChainTypes> = {
66
+ quote: Quote<C> | TradeQuote<C>;
67
+ wallet: HDWallet;
68
+ };
69
+ export declare type ApprovalNeededInput<C extends ChainTypes> = {
70
+ quote: Quote<C> | TradeQuote<C>;
71
+ wallet: HDWallet;
72
+ };
18
73
  export declare class SwapError extends Error {
19
74
  }
20
75
  export interface Swapper {
21
76
  /** Returns the swapper type */
22
77
  getType(): SwapperType;
78
+ /**
79
+ * Get builds a trade with definitive rate & txData that can be executed with executeTrade
80
+ **/
81
+ buildTrade(args: BuildTradeInput): Promise<Trade<ChainTypes>>;
82
+ /**
83
+ * Get a trade quote
84
+ */
85
+ getTradeQuote(input: GetTradeQuoteInput): Promise<TradeQuote<ChainTypes>>;
23
86
  /**
24
87
  * Get a Quote along with an unsigned transaction that can be signed and broadcast to execute the swap
88
+ * @deprecated The method is going away soon.
25
89
  **/
26
90
  buildQuoteTx(args: BuildQuoteTxInput): Promise<Quote<ChainTypes>>;
27
91
  /**
28
92
  * Get a basic quote (rate) for a trading pair
93
+ * @deprecated The method is going away soon.
29
94
  */
30
95
  getQuote(input: GetQuoteInput, wallet?: HDWallet): Promise<Quote<ChainTypes>>;
31
96
  /**
@@ -40,6 +105,10 @@ export interface Swapper {
40
105
  * Execute a quote built with buildQuoteTx by signing and broadcasting
41
106
  */
42
107
  executeQuote(args: ExecQuoteInput<ChainTypes>): Promise<ExecQuoteOutput>;
108
+ /**
109
+ * Execute a trade built with buildTrade by signing and broadcasting
110
+ */
111
+ executeTrade(args: ExecuteTradeInput<ChainTypes>): Promise<ExecQuoteOutput>;
43
112
  /**
44
113
  * Get a boolean if a quote needs approval
45
114
  */
@@ -57,3 +126,4 @@ export interface Swapper {
57
126
  */
58
127
  filterAssetIdsBySellable(assetIds: CAIP19[]): CAIP19[];
59
128
  }
129
+ export {};
@@ -1,6 +1,6 @@
1
1
  import { CAIP19 } from '@shapeshiftoss/caip';
2
2
  import { ApprovalNeededOutput, Asset, ChainTypes, ExecQuoteOutput, GetQuoteInput, MinMaxOutput, Quote, SwapperType } from '@shapeshiftoss/types';
3
- import { BuyAssetBySellIdInput, Swapper } from '../../api';
3
+ import { BuyAssetBySellIdInput, Swapper, Trade, TradeQuote } from '../../api';
4
4
  /**
5
5
  * Playground for testing different scenarios of multiple swappers in the manager.
6
6
  * Meant for local testing only
@@ -18,4 +18,7 @@ export declare class TestSwapper implements Swapper {
18
18
  approveInfinite(): Promise<string>;
19
19
  filterBuyAssetsBySellAssetId(args: BuyAssetBySellIdInput): CAIP19[];
20
20
  filterAssetIdsBySellable(): CAIP19[];
21
+ buildTrade(): Promise<Trade<ChainTypes>>;
22
+ getTradeQuote(): Promise<TradeQuote<ChainTypes>>;
23
+ executeTrade(): Promise<ExecQuoteOutput>;
21
24
  }
@@ -49,5 +49,14 @@ class TestSwapper {
49
49
  filterAssetIdsBySellable() {
50
50
  return this.supportAssets;
51
51
  }
52
+ async buildTrade() {
53
+ throw new Error('TestSwapper: buildTrade unimplemented');
54
+ }
55
+ async getTradeQuote() {
56
+ throw new Error('TestSwapper: getTradeQuote unimplemented');
57
+ }
58
+ async executeTrade() {
59
+ throw new Error('TestSwapper: executeTrade unimplemented');
60
+ }
52
61
  }
53
62
  exports.TestSwapper = TestSwapper;
@@ -1,6 +1,6 @@
1
1
  import { CAIP19 } from '@shapeshiftoss/caip';
2
2
  import { ApprovalNeededOutput, Asset, ChainTypes, ExecQuoteOutput, GetQuoteInput, MinMaxOutput, Quote, SwapperType } from '@shapeshiftoss/types';
3
- import { Swapper } from '../../api';
3
+ import { Swapper, Trade, TradeQuote } from '../../api';
4
4
  export declare class ThorchainSwapper implements Swapper {
5
5
  getType(): SwapperType;
6
6
  getQuote(): Promise<Quote<ChainTypes>>;
@@ -12,4 +12,7 @@ export declare class ThorchainSwapper implements Swapper {
12
12
  approveInfinite(): Promise<string>;
13
13
  filterBuyAssetsBySellAssetId(): CAIP19[];
14
14
  filterAssetIdsBySellable(): CAIP19[];
15
+ buildTrade(): Promise<Trade<ChainTypes>>;
16
+ getTradeQuote(): Promise<TradeQuote<ChainTypes>>;
17
+ executeTrade(): Promise<ExecQuoteOutput>;
15
18
  }
@@ -35,5 +35,14 @@ class ThorchainSwapper {
35
35
  filterAssetIdsBySellable() {
36
36
  return [];
37
37
  }
38
+ async buildTrade() {
39
+ throw new Error('ThorchainSwapper: buildTrade unimplemented');
40
+ }
41
+ async getTradeQuote() {
42
+ throw new Error('ThorchainSwapper: getTradeQuote unimplemented');
43
+ }
44
+ async executeTrade() {
45
+ throw new Error('ThorchainSwapper: executeTrade unimplemented');
46
+ }
38
47
  }
39
48
  exports.ThorchainSwapper = ThorchainSwapper;
@@ -1,3 +1,4 @@
1
- import { ApprovalNeededInput, ApprovalNeededOutput, ChainTypes } from '@shapeshiftoss/types';
1
+ import { ApprovalNeededOutput, ChainTypes } from '@shapeshiftoss/types';
2
+ import { ApprovalNeededInput } from '../../../api';
2
3
  import { ZrxSwapperDeps } from '../ZrxSwapper';
3
4
  export declare function ZrxApprovalNeeded({ adapterManager, web3 }: ZrxSwapperDeps, { quote, wallet }: ApprovalNeededInput<ChainTypes>): Promise<ApprovalNeededOutput>;
@@ -2,9 +2,9 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ZrxApprovalNeeded = void 0;
4
4
  const types_1 = require("@shapeshiftoss/types");
5
- const bignumber_js_1 = require("bignumber.js");
6
5
  const api_1 = require("../../../api");
7
6
  const erc20Allowance_abi_1 = require("../utils/abi/erc20Allowance-abi");
7
+ const bignumber_1 = require("../utils/bignumber");
8
8
  const constants_1 = require("../utils/constants");
9
9
  const helpers_1 = require("../utils/helpers/helpers");
10
10
  async function ZrxApprovalNeeded({ adapterManager, web3 }, { quote, wallet }) {
@@ -30,9 +30,9 @@ async function ZrxApprovalNeeded({ adapterManager, web3 }, { quote, wallet }) {
30
30
  spenderAddress: quote.allowanceContract,
31
31
  ownerAddress: receiveAddress
32
32
  });
33
- const allowanceOnChain = new bignumber_js_1.BigNumber(allowanceResult || '0');
33
+ const allowanceOnChain = (0, bignumber_1.bnOrZero)(allowanceResult);
34
34
  return {
35
- approvalNeeded: allowanceOnChain.lt(new bignumber_js_1.BigNumber(quote.sellAmount || 1)),
35
+ approvalNeeded: allowanceOnChain.lte((0, bignumber_1.bnOrZero)(quote.sellAmount)),
36
36
  gas: constants_1.APPROVAL_GAS_LIMIT,
37
37
  gasPrice: (_b = (_a = quote === null || quote === void 0 ? void 0 : quote.feeData) === null || _a === void 0 ? void 0 : _a.chainSpecific) === null || _b === void 0 ? void 0 : _b.gasPrice
38
38
  };
@@ -1,3 +1,4 @@
1
- import { ApproveInfiniteInput, ChainTypes } from '@shapeshiftoss/types';
1
+ import { ChainTypes } from '@shapeshiftoss/types';
2
+ import { ApproveInfiniteInput } from '../../../api';
2
3
  import { ZrxSwapperDeps } from '../ZrxSwapper';
3
4
  export declare function ZrxApproveInfinite({ adapterManager, web3 }: ZrxSwapperDeps, { quote, wallet }: ApproveInfiniteInput<ChainTypes>): Promise<string>;
@@ -22,17 +22,14 @@ var __importStar = (this && this.__importStar) || function (mod) {
22
22
  __setModuleDefault(result, mod);
23
23
  return result;
24
24
  };
25
- var __importDefault = (this && this.__importDefault) || function (mod) {
26
- return (mod && mod.__esModule) ? mod : { "default": mod };
27
- };
28
25
  Object.defineProperty(exports, "__esModule", { value: true });
29
26
  exports.ZrxBuildQuoteTx = void 0;
30
27
  const types_1 = require("@shapeshiftoss/types");
31
- const bignumber_js_1 = __importDefault(require("bignumber.js"));
32
28
  const rax = __importStar(require("retry-axios"));
33
29
  const __1 = require("../../..");
34
30
  const erc20Allowance_abi_1 = require("../utils/abi/erc20Allowance-abi");
35
31
  const applyAxiosRetry_1 = require("../utils/applyAxiosRetry");
32
+ const bignumber_1 = require("../utils/bignumber");
36
33
  const constants_1 = require("../utils/constants");
37
34
  const helpers_1 = require("../utils/helpers/helpers");
38
35
  const zrxService_1 = require("../utils/zrxService");
@@ -59,12 +56,10 @@ async function ZrxBuildQuoteTx({ adapterManager, web3 }, { input, wallet }) {
59
56
  const adapter = adapterManager.byChain(buyAsset.chain);
60
57
  const bip44Params = adapter.buildBIP44Params({ accountNumber: Number(buyAssetAccountId) });
61
58
  const receiveAddress = await adapter.getAddress({ wallet, bip44Params });
62
- if (new bignumber_js_1.default(slippage || 0).gt(constants_1.MAX_SLIPPAGE)) {
59
+ if ((0, bignumber_1.bnOrZero)(slippage).gt(constants_1.MAX_SLIPPAGE)) {
63
60
  throw new __1.SwapError(`ZrxSwapper:ZrxBuildQuoteTx slippage value of ${slippage} is greater than max slippage value of ${constants_1.MAX_SLIPPAGE}`);
64
61
  }
65
- const slippagePercentage = slippage
66
- ? new bignumber_js_1.default(slippage).div(100).toString()
67
- : constants_1.DEFAULT_SLIPPAGE;
62
+ const slippagePercentage = slippage ? (0, bignumber_1.bnOrZero)(slippage).div(100).toString() : constants_1.DEFAULT_SLIPPAGE;
68
63
  try {
69
64
  /**
70
65
  * /swap/v1/quote
@@ -105,7 +100,7 @@ async function ZrxBuildQuoteTx({ adapterManager, web3 }, { input, wallet }) {
105
100
  }
106
101
  });
107
102
  const { data } = quoteResponse;
108
- const estimatedGas = new bignumber_js_1.default(data.gas || 0);
103
+ const estimatedGas = (0, bignumber_1.bnOrZero)(data.gas);
109
104
  const quote = {
110
105
  sellAsset,
111
106
  buyAsset,
@@ -116,9 +111,7 @@ async function ZrxBuildQuoteTx({ adapterManager, web3 }, { input, wallet }) {
116
111
  rate: data.price,
117
112
  depositAddress: data.to,
118
113
  feeData: {
119
- fee: new bignumber_js_1.default(estimatedGas || 0)
120
- .multipliedBy(new bignumber_js_1.default(data.gasPrice || 0))
121
- .toString(),
114
+ fee: (0, bignumber_1.bnOrZero)(estimatedGas).multipliedBy((0, bignumber_1.bnOrZero)(data.gasPrice)).toString(),
122
115
  chainSpecific: {
123
116
  estimatedGas: estimatedGas.toString(),
124
117
  gasPrice: data.gasPrice
@@ -130,8 +123,15 @@ async function ZrxBuildQuoteTx({ adapterManager, web3 }, { input, wallet }) {
130
123
  allowanceContract: data.allowanceTarget,
131
124
  sources: ((_a = data.sources) === null || _a === void 0 ? void 0 : _a.filter((s) => parseFloat(s.proportion) > 0)) || constants_1.DEFAULT_SOURCE
132
125
  };
126
+ if (!data.allowanceTarget)
127
+ throw new __1.SwapError('ZrxSwapper:ZrxBuildQuoteTx no allowance target');
128
+ if (!data.sellAmount)
129
+ throw new __1.SwapError('ZrxSwapper:ZrxBuildQuoteTx no sell amount');
133
130
  const allowanceRequired = await (0, helpers_1.getAllowanceRequired)({
134
- quote,
131
+ sellAsset,
132
+ allowanceContract: data.allowanceTarget,
133
+ receiveAddress,
134
+ sellAmount: data.sellAmount,
135
135
  web3,
136
136
  erc20AllowanceAbi: erc20Allowance_abi_1.erc20AllowanceAbi
137
137
  });
@@ -140,7 +140,7 @@ async function ZrxBuildQuoteTx({ adapterManager, web3 }, { input, wallet }) {
140
140
  fee: ((_b = quote.feeData) === null || _b === void 0 ? void 0 : _b.fee) || '0',
141
141
  chainSpecific: {
142
142
  ...(_c = quote.feeData) === null || _c === void 0 ? void 0 : _c.chainSpecific,
143
- approvalFee: new bignumber_js_1.default(constants_1.APPROVAL_GAS_LIMIT).multipliedBy(data.gasPrice || 0).toString()
143
+ approvalFee: (0, bignumber_1.bnOrZero)(constants_1.APPROVAL_GAS_LIMIT).multipliedBy((0, bignumber_1.bnOrZero)(data.gasPrice)).toString()
144
144
  }
145
145
  };
146
146
  }
@@ -1,8 +1,8 @@
1
1
  import { CAIP19 } from '@shapeshiftoss/caip';
2
2
  import { ChainAdapterManager } from '@shapeshiftoss/chain-adapters';
3
- import { ApprovalNeededInput, ApprovalNeededOutput, ApproveInfiniteInput, Asset, BuildQuoteTxInput, ChainTypes, ExecQuoteInput, ExecQuoteOutput, GetQuoteInput, MinMaxOutput, Quote, SwapperType } from '@shapeshiftoss/types';
3
+ import { ApprovalNeededOutput, Asset, BuildQuoteTxInput, ChainTypes, ExecQuoteInput, ExecQuoteOutput, GetQuoteInput, MinMaxOutput, Quote, SwapperType } from '@shapeshiftoss/types';
4
4
  import Web3 from 'web3';
5
- import { BuyAssetBySellIdInput, Swapper } from '../../api';
5
+ import { ApprovalNeededInput, ApproveInfiniteInput, BuildTradeInput, BuyAssetBySellIdInput, ExecuteTradeInput, GetTradeQuoteInput, Swapper, Trade, TradeQuote } from '../../api';
6
6
  export declare type ZrxSwapperDeps = {
7
7
  adapterManager: ChainAdapterManager;
8
8
  web3: Web3;
@@ -17,9 +17,12 @@ export declare class ZrxSwapper implements Swapper {
17
17
  getType(): SwapperType;
18
18
  buildQuoteTx(args: BuildQuoteTxInput): Promise<Quote<ChainTypes>>;
19
19
  getQuote(input: GetQuoteInput): Promise<Quote<ChainTypes>>;
20
+ buildTrade(args: BuildTradeInput): Promise<Trade<ChainTypes>>;
21
+ getTradeQuote(input: GetTradeQuoteInput): Promise<TradeQuote<ChainTypes>>;
20
22
  getUsdRate(input: Pick<Asset, 'symbol' | 'tokenId'>): Promise<string>;
21
23
  getMinMax(input: GetQuoteInput): Promise<MinMaxOutput>;
22
24
  executeQuote(args: ExecQuoteInput<ChainTypes>): Promise<ExecQuoteOutput>;
25
+ executeTrade(args: ExecuteTradeInput<ChainTypes>): Promise<ExecQuoteOutput>;
23
26
  approvalNeeded(args: ApprovalNeededInput<ChainTypes>): Promise<ApprovalNeededOutput>;
24
27
  approveInfinite(args: ApproveInfiniteInput<ChainTypes>): Promise<string>;
25
28
  filterBuyAssetsBySellAssetId(args: BuyAssetBySellIdInput): CAIP19[];
@@ -4,11 +4,14 @@ exports.ZrxSwapper = exports.ZrxError = void 0;
4
4
  const types_1 = require("@shapeshiftoss/types");
5
5
  const getZrxMinMax_1 = require("./getZrxMinMax/getZrxMinMax");
6
6
  const getZrxQuote_1 = require("./getZrxQuote/getZrxQuote");
7
+ const getZrxTradeQuote_1 = require("./getZrxTradeQuote/getZrxTradeQuote");
7
8
  const helpers_1 = require("./utils/helpers/helpers");
8
9
  const ZrxApprovalNeeded_1 = require("./ZrxApprovalNeeded/ZrxApprovalNeeded");
9
10
  const ZrxApproveInfinite_1 = require("./ZrxApproveInfinite/ZrxApproveInfinite");
10
11
  const ZrxBuildQuoteTx_1 = require("./ZrxBuildQuoteTx/ZrxBuildQuoteTx");
12
+ const zrxBuildTrade_1 = require("./zrxBuildTrade/zrxBuildTrade");
11
13
  const ZrxExecuteQuote_1 = require("./ZrxExecuteQuote/ZrxExecuteQuote");
14
+ const zrxExecuteTrade_1 = require("./zrxExecuteTrade/zrxExecuteTrade");
12
15
  class ZrxError extends Error {
13
16
  constructor(message) {
14
17
  super(message);
@@ -29,6 +32,12 @@ class ZrxSwapper {
29
32
  async getQuote(input) {
30
33
  return (0, getZrxQuote_1.getZrxQuote)(input);
31
34
  }
35
+ async buildTrade(args) {
36
+ return (0, zrxBuildTrade_1.zrxBuildTrade)(this.deps, args);
37
+ }
38
+ async getTradeQuote(input) {
39
+ return (0, getZrxTradeQuote_1.getZrxTradeQuote)(input);
40
+ }
32
41
  async getUsdRate(input) {
33
42
  return (0, helpers_1.getUsdRate)(input);
34
43
  }
@@ -38,6 +47,9 @@ class ZrxSwapper {
38
47
  async executeQuote(args) {
39
48
  return (0, ZrxExecuteQuote_1.ZrxExecuteQuote)(this.deps, args);
40
49
  }
50
+ async executeTrade(args) {
51
+ return (0, zrxExecuteTrade_1.zrxExecuteTrade)(this.deps, args);
52
+ }
41
53
  async approvalNeeded(args) {
42
54
  return (0, ZrxApprovalNeeded_1.ZrxApprovalNeeded)(this.deps, args);
43
55
  }
@@ -1,11 +1,8 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.getZrxMinMax = void 0;
7
4
  const types_1 = require("@shapeshiftoss/types");
8
- const bignumber_js_1 = __importDefault(require("bignumber.js"));
5
+ const bignumber_1 = require("../utils/bignumber");
9
6
  const constants_1 = require("../utils/constants");
10
7
  const helpers_1 = require("../utils/helpers/helpers");
11
8
  const ZrxSwapper_1 = require("../ZrxSwapper");
@@ -18,7 +15,7 @@ const getZrxMinMax = async (input) => {
18
15
  symbol: sellAsset.symbol,
19
16
  tokenId: sellAsset.tokenId
20
17
  });
21
- const minimum = new bignumber_js_1.default(1).dividedBy(new bignumber_js_1.default(usdRate)).toString();
18
+ const minimum = (0, bignumber_1.bnOrZero)(1).dividedBy((0, bignumber_1.bnOrZero)(usdRate)).toString();
22
19
  return {
23
20
  minimum,
24
21
  maximum: constants_1.MAX_ZRX_TRADE // Arbitrarily large value. 10e+28 here.
@@ -1,11 +1,7 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.getZrxQuote = void 0;
7
4
  const types_1 = require("@shapeshiftoss/types");
8
- const bignumber_js_1 = __importDefault(require("bignumber.js"));
9
5
  const getZrxMinMax_1 = require("../getZrxMinMax/getZrxMinMax");
10
6
  const bignumber_1 = require("../utils/bignumber");
11
7
  const constants_1 = require("../utils/constants");
@@ -60,10 +56,8 @@ async function getZrxQuote(input) {
60
56
  }
61
57
  });
62
58
  const { data } = quoteResponse;
63
- const estimatedGas = data.estimatedGas
64
- ? new bignumber_js_1.default(data.estimatedGas).times(1.5)
65
- : new bignumber_js_1.default(0);
66
- const rate = useSellAmount ? data.price : new bignumber_js_1.default(1).div(data.price).toString();
59
+ const estimatedGas = (0, bignumber_1.bnOrZero)(data.estimatedGas).times(1.5);
60
+ const rate = useSellAmount ? data.price : (0, bignumber_1.bnOrZero)(1).div(data.price).toString();
67
61
  return {
68
62
  sellAsset,
69
63
  buyAsset,
@@ -72,14 +66,12 @@ async function getZrxQuote(input) {
72
66
  minimum: minQuoteSellAmount,
73
67
  maximum: maxSellAmount,
74
68
  feeData: {
75
- fee: new bignumber_js_1.default(estimatedGas || 0)
76
- .multipliedBy(new bignumber_js_1.default(data.gasPrice || 0))
77
- .toString(),
69
+ fee: (0, bignumber_1.bnOrZero)(estimatedGas).multipliedBy((0, bignumber_1.bnOrZero)(data.gasPrice)).toString(),
78
70
  chainSpecific: {
79
71
  estimatedGas: estimatedGas.toString(),
80
72
  gasPrice: data.gasPrice,
81
73
  approvalFee: sellAsset.tokenId &&
82
- new bignumber_js_1.default(constants_1.APPROVAL_GAS_LIMIT).multipliedBy(data.gasPrice || 0).toString()
74
+ (0, bignumber_1.bnOrZero)(constants_1.APPROVAL_GAS_LIMIT).multipliedBy((0, bignumber_1.bnOrZero)(data.gasPrice)).toString()
83
75
  }
84
76
  },
85
77
  sellAmount: data.sellAmount,
@@ -0,0 +1,3 @@
1
+ import { ChainTypes } from '@shapeshiftoss/types';
2
+ import { GetTradeQuoteInput, TradeQuote } from '../../../api';
3
+ export declare function getZrxTradeQuote(input: GetTradeQuoteInput): Promise<TradeQuote<ChainTypes.Ethereum>>;
@@ -0,0 +1,107 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getZrxTradeQuote = void 0;
4
+ const types_1 = require("@shapeshiftoss/types");
5
+ const getZrxMinMax_1 = require("../getZrxMinMax/getZrxMinMax");
6
+ const bignumber_1 = require("../utils/bignumber");
7
+ const constants_1 = require("../utils/constants");
8
+ const helpers_1 = require("../utils/helpers/helpers");
9
+ const zrxService_1 = require("../utils/zrxService");
10
+ const ZrxSwapper_1 = require("../ZrxSwapper");
11
+ async function getZrxTradeQuote(input) {
12
+ var _a, _b, _c, _d, _e, _f, _g;
13
+ const { sellAsset, buyAsset, sellAmount, buyAmount, sellAssetAccountId } = input;
14
+ if (!buyAsset) {
15
+ throw new ZrxSwapper_1.ZrxError('getQuote - Missing buyAsset');
16
+ }
17
+ if (!sellAsset) {
18
+ throw new ZrxSwapper_1.ZrxError('getQuote - Missing sellAsset');
19
+ }
20
+ if (buyAsset.chain !== types_1.ChainTypes.Ethereum || sellAsset.chain !== types_1.ChainTypes.Ethereum) {
21
+ throw new ZrxSwapper_1.ZrxError('getQuote - Both assets need to be on the Ethereum chain to use Zrx');
22
+ }
23
+ if (!sellAmount && !buyAmount) {
24
+ throw new ZrxSwapper_1.ZrxError('getQuote - sellAmount or buyAmount amount is required');
25
+ }
26
+ const useSellAmount = !!sellAmount;
27
+ const buyToken = buyAsset.tokenId || buyAsset.symbol;
28
+ const sellToken = sellAsset.tokenId || sellAsset.symbol;
29
+ const { minimum: minQuoteSellAmount, maximum: maxSellAmount } = await (0, getZrxMinMax_1.getZrxMinMax)(input);
30
+ const minQuoteSellAmountWei = (0, bignumber_1.bnOrZero)(minQuoteSellAmount).times((0, bignumber_1.bnOrZero)(10).exponentiatedBy(sellAsset.precision));
31
+ const amount = useSellAmount ? { sellAmount } : { buyAmount };
32
+ const amountKey = Object.keys(amount)[0];
33
+ const amountValue = Object.values(amount)[0];
34
+ let normalizedAmount = (0, helpers_1.normalizeAmount)(amountValue);
35
+ if (!normalizedAmount || normalizedAmount === '0') {
36
+ normalizedAmount = (0, helpers_1.normalizeAmount)(minQuoteSellAmountWei === null || minQuoteSellAmountWei === void 0 ? void 0 : minQuoteSellAmountWei.toString());
37
+ }
38
+ if (!normalizedAmount || normalizedAmount === '0') {
39
+ throw new ZrxSwapper_1.ZrxError('getQuote - Must have valid sellAmount, buyAmount or minimum amount');
40
+ }
41
+ try {
42
+ /**
43
+ * /swap/v1/price
44
+ * params: {
45
+ * sellToken: contract address (or symbol) of token to sell
46
+ * buyToken: contractAddress (or symbol) of token to buy
47
+ * sellAmount?: integer string value of the smallest increment of the sell token
48
+ * buyAmount?: integer string value of the smallest incremtent of the buy token
49
+ * }
50
+ */
51
+ const quoteResponse = await zrxService_1.zrxService.get('/swap/v1/price', {
52
+ params: {
53
+ sellToken,
54
+ buyToken,
55
+ [amountKey]: normalizedAmount
56
+ }
57
+ });
58
+ const { data } = quoteResponse;
59
+ const estimatedGas = (0, bignumber_1.bnOrZero)(data.estimatedGas).times(1.5);
60
+ const rate = useSellAmount ? data.price : (0, bignumber_1.bnOrZero)(1).div(data.price).toString();
61
+ return {
62
+ success: true,
63
+ statusReason: '',
64
+ rate,
65
+ minimum: minQuoteSellAmount,
66
+ maximum: maxSellAmount,
67
+ feeData: {
68
+ fee: (0, bignumber_1.bnOrZero)(estimatedGas).multipliedBy((0, bignumber_1.bnOrZero)(data.gasPrice)).toString(),
69
+ chainSpecific: {
70
+ estimatedGas: estimatedGas.toString(),
71
+ gasPrice: data.gasPrice,
72
+ approvalFee: sellAsset.tokenId &&
73
+ (0, bignumber_1.bnOrZero)(constants_1.APPROVAL_GAS_LIMIT).multipliedBy((0, bignumber_1.bnOrZero)(data.gasPrice)).toString()
74
+ }
75
+ },
76
+ sellAmount: data.sellAmount,
77
+ buyAmount: data.buyAmount,
78
+ sources: ((_a = data.sources) === null || _a === void 0 ? void 0 : _a.filter((s) => parseFloat(s.proportion) > 0)) || constants_1.DEFAULT_SOURCE,
79
+ allowanceContract: data.allowanceTarget,
80
+ buyAsset,
81
+ sellAsset,
82
+ sellAssetAccountId
83
+ };
84
+ }
85
+ catch (e) {
86
+ const statusReason = ((_e = (_d = (_c = (_b = e === null || e === void 0 ? void 0 : e.response) === null || _b === void 0 ? void 0 : _b.data) === null || _c === void 0 ? void 0 : _c.validationErrors) === null || _d === void 0 ? void 0 : _d[0]) === null || _e === void 0 ? void 0 : _e.reason) ||
87
+ ((_g = (_f = e === null || e === void 0 ? void 0 : e.response) === null || _f === void 0 ? void 0 : _f.data) === null || _g === void 0 ? void 0 : _g.reason) ||
88
+ 'Unknown Error';
89
+ // This hackyness will go away when we correctly handle errors
90
+ return {
91
+ success: false,
92
+ statusReason,
93
+ maximum: '0',
94
+ minimum: '0',
95
+ rate: '0',
96
+ feeData: { fee: '0', chainSpecific: {} },
97
+ buyAmount: '0',
98
+ sellAmount: '0',
99
+ sources: [],
100
+ allowanceContract: '0',
101
+ buyAsset,
102
+ sellAsset,
103
+ sellAssetAccountId
104
+ };
105
+ }
106
+ }
107
+ exports.getZrxTradeQuote = getZrxTradeQuote;
@@ -0,0 +1,17 @@
1
+ import { SwapSource } from '../../api';
2
+ export declare type ZrxCommonResponse = {
3
+ price: string;
4
+ gasPrice: string;
5
+ buyAmount: string;
6
+ sellAmount: string;
7
+ allowanceTarget: string;
8
+ sources: Array<SwapSource>;
9
+ };
10
+ export declare type ZrxPriceResponse = ZrxCommonResponse & {
11
+ estimatedGas: string;
12
+ };
13
+ export declare type ZrxQuoteResponse = ZrxCommonResponse & {
14
+ to: string;
15
+ data: string;
16
+ gas: string;
17
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -5,7 +5,10 @@ import BigNumber from 'bignumber.js';
5
5
  import Web3 from 'web3';
6
6
  import { AbiItem } from 'web3-utils';
7
7
  export declare type GetAllowanceRequiredArgs = {
8
- quote: Quote<ChainTypes>;
8
+ receiveAddress: string;
9
+ allowanceContract: string;
10
+ sellAsset: Asset;
11
+ sellAmount: string;
9
12
  web3: Web3;
10
13
  erc20AllowanceAbi: AbiItem[];
11
14
  };
@@ -33,7 +36,7 @@ declare type GrantAllowanceArgs = {
33
36
  */
34
37
  export declare const normalizeAmount: (amount: string | undefined) => string | undefined;
35
38
  export declare const getERC20Allowance: ({ erc20AllowanceAbi, web3, tokenId, ownerAddress, spenderAddress }: GetERC20AllowanceArgs) => Promise<any>;
36
- export declare const getAllowanceRequired: ({ quote, web3, erc20AllowanceAbi }: GetAllowanceRequiredArgs) => Promise<BigNumber>;
39
+ export declare const getAllowanceRequired: ({ receiveAddress, allowanceContract, sellAsset, sellAmount, web3, erc20AllowanceAbi }: GetAllowanceRequiredArgs) => Promise<BigNumber>;
37
40
  export declare const getUsdRate: (input: Pick<Asset, 'symbol' | 'tokenId'>) => Promise<string>;
38
41
  export declare const grantAllowance: ({ quote, wallet, adapter, erc20Abi, web3 }: GrantAllowanceArgs) => Promise<string>;
39
42
  export {};
@@ -1,13 +1,10 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.grantAllowance = exports.getUsdRate = exports.getAllowanceRequired = exports.getERC20Allowance = exports.normalizeAmount = void 0;
7
- const bignumber_js_1 = __importDefault(require("bignumber.js"));
8
4
  const web3_utils_1 = require("web3-utils");
9
5
  const api_1 = require("../../../../api");
10
6
  const ZrxSwapper_1 = require("../../ZrxSwapper");
7
+ const bignumber_1 = require("../bignumber");
11
8
  const zrxService_1 = require("../zrxService");
12
9
  /**
13
10
  * Very large amounts like those found in ERC20s with a precision of 18 get converted
@@ -20,7 +17,7 @@ const zrxService_1 = require("../zrxService");
20
17
  const normalizeAmount = (amount) => {
21
18
  if (!amount)
22
19
  return;
23
- return new bignumber_js_1.default(amount).toNumber().toLocaleString('fullwide', { useGrouping: false });
20
+ return (0, bignumber_1.bnOrZero)(amount).toNumber().toLocaleString('fullwide', { useGrouping: false });
24
21
  };
25
22
  exports.normalizeAmount = normalizeAmount;
26
23
  const getERC20Allowance = async ({ erc20AllowanceAbi, web3, tokenId, ownerAddress, spenderAddress }) => {
@@ -28,13 +25,13 @@ const getERC20Allowance = async ({ erc20AllowanceAbi, web3, tokenId, ownerAddres
28
25
  return erc20Contract.methods.allowance(ownerAddress, spenderAddress).call();
29
26
  };
30
27
  exports.getERC20Allowance = getERC20Allowance;
31
- const getAllowanceRequired = async ({ quote, web3, erc20AllowanceAbi }) => {
32
- if (quote.sellAsset.symbol === 'ETH') {
33
- return new bignumber_js_1.default(0);
28
+ const getAllowanceRequired = async ({ receiveAddress, allowanceContract, sellAsset, sellAmount, web3, erc20AllowanceAbi }) => {
29
+ if (sellAsset.symbol === 'ETH') {
30
+ return (0, bignumber_1.bnOrZero)(0);
34
31
  }
35
- const ownerAddress = quote.receiveAddress;
36
- const spenderAddress = quote.allowanceContract;
37
- const tokenId = quote.sellAsset.tokenId;
32
+ const ownerAddress = receiveAddress;
33
+ const spenderAddress = allowanceContract;
34
+ const tokenId = sellAsset.tokenId;
38
35
  if (!ownerAddress || !spenderAddress || !tokenId) {
39
36
  throw new api_1.SwapError('getAllowanceRequired - receiveAddress, allowanceContract and tokenId are required');
40
37
  }
@@ -46,13 +43,13 @@ const getAllowanceRequired = async ({ quote, web3, erc20AllowanceAbi }) => {
46
43
  tokenId
47
44
  });
48
45
  if (allowanceOnChain === '0') {
49
- return new bignumber_js_1.default(quote.sellAmount || 0);
46
+ return (0, bignumber_1.bnOrZero)(sellAmount);
50
47
  }
51
48
  if (!allowanceOnChain) {
52
- throw new api_1.SwapError(`No allowance data for ${quote.allowanceContract} to ${quote.receiveAddress}`);
49
+ throw new api_1.SwapError(`No allowance data for ${allowanceContract} to ${receiveAddress}`);
53
50
  }
54
- const allowanceRequired = new bignumber_js_1.default(quote.sellAmount || 0).minus(allowanceOnChain);
55
- return allowanceRequired.lt(0) ? new bignumber_js_1.default(0) : allowanceRequired;
51
+ const allowanceRequired = (0, bignumber_1.bnOrZero)(sellAmount).minus(allowanceOnChain);
52
+ return allowanceRequired.lt(0) ? (0, bignumber_1.bnOrZero)(0) : allowanceRequired;
56
53
  };
57
54
  exports.getAllowanceRequired = getAllowanceRequired;
58
55
  const getUsdRate = async (input) => {
@@ -66,10 +63,10 @@ const getUsdRate = async (input) => {
66
63
  sellToken: tokenId || symbol
67
64
  }
68
65
  });
69
- const price = new bignumber_js_1.default(rateResponse.data.price);
66
+ const price = (0, bignumber_1.bnOrZero)(rateResponse.data.price);
70
67
  if (!price.gt(0))
71
68
  throw new ZrxSwapper_1.ZrxError('getUsdRate - Failed to get price data');
72
- return new bignumber_js_1.default(1).dividedBy(price).toString();
69
+ return (0, bignumber_1.bnOrZero)(1).dividedBy(price).toString();
73
70
  };
74
71
  exports.getUsdRate = getUsdRate;
75
72
  const grantAllowance = async ({ quote, wallet, adapter, erc20Abi, web3 }) => {
@@ -1,4 +1,5 @@
1
1
  import { Asset } from '@shapeshiftoss/types';
2
+ import { ZrxQuoteResponse } from '../../types';
2
3
  export declare const setupQuote: () => {
3
4
  quoteInput: {
4
5
  sellAsset: Asset;
@@ -15,3 +16,8 @@ export declare const setupQuote: () => {
15
16
  buyAsset: Asset;
16
17
  sellAsset: Asset;
17
18
  };
19
+ export declare const setupZrxQuoteResponse: () => {
20
+ quoteResponse: ZrxQuoteResponse;
21
+ buyAsset: Asset;
22
+ sellAsset: Asset;
23
+ };
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.setupQuote = void 0;
3
+ exports.setupZrxQuoteResponse = exports.setupQuote = void 0;
4
4
  const constants_1 = require("../constants");
5
5
  const assets_1 = require("./assets");
6
6
  const setupQuote = () => {
@@ -21,3 +21,20 @@ const setupQuote = () => {
21
21
  return { quoteInput, buyAsset, sellAsset };
22
22
  };
23
23
  exports.setupQuote = setupQuote;
24
+ const setupZrxQuoteResponse = () => {
25
+ const sellAsset = { ...assets_1.FOX };
26
+ const buyAsset = { ...assets_1.WETH };
27
+ const quoteResponse = {
28
+ sellAmount: '1000000000000000000',
29
+ allowanceTarget: 'allowanceTargetAddress',
30
+ price: '1',
31
+ to: '0x123',
32
+ data: '0x1234',
33
+ gas: '1235',
34
+ gasPrice: '1236',
35
+ sources: [],
36
+ buyAmount: ''
37
+ };
38
+ return { quoteResponse, buyAsset, sellAsset };
39
+ };
40
+ exports.setupZrxQuoteResponse = setupZrxQuoteResponse;
@@ -0,0 +1,4 @@
1
+ import { ChainTypes } from '@shapeshiftoss/types';
2
+ import { BuildTradeInput, Trade } from '../../..';
3
+ import { ZrxSwapperDeps } from '../ZrxSwapper';
4
+ export declare function zrxBuildTrade({ adapterManager, web3 }: ZrxSwapperDeps, input: BuildTradeInput): Promise<Trade<ChainTypes>>;
@@ -0,0 +1,169 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.zrxBuildTrade = void 0;
27
+ const types_1 = require("@shapeshiftoss/types");
28
+ const rax = __importStar(require("retry-axios"));
29
+ const __1 = require("../../..");
30
+ const erc20Allowance_abi_1 = require("../utils/abi/erc20Allowance-abi");
31
+ const applyAxiosRetry_1 = require("../utils/applyAxiosRetry");
32
+ const bignumber_1 = require("../utils/bignumber");
33
+ const constants_1 = require("../utils/constants");
34
+ const helpers_1 = require("../utils/helpers/helpers");
35
+ const zrxService_1 = require("../utils/zrxService");
36
+ async function zrxBuildTrade({ adapterManager, web3 }, input) {
37
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
38
+ const { sellAsset, buyAsset, sellAmount, buyAmount, slippage, sellAssetAccountId, buyAssetAccountId, wallet } = input;
39
+ if ((buyAmount && sellAmount) || (!buyAmount && !sellAmount)) {
40
+ throw new __1.SwapError('ZrxSwapper:ZrxBuildTrade Exactly one of buyAmount or sellAmount is required');
41
+ }
42
+ if (!sellAssetAccountId || !buyAssetAccountId) {
43
+ throw new __1.SwapError('ZrxSwapper:ZrxBuildTrade Both sellAssetAccountId and buyAssetAccountId are required');
44
+ }
45
+ const buyToken = buyAsset.tokenId || buyAsset.symbol || buyAsset.network;
46
+ const sellToken = sellAsset.tokenId || sellAsset.symbol || sellAsset.network;
47
+ if (!buyToken) {
48
+ throw new __1.SwapError('ZrxSwapper:ZrxBuildTrade One of buyAssetContract or buyAssetSymbol or buyAssetNetwork are required');
49
+ }
50
+ if (!sellToken) {
51
+ throw new __1.SwapError('ZrxSwapper:ZrxBuildTrade One of sellAssetContract or sellAssetSymbol or sellAssetNetwork are required');
52
+ }
53
+ if (buyAsset.chain !== types_1.ChainTypes.Ethereum) {
54
+ throw new __1.SwapError(`ZrxSwapper:ZrxBuildTrade buyAsset must be on chain [${types_1.ChainTypes.Ethereum}]`);
55
+ }
56
+ const adapter = adapterManager.byChain(buyAsset.chain);
57
+ const bip44Params = adapter.buildBIP44Params({ accountNumber: Number(buyAssetAccountId) });
58
+ const receiveAddress = await adapter.getAddress({ wallet, bip44Params });
59
+ if ((0, bignumber_1.bnOrZero)(slippage).gt(constants_1.MAX_SLIPPAGE)) {
60
+ throw new __1.SwapError(`ZrxSwapper:ZrxBuildTrade slippage value of ${slippage} is greater than max slippage value of ${constants_1.MAX_SLIPPAGE}`);
61
+ }
62
+ const slippagePercentage = slippage ? (0, bignumber_1.bnOrZero)(slippage).div(100).toString() : constants_1.DEFAULT_SLIPPAGE;
63
+ try {
64
+ /**
65
+ * /swap/v1/quote
66
+ * params: {
67
+ * sellToken: contract address (or symbol) of token to sell
68
+ * buyToken: contractAddress (or symbol) of token to buy
69
+ * sellAmount?: integer string value of the smallest increment of the sell token
70
+ * buyAmount?: integer string value of the smallest incremtent of the buy token
71
+ * }
72
+ */
73
+ const zrxRetry = (0, applyAxiosRetry_1.applyAxiosRetry)(zrxService_1.zrxService, {
74
+ statusCodesToRetry: [[400, 400]],
75
+ shouldRetry: (err) => {
76
+ var _a, _b, _c, _d;
77
+ const cfg = rax.getConfig(err);
78
+ const retryAttempt = (_a = cfg === null || cfg === void 0 ? void 0 : cfg.currentRetryAttempt) !== null && _a !== void 0 ? _a : 0;
79
+ const retry = (_b = cfg === null || cfg === void 0 ? void 0 : cfg.retry) !== null && _b !== void 0 ? _b : 3;
80
+ // ensure max retries is always respected
81
+ if (retryAttempt >= retry)
82
+ return false;
83
+ // retry if 0x returns error code 111 Gas estimation failed
84
+ if (((_d = (_c = err === null || err === void 0 ? void 0 : err.response) === null || _c === void 0 ? void 0 : _c.data) === null || _d === void 0 ? void 0 : _d.code) === 111)
85
+ return true;
86
+ // Handle the request based on your other config options, e.g. `statusCodesToRetry`
87
+ return rax.shouldRetryRequest(err);
88
+ }
89
+ });
90
+ const quoteResponse = await zrxRetry.get('/swap/v1/quote', {
91
+ params: {
92
+ buyToken,
93
+ sellToken,
94
+ sellAmount: (0, helpers_1.normalizeAmount)(sellAmount === null || sellAmount === void 0 ? void 0 : sellAmount.toString()),
95
+ buyAmount: (0, helpers_1.normalizeAmount)(buyAmount === null || buyAmount === void 0 ? void 0 : buyAmount.toString()),
96
+ takerAddress: receiveAddress,
97
+ slippagePercentage,
98
+ skipValidation: false,
99
+ affiliateAddress: constants_1.AFFILIATE_ADDRESS
100
+ }
101
+ });
102
+ const { data } = quoteResponse;
103
+ const estimatedGas = (0, bignumber_1.bnOrZero)(data.gas || 0);
104
+ const trade = {
105
+ sellAsset,
106
+ buyAsset,
107
+ success: true,
108
+ statusReason: '',
109
+ sellAssetAccountId,
110
+ receiveAddress,
111
+ rate: data.price,
112
+ depositAddress: data.to,
113
+ feeData: {
114
+ fee: (0, bignumber_1.bnOrZero)(estimatedGas).multipliedBy((0, bignumber_1.bnOrZero)(data.gasPrice)).toString(),
115
+ chainSpecific: {
116
+ estimatedGas: estimatedGas.toString(),
117
+ gasPrice: data.gasPrice
118
+ }
119
+ },
120
+ txData: data.data,
121
+ sellAmount: data.sellAmount,
122
+ buyAmount: data.buyAmount,
123
+ allowanceContract: data.allowanceTarget,
124
+ sources: ((_a = data.sources) === null || _a === void 0 ? void 0 : _a.filter((s) => parseFloat(s.proportion) > 0)) || constants_1.DEFAULT_SOURCE
125
+ };
126
+ const allowanceRequired = await (0, helpers_1.getAllowanceRequired)({
127
+ sellAsset,
128
+ allowanceContract: data.allowanceTarget,
129
+ receiveAddress,
130
+ sellAmount: data.sellAmount,
131
+ web3,
132
+ erc20AllowanceAbi: erc20Allowance_abi_1.erc20AllowanceAbi
133
+ });
134
+ if (allowanceRequired) {
135
+ trade.feeData = {
136
+ fee: ((_b = trade.feeData) === null || _b === void 0 ? void 0 : _b.fee) || '0',
137
+ chainSpecific: {
138
+ ...(_c = trade.feeData) === null || _c === void 0 ? void 0 : _c.chainSpecific,
139
+ approvalFee: (0, bignumber_1.bnOrZero)(constants_1.APPROVAL_GAS_LIMIT).multipliedBy((0, bignumber_1.bnOrZero)(data.gasPrice)).toString()
140
+ }
141
+ };
142
+ }
143
+ return trade;
144
+ }
145
+ catch (e) {
146
+ // eslint-disable-next-line no-console
147
+ const statusReason = ((_g = (_f = (_e = (_d = e === null || e === void 0 ? void 0 : e.response) === null || _d === void 0 ? void 0 : _d.data) === null || _e === void 0 ? void 0 : _e.validationErrors) === null || _f === void 0 ? void 0 : _f[0]) === null || _g === void 0 ? void 0 : _g.reason) ||
148
+ ((_j = (_h = e === null || e === void 0 ? void 0 : e.response) === null || _h === void 0 ? void 0 : _h.data) === null || _j === void 0 ? void 0 : _j.reason) ||
149
+ 'Unknown Error';
150
+ // This hackyness will go away when we correctly handle errors
151
+ return {
152
+ sellAsset,
153
+ buyAsset,
154
+ success: false,
155
+ statusReason,
156
+ sellAmount: '0',
157
+ buyAmount: '0',
158
+ depositAddress: '',
159
+ allowanceContract: '',
160
+ receiveAddress: '',
161
+ sellAssetAccountId,
162
+ txData: '',
163
+ rate: '0',
164
+ feeData: { fee: '0', chainSpecific: {} },
165
+ sources: []
166
+ };
167
+ }
168
+ }
169
+ exports.zrxBuildTrade = zrxBuildTrade;
@@ -0,0 +1,4 @@
1
+ import { ChainTypes } from '@shapeshiftoss/types';
2
+ import { ExecuteTradeInput, TradeResult } from '../../../api';
3
+ import { ZrxSwapperDeps } from '../ZrxSwapper';
4
+ export declare function zrxExecuteTrade({ adapterManager }: ZrxSwapperDeps, { trade, wallet }: ExecuteTradeInput<ChainTypes.Ethereum>): Promise<TradeResult>;
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.zrxExecuteTrade = void 0;
4
+ const web3_utils_1 = require("web3-utils");
5
+ const api_1 = require("../../../api");
6
+ async function zrxExecuteTrade({ adapterManager }, { trade, wallet }) {
7
+ var _a, _b, _c, _d, _e, _f;
8
+ const { sellAsset } = trade;
9
+ if (!sellAsset.symbol) {
10
+ throw new api_1.SwapError('ZrxSwapper:ZrxExecuteTrade sellAssetSymbol is required');
11
+ }
12
+ if (!trade.sellAssetAccountId) {
13
+ throw new api_1.SwapError('ZrxSwapper:ZrxExecuteTrade sellAssetAccountId is required');
14
+ }
15
+ if (!trade.sellAmount) {
16
+ throw new api_1.SwapError('ZrxSwapper:ZrxExecuteTrade sellAmount is required');
17
+ }
18
+ if (!trade.depositAddress) {
19
+ throw new api_1.SwapError('ZrxSwapper:ZrxExecuteTrade depositAddress is required');
20
+ }
21
+ // value is 0 for erc20s
22
+ const value = sellAsset.symbol === 'ETH' ? trade.sellAmount : '0';
23
+ const adapter = adapterManager.byChain(sellAsset.chain);
24
+ const bip44Params = adapter.buildBIP44Params({
25
+ accountNumber: Number(trade.sellAssetAccountId)
26
+ });
27
+ let buildTxResponse, signedTx, txid;
28
+ try {
29
+ buildTxResponse = await adapter.buildSendTransaction({
30
+ value,
31
+ wallet,
32
+ to: trade.depositAddress,
33
+ chainSpecific: {
34
+ gasPrice: (0, web3_utils_1.numberToHex)(((_b = (_a = trade.feeData) === null || _a === void 0 ? void 0 : _a.chainSpecific) === null || _b === void 0 ? void 0 : _b.gasPrice) || 0),
35
+ gasLimit: (0, web3_utils_1.numberToHex)(((_d = (_c = trade.feeData) === null || _c === void 0 ? void 0 : _c.chainSpecific) === null || _d === void 0 ? void 0 : _d.estimatedGas) || 0)
36
+ },
37
+ bip44Params
38
+ });
39
+ }
40
+ catch (error) {
41
+ throw new api_1.SwapError(`ZrxExecuteTrade - buildSendTransaction error: ${error}`);
42
+ }
43
+ const { txToSign } = buildTxResponse;
44
+ const txWithQuoteData = { ...txToSign, data: (_e = trade.txData) !== null && _e !== void 0 ? _e : '' };
45
+ if (wallet.supportsOfflineSigning()) {
46
+ try {
47
+ signedTx = await adapter.signTransaction({ txToSign: txWithQuoteData, wallet });
48
+ }
49
+ catch (error) {
50
+ throw new api_1.SwapError(`ZrxExecuteTrade - signTransaction error: ${error}`);
51
+ }
52
+ if (!signedTx) {
53
+ throw new api_1.SwapError(`ZrxExecuteTrade - Signed transaction is required: ${signedTx}`);
54
+ }
55
+ try {
56
+ txid = await adapter.broadcastTransaction(signedTx);
57
+ }
58
+ catch (error) {
59
+ throw new api_1.SwapError(`ZrxExecuteTrade - broadcastTransaction error: ${error}`);
60
+ }
61
+ return { txid };
62
+ }
63
+ else if (wallet.supportsBroadcast() && adapter.signAndBroadcastTransaction) {
64
+ try {
65
+ txid = await ((_f = adapter.signAndBroadcastTransaction) === null || _f === void 0 ? void 0 : _f.call(adapter, { txToSign: txWithQuoteData, wallet }));
66
+ }
67
+ catch (error) {
68
+ throw new api_1.SwapError(`ZrxExecuteTrade - signAndBroadcastTransaction error: ${error}`);
69
+ }
70
+ return { txid };
71
+ }
72
+ else {
73
+ throw new api_1.SwapError('ZrxExecuteTrade - invalid HDWallet config');
74
+ }
75
+ }
76
+ exports.zrxExecuteTrade = zrxExecuteTrade;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shapeshiftoss/swapper",
3
- "version": "3.0.5",
3
+ "version": "3.0.6",
4
4
  "description": "TODO: description",
5
5
  "repository": "https://github.com/shapeshift/lib",
6
6
  "license": "MIT",