UNPKG

rubic-sdk-next

Version:
137 lines 6.22 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.CrossChainManager = void 0; const errors_1 = require("../../../common/errors"); const tokens_1 = require("../../../common/tokens"); const options_1 = require("../../../common/utils/options"); const p_timeout_1 = __importDefault(require("../../../common/utils/p-timeout")); const blockchains_info_1 = require("../../../core/blockchain/utils/blockchains-info/blockchains-info"); const injector_1 = require("../../../core/injector/injector"); const get_price_tokens_from_input_tokens_1 = require("../../common/utils/get-price-tokens-from-input-tokens"); const default_cross_chain_calculation_options_1 = require("./constants/default-cross-chain-calculation-options"); const default_provider_addresses_1 = require("./constants/default-provider-addresses"); const cross_chain_provider_1 = require("./providers/common/cross-chain-provider"); const transform_utils_1 = require("../../ws-api/transform-utils"); /** * Contains method to calculate best cross-chain trade. */ class CrossChainManager { constructor(providerAddress) { this.providerAddress = providerAddress; } /** * Calculates cross-chain trades and sorts them by exchange courses. * Wrapped trade object may contain error, but sometimes course can be * calculated even with thrown error (e.g. min/max amount error). * * @example * ```ts * const fromBlockchain = BLOCKCHAIN_NAME.ETHEREUM; * // ETH * const fromTokenAddress = '0x0000000000000000000000000000000000000000'; * const fromAmount = 1; * const toBlockchain = BLOCKCHAIN_NAME.BINANCE_SMART_CHAIN; * // BUSD * const toTokenAddress = '0xe9e7cea3dedca5984780bafc599bd69add087d56'; * * const wrappedTrades = await sdk.crossChainManager.calculateTrade( * { blockchain: fromBlockchain, address: fromTokenAddress }, * fromAmount, * { blockchain: toBlockchain, address: toTokenAddress } * ); * const bestTrade = wrappedTrades[0]; * * wrappedTrades.forEach(wrappedTrade => { * if (wrappedTrade.trade) { * console.log(wrappedTrade.tradeType, `to amount: ${wrappedTrade.trade.to.tokenAmount.toFormat(3)}`)); * } * if (wrappedTrade.error) { * console.error(wrappedTrade.tradeType, 'error: wrappedTrade.error'); * } * }); * * ``` * * @param fromToken Token to sell. * @param fromAmount Amount to sell. * @param toToken Token to get. * @param options Additional options. * @returns Array of sorted wrapped cross-chain trades with possible errors. */ async calculateTrade(fromToken, fromAmount, toToken, options) { if (toToken instanceof tokens_1.Token && fromToken.blockchain === toToken.blockchain) { throw new errors_1.RubicSdkError('Blockchains of `from` and `to` tokens must be different.'); } const { from, to } = await (0, get_price_tokens_from_input_tokens_1.getPriceTokensFromInputTokens)(fromToken, fromAmount, toToken); const { disabledProviders, ...providerOptions } = this.getFullOptions(from.blockchain, options); // @TODO API const request = { srcTokenAddress: from.address, dstTokenBlockchain: to.blockchain, srcTokenBlockchain: from.blockchain, srcTokenAmount: from.stringWeiAmount, dstTokenAddress: to.address }; const routes = await injector_1.Injector.rubicApiService.fetchRoutes(request); return Promise.all(routes.routes.map(route => transform_utils_1.TransformUtils.transformCrossChain(route, request, null))); // const calculationPromises = providers.map(provider => // this.getProviderCalculationPromise(provider, from, to, providerOptions) // ); // const wrappedTrades = (await Promise.all(calculationPromises)).filter(notNull); // if (!wrappedTrades?.length) { // throw new RubicSdkError('No success providers calculation for the trade'); // } // // return wrappedTrades.sort((nextTrade, prevTrade) => // compareCrossChainTrades(nextTrade, prevTrade) // ); } getFullOptions(fromBlockchain, options) { const providerAddress = options?.providerAddress ? options.providerAddress : this.getProviderAddress(fromBlockchain); return (0, options_1.combineOptions)({ ...options }, { ...default_cross_chain_calculation_options_1.defaultCrossChainCalculationOptions, providerAddress }); } async getProviderCalculationPromise(provider, from, to, options) { try { const wrappedTrade = await (0, p_timeout_1.default)(provider.calculate(from, to, options), options.timeout); if (!wrappedTrade) { return null; } return { ...wrappedTrade, tradeType: provider.type }; } catch (err) { console.debug(`[RUBIC_SDK] Trade calculation error occurred for ${provider.type} trade provider.`, err); return { trade: null, tradeType: provider.type, error: cross_chain_provider_1.CrossChainProvider.parseError(err) }; } } getProviderAddress(fromBlockchain) { let chainType; try { chainType = blockchains_info_1.BlockchainsInfo.getChainType(fromBlockchain); } catch { } let providerAddress = default_provider_addresses_1.defaultProviderAddresses.crossChain; if (chainType && this.providerAddress?.[chainType]?.crossChain && this.providerAddress[chainType].crossChain !== undefined) { providerAddress = this.providerAddress[chainType].crossChain; } return providerAddress; } } exports.CrossChainManager = CrossChainManager; //# sourceMappingURL=cross-chain-manager.js.map