rubic-sdk
Version:
Simplify dApp creation
213 lines • 10.3 kB
JavaScript
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.LifiCrossChainProvider = void 0;
const sdk_1 = __importDefault(require("@lifi/sdk"));
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 blockchain_1 = require("../../../../../common/utils/blockchain");
const blockchain_id_1 = require("../../../../../core/blockchain/utils/blockchains-info/constants/blockchain-id");
const web3_pure_1 = require("../../../../../core/blockchain/web3-pure/web3-pure");
const injector_1 = require("../../../../../core/injector/injector");
const wl_contract_abi_1 = require("../../../../common/constants/wl-contract-abi");
const wl_contract_address_1 = require("../../../../common/constants/wl-contract-address");
const lifi_config_1 = require("../../../../common/providers/lifi/constants/lifi-config");
const cross_chain_trade_type_1 = require("../../models/cross-chain-trade-type");
const cross_chain_provider_1 = require("../common/cross-chain-provider");
const bridge_type_1 = require("../common/models/bridge-type");
const lifi_cross_chain_supported_blockchain_1 = require("./constants/lifi-cross-chain-supported-blockchain");
const lifi_cross_chain_trade_1 = require("./lifi-cross-chain-trade");
const lifi_bridge_types_1 = require("./models/lifi-bridge-types");
const lifi_providers_1 = require("../../../../on-chain/calculation-manager/providers/lifi/constants/lifi-providers");
class LifiCrossChainProvider extends cross_chain_provider_1.CrossChainProvider {
constructor() {
super(...arguments);
this.type = cross_chain_trade_type_1.CROSS_CHAIN_TRADE_TYPE.LIFI;
this.lifi = new sdk_1.default((0, lifi_config_1.getLifiConfig)());
this.MIN_AMOUNT_USD = new bignumber_js_1.default(30);
this.lifiFee = 0.0015;
}
isSupportedBlockchain(blockchain) {
return lifi_cross_chain_supported_blockchain_1.lifiCrossChainSupportedBlockchains.some(supportedBlockchain => supportedBlockchain === blockchain);
}
async calculate(from, toToken, options) {
const fromBlockchain = from.blockchain;
const toBlockchain = toToken.blockchain;
if (!this.areSupportedBlockchains(fromBlockchain, toBlockchain)) {
return null;
}
// await this.checkContractState(
// fromBlockchain,
// rubicProxyContractAddress[fromBlockchain],
// evmCommonCrossChainAbi
// );
if (options.lifiDisabledBridgeTypes?.length &&
!this.checkBridgeTypes(options.lifiDisabledBridgeTypes)) {
throw new errors_1.RubicSdkError('Incorrect bridges filter param');
}
const routeOptions = {
slippage: options.slippageTolerance,
order: 'RECOMMENDED',
allowSwitchChain: false,
bridges: {
deny: options.lifiDisabledBridgeTypes
},
fee: this.lifiFee,
integrator: 'Rubic'
};
const fromChainId = blockchain_id_1.blockchainId[fromBlockchain];
const toChainId = blockchain_id_1.blockchainId[toBlockchain];
const feeInfo = await this.getFeeInfo(fromBlockchain, options.providerAddress, from);
// const fromWithoutFee = getFromWithoutFee(from, feeInfo.rubicProxy?.platformFee?.percent);
const fromWithoutFee = from;
const fromAddress = this.getWalletAddress(fromBlockchain);
const toAddress = options.receiverAddress || fromAddress;
const routesRequest = {
fromChainId,
fromAmount: fromWithoutFee.stringWeiAmount,
fromTokenAddress: from.address,
toChainId,
toTokenAddress: toToken.address,
options: routeOptions,
...(fromAddress && { fromAddress }),
...(toAddress && { toAddress })
};
const result = await this.lifi.getRoutes(routesRequest);
const { routes } = result;
const bestRoute = routes.find(route => route.steps.length === 1 && !route.containsSwitchChain);
if (!bestRoute) {
throw new errors_1.RubicSdkError('No available routes');
}
// const providerGateway = bestRoute.steps[0]!.estimate.approvalAddress;
// await this.checkProviderIsWhitelisted(from.blockchain, providerGateway);
const { fromAmountUSD, toAmountUSD } = bestRoute;
const priceImpact = new bignumber_js_1.default(fromAmountUSD)
.minus(toAmountUSD)
.dividedBy(fromAmountUSD)
.dp(2)
.toNumber();
from = new tokens_1.PriceTokenAmount({
...from.asStructWithAmount,
price: new bignumber_js_1.default(bestRoute.fromAmountUSD).dividedBy(from.tokenAmount)
});
const to = new tokens_1.PriceTokenAmount({
...toToken.asStruct,
weiAmount: new bignumber_js_1.default(bestRoute.toAmount)
});
const gasData = options.gasCalculation === 'enabled'
? await lifi_cross_chain_trade_1.LifiCrossChainTrade.getGasData(from, to, bestRoute)
: null;
const { onChainType, bridgeType } = this.parseTradeTypes(bestRoute);
const trade = new lifi_cross_chain_trade_1.LifiCrossChainTrade({
from,
to,
route: bestRoute,
gasData,
toTokenAmountMin: web3_pure_1.Web3Pure.fromWei(bestRoute.toAmountMin, to.decimals),
feeInfo,
priceImpact,
onChainSubtype: onChainType,
bridgeType: bridgeType || bridge_type_1.BRIDGE_TYPE.LIFI,
slippage: options.slippageTolerance
}, options.providerAddress);
try {
this.checkMinError(from);
}
catch (err) {
return {
trade,
error: err
};
}
return {
trade
};
}
checkMinError(from) {
const fromUsdAmount = from.price.multipliedBy(from.tokenAmount);
if (fromUsdAmount.lt(this.MIN_AMOUNT_USD)) {
if (from.price.gt(0)) {
const minTokenAmount = this.MIN_AMOUNT_USD.multipliedBy(from.tokenAmount).dividedBy(fromUsdAmount);
throw new errors_1.MinAmountError(minTokenAmount, from.symbol);
}
throw new errors_1.MinAmountError(this.MIN_AMOUNT_USD, 'USDC');
}
}
async getFeeInfo(fromBlockchain, _providerAddress, percentFeeToken) {
return {
rubicProxy: {
fixedFee: {
// amount: await this.getFixedFee(
// fromBlockchain,
// providerAddress,
// rubicProxyContractAddress[fromBlockchain],
// evmCommonCrossChainAbi
// ),
amount: new bignumber_js_1.default(0),
tokenSymbol: native_tokens_1.nativeTokensList[fromBlockchain].symbol
},
platformFee: {
// percent: await this.getFeePercent(
// fromBlockchain,
// providerAddress,
// rubicProxyContractAddress[fromBlockchain],
// evmCommonCrossChainAbi
// ),
percent: 0,
tokenSymbol: percentFeeToken.symbol
}
},
provider: {
platformFee: {
percent: this.lifiFee * 100,
tokenSymbol: percentFeeToken.symbol
}
}
};
}
// @todo move to evm-cross-chain-provider
async checkProviderIsWhitelisted(fromBlockchain, providerRouter, providerGateway) {
const whitelistedContracts = await injector_1.Injector.web3PublicService
.getWeb3Public(fromBlockchain)
.callContractMethod(wl_contract_address_1.wlContractAddress[fromBlockchain], wl_contract_abi_1.wlContractAbi, 'getAvailableCrossChains');
if (!whitelistedContracts.find(whitelistedContract => (0, blockchain_1.compareAddresses)(whitelistedContract, providerRouter)) ||
(providerGateway &&
!whitelistedContracts.find(whitelistedContract => (0, blockchain_1.compareAddresses)(whitelistedContract, providerGateway)))) {
throw new errors_1.NotWhitelistedProviderError(providerRouter, providerGateway, 'crosschain');
}
}
parseTradeTypes(route) {
const steps = route.steps.length === 1 && route.steps[0].includedSteps
? route.steps[0].includedSteps
: route.steps;
const sourceDex = steps?.[0] && steps[0].action.fromChainId === steps[0].action.toChainId
? steps?.[0].toolDetails.name.toLowerCase()
: undefined;
const targetDex = steps
?.slice(1)
?.find(provider => provider.action.fromChainId === provider.action.toChainId)
?.toolDetails.name.toLowerCase();
const subType = steps
?.find(provider => provider.action.fromChainId !== provider.action.toChainId)
?.tool.toLowerCase();
const onChainType = {
from: sourceDex ? lifi_providers_1.lifiProviders[sourceDex] : undefined,
to: targetDex ? lifi_providers_1.lifiProviders[targetDex] : undefined
};
const bridgeType = bridge_type_1.bridges.find(bridge => bridge.toLowerCase() === subType);
return {
onChainType,
bridgeType
};
}
checkBridgeTypes(notAllowedBridgeTypes) {
const lifiBridgeTypes = Object.values(lifi_bridge_types_1.LifiBridgeTypes);
return notAllowedBridgeTypes.every(bridgeType => lifiBridgeTypes.includes(bridgeType));
}
}
exports.LifiCrossChainProvider = LifiCrossChainProvider;
//# sourceMappingURL=lifi-cross-chain-provider.js.map
;