rubic-sdk
Version:
Simplify dApp creation
186 lines • 9.79 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.OneInchProvider = void 0;
const bignumber_js_1 = __importDefault(require("bignumber.js"));
const errors_1 = require("../../../../../../common/errors");
const tokens_1 = require("../../../../../../common/tokens");
const native_tokens_1 = require("../../../../../../common/tokens/constants/native-tokens");
const options_1 = require("../../../../../../common/utils/options");
const blockchain_name_1 = require("../../../../../../core/blockchain/models/blockchain-name");
const token_native_address_proxy_1 = require("../../../../../common/utils/token-native-address-proxy");
const rubic_proxy_contract_address_1 = require("../../../../../cross-chain/calculation-manager/providers/common/constants/rubic-proxy-contract-address");
const arbitrum_protocols_1 = require("./constants/arbitrum-protocols");
const constants_1 = require("./constants/constants");
const one_inch_supported_blockchains_1 = require("./constants/one-inch-supported-blockchains");
const one_inch_api_service_1 = require("./one-inch-api-service");
const one_inch_trade_1 = require("./one-inch-trade");
const on_chain_trade_type_1 = require("../../common/models/on-chain-trade-type");
const get_gas_fee_info_1 = require("../../common/utils/get-gas-fee-info");
const get_gas_price_info_1 = require("../../common/utils/get-gas-price-info");
const evm_provider_default_options_1 = require("../../dexes/common/on-chain-provider/evm-on-chain-provider/constants/evm-provider-default-options");
const aggregator_on_chain_provider_abstract_1 = require("../../common/on-chain-aggregator/aggregator-on-chain-provider-abstract");
class OneInchProvider extends aggregator_on_chain_provider_abstract_1.AggregatorOnChainProvider {
constructor() {
super(...arguments);
this.defaultOptions = {
...evm_provider_default_options_1.evmProviderDefaultOptions,
disableMultihops: false,
wrappedAddress: constants_1.oneinchApiParams.nativeAddress
};
this.tradeType = on_chain_trade_type_1.ON_CHAIN_TRADE_TYPE.ONE_INCH;
}
isSupportedBlockchain(blockchain) {
return one_inch_supported_blockchains_1.oneInchSupportedBlockchains.some(item => item === blockchain);
}
async calculate(from, toToken, options) {
const fromBlockchain = from.blockchain;
const fromAddress = options?.useProxy || this.defaultOptions.useProxy
? rubic_proxy_contract_address_1.rubicProxyContractAddress[from.blockchain].gateway
: this.getWalletAddress(from.blockchain);
const fullOptions = (0, options_1.combineOptions)(options, {
...this.defaultOptions,
fromAddress
});
const { fromWithoutFee, proxyFeeInfo } = await this.handleProxyContract(from, fullOptions);
const fromTokenClone = (0, token_native_address_proxy_1.createTokenNativeAddressProxy)(fromWithoutFee, constants_1.oneinchApiParams.nativeAddress);
const toTokenClone = (0, token_native_address_proxy_1.createTokenNativeAddressProxy)(toToken, constants_1.oneinchApiParams.nativeAddress);
const [dexContractAddress, { toTokenAmountInWei, path, data, estimatedGas }] = await Promise.all([
this.loadContractAddress(fromBlockchain),
this.getTradeInfo(fromTokenClone, toTokenClone, fromWithoutFee, fullOptions)
]);
path[0] = from;
path[path.length - 1] = toToken;
const to = new tokens_1.PriceTokenAmount({
...toToken.asStruct,
weiAmount: toTokenAmountInWei
});
const availableProtocols = this.getAvailableProtocols(fromBlockchain);
const oneinchTradeStruct = {
dexContractAddress,
from,
to,
slippageTolerance: fullOptions.slippageTolerance,
disableMultihops: fullOptions.disableMultihops,
path,
gasFeeInfo: await this.getGasFeeInfo(from, estimatedGas),
data,
useProxy: fullOptions.useProxy,
proxyFeeInfo,
fromWithoutFee,
withDeflation: fullOptions.withDeflation,
usedForCrossChain: fullOptions.usedForCrossChain,
availableProtocols
};
return new one_inch_trade_1.OneInchTrade(oneinchTradeStruct, fullOptions.providerAddress);
}
async getTradeInfo(from, toToken, fromWithoutFee, options) {
const fakeAddress = '0xe388Ed184958062a2ea29B7fD049ca21244AE02e';
const isDefaultWrappedAddress = options.wrappedAddress === constants_1.oneinchApiParams.nativeAddress;
const isNative = from.isNative || from.address === constants_1.oneinchApiParams.nativeAddress;
const fromTokenAddress = isNative && !isDefaultWrappedAddress ? options.wrappedAddress : from.address;
const toTokenAddress = toToken.address;
const availableProtocols = this.getAvailableProtocols(from.blockchain);
const quoteTradeParams = {
params: {
src: fromTokenAddress,
dst: toTokenAddress,
amount: from.stringWeiAmount,
...(options.disableMultihops && {
connectorTokens: `${fromTokenAddress},${toTokenAddress}`
}),
...(availableProtocols && { protocols: availableProtocols })
}
};
let oneInchTrade;
let estimatedGas;
let toTokenAmount;
let data = null;
let path = [];
try {
if (!options.fromAddress)
throw new Error('Address is not set');
if (options.gasCalculation !== 'disabled') {
await one_inch_trade_1.OneInchTrade.checkIfNeedApproveAndThrowError(from, toToken, fromWithoutFee, options.fromAddress, options.useProxy);
}
const swapTradeParams = {
params: {
...quoteTradeParams.params,
slippage: (options.slippageTolerance * 100).toString(),
from: this.getWalletAddress(from.blockchain) ||
fakeAddress,
disableEstimate: options.gasCalculation === 'disabled'
}
};
oneInchTrade = await one_inch_api_service_1.OneInchApiService.oneInchHttpGetRequest('swap', from.blockchain, swapTradeParams);
estimatedGas = new bignumber_js_1.default(oneInchTrade.tx.gas);
toTokenAmount = oneInchTrade.dstAmount;
data = oneInchTrade.tx.data;
}
catch (_err) {
oneInchTrade = await one_inch_api_service_1.OneInchApiService.oneInchHttpGetRequest('quote', from.blockchain, quoteTradeParams);
if (oneInchTrade.hasOwnProperty('errors') || !oneInchTrade.dstAmount) {
throw new errors_1.RubicSdkError('1inch quote error');
}
estimatedGas = new bignumber_js_1.default(oneInchTrade.gas);
toTokenAmount = oneInchTrade.dstAmount;
}
if (oneInchTrade?.protocols?.length) {
path = await this.extractPath(from, toToken, oneInchTrade);
}
return { toTokenAmountInWei: new bignumber_js_1.default(toTokenAmount), estimatedGas, path, data };
}
async getGasFeeInfo(from, gasLimit) {
try {
const gasPriceInfo = await (0, get_gas_price_info_1.getGasPriceInfo)(from.blockchain);
return (0, get_gas_fee_info_1.getGasFeeInfo)(gasPriceInfo, { gasLimit });
}
catch {
return null;
}
}
getAvailableProtocols(fromBlockchain) {
if (fromBlockchain === blockchain_name_1.BLOCKCHAIN_NAME.ARBITRUM) {
return arbitrum_protocols_1.oneinchArbitrumProtocols.join(',');
}
if (fromBlockchain === blockchain_name_1.BLOCKCHAIN_NAME.ZK_SYNC) {
return 'ZKSYNC_MUTE,ZKSYNC_PMMX,ZKSYNC_SPACEFI,ZKSYNC_SYNCSWAP,ZKSYNC_GEM,ZKSYNC_MAVERICK_V1';
}
return undefined;
}
/**
* Extracts tokens path from oneInch api response.
* @returns Promise<Token[]> Tokens array, used in the route.
*/
async extractPath(fromToken, toToken, oneInchTrade) {
const addressesPath = oneInchTrade.protocols[0].map(protocol => {
if (!protocol?.[0]) {
throw new errors_1.RubicSdkError('Protocol array must not be empty');
}
return protocol[0].toTokenAddress;
});
addressesPath.pop();
const tokensPathWithoutNative = await tokens_1.Token.createTokens(addressesPath.filter(tokenAddress => tokenAddress !== constants_1.oneinchApiParams.nativeAddress), fromToken.blockchain);
let tokensPathWithoutNativeIndex = 0;
const tokensPath = addressesPath.map(tokenAddress => {
if (tokenAddress === constants_1.oneinchApiParams.nativeAddress) {
return native_tokens_1.nativeTokensList[fromToken.blockchain];
}
const token = tokensPathWithoutNative[tokensPathWithoutNativeIndex];
if (!token) {
throw new errors_1.RubicSdkError('Token has to be defined');
}
tokensPathWithoutNativeIndex++;
return token;
});
return [fromToken, ...tokensPath, toToken];
}
async loadContractAddress(fromBlockchain) {
const response = await one_inch_api_service_1.OneInchApiService.oneInchHttpGetApproveRequest('approve/spender', fromBlockchain);
return response.address;
}
}
exports.OneInchProvider = OneInchProvider;
//# sourceMappingURL=one-inch-provider.js.map