@shapeshiftoss/swapper 6.1.0 → 6.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api.d.ts +6 -4
- package/dist/api.js +1 -0
- package/dist/manager/SwapperManager.d.ts +2 -2
- package/dist/swappercli.js +5 -4
- package/dist/swappers/thorchain/ThorchainSwapper.d.ts +2 -2
- package/dist/swappers/thorchain/ThorchainSwapper.js +3 -2
- package/dist/swappers/thorchain/getThorTradeQuote/getTradeQuote.d.ts +7 -0
- package/dist/swappers/thorchain/getThorTradeQuote/getTradeQuote.js +94 -0
- package/dist/swappers/thorchain/utils/constants.d.ts +1 -0
- package/dist/swappers/thorchain/utils/constants.js +4 -0
- package/dist/swappers/thorchain/utils/ethereum/makeTradeTx.d.ts +0 -3
- package/dist/swappers/thorchain/utils/ethereum/makeTradeTx.js +9 -50
- package/dist/swappers/thorchain/utils/ethereum/utils/getThorTxData.d.ts +15 -0
- package/dist/swappers/thorchain/utils/ethereum/utils/getThorTxData.js +55 -0
- package/dist/swappers/thorchain/utils/getTradeRate/getTradeRate.d.ts +4 -0
- package/dist/swappers/thorchain/utils/getTradeRate/getTradeRate.js +57 -0
- package/dist/swappers/thorchain/utils/txFeeHelpers/ethTxFees/getEthTxFees.d.ts +15 -0
- package/dist/swappers/thorchain/utils/txFeeHelpers/ethTxFees/getEthTxFees.js +38 -0
- package/dist/swappers/utils/bignumber.d.ts +2 -0
- package/dist/swappers/utils/bignumber.js +14 -1
- package/dist/swappers/utils/constants.d.ts +2 -0
- package/dist/swappers/utils/constants.js +5 -0
- package/dist/swappers/utils/helpers/helpers.d.ts +7 -0
- package/dist/swappers/utils/helpers/helpers.js +13 -0
- package/dist/swappers/utils/test-data/assets.d.ts +1 -0
- package/dist/swappers/utils/test-data/assets.js +15 -1
- package/dist/swappers/zrx/ZrxApprovalNeeded/ZrxApprovalNeeded.js +1 -1
- package/dist/swappers/zrx/getZrxTradeQuote/getZrxTradeQuote.js +6 -5
- package/dist/swappers/zrx/utils/constants.d.ts +0 -4
- package/dist/swappers/zrx/utils/constants.js +1 -5
- package/dist/swappers/zrx/utils/helpers/helpers.d.ts +2 -11
- package/dist/swappers/zrx/utils/helpers/helpers.js +2 -14
- package/dist/swappers/zrx/utils/test-data/setupSwapQuote.d.ts +3 -3
- package/dist/swappers/zrx/utils/test-data/setupSwapQuote.js +5 -5
- package/dist/swappers/zrx/zrxBuildTrade/zrxBuildTrade.js +12 -9
- package/dist/swappers/zrx/zrxExecuteTrade/zrxExecuteTrade.js +1 -2
- package/package.json +1 -1
package/dist/api.d.ts
CHANGED
|
@@ -58,11 +58,12 @@ export declare type CommonTradeInput = {
|
|
|
58
58
|
buyAsset: Asset;
|
|
59
59
|
sellAmount: string;
|
|
60
60
|
sendMax: boolean;
|
|
61
|
-
|
|
61
|
+
sellAssetAccountNumber: number;
|
|
62
|
+
wallet?: HDWallet;
|
|
62
63
|
};
|
|
63
64
|
export declare type GetTradeQuoteInput = CommonTradeInput;
|
|
64
65
|
export declare type BuildTradeInput = CommonTradeInput & {
|
|
65
|
-
|
|
66
|
+
buyAssetAccountNumber: number;
|
|
66
67
|
slippage?: string;
|
|
67
68
|
wallet: HDWallet;
|
|
68
69
|
};
|
|
@@ -74,7 +75,7 @@ interface TradeBase<C extends SupportedChainIds> {
|
|
|
74
75
|
sources: Array<SwapSource>;
|
|
75
76
|
buyAsset: Asset;
|
|
76
77
|
sellAsset: Asset;
|
|
77
|
-
|
|
78
|
+
sellAssetAccountNumber: number;
|
|
78
79
|
}
|
|
79
80
|
export interface TradeQuote<C extends SupportedChainIds> extends TradeBase<C> {
|
|
80
81
|
allowanceContract: string;
|
|
@@ -155,7 +156,8 @@ export declare enum SwapErrorTypes {
|
|
|
155
156
|
UNSUPPORTED_CHAIN = "UNSUPPORTED_CHAIN",
|
|
156
157
|
VALIDATION_FAILED = "VALIDATION_FAILED",
|
|
157
158
|
MAKE_MEMO_FAILED = "MAKE_MEMO_FAILED",
|
|
158
|
-
PRICE_RATIO_FAILED = "PRICE_RATIO_FAILED"
|
|
159
|
+
PRICE_RATIO_FAILED = "PRICE_RATIO_FAILED",
|
|
160
|
+
POOL_NOT_FOUND = "POOL_NOT_FOUND"
|
|
159
161
|
}
|
|
160
162
|
export interface Swapper {
|
|
161
163
|
/** perform any necessary async initialization */
|
package/dist/api.js
CHANGED
|
@@ -31,4 +31,5 @@ var SwapErrorTypes;
|
|
|
31
31
|
SwapErrorTypes["VALIDATION_FAILED"] = "VALIDATION_FAILED";
|
|
32
32
|
SwapErrorTypes["MAKE_MEMO_FAILED"] = "MAKE_MEMO_FAILED";
|
|
33
33
|
SwapErrorTypes["PRICE_RATIO_FAILED"] = "PRICE_RATIO_FAILED";
|
|
34
|
+
SwapErrorTypes["POOL_NOT_FOUND"] = "POOL_NOT_FOUND";
|
|
34
35
|
})(SwapErrorTypes = exports.SwapErrorTypes || (exports.SwapErrorTypes = {}));
|
|
@@ -30,6 +30,6 @@ export declare class SwapperManager {
|
|
|
30
30
|
* @returns {SwapperType}
|
|
31
31
|
*/
|
|
32
32
|
getSwappersByPair(pair: ByPairInput): Swapper[];
|
|
33
|
-
getSupportedBuyAssetIdsFromSellId(args: BuyAssetBySellIdInput):
|
|
34
|
-
getSupportedSellableAssetIds(args: SupportedSellAssetsInput):
|
|
33
|
+
getSupportedBuyAssetIdsFromSellId(args: BuyAssetBySellIdInput): import("@shapeshiftoss/caip").AssetId[];
|
|
34
|
+
getSupportedSellableAssetIds(args: SupportedSellAssetsInput): import("@shapeshiftoss/caip").AssetId[];
|
|
35
35
|
}
|
package/dist/swappercli.js
CHANGED
|
@@ -74,7 +74,7 @@ const main = async () => {
|
|
|
74
74
|
const zrxSwapperDeps = { wallet, adapterManager, web3 };
|
|
75
75
|
const thorchainSwapperDeps = {
|
|
76
76
|
midgardUrl: 'https://midgard.thorchain.info/v2',
|
|
77
|
-
adapterManager
|
|
77
|
+
adapterManager
|
|
78
78
|
};
|
|
79
79
|
const manager = new SwapperManager_1.SwapperManager();
|
|
80
80
|
const zrxSwapper = new ZrxSwapper_1.ZrxSwapper(zrxSwapperDeps);
|
|
@@ -95,7 +95,8 @@ const main = async () => {
|
|
|
95
95
|
sellAsset,
|
|
96
96
|
buyAsset,
|
|
97
97
|
sellAmount: sellAmountBase,
|
|
98
|
-
|
|
98
|
+
sellAssetAccountNumber: 0,
|
|
99
|
+
wallet,
|
|
99
100
|
sendMax: false
|
|
100
101
|
});
|
|
101
102
|
}
|
|
@@ -115,8 +116,8 @@ const main = async () => {
|
|
|
115
116
|
sendMax: false,
|
|
116
117
|
sellAmount: sellAmountBase,
|
|
117
118
|
sellAsset,
|
|
118
|
-
|
|
119
|
-
|
|
119
|
+
sellAssetAccountNumber: 0,
|
|
120
|
+
buyAssetAccountNumber: 0
|
|
120
121
|
});
|
|
121
122
|
const txid = await swapper.executeTrade({ trade, wallet });
|
|
122
123
|
console.info('broadcast tx with id: ', txid);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AssetId } from '@shapeshiftoss/caip';
|
|
2
2
|
import { Asset, SupportedChainIds } from '@shapeshiftoss/types';
|
|
3
|
-
import { ApprovalNeededOutput, BuyAssetBySellIdInput, ExecuteTradeInput, Swapper, SwapperType, Trade, TradeQuote, TradeResult, TradeTxs } from '../../api';
|
|
3
|
+
import { ApprovalNeededOutput, BuyAssetBySellIdInput, ExecuteTradeInput, GetTradeQuoteInput, Swapper, SwapperType, Trade, TradeQuote, TradeResult, TradeTxs } from '../../api';
|
|
4
4
|
import { ThorchainSwapperDeps } from './types';
|
|
5
5
|
export declare class ThorchainSwapper implements Swapper {
|
|
6
6
|
private swapSupportedChainIds;
|
|
@@ -15,7 +15,7 @@ export declare class ThorchainSwapper implements Swapper {
|
|
|
15
15
|
filterBuyAssetsBySellAssetId(args: BuyAssetBySellIdInput): AssetId[];
|
|
16
16
|
filterAssetIdsBySellable(): AssetId[];
|
|
17
17
|
buildTrade(): Promise<Trade<SupportedChainIds>>;
|
|
18
|
-
getTradeQuote(): Promise<TradeQuote<SupportedChainIds>>;
|
|
18
|
+
getTradeQuote(input: GetTradeQuoteInput): Promise<TradeQuote<SupportedChainIds>>;
|
|
19
19
|
executeTrade(args: ExecuteTradeInput<SupportedChainIds>): Promise<TradeResult>;
|
|
20
20
|
getTradeTxs(): Promise<TradeTxs>;
|
|
21
21
|
}
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.ThorchainSwapper = void 0;
|
|
4
4
|
const caip_1 = require("@shapeshiftoss/caip");
|
|
5
5
|
const api_1 = require("../../api");
|
|
6
|
+
const getTradeQuote_1 = require("./getThorTradeQuote/getTradeQuote");
|
|
6
7
|
const getUsdRate_1 = require("./utils/getUsdRate/getUsdRate");
|
|
7
8
|
const thorService_1 = require("./utils/thorService");
|
|
8
9
|
class ThorchainSwapper {
|
|
@@ -55,8 +56,8 @@ class ThorchainSwapper {
|
|
|
55
56
|
async buildTrade() {
|
|
56
57
|
throw new Error('ThorchainSwapper: buildTrade unimplemented');
|
|
57
58
|
}
|
|
58
|
-
async getTradeQuote() {
|
|
59
|
-
|
|
59
|
+
async getTradeQuote(input) {
|
|
60
|
+
return (0, getTradeQuote_1.getThorTradeQuote)({ deps: this.deps, input });
|
|
60
61
|
}
|
|
61
62
|
async executeTrade(args) {
|
|
62
63
|
const { trade, wallet } = args;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { SupportedChainIds } from '@shapeshiftoss/types';
|
|
2
|
+
import { GetTradeQuoteInput, TradeQuote } from '../../../api';
|
|
3
|
+
import { ThorchainSwapperDeps } from '../types';
|
|
4
|
+
export declare const getThorTradeQuote: ({ deps, input }: {
|
|
5
|
+
deps: ThorchainSwapperDeps;
|
|
6
|
+
input: GetTradeQuoteInput;
|
|
7
|
+
}) => Promise<TradeQuote<SupportedChainIds>>;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getThorTradeQuote = void 0;
|
|
4
|
+
const caip_1 = require("@shapeshiftoss/caip");
|
|
5
|
+
const api_1 = require("../../../api");
|
|
6
|
+
const bignumber_1 = require("../../utils/bignumber");
|
|
7
|
+
const bignumber_2 = require("../../utils/bignumber");
|
|
8
|
+
const constants_1 = require("../../utils/constants");
|
|
9
|
+
const helpers_1 = require("../../utils/helpers/helpers");
|
|
10
|
+
const constants_2 = require("../utils/constants");
|
|
11
|
+
const getThorTxData_1 = require("../utils/ethereum/utils/getThorTxData");
|
|
12
|
+
const getPriceRatio_1 = require("../utils/getPriceRatio/getPriceRatio");
|
|
13
|
+
const getEthTxFees_1 = require("../utils/txFeeHelpers/ethTxFees/getEthTxFees");
|
|
14
|
+
const getThorTradeQuote = async ({ deps, input }) => {
|
|
15
|
+
const { sellAsset, buyAsset, sellAmount, sellAssetAccountNumber, wallet } = input;
|
|
16
|
+
if (!wallet)
|
|
17
|
+
throw new api_1.SwapError('[getTradeQuote] - wallet is required', {
|
|
18
|
+
code: api_1.SwapErrorTypes.VALIDATION_FAILED
|
|
19
|
+
});
|
|
20
|
+
try {
|
|
21
|
+
const { assetReference: sellAssetErc20Address, chainReference, chainNamespace } = (0, caip_1.fromAssetId)(sellAsset.assetId);
|
|
22
|
+
const isErc20Trade = sellAssetErc20Address.startsWith('0x');
|
|
23
|
+
const sellAssetChainId = (0, caip_1.toChainId)({ chainReference, chainNamespace });
|
|
24
|
+
const adapter = deps.adapterManager.byChainId(sellAssetChainId);
|
|
25
|
+
const bip44Params = adapter.buildBIP44Params({ accountNumber: Number(sellAssetAccountNumber) });
|
|
26
|
+
const receiveAddress = await adapter.getAddress({ wallet, bip44Params });
|
|
27
|
+
const { data, router } = await (0, getThorTxData_1.getThorTxInfo)({
|
|
28
|
+
deps,
|
|
29
|
+
sellAsset,
|
|
30
|
+
buyAsset,
|
|
31
|
+
sellAmount,
|
|
32
|
+
slippageTolerance: constants_1.DEFAULT_SLIPPAGE,
|
|
33
|
+
destinationAddress: receiveAddress,
|
|
34
|
+
isErc20Trade
|
|
35
|
+
});
|
|
36
|
+
const feeData = await (async () => {
|
|
37
|
+
switch (sellAssetChainId) {
|
|
38
|
+
case 'eip155:1':
|
|
39
|
+
return await (0, getEthTxFees_1.getEthTxFees)({
|
|
40
|
+
deps,
|
|
41
|
+
data,
|
|
42
|
+
router,
|
|
43
|
+
buyAsset,
|
|
44
|
+
sellAmount,
|
|
45
|
+
adapterManager: deps.adapterManager,
|
|
46
|
+
receiveAddress,
|
|
47
|
+
sellAssetReference: sellAssetErc20Address
|
|
48
|
+
});
|
|
49
|
+
default:
|
|
50
|
+
throw new api_1.SwapError('[getThorTxInfo] - Asset chainId is not supported.', {
|
|
51
|
+
code: api_1.SwapErrorTypes.UNSUPPORTED_CHAIN,
|
|
52
|
+
details: { sellAssetChainId }
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
})();
|
|
56
|
+
const sellAssetId = sellAsset.assetId;
|
|
57
|
+
const buyAssetId = buyAsset.assetId;
|
|
58
|
+
const feeAssetId = (0, caip_1.getFeeAssetIdFromAssetId)(buyAssetId);
|
|
59
|
+
if (!feeAssetId)
|
|
60
|
+
throw new api_1.SwapError(`[getThorTxInfo] - No feeAssetId found for ${buyAssetId}.`, {
|
|
61
|
+
code: api_1.SwapErrorTypes.VALIDATION_FAILED,
|
|
62
|
+
details: { buyAssetId }
|
|
63
|
+
});
|
|
64
|
+
const feeAssetRatio = await (0, getPriceRatio_1.getPriceRatio)(deps, { sellAssetId, buyAssetId: feeAssetId });
|
|
65
|
+
const priceRatio = await (0, getPriceRatio_1.getPriceRatio)(deps, { sellAssetId, buyAssetId });
|
|
66
|
+
const rate = (0, bignumber_2.bnOrZero)(1).div(priceRatio).toString();
|
|
67
|
+
const buyAmount = (0, helpers_1.normalizeAmount)((0, bignumber_2.bnOrZero)(sellAmount).times(rate));
|
|
68
|
+
const sellAssetTradeFee = (0, bignumber_2.bnOrZero)(feeData.tradeFee).times((0, bignumber_2.bnOrZero)(feeAssetRatio));
|
|
69
|
+
// padding minimum by 1.5 the trade fee to avoid thorchain "not enough to cover fee" errors.
|
|
70
|
+
const minimum = (0, bignumber_1.fromBaseUnit)(sellAssetTradeFee.times(1.5).toString(), sellAsset.precision);
|
|
71
|
+
return {
|
|
72
|
+
rate,
|
|
73
|
+
minimum,
|
|
74
|
+
maximum: constants_2.MAX_THORCHAIN_TRADE,
|
|
75
|
+
feeData,
|
|
76
|
+
sellAmount,
|
|
77
|
+
buyAmount,
|
|
78
|
+
sources: [{ name: 'thorchain', proportion: '1' }],
|
|
79
|
+
allowanceContract: router,
|
|
80
|
+
buyAsset,
|
|
81
|
+
sellAsset,
|
|
82
|
+
sellAssetAccountNumber
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
catch (e) {
|
|
86
|
+
if (e instanceof api_1.SwapError)
|
|
87
|
+
throw e;
|
|
88
|
+
throw new api_1.SwapError('[getThorTradeQuote]', {
|
|
89
|
+
cause: e,
|
|
90
|
+
code: api_1.SwapErrorTypes.TRADE_QUOTE_FAILED
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
exports.getThorTradeQuote = getThorTradeQuote;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const MAX_THORCHAIN_TRADE = "100000000000000000000000000";
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
import { ethereum } from '@shapeshiftoss/chain-adapters';
|
|
2
2
|
import { ETHSignTx, HDWallet } from '@shapeshiftoss/hdwallet-core';
|
|
3
3
|
import { Asset, BIP44Params } from '@shapeshiftoss/types';
|
|
4
|
-
import BigNumber from 'bignumber.js';
|
|
5
4
|
import { ThorchainSwapperDeps } from '../../types';
|
|
6
|
-
export declare const fromBaseUnit: (value: BigNumber.Value, decimals: number, displayDecimals?: number) => string;
|
|
7
|
-
export declare const toBaseUnit: (amount: BigNumber.Value | undefined, precision: number) => string;
|
|
8
5
|
export declare const makeTradeTx: ({ wallet, bip44Params, sellAmount, buyAsset, sellAsset, destinationAddress, adapter, maxFeePerGas, maxPriorityFeePerGas, slippageTolerance, deps, gasLimit }: {
|
|
9
6
|
wallet: HDWallet;
|
|
10
7
|
bip44Params: BIP44Params;
|
|
@@ -1,63 +1,22 @@
|
|
|
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
|
-
exports.makeTradeTx =
|
|
3
|
+
exports.makeTradeTx = void 0;
|
|
7
4
|
const caip_1 = require("@shapeshiftoss/caip");
|
|
8
|
-
const bignumber_js_1 = __importDefault(require("bignumber.js"));
|
|
9
5
|
const api_1 = require("../../../../api");
|
|
10
|
-
const
|
|
11
|
-
const getPriceRatio_1 = require("../getPriceRatio/getPriceRatio");
|
|
12
|
-
const makeSwapMemo_1 = require("../makeSwapMemo/makeSwapMemo");
|
|
13
|
-
const thorService_1 = require("../thorService");
|
|
14
|
-
const routerCalldata_1 = require("./routerCalldata");
|
|
15
|
-
const fromBaseUnit = (value, decimals, displayDecimals = 6) => {
|
|
16
|
-
return (0, bignumber_1.bnOrZero)(value)
|
|
17
|
-
.div(`1e+${decimals}`)
|
|
18
|
-
.decimalPlaces(displayDecimals, bignumber_js_1.default.ROUND_DOWN)
|
|
19
|
-
.toString();
|
|
20
|
-
};
|
|
21
|
-
exports.fromBaseUnit = fromBaseUnit;
|
|
22
|
-
const toBaseUnit = (amount, precision) => {
|
|
23
|
-
return (0, bignumber_1.bnOrZero)(amount)
|
|
24
|
-
.times(new bignumber_js_1.default(10).exponentiatedBy((0, bignumber_1.bnOrZero)(precision)))
|
|
25
|
-
.toFixed(0);
|
|
26
|
-
};
|
|
27
|
-
exports.toBaseUnit = toBaseUnit;
|
|
6
|
+
const getThorTxData_1 = require("../ethereum/utils/getThorTxData");
|
|
28
7
|
const makeTradeTx = async ({ wallet, bip44Params, sellAmount, buyAsset, sellAsset, destinationAddress, adapter, maxFeePerGas, maxPriorityFeePerGas, slippageTolerance, deps, gasLimit }) => {
|
|
29
8
|
try {
|
|
30
9
|
const { assetReference } = (0, caip_1.fromAssetId)(sellAsset.assetId);
|
|
31
10
|
const isErc20Trade = assetReference.startsWith('0x');
|
|
32
|
-
const { data
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
code: api_1.SwapErrorTypes.RESPONSE_ERROR,
|
|
39
|
-
details: { inboundAddresses }
|
|
40
|
-
});
|
|
41
|
-
const priceRatio = await (0, getPriceRatio_1.getPriceRatio)(deps, {
|
|
42
|
-
buyAssetId: buyAsset.assetId,
|
|
43
|
-
sellAssetId: sellAsset.assetId
|
|
44
|
-
});
|
|
45
|
-
const expectedBuyAmount = (0, exports.toBaseUnit)((0, exports.fromBaseUnit)((0, bignumber_1.bnOrZero)(sellAmount).dividedBy(priceRatio), sellAsset.precision), buyAsset.precision);
|
|
46
|
-
if (!(0, bignumber_1.bnOrZero)(expectedBuyAmount).gte(0) ||
|
|
47
|
-
!((0, bignumber_1.bnOrZero)(slippageTolerance).gte(0) && (0, bignumber_1.bnOrZero)(slippageTolerance).lte(1)))
|
|
48
|
-
throw new api_1.SwapError('[makeTradeTx]: bad expected buy amount or bad slippage tolerance', {
|
|
49
|
-
code: api_1.SwapErrorTypes.BUILD_TRADE_FAILED
|
|
50
|
-
});
|
|
51
|
-
const limit = (0, bignumber_1.bnOrZero)(expectedBuyAmount)
|
|
52
|
-
.times(new bignumber_js_1.default(1).minus(slippageTolerance))
|
|
53
|
-
.decimalPlaces(0)
|
|
54
|
-
.toString();
|
|
55
|
-
const memo = (0, makeSwapMemo_1.makeSwapMemo)({
|
|
56
|
-
buyAssetId: buyAsset.assetId,
|
|
11
|
+
const { data, router } = await (0, getThorTxData_1.getThorTxInfo)({
|
|
12
|
+
deps,
|
|
13
|
+
sellAsset,
|
|
14
|
+
buyAsset,
|
|
15
|
+
sellAmount,
|
|
16
|
+
slippageTolerance,
|
|
57
17
|
destinationAddress,
|
|
58
|
-
|
|
18
|
+
isErc20Trade
|
|
59
19
|
});
|
|
60
|
-
const data = await (0, routerCalldata_1.deposit)(vault, router, isErc20Trade ? assetReference : '0x0000000000000000000000000000000000000000', sellAmount, memo);
|
|
61
20
|
return adapter.buildCustomTx({
|
|
62
21
|
wallet,
|
|
63
22
|
bip44Params,
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Asset } from '@shapeshiftoss/types';
|
|
2
|
+
import { ThorchainSwapperDeps } from '../../../types';
|
|
3
|
+
export declare const getThorTxInfo: ({ deps, sellAsset, buyAsset, sellAmount, slippageTolerance, destinationAddress, isErc20Trade }: {
|
|
4
|
+
deps: ThorchainSwapperDeps;
|
|
5
|
+
sellAsset: Asset;
|
|
6
|
+
buyAsset: Asset;
|
|
7
|
+
sellAmount: string;
|
|
8
|
+
slippageTolerance: string;
|
|
9
|
+
destinationAddress: string;
|
|
10
|
+
isErc20Trade: boolean;
|
|
11
|
+
}) => Promise<{
|
|
12
|
+
data: any;
|
|
13
|
+
memo: string;
|
|
14
|
+
router: string;
|
|
15
|
+
}>;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getThorTxInfo = void 0;
|
|
4
|
+
const caip_1 = require("@shapeshiftoss/caip");
|
|
5
|
+
const api_1 = require("../../../../../api");
|
|
6
|
+
const bignumber_1 = require("../../../../utils/bignumber");
|
|
7
|
+
const getPriceRatio_1 = require("../../getPriceRatio/getPriceRatio");
|
|
8
|
+
const makeSwapMemo_1 = require("../../makeSwapMemo/makeSwapMemo");
|
|
9
|
+
const thorService_1 = require("../../thorService");
|
|
10
|
+
const routerCalldata_1 = require("../routerCalldata");
|
|
11
|
+
const getThorTxInfo = async ({ deps, sellAsset, buyAsset, sellAmount, slippageTolerance, destinationAddress, isErc20Trade }) => {
|
|
12
|
+
try {
|
|
13
|
+
const { assetReference } = (0, caip_1.fromAssetId)(sellAsset.assetId);
|
|
14
|
+
const { data: inboundAddresses } = await thorService_1.thorService.get(`${deps.midgardUrl}/thorchain/inbound_addresses`);
|
|
15
|
+
const ethInboundAddresses = inboundAddresses.find((inbound) => inbound.chain === 'ETH');
|
|
16
|
+
const vault = ethInboundAddresses === null || ethInboundAddresses === void 0 ? void 0 : ethInboundAddresses.address;
|
|
17
|
+
const router = ethInboundAddresses === null || ethInboundAddresses === void 0 ? void 0 : ethInboundAddresses.router;
|
|
18
|
+
if (!vault || !router)
|
|
19
|
+
throw new api_1.SwapError(`[getPriceRatio]: router or vault found for ETH`, {
|
|
20
|
+
code: api_1.SwapErrorTypes.RESPONSE_ERROR,
|
|
21
|
+
details: { inboundAddresses }
|
|
22
|
+
});
|
|
23
|
+
const priceRatio = await (0, getPriceRatio_1.getPriceRatio)(deps, {
|
|
24
|
+
buyAssetId: buyAsset.assetId,
|
|
25
|
+
sellAssetId: sellAsset.assetId
|
|
26
|
+
});
|
|
27
|
+
const expectedBuyAmount = (0, bignumber_1.toBaseUnit)((0, bignumber_1.fromBaseUnit)((0, bignumber_1.bnOrZero)(sellAmount).dividedBy(priceRatio), sellAsset.precision), buyAsset.precision);
|
|
28
|
+
if (!(0, bignumber_1.bnOrZero)(expectedBuyAmount).gte(0) ||
|
|
29
|
+
!((0, bignumber_1.bnOrZero)(slippageTolerance).gte(0) && (0, bignumber_1.bnOrZero)(slippageTolerance).lte(1)))
|
|
30
|
+
throw new api_1.SwapError('[makeTradeTx]: bad expected buy amount or bad slippage tolerance', {
|
|
31
|
+
code: api_1.SwapErrorTypes.BUILD_TRADE_FAILED
|
|
32
|
+
});
|
|
33
|
+
const limit = (0, bignumber_1.bnOrZero)(expectedBuyAmount)
|
|
34
|
+
.times((0, bignumber_1.bn)(1).minus(slippageTolerance))
|
|
35
|
+
.decimalPlaces(0)
|
|
36
|
+
.toString();
|
|
37
|
+
const memo = (0, makeSwapMemo_1.makeSwapMemo)({
|
|
38
|
+
buyAssetId: buyAsset.assetId,
|
|
39
|
+
destinationAddress,
|
|
40
|
+
limit
|
|
41
|
+
});
|
|
42
|
+
const data = await (0, routerCalldata_1.deposit)(router, vault, isErc20Trade ? assetReference : '0x0000000000000000000000000000000000000000', sellAmount, memo);
|
|
43
|
+
return {
|
|
44
|
+
data,
|
|
45
|
+
memo,
|
|
46
|
+
router
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
catch (e) {
|
|
50
|
+
if (e instanceof api_1.SwapError)
|
|
51
|
+
throw e;
|
|
52
|
+
throw new api_1.SwapError('[getThorTxInfo]', { cause: e, code: api_1.SwapErrorTypes.TRADE_QUOTE_FAILED });
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
exports.getThorTxInfo = getThorTxInfo;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { AssetId } from '@shapeshiftoss/caip';
|
|
2
|
+
import { Asset } from '@shapeshiftoss/types';
|
|
3
|
+
import { ThorchainSwapperDeps } from '../../types';
|
|
4
|
+
export declare const getTradeRate: (sellAsset: Asset, buyAssetId: AssetId, sellAmount: string, deps: ThorchainSwapperDeps) => Promise<string>;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getTradeRate = void 0;
|
|
4
|
+
const caip_1 = require("@shapeshiftoss/caip");
|
|
5
|
+
const api_1 = require("../../../../api");
|
|
6
|
+
const bignumber_1 = require("../../../utils/bignumber");
|
|
7
|
+
const bignumber_2 = require("../../../utils/bignumber");
|
|
8
|
+
const thorService_1 = require("../thorService");
|
|
9
|
+
const THOR_PRECISION = 8;
|
|
10
|
+
const getSwapOutput = (inputAmount, poolData, toRune) => {
|
|
11
|
+
const x = inputAmount;
|
|
12
|
+
const X = toRune ? poolData.assetBalance : poolData.runeBalance;
|
|
13
|
+
const Y = toRune ? poolData.runeBalance : poolData.assetBalance;
|
|
14
|
+
const numerator = x.times(X).times(Y);
|
|
15
|
+
const denominator = x.plus(X).pow(2);
|
|
16
|
+
return numerator.div(denominator);
|
|
17
|
+
};
|
|
18
|
+
const getDoubleSwapOutput = (input, inputPool, outputPool) => {
|
|
19
|
+
const runeToOutput = getSwapOutput(input, inputPool, true);
|
|
20
|
+
return getSwapOutput(runeToOutput, outputPool, false);
|
|
21
|
+
};
|
|
22
|
+
// https://docs.thorchain.org/how-it-works/prices
|
|
23
|
+
// TODO this does not support swaps between native "RUNE"
|
|
24
|
+
// Rune swaps use a different calculation because its 1 hop between pools instead of 2
|
|
25
|
+
const getTradeRate = async (sellAsset, buyAssetId, sellAmount, deps) => {
|
|
26
|
+
const buyPoolId = caip_1.adapters.assetIdToPoolAssetId({ assetId: buyAssetId });
|
|
27
|
+
const sellPoolId = caip_1.adapters.assetIdToPoolAssetId({ assetId: sellAsset.assetId });
|
|
28
|
+
if (!buyPoolId || !sellPoolId)
|
|
29
|
+
throw new api_1.SwapError(`[getPriceRatio]: No thorchain pool found`, {
|
|
30
|
+
code: api_1.SwapErrorTypes.POOL_NOT_FOUND,
|
|
31
|
+
fn: 'getPriceRatio',
|
|
32
|
+
details: { buyPoolId, sellPoolId }
|
|
33
|
+
});
|
|
34
|
+
const { data: responseData } = await thorService_1.thorService.get(`${deps.midgardUrl}/pools`);
|
|
35
|
+
const buyPool = responseData.find((response) => response.asset === buyPoolId);
|
|
36
|
+
const sellPool = responseData.find((response) => response.asset === sellPoolId);
|
|
37
|
+
if (!buyPool || !sellPool)
|
|
38
|
+
throw new api_1.SwapError(`[getPriceRatio]: no pools found for`, {
|
|
39
|
+
code: api_1.SwapErrorTypes.POOL_NOT_FOUND,
|
|
40
|
+
fn: 'getPriceRatio',
|
|
41
|
+
details: { buyPoolId, sellPoolId }
|
|
42
|
+
});
|
|
43
|
+
// All thorchain pool amounts are base 8 regardless of token precision
|
|
44
|
+
const sellBaseAmount = (0, bignumber_1.bn)((0, bignumber_2.toBaseUnit)((0, bignumber_2.fromBaseUnit)(sellAmount, sellAsset.precision), THOR_PRECISION));
|
|
45
|
+
const sellAssetPoolData = {
|
|
46
|
+
assetBalance: (0, bignumber_1.bn)(sellPool.assetDepth),
|
|
47
|
+
runeBalance: (0, bignumber_1.bn)(sellPool.runeDepth)
|
|
48
|
+
};
|
|
49
|
+
const buyAssetPoolData = {
|
|
50
|
+
assetBalance: (0, bignumber_1.bn)(buyPool.assetDepth),
|
|
51
|
+
runeBalance: (0, bignumber_1.bn)(buyPool.runeDepth)
|
|
52
|
+
};
|
|
53
|
+
const outputAmountBase8 = getDoubleSwapOutput(sellBaseAmount, sellAssetPoolData, buyAssetPoolData);
|
|
54
|
+
const outputAmount = (0, bignumber_2.fromBaseUnit)(outputAmountBase8, THOR_PRECISION);
|
|
55
|
+
return (0, bignumber_1.bn)(outputAmount).div((0, bignumber_2.fromBaseUnit)(sellAmount, sellAsset.precision)).toString();
|
|
56
|
+
};
|
|
57
|
+
exports.getTradeRate = getTradeRate;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { AssetReference } from '@shapeshiftoss/caip';
|
|
2
|
+
import { ChainAdapterManager } from '@shapeshiftoss/chain-adapters';
|
|
3
|
+
import { Asset } from '@shapeshiftoss/types';
|
|
4
|
+
import { QuoteFeeData } from '../../../../../api';
|
|
5
|
+
import { ThorchainSwapperDeps } from '../../../types';
|
|
6
|
+
export declare const getEthTxFees: ({ deps, data, router, buyAsset, sellAmount, adapterManager, receiveAddress, sellAssetReference }: {
|
|
7
|
+
deps: ThorchainSwapperDeps;
|
|
8
|
+
data: string;
|
|
9
|
+
router: string;
|
|
10
|
+
buyAsset: Asset;
|
|
11
|
+
sellAmount: string;
|
|
12
|
+
sellAssetReference: AssetReference | string;
|
|
13
|
+
adapterManager: ChainAdapterManager;
|
|
14
|
+
receiveAddress: string;
|
|
15
|
+
}) => Promise<QuoteFeeData<'eip155:1'>>;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getEthTxFees = void 0;
|
|
4
|
+
const api_1 = require("../../../../../api");
|
|
5
|
+
const bignumber_1 = require("../../../../utils/bignumber");
|
|
6
|
+
const constants_1 = require("../../../../utils/constants");
|
|
7
|
+
const estimateTradeFee_1 = require("../../estimateTradeFee/estimateTradeFee");
|
|
8
|
+
const getEthTxFees = async ({ deps, data, router, buyAsset, sellAmount, adapterManager, receiveAddress, sellAssetReference }) => {
|
|
9
|
+
try {
|
|
10
|
+
const adapter = adapterManager.byChainId('eip155:1');
|
|
11
|
+
// TODO(ryankk): add falling back on hard coded gas Limit * new chain adapter method if it fails
|
|
12
|
+
const feeDataOptions = await adapter.getFeeData({
|
|
13
|
+
to: router,
|
|
14
|
+
value: sellAmount,
|
|
15
|
+
chainSpecific: { from: receiveAddress, contractData: data }
|
|
16
|
+
});
|
|
17
|
+
const feeData = feeDataOptions['fast'];
|
|
18
|
+
const tradeFee = await (0, estimateTradeFee_1.estimateTradeFee)(deps, buyAsset.assetId);
|
|
19
|
+
return {
|
|
20
|
+
fee: feeData.txFee,
|
|
21
|
+
chainSpecific: {
|
|
22
|
+
estimatedGas: feeData.chainSpecific.gasLimit,
|
|
23
|
+
gasPrice: feeData.chainSpecific.gasPrice,
|
|
24
|
+
approvalFee: sellAssetReference &&
|
|
25
|
+
(0, bignumber_1.bnOrZero)(constants_1.APPROVAL_GAS_LIMIT)
|
|
26
|
+
.multipliedBy((0, bignumber_1.bnOrZero)(feeData.chainSpecific.gasPrice))
|
|
27
|
+
.toString()
|
|
28
|
+
},
|
|
29
|
+
tradeFee
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
catch (e) {
|
|
33
|
+
if (e instanceof api_1.SwapError)
|
|
34
|
+
throw e;
|
|
35
|
+
throw new api_1.SwapError('[getThorTxInfo]', { cause: e, code: api_1.SwapErrorTypes.TRADE_QUOTE_FAILED });
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
exports.getEthTxFees = getEthTxFees;
|
|
@@ -2,3 +2,5 @@ import BigNumber from 'bignumber.js';
|
|
|
2
2
|
export declare type BN = BigNumber;
|
|
3
3
|
export declare const bn: (n: BigNumber.Value, base?: number) => BN;
|
|
4
4
|
export declare const bnOrZero: (n: BigNumber.Value | null | undefined) => BN;
|
|
5
|
+
export declare const fromBaseUnit: (value: BigNumber.Value, decimals: number, displayDecimals?: number) => string;
|
|
6
|
+
export declare const toBaseUnit: (amount: BigNumber.Value | undefined, precision: number) => string;
|
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.bnOrZero = exports.bn = void 0;
|
|
6
|
+
exports.toBaseUnit = exports.fromBaseUnit = exports.bnOrZero = exports.bn = void 0;
|
|
7
7
|
const bignumber_js_1 = __importDefault(require("bignumber.js"));
|
|
8
8
|
const bn = (n, base = 10) => new bignumber_js_1.default(n, base);
|
|
9
9
|
exports.bn = bn;
|
|
@@ -12,3 +12,16 @@ const bnOrZero = (n) => {
|
|
|
12
12
|
return value.isNaN() ? (0, exports.bn)(0) : value;
|
|
13
13
|
};
|
|
14
14
|
exports.bnOrZero = bnOrZero;
|
|
15
|
+
const fromBaseUnit = (value, decimals, displayDecimals = 6) => {
|
|
16
|
+
return (0, exports.bnOrZero)(value)
|
|
17
|
+
.div(`1e+${decimals}`)
|
|
18
|
+
.decimalPlaces(displayDecimals, bignumber_js_1.default.ROUND_DOWN)
|
|
19
|
+
.toString();
|
|
20
|
+
};
|
|
21
|
+
exports.fromBaseUnit = fromBaseUnit;
|
|
22
|
+
const toBaseUnit = (amount, precision) => {
|
|
23
|
+
return (0, exports.bnOrZero)(amount)
|
|
24
|
+
.times(new bignumber_js_1.default(10).exponentiatedBy((0, exports.bnOrZero)(precision)))
|
|
25
|
+
.toFixed(0);
|
|
26
|
+
};
|
|
27
|
+
exports.toBaseUnit = toBaseUnit;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_SLIPPAGE = exports.APPROVAL_GAS_LIMIT = void 0;
|
|
4
|
+
exports.APPROVAL_GAS_LIMIT = '100000'; // Most approvals are around 40k, we've seen 72k in the wild, so 100000 for safety.
|
|
5
|
+
exports.DEFAULT_SLIPPAGE = '0.03'; // 3%
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { BN } from '../bignumber';
|
|
2
|
+
/**
|
|
3
|
+
* This function keeps 17 significant digits, so even if we try to trade 1 Billion of an
|
|
4
|
+
* ETH or ERC20, we still keep 7 decimal places.
|
|
5
|
+
* @param amount
|
|
6
|
+
*/
|
|
7
|
+
export declare const normalizeAmount: (amount: string | number | BN) => string;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.normalizeAmount = void 0;
|
|
4
|
+
const bignumber_1 = require("../bignumber");
|
|
5
|
+
/**
|
|
6
|
+
* This function keeps 17 significant digits, so even if we try to trade 1 Billion of an
|
|
7
|
+
* ETH or ERC20, we still keep 7 decimal places.
|
|
8
|
+
* @param amount
|
|
9
|
+
*/
|
|
10
|
+
const normalizeAmount = (amount) => {
|
|
11
|
+
return (0, bignumber_1.bnOrZero)(amount).toNumber().toLocaleString('fullwide', { useGrouping: false });
|
|
12
|
+
};
|
|
13
|
+
exports.normalizeAmount = normalizeAmount;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ETH = exports.WBTC = exports.FOX = exports.WETH = exports.BTC = void 0;
|
|
3
|
+
exports.UNSUPPORTED = exports.ETH = exports.WBTC = exports.FOX = exports.WETH = exports.BTC = void 0;
|
|
4
4
|
const types_1 = require("@shapeshiftoss/types");
|
|
5
5
|
exports.BTC = {
|
|
6
6
|
assetId: 'bip122:000000000019d6689c085ae165831e93/slip44:0',
|
|
@@ -72,3 +72,17 @@ exports.ETH = {
|
|
|
72
72
|
explorerTxLink: 'https://etherscan.io/tx/',
|
|
73
73
|
explorerAddressLink: 'https://etherscan.io/address/'
|
|
74
74
|
};
|
|
75
|
+
exports.UNSUPPORTED = {
|
|
76
|
+
assetId: 'eip155:1/slip44:420',
|
|
77
|
+
chainId: 'eip155:1',
|
|
78
|
+
chain: types_1.ChainTypes.Ethereum,
|
|
79
|
+
network: types_1.NetworkTypes.MAINNET,
|
|
80
|
+
symbol: 'ETH',
|
|
81
|
+
name: 'Ethereum',
|
|
82
|
+
precision: 18,
|
|
83
|
+
color: '#FFFFFF',
|
|
84
|
+
icon: 'https://assets.coincap.io/assets/icons/eth@2x.png',
|
|
85
|
+
explorer: 'https://etherscan.io',
|
|
86
|
+
explorerTxLink: 'https://etherscan.io/tx/',
|
|
87
|
+
explorerAddressLink: 'https://etherscan.io/address/'
|
|
88
|
+
};
|
|
@@ -21,7 +21,7 @@ async function ZrxApprovalNeeded({ adapterManager, web3 }, { quote, wallet }) {
|
|
|
21
21
|
if (sellAsset.assetId === (0, caip_1.getFeeAssetIdFromAssetId)(sellAsset.assetId)) {
|
|
22
22
|
return { approvalNeeded: false };
|
|
23
23
|
}
|
|
24
|
-
const accountNumber =
|
|
24
|
+
const accountNumber = quote.sellAssetAccountNumber;
|
|
25
25
|
const adapter = await adapterManager.byChainId(sellAsset.chainId);
|
|
26
26
|
const bip44Params = adapter.buildBIP44Params({ accountNumber });
|
|
27
27
|
const receiveAddress = await adapter.getAddress({ wallet, bip44Params });
|
|
@@ -4,14 +4,15 @@ exports.getZrxTradeQuote = void 0;
|
|
|
4
4
|
const caip_1 = require("@shapeshiftoss/caip");
|
|
5
5
|
const api_1 = require("../../../api");
|
|
6
6
|
const bignumber_1 = require("../../utils/bignumber");
|
|
7
|
+
const constants_1 = require("../../utils/constants");
|
|
8
|
+
const helpers_1 = require("../../utils/helpers/helpers");
|
|
7
9
|
const getZrxMinMax_1 = require("../getZrxMinMax/getZrxMinMax");
|
|
8
|
-
const
|
|
9
|
-
const helpers_1 = require("../utils/helpers/helpers");
|
|
10
|
+
const constants_2 = require("../utils/constants");
|
|
10
11
|
const zrxService_1 = require("../utils/zrxService");
|
|
11
12
|
async function getZrxTradeQuote(input) {
|
|
12
13
|
var _a;
|
|
13
14
|
try {
|
|
14
|
-
const { sellAsset, buyAsset, sellAmount,
|
|
15
|
+
const { sellAsset, buyAsset, sellAmount, sellAssetAccountNumber } = input;
|
|
15
16
|
if (buyAsset.chainId !== 'eip155:1' || sellAsset.chainId !== 'eip155:1') {
|
|
16
17
|
throw new api_1.SwapError('[getZrxTradeQuote] - Both assets need to be on the Ethereum chain to use Zrx', {
|
|
17
18
|
code: api_1.SwapErrorTypes.UNSUPPORTED_PAIR,
|
|
@@ -61,11 +62,11 @@ async function getZrxTradeQuote(input) {
|
|
|
61
62
|
},
|
|
62
63
|
sellAmount: data.sellAmount,
|
|
63
64
|
buyAmount: data.buyAmount,
|
|
64
|
-
sources: ((_a = data.sources) === null || _a === void 0 ? void 0 : _a.filter((s) => parseFloat(s.proportion) > 0)) ||
|
|
65
|
+
sources: ((_a = data.sources) === null || _a === void 0 ? void 0 : _a.filter((s) => parseFloat(s.proportion) > 0)) || constants_2.DEFAULT_SOURCE,
|
|
65
66
|
allowanceContract: data.allowanceTarget,
|
|
66
67
|
buyAsset,
|
|
67
68
|
sellAsset,
|
|
68
|
-
|
|
69
|
+
sellAssetAccountNumber
|
|
69
70
|
};
|
|
70
71
|
}
|
|
71
72
|
catch (e) {
|
|
@@ -5,7 +5,6 @@ export declare const FOX_TOKEN_CONTRACT_ADDRESS = "0xc770EEfAd204B5180dF6a14Ee19
|
|
|
5
5
|
export declare const WETH_TOKEN_CONTRACT_ADDRESS = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2";
|
|
6
6
|
export declare const UNISWAP_WETH_FOX_POOL_ADDRESS = "0x470e8de2ebaef52014a47cb5e6af86884947f08c";
|
|
7
7
|
export declare const MAX_ALLOWANCE = "100000000000000000000000000";
|
|
8
|
-
export declare const APPROVAL_GAS_LIMIT = "100000";
|
|
9
8
|
export declare const LIQUIDITY_GAS_LIMIT = "350000";
|
|
10
9
|
export declare const MAX_GAS_PRICE = "1000000000000";
|
|
11
10
|
export declare const MAX_ZRX_TRADE = "100000000000000000000000000";
|
|
@@ -13,8 +12,5 @@ export declare const DEFAULT_SOURCE: {
|
|
|
13
12
|
name: string;
|
|
14
13
|
proportion: string;
|
|
15
14
|
}[];
|
|
16
|
-
export declare const DEFAULT_SLIPPAGE = "0.03";
|
|
17
|
-
export declare const MAX_SLIPPAGE = "0.3";
|
|
18
|
-
export declare const ETH_FEE_ESTIMATE_PADDING = "1.2";
|
|
19
15
|
export declare const AFFILIATE_ADDRESS = "0xc770eefad204b5180df6a14ee197d99d808ee52d";
|
|
20
16
|
export declare const APPROVAL_BUY_AMOUNT = "100000000000000000";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.APPROVAL_BUY_AMOUNT = exports.AFFILIATE_ADDRESS = exports.
|
|
3
|
+
exports.APPROVAL_BUY_AMOUNT = exports.AFFILIATE_ADDRESS = exports.DEFAULT_SOURCE = exports.MAX_ZRX_TRADE = exports.MAX_GAS_PRICE = exports.LIQUIDITY_GAS_LIMIT = exports.MAX_ALLOWANCE = exports.UNISWAP_WETH_FOX_POOL_ADDRESS = exports.WETH_TOKEN_CONTRACT_ADDRESS = exports.FOX_TOKEN_CONTRACT_ADDRESS = exports.ZERO_ADDRESS = exports.UNISWAP_FACTORY_ADDRESS = exports.UNISWAP_ROUTER_ADDRESS = void 0;
|
|
4
4
|
exports.UNISWAP_ROUTER_ADDRESS = '0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D';
|
|
5
5
|
exports.UNISWAP_FACTORY_ADDRESS = '0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f';
|
|
6
6
|
exports.ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
|
|
@@ -8,13 +8,9 @@ exports.FOX_TOKEN_CONTRACT_ADDRESS = '0xc770EEfAd204B5180dF6a14Ee197D99d808ee52d
|
|
|
8
8
|
exports.WETH_TOKEN_CONTRACT_ADDRESS = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2';
|
|
9
9
|
exports.UNISWAP_WETH_FOX_POOL_ADDRESS = '0x470e8de2ebaef52014a47cb5e6af86884947f08c';
|
|
10
10
|
exports.MAX_ALLOWANCE = '100000000000000000000000000';
|
|
11
|
-
exports.APPROVAL_GAS_LIMIT = '100000'; // Most approvals are around 40k, we've seen 72k in the wild, so 100000 for safety.
|
|
12
11
|
exports.LIQUIDITY_GAS_LIMIT = '350000'; // Most Liquidity txs are around 150000
|
|
13
12
|
exports.MAX_GAS_PRICE = '1000000000000'; // 1000 GWei
|
|
14
13
|
exports.MAX_ZRX_TRADE = '100000000000000000000000000';
|
|
15
14
|
exports.DEFAULT_SOURCE = [{ name: '0x', proportion: '1' }];
|
|
16
|
-
exports.DEFAULT_SLIPPAGE = '0.03'; // 3%
|
|
17
|
-
exports.MAX_SLIPPAGE = '0.3'; // 30%
|
|
18
|
-
exports.ETH_FEE_ESTIMATE_PADDING = '1.2'; // Padding the fee estimate by 20% to avoid trade errors.
|
|
19
15
|
exports.AFFILIATE_ADDRESS = '0xc770eefad204b5180df6a14ee197d99d808ee52d';
|
|
20
16
|
exports.APPROVAL_BUY_AMOUNT = '100000000000000000'; // A valid buy amount - 0.1 ETH
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { ChainAdapterManager } from '@shapeshiftoss/chain-adapters';
|
|
2
2
|
import { HDWallet } from '@shapeshiftoss/hdwallet-core';
|
|
3
3
|
import { Asset, SupportedChainIds } from '@shapeshiftoss/types';
|
|
4
|
-
import BigNumber from 'bignumber.js';
|
|
5
4
|
import Web3 from 'web3';
|
|
6
5
|
import { AbiItem } from 'web3-utils';
|
|
7
6
|
import { TradeQuote } from '../../../../api';
|
|
7
|
+
import { BN } from '../../../utils/bignumber';
|
|
8
8
|
export declare type GetAllowanceRequiredArgs = {
|
|
9
9
|
receiveAddress: string;
|
|
10
10
|
allowanceContract: string;
|
|
@@ -27,17 +27,8 @@ declare type GrantAllowanceArgs = {
|
|
|
27
27
|
erc20Abi: AbiItem[];
|
|
28
28
|
web3: Web3;
|
|
29
29
|
};
|
|
30
|
-
/**
|
|
31
|
-
* Very large amounts like those found in ERC20s with a precision of 18 get converted
|
|
32
|
-
* to exponential notation ('1.6e+21') in javascript. The 0x api doesn't play well with
|
|
33
|
-
* exponential notation so we need to ensure that it is represented as an integer string.
|
|
34
|
-
* This function keeps 17 significant digits, so even if we try to trade 1 Billion of an
|
|
35
|
-
* ETH or ERC20, we still keep 7 decimal places.
|
|
36
|
-
* @param amount
|
|
37
|
-
*/
|
|
38
|
-
export declare const normalizeAmount: (amount: string | number | BigNumber) => string;
|
|
39
30
|
export declare const getERC20Allowance: ({ erc20AllowanceAbi, web3, sellAssetErc20Address, ownerAddress, spenderAddress }: GetERC20AllowanceArgs) => Promise<any>;
|
|
40
|
-
export declare const getAllowanceRequired: ({ receiveAddress, allowanceContract, sellAsset, sellAmount, web3, erc20AllowanceAbi }: GetAllowanceRequiredArgs) => Promise<
|
|
31
|
+
export declare const getAllowanceRequired: ({ receiveAddress, allowanceContract, sellAsset, sellAmount, web3, erc20AllowanceAbi }: GetAllowanceRequiredArgs) => Promise<BN>;
|
|
41
32
|
export declare const getUsdRate: (asset: Asset) => Promise<string>;
|
|
42
33
|
export declare const grantAllowance: ({ quote, wallet, adapterManager, erc20Abi, web3 }: GrantAllowanceArgs) => Promise<string>;
|
|
43
34
|
export {};
|
|
@@ -1,23 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.grantAllowance = exports.getUsdRate = exports.getAllowanceRequired = exports.getERC20Allowance =
|
|
3
|
+
exports.grantAllowance = exports.getUsdRate = exports.getAllowanceRequired = exports.getERC20Allowance = void 0;
|
|
4
4
|
const caip_1 = require("@shapeshiftoss/caip");
|
|
5
5
|
const web3_utils_1 = require("web3-utils");
|
|
6
6
|
const api_1 = require("../../../../api");
|
|
7
7
|
const bignumber_1 = require("../../../utils/bignumber");
|
|
8
8
|
const zrxService_1 = require("../zrxService");
|
|
9
|
-
/**
|
|
10
|
-
* Very large amounts like those found in ERC20s with a precision of 18 get converted
|
|
11
|
-
* to exponential notation ('1.6e+21') in javascript. The 0x api doesn't play well with
|
|
12
|
-
* exponential notation so we need to ensure that it is represented as an integer string.
|
|
13
|
-
* This function keeps 17 significant digits, so even if we try to trade 1 Billion of an
|
|
14
|
-
* ETH or ERC20, we still keep 7 decimal places.
|
|
15
|
-
* @param amount
|
|
16
|
-
*/
|
|
17
|
-
const normalizeAmount = (amount) => {
|
|
18
|
-
return (0, bignumber_1.bnOrZero)(amount).toNumber().toLocaleString('fullwide', { useGrouping: false });
|
|
19
|
-
};
|
|
20
|
-
exports.normalizeAmount = normalizeAmount;
|
|
21
9
|
const getERC20Allowance = async ({ erc20AllowanceAbi, web3, sellAssetErc20Address, ownerAddress, spenderAddress }) => {
|
|
22
10
|
const erc20Contract = new web3.eth.Contract(erc20AllowanceAbi, sellAssetErc20Address);
|
|
23
11
|
return erc20Contract.methods.allowance(ownerAddress, spenderAddress).call();
|
|
@@ -99,7 +87,7 @@ const grantAllowance = async ({ quote, wallet, adapterManager, erc20Abi, web3 })
|
|
|
99
87
|
const approveTx = erc20Contract.methods
|
|
100
88
|
.approve(quote.allowanceContract, quote.sellAmount)
|
|
101
89
|
.encodeABI();
|
|
102
|
-
const accountNumber =
|
|
90
|
+
const accountNumber = quote.sellAssetAccountNumber;
|
|
103
91
|
const bip44Params = adapter.buildBIP44Params({ accountNumber });
|
|
104
92
|
const { txToSign } = await adapter.buildSendTransaction({
|
|
105
93
|
wallet,
|
|
@@ -21,8 +21,8 @@ export declare const setupBuildTrade: () => {
|
|
|
21
21
|
buyAmount: string;
|
|
22
22
|
buyAsset: Asset;
|
|
23
23
|
sendMax: boolean;
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
sellAssetAccountNumber: number;
|
|
25
|
+
buyAssetAccountNumber: number;
|
|
26
26
|
sellAsset: Asset;
|
|
27
27
|
};
|
|
28
28
|
buyAsset: Asset;
|
|
@@ -40,7 +40,7 @@ export declare const setupExecuteTrade: () => {
|
|
|
40
40
|
buyAsset: Asset;
|
|
41
41
|
sellAsset: Asset;
|
|
42
42
|
sendMax: boolean;
|
|
43
|
-
|
|
43
|
+
sellAssetAccountNumber: number;
|
|
44
44
|
txData: string;
|
|
45
45
|
depositAddress: string;
|
|
46
46
|
receiveAddress: string;
|
|
@@ -11,7 +11,7 @@ const setupQuote = () => {
|
|
|
11
11
|
sellAsset,
|
|
12
12
|
buyAsset,
|
|
13
13
|
allowanceContract: 'allowanceContractAddress',
|
|
14
|
-
|
|
14
|
+
sellAssetAccountNumber: 0,
|
|
15
15
|
minimum: '0',
|
|
16
16
|
maximum: '999999999999',
|
|
17
17
|
feeData: { fee: '0', tradeFee: '0', chainSpecific: {} },
|
|
@@ -22,7 +22,7 @@ const setupQuote = () => {
|
|
|
22
22
|
sellAmount: '1000000000000000000',
|
|
23
23
|
sellAsset,
|
|
24
24
|
buyAsset,
|
|
25
|
-
|
|
25
|
+
sellAssetAccountNumber: 0,
|
|
26
26
|
sendMax: false
|
|
27
27
|
};
|
|
28
28
|
return { quoteInput, tradeQuote, buyAsset, sellAsset };
|
|
@@ -56,8 +56,8 @@ const setupBuildTrade = () => {
|
|
|
56
56
|
buyAmount: '',
|
|
57
57
|
buyAsset,
|
|
58
58
|
sendMax: false,
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
sellAssetAccountNumber: 0,
|
|
60
|
+
buyAssetAccountNumber: 0,
|
|
61
61
|
sellAsset
|
|
62
62
|
};
|
|
63
63
|
return { buildTradeInput, buyAsset, sellAsset };
|
|
@@ -77,7 +77,7 @@ const setupExecuteTrade = () => {
|
|
|
77
77
|
buyAsset,
|
|
78
78
|
sellAsset,
|
|
79
79
|
sendMax: false,
|
|
80
|
-
|
|
80
|
+
sellAssetAccountNumber: 0,
|
|
81
81
|
txData: '0x0',
|
|
82
82
|
depositAddress: '0x0',
|
|
83
83
|
receiveAddress: '0x0',
|
|
@@ -28,14 +28,17 @@ const caip_1 = require("@shapeshiftoss/caip");
|
|
|
28
28
|
const rax = __importStar(require("retry-axios"));
|
|
29
29
|
const __1 = require("../../..");
|
|
30
30
|
const bignumber_1 = require("../../utils/bignumber");
|
|
31
|
+
const constants_1 = require("../../utils/constants");
|
|
32
|
+
const constants_2 = require("../../utils/constants");
|
|
33
|
+
const helpers_1 = require("../../utils/helpers/helpers");
|
|
31
34
|
const erc20Allowance_abi_1 = require("../utils/abi/erc20Allowance-abi");
|
|
32
35
|
const applyAxiosRetry_1 = require("../utils/applyAxiosRetry");
|
|
33
|
-
const
|
|
34
|
-
const
|
|
36
|
+
const constants_3 = require("../utils/constants");
|
|
37
|
+
const helpers_2 = require("../utils/helpers/helpers");
|
|
35
38
|
const zrxService_1 = require("../utils/zrxService");
|
|
36
39
|
async function zrxBuildTrade({ adapterManager, web3 }, input) {
|
|
37
40
|
var _a, _b, _c;
|
|
38
|
-
const { sellAsset, buyAsset, sellAmount, slippage,
|
|
41
|
+
const { sellAsset, buyAsset, sellAmount, slippage, sellAssetAccountNumber, buyAssetAccountNumber, wallet } = input;
|
|
39
42
|
try {
|
|
40
43
|
const { assetReference: buyAssetErc20Address, assetNamespace: buyAssetNamespace } = (0, caip_1.fromAssetId)(buyAsset.assetId);
|
|
41
44
|
const { assetReference: sellAssetErc20Address, assetNamespace: sellAssetNamespace } = (0, caip_1.fromAssetId)(sellAsset.assetId);
|
|
@@ -48,7 +51,7 @@ async function zrxBuildTrade({ adapterManager, web3 }, input) {
|
|
|
48
51
|
});
|
|
49
52
|
}
|
|
50
53
|
const adapter = await adapterManager.byChainId(buyAsset.chainId);
|
|
51
|
-
const bip44Params = adapter.buildBIP44Params({ accountNumber:
|
|
54
|
+
const bip44Params = adapter.buildBIP44Params({ accountNumber: buyAssetAccountNumber });
|
|
52
55
|
const receiveAddress = await adapter.getAddress({ wallet, bip44Params });
|
|
53
56
|
const slippagePercentage = slippage ? (0, bignumber_1.bnOrZero)(slippage).div(100).toString() : constants_1.DEFAULT_SLIPPAGE;
|
|
54
57
|
/**
|
|
@@ -84,7 +87,7 @@ async function zrxBuildTrade({ adapterManager, web3 }, input) {
|
|
|
84
87
|
takerAddress: receiveAddress,
|
|
85
88
|
slippagePercentage,
|
|
86
89
|
skipValidation: false,
|
|
87
|
-
affiliateAddress:
|
|
90
|
+
affiliateAddress: constants_3.AFFILIATE_ADDRESS
|
|
88
91
|
}
|
|
89
92
|
});
|
|
90
93
|
const { data } = quoteResponse;
|
|
@@ -92,7 +95,7 @@ async function zrxBuildTrade({ adapterManager, web3 }, input) {
|
|
|
92
95
|
const trade = {
|
|
93
96
|
sellAsset,
|
|
94
97
|
buyAsset,
|
|
95
|
-
|
|
98
|
+
sellAssetAccountNumber,
|
|
96
99
|
receiveAddress,
|
|
97
100
|
rate: data.price,
|
|
98
101
|
depositAddress: data.to,
|
|
@@ -107,9 +110,9 @@ async function zrxBuildTrade({ adapterManager, web3 }, input) {
|
|
|
107
110
|
txData: data.data,
|
|
108
111
|
sellAmount: data.sellAmount,
|
|
109
112
|
buyAmount: data.buyAmount,
|
|
110
|
-
sources: ((_a = data.sources) === null || _a === void 0 ? void 0 : _a.filter((s) => parseFloat(s.proportion) > 0)) ||
|
|
113
|
+
sources: ((_a = data.sources) === null || _a === void 0 ? void 0 : _a.filter((s) => parseFloat(s.proportion) > 0)) || constants_3.DEFAULT_SOURCE
|
|
111
114
|
};
|
|
112
|
-
const allowanceRequired = await (0,
|
|
115
|
+
const allowanceRequired = await (0, helpers_2.getAllowanceRequired)({
|
|
113
116
|
sellAsset,
|
|
114
117
|
allowanceContract: data.allowanceTarget,
|
|
115
118
|
receiveAddress,
|
|
@@ -122,7 +125,7 @@ async function zrxBuildTrade({ adapterManager, web3 }, input) {
|
|
|
122
125
|
fee: ((_b = trade.feeData) === null || _b === void 0 ? void 0 : _b.fee) || '0',
|
|
123
126
|
chainSpecific: {
|
|
124
127
|
...(_c = trade.feeData) === null || _c === void 0 ? void 0 : _c.chainSpecific,
|
|
125
|
-
approvalFee: (0, bignumber_1.bnOrZero)(
|
|
128
|
+
approvalFee: (0, bignumber_1.bnOrZero)(constants_2.APPROVAL_GAS_LIMIT).multipliedBy((0, bignumber_1.bnOrZero)(data.gasPrice)).toString()
|
|
126
129
|
},
|
|
127
130
|
tradeFee: '0'
|
|
128
131
|
};
|
|
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.zrxExecuteTrade = void 0;
|
|
4
4
|
const web3_utils_1 = require("web3-utils");
|
|
5
5
|
const api_1 = require("../../../api");
|
|
6
|
-
const bignumber_1 = require("../../utils/bignumber");
|
|
7
6
|
async function zrxExecuteTrade({ adapterManager }, { trade, wallet }) {
|
|
8
7
|
var _a, _b, _c, _d, _e, _f;
|
|
9
8
|
const zrxTrade = trade;
|
|
@@ -13,7 +12,7 @@ async function zrxExecuteTrade({ adapterManager }, { trade, wallet }) {
|
|
|
13
12
|
const value = sellAsset.assetId === 'eip155:1/slip44:60' ? trade.sellAmount : '0';
|
|
14
13
|
const adapter = await adapterManager.byChainId(sellAsset.chainId);
|
|
15
14
|
const bip44Params = adapter.buildBIP44Params({
|
|
16
|
-
accountNumber:
|
|
15
|
+
accountNumber: trade.sellAssetAccountNumber
|
|
17
16
|
});
|
|
18
17
|
const buildTxResponse = await adapter.buildSendTransaction({
|
|
19
18
|
value,
|