@shapeshiftoss/swapper 9.0.1 → 9.2.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.
- package/dist/api.d.ts +0 -1
- package/dist/swappercli.js +0 -1
- package/dist/swappers/cow/types.d.ts +0 -4
- package/dist/swappers/cow/utils/constants.d.ts +2 -1
- package/dist/swappers/cow/utils/constants.js +3 -2
- package/dist/swappers/cow/utils/helpers/helpers.d.ts +8 -3
- package/dist/swappers/cow/utils/helpers/helpers.js +43 -17
- package/dist/swappers/thorchain/ThorchainSwapper.d.ts +3 -3
- package/dist/swappers/thorchain/ThorchainSwapper.js +47 -19
- package/dist/swappers/thorchain/buildThorTrade/buildThorTrade.d.ts +7 -0
- package/dist/swappers/thorchain/buildThorTrade/buildThorTrade.js +95 -0
- package/dist/swappers/thorchain/getThorTradeQuote/getTradeQuote.js +19 -24
- package/dist/swappers/thorchain/thorTradeApprovalNeeded/thorTradeApprovalNeeded.js +2 -6
- package/dist/swappers/thorchain/utils/bitcoin/utils/getThorTxData.d.ts +1 -0
- package/dist/swappers/thorchain/utils/bitcoin/utils/getThorTxData.js +10 -10
- package/dist/swappers/thorchain/utils/constants.d.ts +5 -0
- package/dist/swappers/thorchain/utils/constants.js +8 -1
- package/dist/swappers/thorchain/utils/estimateTradeFee/estimateTradeFee.d.ts +2 -2
- package/dist/swappers/thorchain/utils/estimateTradeFee/estimateTradeFee.js +28 -19
- package/dist/swappers/thorchain/utils/ethereum/makeTradeTx.d.ts +2 -1
- package/dist/swappers/thorchain/utils/ethereum/makeTradeTx.js +5 -3
- package/dist/swappers/thorchain/utils/ethereum/utils/getThorTxData.d.ts +1 -0
- package/dist/swappers/thorchain/utils/ethereum/utils/getThorTxData.js +10 -10
- package/dist/swappers/thorchain/utils/getTradeRate/getTradeRate.js +8 -0
- package/dist/swappers/thorchain/utils/test-data/setupThorswapDeps.js +19 -1
- package/dist/swappers/thorchain/utils/txFeeHelpers/btcTxFees/getBtcTxFees.d.ts +2 -5
- package/dist/swappers/thorchain/utils/txFeeHelpers/btcTxFees/getBtcTxFees.js +1 -3
- package/dist/swappers/thorchain/utils/txFeeHelpers/ethTxFees/getEthTxFees.d.ts +3 -10
- package/dist/swappers/thorchain/utils/txFeeHelpers/ethTxFees/getEthTxFees.js +14 -26
- package/dist/swappers/utils/test-data/setupSwapQuote.d.ts +0 -1
- package/dist/swappers/utils/test-data/setupSwapQuote.js +0 -1
- package/dist/swappers/zrx/utils/test-data/setupZrxSwapQuote.d.ts +0 -1
- package/dist/swappers/zrx/utils/test-data/setupZrxSwapQuote.js +0 -1
- package/dist/swappers/zrx/zrxBuildTrade/zrxBuildTrade.js +1 -3
- package/package.json +1 -1
package/dist/api.d.ts
CHANGED
|
@@ -85,7 +85,6 @@ declare type GetBtcTradeQuoteInput = CommonTradeInput & {
|
|
|
85
85
|
};
|
|
86
86
|
export declare type GetTradeQuoteInput = GetBtcTradeQuoteInput | GetEvmTradeQuoteInput | GetCosmosSdkTradeQuoteInput;
|
|
87
87
|
export declare type BuildTradeInput = GetTradeQuoteInput & {
|
|
88
|
-
buyAssetAccountNumber: number;
|
|
89
88
|
slippage?: string;
|
|
90
89
|
wallet: HDWallet;
|
|
91
90
|
};
|
package/dist/swappercli.js
CHANGED
|
@@ -137,7 +137,6 @@ const main = async () => {
|
|
|
137
137
|
sellAmount: sellAmountBase,
|
|
138
138
|
sellAsset,
|
|
139
139
|
sellAssetAccountNumber: 0,
|
|
140
|
-
buyAssetAccountNumber: 0,
|
|
141
140
|
receiveAddress: '0xc770eefad204b5180df6a14ee197d99d808ee52d'
|
|
142
141
|
});
|
|
143
142
|
const txid = await swapper.executeTrade({ trade, wallet });
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export declare const MAX_ALLOWANCE = "100000000000000000000000000";
|
|
2
2
|
export declare const MAX_COWSWAP_TRADE = "100000000000000000000000000";
|
|
3
|
-
export declare const MIN_COWSWAP_VALUE_USD =
|
|
3
|
+
export declare const MIN_COWSWAP_VALUE_USD = 20;
|
|
4
4
|
export declare const DEFAULT_SOURCE: {
|
|
5
5
|
name: string;
|
|
6
6
|
proportion: string;
|
|
@@ -11,6 +11,7 @@ export declare const COW_SWAP_VAULT_RELAYER_ADDRESS = "0xc92e8bdf79f0507f65a392b
|
|
|
11
11
|
export declare const COW_SWAP_SETTLEMENT_ADDRESS = "0x9008D19f58AAbD9eD0D60971565AA8510560ab41";
|
|
12
12
|
export declare const WETH_ASSET_ID = "eip155:1/erc20:0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2";
|
|
13
13
|
export declare const ORDER_KIND_SELL = "sell";
|
|
14
|
+
export declare const ORDER_KIND_BUY = "buy";
|
|
14
15
|
export declare const SIGNING_SCHEME = "ethsign";
|
|
15
16
|
export declare const ERC20_TOKEN_BALANCE = "erc20";
|
|
16
17
|
export declare const ORDER_STATUS_FULFILLED = "fulfilled";
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ORDER_STATUS_FULFILLED = exports.ERC20_TOKEN_BALANCE = exports.SIGNING_SCHEME = exports.ORDER_KIND_SELL = exports.WETH_ASSET_ID = exports.COW_SWAP_SETTLEMENT_ADDRESS = exports.COW_SWAP_VAULT_RELAYER_ADDRESS = exports.DEFAULT_APP_DATA = exports.DEFAULT_ADDRESS = exports.DEFAULT_SOURCE = exports.MIN_COWSWAP_VALUE_USD = exports.MAX_COWSWAP_TRADE = exports.MAX_ALLOWANCE = void 0;
|
|
3
|
+
exports.ORDER_STATUS_FULFILLED = exports.ERC20_TOKEN_BALANCE = exports.SIGNING_SCHEME = exports.ORDER_KIND_BUY = exports.ORDER_KIND_SELL = exports.WETH_ASSET_ID = exports.COW_SWAP_SETTLEMENT_ADDRESS = exports.COW_SWAP_VAULT_RELAYER_ADDRESS = exports.DEFAULT_APP_DATA = exports.DEFAULT_ADDRESS = exports.DEFAULT_SOURCE = exports.MIN_COWSWAP_VALUE_USD = exports.MAX_COWSWAP_TRADE = exports.MAX_ALLOWANCE = void 0;
|
|
4
4
|
const constants_1 = require("@ethersproject/constants");
|
|
5
5
|
exports.MAX_ALLOWANCE = '100000000000000000000000000';
|
|
6
6
|
exports.MAX_COWSWAP_TRADE = '100000000000000000000000000';
|
|
7
|
-
exports.MIN_COWSWAP_VALUE_USD =
|
|
7
|
+
exports.MIN_COWSWAP_VALUE_USD = 20;
|
|
8
8
|
exports.DEFAULT_SOURCE = [{ name: 'CowSwap', proportion: '1' }];
|
|
9
9
|
exports.DEFAULT_ADDRESS = constants_1.AddressZero;
|
|
10
10
|
exports.DEFAULT_APP_DATA = constants_1.HashZero;
|
|
@@ -12,6 +12,7 @@ exports.COW_SWAP_VAULT_RELAYER_ADDRESS = '0xc92e8bdf79f0507f65a392b0ab4667716bfe
|
|
|
12
12
|
exports.COW_SWAP_SETTLEMENT_ADDRESS = '0x9008D19f58AAbD9eD0D60971565AA8510560ab41';
|
|
13
13
|
exports.WETH_ASSET_ID = 'eip155:1/erc20:0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2';
|
|
14
14
|
exports.ORDER_KIND_SELL = 'sell';
|
|
15
|
+
exports.ORDER_KIND_BUY = 'buy';
|
|
15
16
|
exports.SIGNING_SCHEME = 'ethsign';
|
|
16
17
|
exports.ERC20_TOKEN_BALANCE = 'erc20';
|
|
17
18
|
exports.ORDER_STATUS_FULFILLED = 'fulfilled';
|
|
@@ -23,19 +23,24 @@ export declare type CowSwapOrder = {
|
|
|
23
23
|
sellTokenBalance: string;
|
|
24
24
|
buyTokenBalance: string;
|
|
25
25
|
};
|
|
26
|
-
export declare type
|
|
26
|
+
export declare type CowSwapQuoteApiInputBase = {
|
|
27
27
|
appData: string;
|
|
28
28
|
buyToken: string;
|
|
29
29
|
from: string;
|
|
30
30
|
kind: string;
|
|
31
31
|
partiallyFillable: boolean;
|
|
32
32
|
receiver: string;
|
|
33
|
-
sellAmountBeforeFee: string;
|
|
34
33
|
sellToken: string;
|
|
35
34
|
validTo: number;
|
|
36
35
|
};
|
|
37
|
-
export declare
|
|
36
|
+
export declare type CowSwapSellQuoteApiInput = CowSwapQuoteApiInputBase & {
|
|
37
|
+
sellAmountBeforeFee: string;
|
|
38
|
+
};
|
|
39
|
+
export declare type CowSwapBuyQuoteApiInput = CowSwapQuoteApiInputBase & {
|
|
40
|
+
buyAmountAfterFee: string;
|
|
41
|
+
};
|
|
38
42
|
export declare const getNowPlusThirtyMinutesTimestamp: () => number;
|
|
43
|
+
export declare const getUsdRate: ({ apiUrl }: CowSwapperDeps, input: Asset) => Promise<string>;
|
|
39
44
|
export declare const hashTypedData: (domain: TypedDataDomain, types: TypedDataTypes, data: Record<string, unknown>) => string;
|
|
40
45
|
/**
|
|
41
46
|
* Compute the 32-byte signing hash for the specified order.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.domain = exports.hashOrder = exports.hashTypedData = exports.
|
|
3
|
+
exports.domain = exports.hashOrder = exports.hashTypedData = exports.getUsdRate = exports.getNowPlusThirtyMinutesTimestamp = exports.ORDER_TYPE_FIELDS = void 0;
|
|
4
4
|
const asset_service_1 = require("@shapeshiftoss/asset-service");
|
|
5
5
|
const caip_1 = require("@shapeshiftoss/caip");
|
|
6
6
|
const ethers_1 = require("ethers");
|
|
@@ -24,6 +24,12 @@ exports.ORDER_TYPE_FIELDS = [
|
|
|
24
24
|
{ name: 'sellTokenBalance', type: 'string' },
|
|
25
25
|
{ name: 'buyTokenBalance', type: 'string' }
|
|
26
26
|
];
|
|
27
|
+
const getNowPlusThirtyMinutesTimestamp = () => {
|
|
28
|
+
const ts = new Date();
|
|
29
|
+
ts.setMinutes(ts.getMinutes() + 30);
|
|
30
|
+
return Math.round(ts.getTime() / 1000);
|
|
31
|
+
};
|
|
32
|
+
exports.getNowPlusThirtyMinutesTimestamp = getNowPlusThirtyMinutesTimestamp;
|
|
27
33
|
const getUsdRate = async ({ apiUrl }, input) => {
|
|
28
34
|
// Replacing ETH by WETH specifically for CowSwap in order to get an usd rate when called with ETH as feeAsset
|
|
29
35
|
const asset = input.assetId !== caip_1.ethAssetId ? input : new asset_service_1.AssetService().getAll()[constants_1.WETH_ASSET_ID];
|
|
@@ -37,20 +43,46 @@ const getUsdRate = async ({ apiUrl }, input) => {
|
|
|
37
43
|
if (erc20Address === USDC_CONTRACT_ADDRESS) {
|
|
38
44
|
return '1';
|
|
39
45
|
}
|
|
46
|
+
// rate is imprecise for low $ values, hence asking for $1000
|
|
40
47
|
const buyAmountInDollars = 1000;
|
|
41
|
-
const buyAmount = (0, bignumber_1.bn)(buyAmountInDollars)
|
|
48
|
+
const buyAmount = (0, bignumber_1.bn)(buyAmountInDollars)
|
|
49
|
+
.times((0, bignumber_1.bn)(10).exponentiatedBy(USDC_ASSET_PRECISION))
|
|
50
|
+
.toString();
|
|
42
51
|
try {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
52
|
+
const apiInput = {
|
|
53
|
+
sellToken: erc20Address,
|
|
54
|
+
buyToken: USDC_CONTRACT_ADDRESS,
|
|
55
|
+
receiver: constants_1.DEFAULT_ADDRESS,
|
|
56
|
+
validTo: (0, exports.getNowPlusThirtyMinutesTimestamp)(),
|
|
57
|
+
appData: constants_1.DEFAULT_APP_DATA,
|
|
58
|
+
partiallyFillable: false,
|
|
59
|
+
from: constants_1.DEFAULT_ADDRESS,
|
|
60
|
+
kind: constants_1.ORDER_KIND_BUY,
|
|
61
|
+
buyAmountAfterFee: buyAmount
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* /v1/quote
|
|
65
|
+
* params: {
|
|
66
|
+
* sellToken: contract address of token to sell
|
|
67
|
+
* buyToken: contractAddress of token to buy
|
|
68
|
+
* receiver: receiver address can be defaulted to "0x0000000000000000000000000000000000000000"
|
|
69
|
+
* validTo: time duration during which quote is valid (eg : 1654851610 as timestamp)
|
|
70
|
+
* appData: appData for the CowSwap quote that can be used later, can be defaulted to "0x0000000000000000000000000000000000000000000000000000000000000000"
|
|
71
|
+
* partiallyFillable: false
|
|
72
|
+
* from: sender address can be defaulted to "0x0000000000000000000000000000000000000000"
|
|
73
|
+
* kind: "sell" or "buy"
|
|
74
|
+
* sellAmountBeforeFee / buyAmountAfterFee: amount in base unit
|
|
75
|
+
* }
|
|
76
|
+
*/
|
|
77
|
+
const quoteResponse = await cowService_1.cowService.post(`${apiUrl}/v1/quote/`, apiInput);
|
|
78
|
+
const { data: { quote } } = quoteResponse;
|
|
79
|
+
const sellCryptoAmount = (0, bignumber_1.bn)(quote.sellAmount).div((0, bignumber_1.bn)(10).exponentiatedBy(asset.precision));
|
|
80
|
+
if (!sellCryptoAmount.gt(0))
|
|
81
|
+
throw new api_1.SwapError('[getUsdRate] - Failed to get sell token amount', {
|
|
50
82
|
code: api_1.SwapErrorTypes.RESPONSE_ERROR
|
|
51
83
|
});
|
|
52
|
-
// dividing $1000 by amount of token received
|
|
53
|
-
return (0, bignumber_1.bn)(buyAmountInDollars).
|
|
84
|
+
// dividing $1000 by amount of sell token received
|
|
85
|
+
return (0, bignumber_1.bn)(buyAmountInDollars).div(sellCryptoAmount).toString();
|
|
54
86
|
}
|
|
55
87
|
catch (e) {
|
|
56
88
|
if (e instanceof api_1.SwapError)
|
|
@@ -62,12 +94,6 @@ const getUsdRate = async ({ apiUrl }, input) => {
|
|
|
62
94
|
}
|
|
63
95
|
};
|
|
64
96
|
exports.getUsdRate = getUsdRate;
|
|
65
|
-
const getNowPlusThirtyMinutesTimestamp = () => {
|
|
66
|
-
const ts = new Date();
|
|
67
|
-
ts.setMinutes(ts.getMinutes() + 30);
|
|
68
|
-
return Math.round(ts.getTime() / 1000);
|
|
69
|
-
};
|
|
70
|
-
exports.getNowPlusThirtyMinutesTimestamp = getNowPlusThirtyMinutesTimestamp;
|
|
71
97
|
const hashTypedData = (domain, types, data) => {
|
|
72
98
|
return ethers_1.ethers.utils._TypedDataEncoder.hash(domain, types, data);
|
|
73
99
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Asset } from '@shapeshiftoss/asset-service';
|
|
2
2
|
import { AssetId, ChainId } from '@shapeshiftoss/caip';
|
|
3
3
|
import { KnownChainIds } from '@shapeshiftoss/types';
|
|
4
|
-
import { ApprovalNeededInput, ApprovalNeededOutput, ApproveInfiniteInput, BuyAssetBySellIdInput, ExecuteTradeInput, GetTradeQuoteInput, Swapper, SwapperType, Trade, TradeQuote, TradeResult, TradeTxs } from '../../api';
|
|
4
|
+
import { ApprovalNeededInput, ApprovalNeededOutput, ApproveInfiniteInput, BuildTradeInput, BuyAssetBySellIdInput, ExecuteTradeInput, GetTradeQuoteInput, Swapper, SwapperType, Trade, TradeQuote, TradeResult, TradeTxs } from '../../api';
|
|
5
5
|
import { ThorchainSwapperDeps } from './types';
|
|
6
6
|
export declare class ThorchainSwapper implements Swapper<ChainId> {
|
|
7
7
|
readonly name = "Thorchain";
|
|
@@ -16,8 +16,8 @@ export declare class ThorchainSwapper implements Swapper<ChainId> {
|
|
|
16
16
|
approveInfinite(input: ApproveInfiniteInput<KnownChainIds.EthereumMainnet>): Promise<string>;
|
|
17
17
|
filterBuyAssetsBySellAssetId(args: BuyAssetBySellIdInput): AssetId[];
|
|
18
18
|
filterAssetIdsBySellable(): AssetId[];
|
|
19
|
-
buildTrade(): Promise<Trade<ChainId>>;
|
|
19
|
+
buildTrade(input: BuildTradeInput): Promise<Trade<ChainId>>;
|
|
20
20
|
getTradeQuote(input: GetTradeQuoteInput): Promise<TradeQuote<ChainId>>;
|
|
21
21
|
executeTrade(args: ExecuteTradeInput<ChainId>): Promise<TradeResult>;
|
|
22
|
-
getTradeTxs(): Promise<TradeTxs>;
|
|
22
|
+
getTradeTxs(tradeResult: TradeResult): Promise<TradeTxs>;
|
|
23
23
|
}
|
|
@@ -4,6 +4,7 @@ exports.ThorchainSwapper = void 0;
|
|
|
4
4
|
const caip_1 = require("@shapeshiftoss/caip");
|
|
5
5
|
const types_1 = require("@shapeshiftoss/types");
|
|
6
6
|
const api_1 = require("../../api");
|
|
7
|
+
const buildThorTrade_1 = require("./buildThorTrade/buildThorTrade");
|
|
7
8
|
const getTradeQuote_1 = require("./getThorTradeQuote/getTradeQuote");
|
|
8
9
|
const thorTradeApprovalNeeded_1 = require("./thorTradeApprovalNeeded/thorTradeApprovalNeeded");
|
|
9
10
|
const thorTradeApproveInfinite_1 = require("./thorTradeApproveInfinite/thorTradeApproveInfinite");
|
|
@@ -13,8 +14,8 @@ class ThorchainSwapper {
|
|
|
13
14
|
constructor(deps) {
|
|
14
15
|
this.name = 'Thorchain';
|
|
15
16
|
this.swapSupportedChainIds = {
|
|
16
|
-
|
|
17
|
-
|
|
17
|
+
[types_1.KnownChainIds.EthereumMainnet]: true,
|
|
18
|
+
[types_1.KnownChainIds.BitcoinMainnet]: true
|
|
18
19
|
};
|
|
19
20
|
this.supportedAssetIds = [];
|
|
20
21
|
this.deps = deps;
|
|
@@ -59,33 +60,60 @@ class ThorchainSwapper {
|
|
|
59
60
|
filterAssetIdsBySellable() {
|
|
60
61
|
return this.supportedAssetIds;
|
|
61
62
|
}
|
|
62
|
-
async buildTrade() {
|
|
63
|
-
|
|
63
|
+
async buildTrade(input) {
|
|
64
|
+
return (0, buildThorTrade_1.buildTrade)({ deps: this.deps, input });
|
|
64
65
|
}
|
|
65
66
|
async getTradeQuote(input) {
|
|
66
67
|
return (0, getTradeQuote_1.getThorTradeQuote)({ deps: this.deps, input });
|
|
67
68
|
}
|
|
68
69
|
async executeTrade(args) {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
70
|
+
try {
|
|
71
|
+
const { trade, wallet } = args;
|
|
72
|
+
const adapter = this.deps.adapterManager.get(trade.sellAsset.chainId);
|
|
73
|
+
if (!adapter)
|
|
74
|
+
throw new api_1.SwapError('[executeTrade]: no adapter for sell asset chain id', {
|
|
75
|
+
code: api_1.SwapErrorTypes.SIGN_AND_BROADCAST_FAILED,
|
|
76
|
+
details: { chainId: trade.sellAsset.chainId },
|
|
77
|
+
fn: 'executeTrade'
|
|
78
|
+
});
|
|
79
|
+
if (trade.sellAsset.chainId === types_1.KnownChainIds.EthereumMainnet) {
|
|
80
|
+
const signedTx = await adapter.signTransaction({
|
|
81
|
+
txToSign: trade.txData,
|
|
82
|
+
wallet
|
|
83
|
+
});
|
|
84
|
+
const txid = await adapter.broadcastTransaction(signedTx);
|
|
85
|
+
return { tradeId: txid };
|
|
86
|
+
}
|
|
87
|
+
else if (trade.sellAsset.chainId === types_1.KnownChainIds.BitcoinMainnet) {
|
|
88
|
+
const signedTx = await adapter.signTransaction({
|
|
89
|
+
txToSign: trade.txData,
|
|
90
|
+
wallet
|
|
91
|
+
});
|
|
92
|
+
const txid = await adapter.broadcastTransaction(signedTx);
|
|
93
|
+
return { tradeId: txid };
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
throw new api_1.SwapError('[executeTrade]: unsupported trade', {
|
|
97
|
+
code: api_1.SwapErrorTypes.SIGN_AND_BROADCAST_FAILED,
|
|
98
|
+
fn: 'executeTrade'
|
|
99
|
+
});
|
|
100
|
+
}
|
|
79
101
|
}
|
|
80
|
-
|
|
81
|
-
|
|
102
|
+
catch (e) {
|
|
103
|
+
if (e instanceof api_1.SwapError)
|
|
104
|
+
throw e;
|
|
105
|
+
throw new api_1.SwapError('[executeTrade]: failed to sign or broadcast', {
|
|
82
106
|
code: api_1.SwapErrorTypes.SIGN_AND_BROADCAST_FAILED,
|
|
83
|
-
|
|
107
|
+
cause: e
|
|
84
108
|
});
|
|
85
109
|
}
|
|
86
110
|
}
|
|
87
|
-
async getTradeTxs() {
|
|
88
|
-
|
|
111
|
+
async getTradeTxs(tradeResult) {
|
|
112
|
+
// TODO poll midgard for the correct buyTxid
|
|
113
|
+
return {
|
|
114
|
+
sellTxid: tradeResult.tradeId,
|
|
115
|
+
buyTxid: tradeResult.tradeId
|
|
116
|
+
};
|
|
89
117
|
}
|
|
90
118
|
}
|
|
91
119
|
exports.ThorchainSwapper = ThorchainSwapper;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ChainId } from '@shapeshiftoss/caip';
|
|
2
|
+
import { BuildTradeInput } from '../../../api';
|
|
3
|
+
import { ThorchainSwapperDeps, ThorTrade } from '../types';
|
|
4
|
+
export declare const buildTrade: ({ deps, input }: {
|
|
5
|
+
deps: ThorchainSwapperDeps;
|
|
6
|
+
input: BuildTradeInput;
|
|
7
|
+
}) => Promise<ThorTrade<ChainId>>;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildTrade = void 0;
|
|
4
|
+
const types_1 = require("@shapeshiftoss/types");
|
|
5
|
+
const api_1 = require("../../../api");
|
|
6
|
+
const constants_1 = require("../../utils/constants");
|
|
7
|
+
const getTradeQuote_1 = require("../getThorTradeQuote/getTradeQuote");
|
|
8
|
+
const getThorTxData_1 = require("../utils/bitcoin/utils/getThorTxData");
|
|
9
|
+
const makeTradeTx_1 = require("../utils/ethereum/makeTradeTx");
|
|
10
|
+
const buildTrade = async ({ deps, input }) => {
|
|
11
|
+
var _a, _b, _c, _d;
|
|
12
|
+
try {
|
|
13
|
+
const { buyAsset, sellAsset, sellAssetAccountNumber, sellAmount, wallet, slippage: slippageTolerance = constants_1.DEFAULT_SLIPPAGE, receiveAddress: destinationAddress } = input;
|
|
14
|
+
const quote = await (0, getTradeQuote_1.getThorTradeQuote)({ deps, input });
|
|
15
|
+
const sellAdapter = deps.adapterManager.get(sellAsset.chainId);
|
|
16
|
+
if (!sellAdapter)
|
|
17
|
+
throw new api_1.SwapError('[buildTrade]: unsupported sell asset', {
|
|
18
|
+
code: api_1.SwapErrorTypes.BUILD_TRADE_FAILED,
|
|
19
|
+
fn: 'buildTrade',
|
|
20
|
+
details: { sellAsset }
|
|
21
|
+
});
|
|
22
|
+
const sellAssetBip44Params = sellAdapter.buildBIP44Params({
|
|
23
|
+
accountNumber: sellAssetAccountNumber
|
|
24
|
+
});
|
|
25
|
+
if (input.chainId === types_1.KnownChainIds.EthereumMainnet) {
|
|
26
|
+
const ethTradeTx = await (0, makeTradeTx_1.makeTradeTx)({
|
|
27
|
+
wallet,
|
|
28
|
+
slippageTolerance,
|
|
29
|
+
bip44Params: sellAssetBip44Params,
|
|
30
|
+
sellAsset,
|
|
31
|
+
buyAsset,
|
|
32
|
+
adapter: sellAdapter,
|
|
33
|
+
sellAmount,
|
|
34
|
+
destinationAddress,
|
|
35
|
+
deps,
|
|
36
|
+
gasPrice: (_b = (_a = quote.feeData.chainSpecific) === null || _a === void 0 ? void 0 : _a.gasPrice) !== null && _b !== void 0 ? _b : '0',
|
|
37
|
+
gasLimit: (_d = (_c = quote.feeData.chainSpecific) === null || _c === void 0 ? void 0 : _c.estimatedGas) !== null && _d !== void 0 ? _d : '0',
|
|
38
|
+
tradeFee: quote.feeData.tradeFee
|
|
39
|
+
});
|
|
40
|
+
return {
|
|
41
|
+
chainId: types_1.KnownChainIds.EthereumMainnet,
|
|
42
|
+
...quote,
|
|
43
|
+
receiveAddress: destinationAddress,
|
|
44
|
+
txData: ethTradeTx.txToSign
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
else if (input.chainId === types_1.KnownChainIds.BitcoinMainnet) {
|
|
48
|
+
const { vault, opReturnData } = await (0, getThorTxData_1.getThorTxInfo)({
|
|
49
|
+
deps,
|
|
50
|
+
sellAsset,
|
|
51
|
+
buyAsset,
|
|
52
|
+
sellAmount,
|
|
53
|
+
slippageTolerance,
|
|
54
|
+
destinationAddress,
|
|
55
|
+
wallet,
|
|
56
|
+
bip44Params: sellAssetBip44Params,
|
|
57
|
+
accountType: input.accountType,
|
|
58
|
+
tradeFee: quote.feeData.tradeFee
|
|
59
|
+
});
|
|
60
|
+
const buildTxResponse = await sellAdapter.buildSendTransaction({
|
|
61
|
+
value: sellAmount,
|
|
62
|
+
wallet,
|
|
63
|
+
to: vault,
|
|
64
|
+
chainSpecific: {
|
|
65
|
+
accountType: input.accountType,
|
|
66
|
+
satoshiPerByte: quote.feeData.chainSpecific
|
|
67
|
+
.satsPerByte,
|
|
68
|
+
opReturnData
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
return {
|
|
72
|
+
chainId: types_1.KnownChainIds.BitcoinMainnet,
|
|
73
|
+
...quote,
|
|
74
|
+
receiveAddress: destinationAddress,
|
|
75
|
+
txData: buildTxResponse.txToSign
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
throw new api_1.SwapError('[buildTrade]: unsupported chain id', {
|
|
80
|
+
code: api_1.SwapErrorTypes.BUILD_TRADE_FAILED,
|
|
81
|
+
fn: 'buildTrade',
|
|
82
|
+
details: { sellAsset }
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
catch (e) {
|
|
87
|
+
if (e instanceof api_1.SwapError)
|
|
88
|
+
throw e;
|
|
89
|
+
throw new api_1.SwapError('[buildTrade]: error building trade', {
|
|
90
|
+
code: api_1.SwapErrorTypes.BUILD_TRADE_FAILED,
|
|
91
|
+
fn: 'buildTrade'
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
exports.buildTrade = buildTrade;
|
|
@@ -6,18 +6,17 @@ const types_1 = require("@shapeshiftoss/types");
|
|
|
6
6
|
const api_1 = require("../../../api");
|
|
7
7
|
const bignumber_1 = require("../../utils/bignumber");
|
|
8
8
|
const constants_1 = require("../../utils/constants");
|
|
9
|
-
const helpers_1 = require("../../utils/helpers/helpers");
|
|
10
9
|
const getThorTxData_1 = require("../utils/bitcoin/utils/getThorTxData");
|
|
11
10
|
const constants_2 = require("../utils/constants");
|
|
12
11
|
const estimateTradeFee_1 = require("../utils/estimateTradeFee/estimateTradeFee");
|
|
13
12
|
const getThorTxData_2 = require("../utils/ethereum/utils/getThorTxData");
|
|
14
|
-
const
|
|
13
|
+
const getTradeRate_1 = require("../utils/getTradeRate/getTradeRate");
|
|
15
14
|
const getBtcTxFees_1 = require("../utils/txFeeHelpers/btcTxFees/getBtcTxFees");
|
|
16
15
|
const getEthTxFees_1 = require("../utils/txFeeHelpers/ethTxFees/getEthTxFees");
|
|
17
16
|
const getThorTradeQuote = async ({ deps, input }) => {
|
|
18
17
|
const { sellAsset, buyAsset, sellAmount, sellAssetAccountNumber, wallet, chainId, receiveAddress } = input;
|
|
19
18
|
if (!wallet)
|
|
20
|
-
throw new api_1.SwapError('[
|
|
19
|
+
throw new api_1.SwapError('[getThorTradeQuote] - wallet is required', {
|
|
21
20
|
code: api_1.SwapErrorTypes.VALIDATION_FAILED
|
|
22
21
|
});
|
|
23
22
|
try {
|
|
@@ -28,7 +27,6 @@ const getThorTradeQuote = async ({ deps, input }) => {
|
|
|
28
27
|
code: api_1.SwapErrorTypes.UNSUPPORTED_CHAIN,
|
|
29
28
|
details: { chainId }
|
|
30
29
|
});
|
|
31
|
-
const sellAssetId = sellAsset.assetId;
|
|
32
30
|
const buyAssetId = buyAsset.assetId;
|
|
33
31
|
const feeAssetId = (0, caip_1.getFeeAssetIdFromAssetId)(buyAssetId);
|
|
34
32
|
if (!feeAssetId)
|
|
@@ -36,13 +34,14 @@ const getThorTradeQuote = async ({ deps, input }) => {
|
|
|
36
34
|
code: api_1.SwapErrorTypes.VALIDATION_FAILED,
|
|
37
35
|
details: { buyAssetId }
|
|
38
36
|
});
|
|
39
|
-
const
|
|
40
|
-
const rate = (0, bignumber_1.bnOrZero)(1).div(
|
|
41
|
-
const buyAmount = (0,
|
|
42
|
-
const tradeFee = await (0, estimateTradeFee_1.estimateTradeFee)(deps, buyAsset
|
|
43
|
-
const sellAssetTradeFee = (0, bignumber_1.
|
|
44
|
-
//
|
|
45
|
-
|
|
37
|
+
const tradeRate = await (0, getTradeRate_1.getTradeRate)(sellAsset, buyAsset.assetId, sellAmount, deps);
|
|
38
|
+
const rate = (0, bignumber_1.bnOrZero)(1).div(tradeRate).toString();
|
|
39
|
+
const buyAmount = (0, bignumber_1.toBaseUnit)((0, bignumber_1.bnOrZero)((0, bignumber_1.fromBaseUnit)(sellAmount, sellAsset.precision)).times(tradeRate), buyAsset.precision);
|
|
40
|
+
const tradeFee = await (0, estimateTradeFee_1.estimateTradeFee)(deps, buyAsset);
|
|
41
|
+
const sellAssetTradeFee = (0, bignumber_1.bnOrZero)(tradeFee).times((0, bignumber_1.bnOrZero)(rate));
|
|
42
|
+
// minimum is tradeFee padded by an amount to be sure they get something back
|
|
43
|
+
// usually it will be slightly more than the amount because sellAssetTradeFee is already a high estimate
|
|
44
|
+
const minimum = (0, bignumber_1.bnOrZero)(sellAssetTradeFee).times(constants_2.THOR_MINIMUM_PADDING).toString();
|
|
46
45
|
const commonQuoteFields = {
|
|
47
46
|
rate,
|
|
48
47
|
maximum: constants_2.MAX_THORCHAIN_TRADE,
|
|
@@ -57,23 +56,19 @@ const getThorTradeQuote = async ({ deps, input }) => {
|
|
|
57
56
|
switch (chainId) {
|
|
58
57
|
case types_1.KnownChainIds.EthereumMainnet:
|
|
59
58
|
return (async () => {
|
|
60
|
-
const {
|
|
59
|
+
const { router } = await (0, getThorTxData_2.getThorTxInfo)({
|
|
61
60
|
deps,
|
|
62
61
|
sellAsset,
|
|
63
62
|
buyAsset,
|
|
64
63
|
sellAmount,
|
|
65
64
|
slippageTolerance: constants_1.DEFAULT_SLIPPAGE,
|
|
66
|
-
destinationAddress: receiveAddress
|
|
65
|
+
destinationAddress: receiveAddress,
|
|
66
|
+
tradeFee
|
|
67
67
|
});
|
|
68
68
|
const feeData = await (0, getEthTxFees_1.getEthTxFees)({
|
|
69
|
-
deps,
|
|
70
|
-
data,
|
|
71
|
-
router,
|
|
72
|
-
buyAsset,
|
|
73
|
-
sellAmount,
|
|
74
69
|
adapterManager: deps.adapterManager,
|
|
75
|
-
|
|
76
|
-
|
|
70
|
+
sellAssetReference: sellAssetErc20Address,
|
|
71
|
+
tradeFee
|
|
77
72
|
});
|
|
78
73
|
return {
|
|
79
74
|
...commonQuoteFields,
|
|
@@ -92,16 +87,16 @@ const getThorTradeQuote = async ({ deps, input }) => {
|
|
|
92
87
|
destinationAddress: receiveAddress,
|
|
93
88
|
wallet,
|
|
94
89
|
bip44Params: input.bip44Params,
|
|
95
|
-
accountType: input.accountType
|
|
90
|
+
accountType: input.accountType,
|
|
91
|
+
tradeFee
|
|
96
92
|
});
|
|
97
93
|
const feeData = await (0, getBtcTxFees_1.getBtcTxFees)({
|
|
98
|
-
deps,
|
|
99
|
-
buyAsset,
|
|
100
94
|
sellAmount,
|
|
101
95
|
vault,
|
|
102
96
|
opReturnData,
|
|
103
97
|
pubkey,
|
|
104
|
-
adapterManager: deps.adapterManager
|
|
98
|
+
adapterManager: deps.adapterManager,
|
|
99
|
+
tradeFee
|
|
105
100
|
});
|
|
106
101
|
return {
|
|
107
102
|
...commonQuoteFields,
|
|
@@ -14,12 +14,8 @@ const thorTradeApprovalNeeded = async ({ deps, input }) => {
|
|
|
14
14
|
const { adapterManager, web3 } = deps;
|
|
15
15
|
const { assetReference: sellAssetErc20Address } = (0, caip_1.fromAssetId)(sellAsset.assetId);
|
|
16
16
|
const { chainNamespace } = (0, caip_1.fromChainId)(sellAsset.chainId);
|
|
17
|
-
if (chainNamespace !==
|
|
18
|
-
|
|
19
|
-
code: api_1.SwapErrorTypes.UNSUPPORTED_CHAIN,
|
|
20
|
-
details: { chainNamespace }
|
|
21
|
-
});
|
|
22
|
-
}
|
|
17
|
+
if (chainNamespace !== caip_1.CHAIN_NAMESPACE.Ethereum)
|
|
18
|
+
return { approvalNeeded: false };
|
|
23
19
|
// No approval needed for selling a fee asset
|
|
24
20
|
if (sellAsset.assetId === (0, caip_1.getFeeAssetIdFromAssetId)(sellAsset.assetId)) {
|
|
25
21
|
return { approvalNeeded: false };
|
|
@@ -4,10 +4,11 @@ exports.getThorTxInfo = void 0;
|
|
|
4
4
|
const caip_1 = require("@shapeshiftoss/caip");
|
|
5
5
|
const api_1 = require("../../../../../api");
|
|
6
6
|
const bignumber_1 = require("../../../../utils/bignumber");
|
|
7
|
-
const
|
|
7
|
+
const constants_1 = require("../../constants");
|
|
8
|
+
const getTradeRate_1 = require("../../getTradeRate/getTradeRate");
|
|
8
9
|
const makeSwapMemo_1 = require("../../makeSwapMemo/makeSwapMemo");
|
|
9
10
|
const thorService_1 = require("../../thorService");
|
|
10
|
-
const getThorTxInfo = async ({ deps, sellAsset, buyAsset, sellAmount, slippageTolerance, destinationAddress, wallet, bip44Params, accountType }) => {
|
|
11
|
+
const getThorTxInfo = async ({ deps, sellAsset, buyAsset, sellAmount, slippageTolerance, destinationAddress, wallet, bip44Params, accountType, tradeFee }) => {
|
|
11
12
|
try {
|
|
12
13
|
const { data: inboundAddresses } = await thorService_1.thorService.get(`${deps.midgardUrl}/thorchain/inbound_addresses`);
|
|
13
14
|
const btcInboundAddresses = inboundAddresses.find((inbound) => inbound.chain === 'BTC');
|
|
@@ -17,19 +18,18 @@ const getThorTxInfo = async ({ deps, sellAsset, buyAsset, sellAmount, slippageTo
|
|
|
17
18
|
code: api_1.SwapErrorTypes.RESPONSE_ERROR,
|
|
18
19
|
details: { inboundAddresses }
|
|
19
20
|
});
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
sellAssetId: sellAsset.assetId
|
|
23
|
-
});
|
|
24
|
-
const expectedBuyAmount = (0, bignumber_1.toBaseUnit)((0, bignumber_1.fromBaseUnit)((0, bignumber_1.bnOrZero)(sellAmount).dividedBy(priceRatio), sellAsset.precision), buyAsset.precision);
|
|
21
|
+
const tradeRate = await (0, getTradeRate_1.getTradeRate)(sellAsset, buyAsset.assetId, sellAmount, deps);
|
|
22
|
+
const expectedBuyAmountPrecision8 = (0, bignumber_1.toBaseUnit)((0, bignumber_1.fromBaseUnit)((0, bignumber_1.bnOrZero)(sellAmount).times(tradeRate), sellAsset.precision), constants_1.THORCHAIN_FIXED_PRECISION);
|
|
25
23
|
const isValidSlippageRange = (0, bignumber_1.bnOrZero)(slippageTolerance).gte(0) && (0, bignumber_1.bnOrZero)(slippageTolerance).lte(1);
|
|
26
|
-
if ((0, bignumber_1.bnOrZero)(
|
|
24
|
+
if ((0, bignumber_1.bnOrZero)(expectedBuyAmountPrecision8).lt(0) || !isValidSlippageRange)
|
|
27
25
|
throw new api_1.SwapError('[getThorTxInfo]: bad expected buy amount or bad slippage tolerance', {
|
|
28
26
|
code: api_1.SwapErrorTypes.BUILD_TRADE_FAILED,
|
|
29
|
-
details: {
|
|
27
|
+
details: { expectedBuyAmountPrecision8, slippageTolerance }
|
|
30
28
|
});
|
|
31
|
-
const
|
|
29
|
+
const tradeFeePrecision8 = (0, bignumber_1.toBaseUnit)((0, bignumber_1.bnOrZero)(tradeFee), constants_1.THORCHAIN_FIXED_PRECISION);
|
|
30
|
+
const limit = (0, bignumber_1.bnOrZero)(expectedBuyAmountPrecision8)
|
|
32
31
|
.times((0, bignumber_1.bn)(1).minus(slippageTolerance))
|
|
32
|
+
.minus((0, bignumber_1.bnOrZero)(tradeFeePrecision8))
|
|
33
33
|
.decimalPlaces(0)
|
|
34
34
|
.toString();
|
|
35
35
|
const memo = (0, makeSwapMemo_1.makeSwapMemo)({
|
|
@@ -1,2 +1,7 @@
|
|
|
1
1
|
export declare const MAX_THORCHAIN_TRADE = "100000000000000000000000000";
|
|
2
2
|
export declare const MAX_ALLOWANCE = "100000000000000000000000000";
|
|
3
|
+
export declare const THOR_MINIMUM_PADDING = 1.2;
|
|
4
|
+
export declare const THOR_ETH_GAS_LIMIT = "100000";
|
|
5
|
+
export declare const THORCHAIN_FIXED_PRECISION = 8;
|
|
6
|
+
export declare const THOR_TRADE_FEE_BTC_SIZE = 1000;
|
|
7
|
+
export declare const THOR_TRADE_FEE_ETH_GAS = 120000;
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.MAX_ALLOWANCE = exports.MAX_THORCHAIN_TRADE = void 0;
|
|
3
|
+
exports.THOR_TRADE_FEE_ETH_GAS = exports.THOR_TRADE_FEE_BTC_SIZE = exports.THORCHAIN_FIXED_PRECISION = exports.THOR_ETH_GAS_LIMIT = exports.THOR_MINIMUM_PADDING = exports.MAX_ALLOWANCE = exports.MAX_THORCHAIN_TRADE = void 0;
|
|
4
4
|
exports.MAX_THORCHAIN_TRADE = '100000000000000000000000000';
|
|
5
5
|
exports.MAX_ALLOWANCE = '100000000000000000000000000';
|
|
6
|
+
exports.THOR_MINIMUM_PADDING = 1.2;
|
|
7
|
+
exports.THOR_ETH_GAS_LIMIT = '100000'; // for sends of eth / erc20 into thorchain router
|
|
8
|
+
exports.THORCHAIN_FIXED_PRECISION = 8; // limit values are precision 8 regardless of the chain
|
|
9
|
+
// These are different from THOR_ETH_GAS_LIMIT
|
|
10
|
+
// Used to estimate the fee thorchain will take out of the buyAsset
|
|
11
|
+
exports.THOR_TRADE_FEE_BTC_SIZE = 1000; // used for estimating thorchain side fees
|
|
12
|
+
exports.THOR_TRADE_FEE_ETH_GAS = 120000; // used for estimating thorchain side fees
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Asset } from '@shapeshiftoss/asset-service';
|
|
2
2
|
import { ThorchainSwapperDeps } from '../../types';
|
|
3
|
-
export declare const estimateTradeFee: (deps: ThorchainSwapperDeps,
|
|
3
|
+
export declare const estimateTradeFee: (deps: ThorchainSwapperDeps, buyAsset: Asset) => Promise<string>;
|
|
@@ -4,23 +4,32 @@ exports.estimateTradeFee = void 0;
|
|
|
4
4
|
const caip_1 = require("@shapeshiftoss/caip");
|
|
5
5
|
const api_1 = require("../../../../api");
|
|
6
6
|
const bignumber_1 = require("../../../utils/bignumber");
|
|
7
|
+
const constants_1 = require("../constants");
|
|
7
8
|
const getPriceRatio_1 = require("../getPriceRatio/getPriceRatio");
|
|
8
9
|
const thorService_1 = require("../thorService");
|
|
9
10
|
const gweiGasPrecision = 9;
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
|
|
14
|
-
//
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
11
|
+
// Official docs on fees are incorrect
|
|
12
|
+
// https://discord.com/channels/838986635756044328/997675038675316776/998552541170253834
|
|
13
|
+
// This is still not "perfect" and tends to overestimate by a randomish amount
|
|
14
|
+
// TODO figure out if its possible to accurately estimate the outbound fee.
|
|
15
|
+
// Neither the discord nor official docs are correct
|
|
16
|
+
const ethEstimate = (gasRate) => (0, bignumber_1.bnOrZero)(gasRate)
|
|
17
|
+
.times(constants_1.THOR_TRADE_FEE_ETH_GAS)
|
|
18
|
+
.times(2)
|
|
19
|
+
.times((0, bignumber_1.bn)(10).exponentiatedBy(gweiGasPrecision))
|
|
20
|
+
.toString();
|
|
21
|
+
const erc20Estimate = (gasRate) => (0, bignumber_1.bnOrZero)(gasRate)
|
|
22
|
+
.times(constants_1.THOR_TRADE_FEE_ETH_GAS)
|
|
23
|
+
.times(2)
|
|
24
|
+
.times((0, bignumber_1.bn)(10).exponentiatedBy(gweiGasPrecision))
|
|
25
|
+
.toString();
|
|
26
|
+
const btcEstimate = (gasRate) => (0, bignumber_1.bnOrZero)(gasRate).times(constants_1.THOR_TRADE_FEE_BTC_SIZE).times(2).toString();
|
|
27
|
+
const estimateTradeFee = async (deps, buyAsset) => {
|
|
28
|
+
const thorId = caip_1.adapters.assetIdToPoolAssetId({ assetId: buyAsset.assetId });
|
|
20
29
|
if (!thorId)
|
|
21
30
|
throw new api_1.SwapError('[estimateTradeFee] - undefined thorId for given buyAssetId', {
|
|
22
31
|
code: api_1.SwapErrorTypes.VALIDATION_FAILED,
|
|
23
|
-
details: { buyAssetId }
|
|
32
|
+
details: { buyAssetId: buyAsset.assetId }
|
|
24
33
|
});
|
|
25
34
|
const thorPoolChainId = thorId.slice(0, thorId.indexOf('.'));
|
|
26
35
|
const { data: inboundAddresses } = await thorService_1.thorService.get(`${deps.midgardUrl}/thorchain/inbound_addresses`);
|
|
@@ -31,28 +40,28 @@ const estimateTradeFee = async (deps, buyAssetId) => {
|
|
|
31
40
|
details: { thorPoolChainId }
|
|
32
41
|
});
|
|
33
42
|
const gasRate = inboundInfo.gas_rate;
|
|
34
|
-
const { chainId, assetNamespace } = (0, caip_1.fromAssetId)(
|
|
35
|
-
const feeAssetId = (0, caip_1.getFeeAssetIdFromAssetId)(
|
|
43
|
+
const { chainId, assetNamespace } = (0, caip_1.fromAssetId)(buyAsset.assetId);
|
|
44
|
+
const feeAssetId = (0, caip_1.getFeeAssetIdFromAssetId)(buyAsset.assetId);
|
|
36
45
|
if (!feeAssetId)
|
|
37
46
|
throw new api_1.SwapError('[estimateTradeFee] - no fee assetId', {
|
|
38
47
|
code: api_1.SwapErrorTypes.VALIDATION_FAILED,
|
|
39
|
-
details: { buyAssetId }
|
|
48
|
+
details: { buyAssetId: buyAsset.assetId }
|
|
40
49
|
});
|
|
41
|
-
const feeAssetRatio =
|
|
50
|
+
const feeAssetRatio = buyAsset.assetId !== feeAssetId
|
|
42
51
|
? await (0, getPriceRatio_1.getPriceRatio)(deps, {
|
|
43
|
-
sellAssetId:
|
|
52
|
+
sellAssetId: buyAsset.assetId,
|
|
44
53
|
buyAssetId: feeAssetId
|
|
45
54
|
})
|
|
46
55
|
: '1';
|
|
47
56
|
switch (chainId) {
|
|
48
57
|
case 'bip122:000000000019d6689c085ae165831e93':
|
|
49
|
-
return (0, bignumber_1.bnOrZero)(btcEstimate(gasRate)).times(feeAssetRatio).dp(0).
|
|
58
|
+
return (0, bignumber_1.fromBaseUnit)((0, bignumber_1.bnOrZero)(btcEstimate(gasRate)).times(feeAssetRatio).dp(0), buyAsset.precision);
|
|
50
59
|
case 'eip155:1':
|
|
51
60
|
switch (assetNamespace) {
|
|
52
61
|
case 'slip44':
|
|
53
|
-
return (0, bignumber_1.bnOrZero)(ethEstimate(gasRate)).times(feeAssetRatio).dp(0).
|
|
62
|
+
return (0, bignumber_1.fromBaseUnit)((0, bignumber_1.bnOrZero)(ethEstimate(gasRate)).times(feeAssetRatio).dp(0), buyAsset.precision);
|
|
54
63
|
case 'erc20':
|
|
55
|
-
return (0, bignumber_1.bnOrZero)(erc20Estimate(gasRate)).times(feeAssetRatio).dp(0).
|
|
64
|
+
return (0, bignumber_1.fromBaseUnit)((0, bignumber_1.bnOrZero)(erc20Estimate(gasRate)).times(feeAssetRatio).dp(0), buyAsset.precision);
|
|
56
65
|
default:
|
|
57
66
|
throw new api_1.SwapError('[estimateTradeFee] - unsupported asset namespace', {
|
|
58
67
|
code: api_1.SwapErrorTypes.VALIDATION_FAILED,
|
|
@@ -3,7 +3,7 @@ import { ethereum } from '@shapeshiftoss/chain-adapters';
|
|
|
3
3
|
import { ETHSignTx, HDWallet } from '@shapeshiftoss/hdwallet-core';
|
|
4
4
|
import { BIP44Params } from '@shapeshiftoss/types';
|
|
5
5
|
import { ThorchainSwapperDeps } from '../../types';
|
|
6
|
-
export declare const makeTradeTx: ({ wallet, bip44Params, sellAmount, buyAsset, sellAsset, destinationAddress, adapter, maxFeePerGas, maxPriorityFeePerGas, gasPrice, slippageTolerance, deps, gasLimit }: {
|
|
6
|
+
export declare const makeTradeTx: ({ wallet, bip44Params, sellAmount, buyAsset, sellAsset, destinationAddress, adapter, maxFeePerGas, maxPriorityFeePerGas, gasPrice, slippageTolerance, deps, gasLimit, tradeFee }: {
|
|
7
7
|
wallet: HDWallet;
|
|
8
8
|
bip44Params: BIP44Params;
|
|
9
9
|
sellAmount: string;
|
|
@@ -14,6 +14,7 @@ export declare const makeTradeTx: ({ wallet, bip44Params, sellAmount, buyAsset,
|
|
|
14
14
|
slippageTolerance: string;
|
|
15
15
|
deps: ThorchainSwapperDeps;
|
|
16
16
|
gasLimit: string;
|
|
17
|
+
tradeFee: string;
|
|
17
18
|
} & ({
|
|
18
19
|
gasPrice: string;
|
|
19
20
|
maxFeePerGas?: undefined;
|
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.makeTradeTx = void 0;
|
|
4
4
|
const caip_1 = require("@shapeshiftoss/caip");
|
|
5
|
+
const web3_utils_1 = require("web3-utils");
|
|
5
6
|
const api_1 = require("../../../../api");
|
|
6
7
|
const getThorTxData_1 = require("../ethereum/utils/getThorTxData");
|
|
7
|
-
const makeTradeTx = async ({ wallet, bip44Params, sellAmount, buyAsset, sellAsset, destinationAddress, adapter, maxFeePerGas, maxPriorityFeePerGas, gasPrice, slippageTolerance, deps, gasLimit }) => {
|
|
8
|
+
const makeTradeTx = async ({ wallet, bip44Params, sellAmount, buyAsset, sellAsset, destinationAddress, adapter, maxFeePerGas, maxPriorityFeePerGas, gasPrice, slippageTolerance, deps, gasLimit, tradeFee }) => {
|
|
8
9
|
try {
|
|
9
10
|
const { assetNamespace } = (0, caip_1.fromAssetId)(sellAsset.assetId);
|
|
10
11
|
const isErc20Trade = assetNamespace === 'erc20';
|
|
@@ -14,7 +15,8 @@ const makeTradeTx = async ({ wallet, bip44Params, sellAmount, buyAsset, sellAsse
|
|
|
14
15
|
buyAsset,
|
|
15
16
|
sellAmount,
|
|
16
17
|
slippageTolerance,
|
|
17
|
-
destinationAddress
|
|
18
|
+
destinationAddress,
|
|
19
|
+
tradeFee
|
|
18
20
|
});
|
|
19
21
|
return adapter.buildCustomTx({
|
|
20
22
|
wallet,
|
|
@@ -29,7 +31,7 @@ const makeTradeTx = async ({ wallet, bip44Params, sellAmount, buyAsset, sellAsse
|
|
|
29
31
|
maxFeePerGas,
|
|
30
32
|
maxPriorityFeePerGas
|
|
31
33
|
}),
|
|
32
|
-
value: isErc20Trade ? '
|
|
34
|
+
value: isErc20Trade ? '0x0' : (0, web3_utils_1.numberToHex)(sellAmount),
|
|
33
35
|
data
|
|
34
36
|
});
|
|
35
37
|
}
|
|
@@ -4,11 +4,12 @@ exports.getThorTxInfo = void 0;
|
|
|
4
4
|
const caip_1 = require("@shapeshiftoss/caip");
|
|
5
5
|
const api_1 = require("../../../../../api");
|
|
6
6
|
const bignumber_1 = require("../../../../utils/bignumber");
|
|
7
|
-
const
|
|
7
|
+
const getTradeRate_1 = require("../../../utils/getTradeRate/getTradeRate");
|
|
8
|
+
const constants_1 = require("../../constants");
|
|
8
9
|
const makeSwapMemo_1 = require("../../makeSwapMemo/makeSwapMemo");
|
|
9
10
|
const thorService_1 = require("../../thorService");
|
|
10
11
|
const routerCalldata_1 = require("../routerCalldata");
|
|
11
|
-
const getThorTxInfo = async ({ deps, sellAsset, buyAsset, sellAmount, slippageTolerance, destinationAddress }) => {
|
|
12
|
+
const getThorTxInfo = async ({ deps, sellAsset, buyAsset, sellAmount, slippageTolerance, destinationAddress, tradeFee }) => {
|
|
12
13
|
try {
|
|
13
14
|
const { assetReference, assetNamespace } = (0, caip_1.fromAssetId)(sellAsset.assetId);
|
|
14
15
|
const isErc20Trade = assetNamespace === 'erc20';
|
|
@@ -21,19 +22,18 @@ const getThorTxInfo = async ({ deps, sellAsset, buyAsset, sellAmount, slippageTo
|
|
|
21
22
|
code: api_1.SwapErrorTypes.RESPONSE_ERROR,
|
|
22
23
|
details: { inboundAddresses }
|
|
23
24
|
});
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
});
|
|
28
|
-
const expectedBuyAmount = (0, bignumber_1.toBaseUnit)((0, bignumber_1.fromBaseUnit)((0, bignumber_1.bnOrZero)(sellAmount).dividedBy(priceRatio), sellAsset.precision), buyAsset.precision);
|
|
25
|
+
const tradeRate = await (0, getTradeRate_1.getTradeRate)(sellAsset, buyAsset.assetId, sellAmount, deps);
|
|
26
|
+
const expectedBuyAmountPrecision8 = (0, bignumber_1.toBaseUnit)((0, bignumber_1.fromBaseUnit)((0, bignumber_1.bnOrZero)(sellAmount).times(tradeRate), sellAsset.precision), constants_1.THORCHAIN_FIXED_PRECISION);
|
|
27
|
+
const tradeFeePrecision8 = (0, bignumber_1.toBaseUnit)((0, bignumber_1.bnOrZero)(tradeFee), constants_1.THORCHAIN_FIXED_PRECISION);
|
|
29
28
|
const isValidSlippageRange = (0, bignumber_1.bnOrZero)(slippageTolerance).gte(0) && (0, bignumber_1.bnOrZero)(slippageTolerance).lte(1);
|
|
30
|
-
if ((0, bignumber_1.bnOrZero)(
|
|
29
|
+
if ((0, bignumber_1.bnOrZero)(expectedBuyAmountPrecision8).lt(0) || !isValidSlippageRange)
|
|
31
30
|
throw new api_1.SwapError('[makeTradeTx]: bad expected buy amount or bad slippage tolerance', {
|
|
32
31
|
code: api_1.SwapErrorTypes.BUILD_TRADE_FAILED,
|
|
33
|
-
details: {
|
|
32
|
+
details: { expectedBuyAmountPrecision8, slippageTolerance }
|
|
34
33
|
});
|
|
35
|
-
const limit = (0, bignumber_1.bnOrZero)(
|
|
34
|
+
const limit = (0, bignumber_1.bnOrZero)(expectedBuyAmountPrecision8)
|
|
36
35
|
.times((0, bignumber_1.bn)(1).minus(slippageTolerance))
|
|
36
|
+
.minus((0, bignumber_1.bnOrZero)(tradeFeePrecision8))
|
|
37
37
|
.decimalPlaces(0)
|
|
38
38
|
.toString();
|
|
39
39
|
const memo = (0, makeSwapMemo_1.makeSwapMemo)({
|
|
@@ -5,6 +5,7 @@ const caip_1 = require("@shapeshiftoss/caip");
|
|
|
5
5
|
const api_1 = require("../../../../api");
|
|
6
6
|
const bignumber_1 = require("../../../utils/bignumber");
|
|
7
7
|
const bignumber_2 = require("../../../utils/bignumber");
|
|
8
|
+
const getPriceRatio_1 = require("../getPriceRatio/getPriceRatio");
|
|
8
9
|
const thorService_1 = require("../thorService");
|
|
9
10
|
const THOR_PRECISION = 8;
|
|
10
11
|
const getSwapOutput = (inputAmount, poolData, toRune) => {
|
|
@@ -23,6 +24,13 @@ const getDoubleSwapOutput = (input, inputPool, outputPool) => {
|
|
|
23
24
|
// TODO this does not support swaps between native "RUNE"
|
|
24
25
|
// Rune swaps use a different calculation because its 1 hop between pools instead of 2
|
|
25
26
|
const getTradeRate = async (sellAsset, buyAssetId, sellAmount, deps) => {
|
|
27
|
+
// we can't get a quote for a zero amount so use getPriceRatio between pools instead
|
|
28
|
+
if ((0, bignumber_1.bnOrZero)(sellAmount).eq(0)) {
|
|
29
|
+
return (0, getPriceRatio_1.getPriceRatio)(deps, {
|
|
30
|
+
sellAssetId: sellAsset.assetId,
|
|
31
|
+
buyAssetId
|
|
32
|
+
});
|
|
33
|
+
}
|
|
26
34
|
const buyPoolId = caip_1.adapters.assetIdToPoolAssetId({ assetId: buyAssetId });
|
|
27
35
|
const sellPoolId = caip_1.adapters.assetIdToPoolAssetId({ assetId: sellAsset.assetId });
|
|
28
36
|
if (!buyPoolId || !sellPoolId)
|
|
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.setupThorswapDeps = void 0;
|
|
7
|
+
const chain_adapters_1 = require("@shapeshiftoss/chain-adapters");
|
|
7
8
|
const web3_1 = __importDefault(require("web3"));
|
|
8
9
|
jest.mock('web3');
|
|
9
10
|
const setupThorswapDeps = () => {
|
|
@@ -20,7 +21,24 @@ const setupThorswapDeps = () => {
|
|
|
20
21
|
{
|
|
21
22
|
buildBIP44Params: jest.fn(() => ({ purpose: 44, coinType: 60, accountNumber: 0 })),
|
|
22
23
|
getAddress: jest.fn(() => Promise.resolve('0xthisIsMyAddress')),
|
|
23
|
-
getFeeData: jest.fn(() => feeData)
|
|
24
|
+
getFeeData: jest.fn(() => feeData),
|
|
25
|
+
getGasFeeData: jest.fn(() => ({
|
|
26
|
+
[chain_adapters_1.FeeDataKey.Slow]: {
|
|
27
|
+
gasPrice: '1',
|
|
28
|
+
maxFeePerGas: '2',
|
|
29
|
+
maxPriorityFeePerGas: '3'
|
|
30
|
+
},
|
|
31
|
+
[chain_adapters_1.FeeDataKey.Average]: {
|
|
32
|
+
gasPrice: '4',
|
|
33
|
+
maxFeePerGas: '5',
|
|
34
|
+
maxPriorityFeePerGas: '6'
|
|
35
|
+
},
|
|
36
|
+
[chain_adapters_1.FeeDataKey.Fast]: {
|
|
37
|
+
gasPrice: '7',
|
|
38
|
+
maxFeePerGas: '8',
|
|
39
|
+
maxPriorityFeePerGas: '9'
|
|
40
|
+
}
|
|
41
|
+
}))
|
|
24
42
|
}
|
|
25
43
|
]
|
|
26
44
|
]);
|
|
@@ -1,14 +1,11 @@
|
|
|
1
|
-
import { Asset } from '@shapeshiftoss/asset-service';
|
|
2
1
|
import { ChainAdapterManager } from '@shapeshiftoss/chain-adapters';
|
|
3
2
|
import { KnownChainIds } from '@shapeshiftoss/types';
|
|
4
3
|
import { QuoteFeeData } from '../../../../../api';
|
|
5
|
-
|
|
6
|
-
export declare const getBtcTxFees: ({ deps, opReturnData, vault, buyAsset, sellAmount, adapterManager, pubkey }: {
|
|
7
|
-
deps: ThorchainSwapperDeps;
|
|
4
|
+
export declare const getBtcTxFees: ({ opReturnData, vault, sellAmount, adapterManager, pubkey, tradeFee }: {
|
|
8
5
|
opReturnData: string;
|
|
9
6
|
vault: string;
|
|
10
|
-
buyAsset: Asset;
|
|
11
7
|
sellAmount: string;
|
|
12
8
|
adapterManager: ChainAdapterManager;
|
|
13
9
|
pubkey: string;
|
|
10
|
+
tradeFee: string;
|
|
14
11
|
}) => Promise<QuoteFeeData<KnownChainIds.BitcoinMainnet>>;
|
|
@@ -3,8 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.getBtcTxFees = void 0;
|
|
4
4
|
const api_1 = require("../../../../../api");
|
|
5
5
|
const bignumber_1 = require("../../../../utils/bignumber");
|
|
6
|
-
const
|
|
7
|
-
const getBtcTxFees = async ({ deps, opReturnData, vault, buyAsset, sellAmount, adapterManager, pubkey }) => {
|
|
6
|
+
const getBtcTxFees = async ({ opReturnData, vault, sellAmount, adapterManager, pubkey, tradeFee }) => {
|
|
8
7
|
try {
|
|
9
8
|
const adapter = adapterManager.get('bip122:000000000019d6689c085ae165831e93');
|
|
10
9
|
if (!adapter)
|
|
@@ -18,7 +17,6 @@ const getBtcTxFees = async ({ deps, opReturnData, vault, buyAsset, sellAmount, a
|
|
|
18
17
|
chainSpecific: { pubkey, opReturnData }
|
|
19
18
|
});
|
|
20
19
|
const feeData = feeDataOptions['fast'];
|
|
21
|
-
const tradeFee = await (0, estimateTradeFee_1.estimateTradeFee)(deps, buyAsset.assetId);
|
|
22
20
|
return {
|
|
23
21
|
fee: feeData.txFee,
|
|
24
22
|
tradeFee,
|
|
@@ -1,16 +1,9 @@
|
|
|
1
|
-
import { Asset } from '@shapeshiftoss/asset-service';
|
|
2
1
|
import { AssetReference } from '@shapeshiftoss/caip';
|
|
3
2
|
import { ChainAdapterManager } from '@shapeshiftoss/chain-adapters';
|
|
4
3
|
import { KnownChainIds } from '@shapeshiftoss/types';
|
|
5
4
|
import { QuoteFeeData } from '../../../../../api';
|
|
6
|
-
|
|
7
|
-
export declare const getEthTxFees: ({ deps, data, router, buyAsset, sellAmount, adapterManager, receiveAddress, sellAssetReference }: {
|
|
8
|
-
deps: ThorchainSwapperDeps;
|
|
9
|
-
data: string;
|
|
10
|
-
router: string;
|
|
11
|
-
buyAsset: Asset;
|
|
12
|
-
sellAmount: string;
|
|
13
|
-
sellAssetReference: AssetReference | string;
|
|
5
|
+
export declare const getEthTxFees: ({ adapterManager, sellAssetReference, tradeFee }: {
|
|
14
6
|
adapterManager: ChainAdapterManager;
|
|
15
|
-
|
|
7
|
+
sellAssetReference: AssetReference | string;
|
|
8
|
+
tradeFee: string;
|
|
16
9
|
}) => Promise<QuoteFeeData<KnownChainIds.EthereumMainnet>>;
|
|
@@ -6,8 +6,8 @@ const types_1 = require("@shapeshiftoss/types");
|
|
|
6
6
|
const api_1 = require("../../../../../api");
|
|
7
7
|
const bignumber_1 = require("../../../../utils/bignumber");
|
|
8
8
|
const constants_1 = require("../../../../utils/constants");
|
|
9
|
-
const
|
|
10
|
-
const getEthTxFees = async ({
|
|
9
|
+
const constants_2 = require("../../constants");
|
|
10
|
+
const getEthTxFees = async ({ adapterManager, sellAssetReference, tradeFee }) => {
|
|
11
11
|
try {
|
|
12
12
|
const adapter = adapterManager.get(types_1.KnownChainIds.EthereumMainnet);
|
|
13
13
|
if (!adapter) {
|
|
@@ -16,32 +16,20 @@ const getEthTxFees = async ({ deps, data, router, buyAsset, sellAmount, adapterM
|
|
|
16
16
|
details: { chainId: types_1.KnownChainIds.EthereumMainnet }
|
|
17
17
|
});
|
|
18
18
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
// eslint-disable-next-line no-console
|
|
30
|
-
console.debug('[ThorSwapper:getEthTxFees] precise gas estimate failed, falling back on hard coded limit');
|
|
31
|
-
const gasFeeData = await adapter.getGasFeeData();
|
|
32
|
-
const gasLimit = '100000'; // good value to cover all thortrades out of eth/erc20
|
|
33
|
-
feeDataOptions = {
|
|
34
|
-
fast: {
|
|
35
|
-
txFee: (0, bignumber_1.bn)(gasLimit).times(gasFeeData[chain_adapters_1.FeeDataKey.Fast].gasPrice).toString(),
|
|
36
|
-
chainSpecific: {
|
|
37
|
-
gasPrice: gasFeeData[chain_adapters_1.FeeDataKey.Fast].gasPrice,
|
|
38
|
-
gasLimit
|
|
39
|
-
}
|
|
19
|
+
const gasFeeData = await adapter.getGasFeeData();
|
|
20
|
+
// this is a good value to cover all thortrades out of eth/erc20
|
|
21
|
+
// in the future we may want to look at doing this more precisely and in a future-proof way
|
|
22
|
+
const gasLimit = constants_2.THOR_ETH_GAS_LIMIT;
|
|
23
|
+
const feeDataOptions = {
|
|
24
|
+
fast: {
|
|
25
|
+
txFee: (0, bignumber_1.bn)(gasLimit).times(gasFeeData[chain_adapters_1.FeeDataKey.Fast].gasPrice).toString(),
|
|
26
|
+
chainSpecific: {
|
|
27
|
+
gasPrice: gasFeeData[chain_adapters_1.FeeDataKey.Fast].gasPrice,
|
|
28
|
+
gasLimit
|
|
40
29
|
}
|
|
41
|
-
}
|
|
42
|
-
}
|
|
30
|
+
}
|
|
31
|
+
};
|
|
43
32
|
const feeData = feeDataOptions['fast'];
|
|
44
|
-
const tradeFee = await (0, estimateTradeFee_1.estimateTradeFee)(deps, buyAsset.assetId);
|
|
45
33
|
return {
|
|
46
34
|
fee: feeData.txFee,
|
|
47
35
|
chainSpecific: {
|
|
@@ -37,7 +37,7 @@ const helpers_2 = require("../utils/helpers/helpers");
|
|
|
37
37
|
const zrxService_1 = require("../utils/zrxService");
|
|
38
38
|
async function zrxBuildTrade({ adapter, web3 }, input) {
|
|
39
39
|
var _a, _b, _c;
|
|
40
|
-
const { sellAsset, buyAsset, sellAmount, slippage, sellAssetAccountNumber,
|
|
40
|
+
const { sellAsset, buyAsset, sellAmount, slippage, sellAssetAccountNumber, receiveAddress } = input;
|
|
41
41
|
try {
|
|
42
42
|
const { assetReference: buyAssetErc20Address, assetNamespace: buyAssetNamespace } = (0, caip_1.fromAssetId)(buyAsset.assetId);
|
|
43
43
|
const { assetReference: sellAssetErc20Address, assetNamespace: sellAssetNamespace } = (0, caip_1.fromAssetId)(sellAsset.assetId);
|
|
@@ -50,8 +50,6 @@ async function zrxBuildTrade({ adapter, web3 }, input) {
|
|
|
50
50
|
details: { chainId: sellAsset.chainId }
|
|
51
51
|
});
|
|
52
52
|
}
|
|
53
|
-
const bip44Params = adapter.buildBIP44Params({ accountNumber: Number(buyAssetAccountNumber) });
|
|
54
|
-
const receiveAddress = await adapter.getAddress({ wallet, bip44Params });
|
|
55
53
|
const slippagePercentage = slippage ? (0, bignumber_1.bnOrZero)(slippage).div(100).toString() : constants_1.DEFAULT_SLIPPAGE;
|
|
56
54
|
const baseUrl = (0, helpers_2.baseUrlFromChainId)(buyAsset.chainId);
|
|
57
55
|
const zrxService = (0, zrxService_1.zrxServiceFactory)(baseUrl);
|
package/package.json
CHANGED