rubic-sdk-next
Version:
Simplify dApp creation
137 lines • 6.22 kB
JavaScript
;
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