rubic-sdk
Version:
Simplify dApp creation
187 lines • 9.65 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.RetroBridgeProvider = void 0;
const core_1 = require("@ton/core");
const bignumber_js_1 = __importDefault(require("bignumber.js"));
const errors_1 = require("../../../../../common/errors");
const max_decimals_error_1 = require("../../../../../common/errors/swap/max-decimals.error");
const tokens_1 = require("../../../../../common/tokens");
const blockchain_1 = require("../../../../../common/utils/blockchain");
const errors_2 = require("../../../../../common/utils/errors");
const blockchain_name_1 = require("../../../../../core/blockchain/models/blockchain-name");
const chain_type_1 = require("../../../../../core/blockchain/models/chain-type");
const blockchains_info_1 = require("../../../../../core/blockchain/utils/blockchains-info/blockchains-info");
const web3_pure_1 = require("../../../../../core/blockchain/web3-pure/web3-pure");
const get_from_without_fee_1 = require("../../../../common/utils/get-from-without-fee");
const retro_bridge_factory_1 = require("./retro-bridge-factory");
const cross_chain_trade_type_1 = require("../../models/cross-chain-trade-type");
const cross_chain_provider_1 = require("../common/cross-chain-provider");
const proxy_cross_chain_evm_trade_1 = require("../common/proxy-cross-chain-evm-facade/proxy-cross-chain-evm-trade");
const retro_bridge_blockchain_ticker_1 = require("./constants/retro-bridge-blockchain-ticker");
const retro_bridge_supported_blockchain_1 = require("./constants/retro-bridge-supported-blockchain");
const retro_bridge_api_service_1 = require("./services/retro-bridge-api-service");
class RetroBridgeProvider extends cross_chain_provider_1.CrossChainProvider {
constructor() {
super(...arguments);
this.MAX_DECIMAL = 6;
this.type = cross_chain_trade_type_1.CROSS_CHAIN_TRADE_TYPE.RETRO_BRIDGE;
}
isSupportedBlockchain(blockchain) {
return retro_bridge_supported_blockchain_1.retroBridgeSupportedBlockchain.some(chain => chain === blockchain);
}
async calculate(from, toToken, options) {
const fromBlockchain = from.blockchain;
let useProxy = options?.useProxy?.[this.type] ?? true;
if (blockchains_info_1.BlockchainsInfo.getChainType(fromBlockchain) !== chain_type_1.CHAIN_TYPE.EVM) {
useProxy = false;
}
try {
const { fromTokenTicker, toTokenTicker } = await this.getFromToTokenTickers(from, toToken);
this.checkFromAmountDecimals(from);
const feeInfo = await this.getFeeInfo(fromBlockchain, options.providerAddress, from, useProxy);
const fromWithoutFee = (0, get_from_without_fee_1.getFromWithoutFee)(from, feeInfo.rubicProxy?.platformFee?.percent);
const srcChain = this.getBlockchainTicker(from.blockchain);
const dstChain = this.getBlockchainTicker(toToken.blockchain);
const quoteSendParams = {
source_chain: srcChain,
destination_chain: dstChain,
asset_from: fromTokenTicker,
asset_to: toTokenTicker,
amount: web3_pure_1.Web3Pure.fromWei(fromWithoutFee.stringWeiAmount, fromWithoutFee.decimals).toFixed()
};
try {
await this.checkMinMaxAmount(from, toToken, fromTokenTicker, toTokenTicker);
}
catch (err) {
if (err instanceof errors_1.MinAmountError || err instanceof errors_1.MaxAmountError) {
return this.getEmptyTrade(from, toToken, feeInfo, quoteSendParams, options.providerAddress, err);
}
throw err;
}
const retroBridgeQuoteConfig = await retro_bridge_api_service_1.RetroBridgeApiService.getQuote(quoteSendParams);
const to = new tokens_1.PriceTokenAmount({
...toToken.asStruct,
tokenAmount: new bignumber_js_1.default(retroBridgeQuoteConfig.amount_out)
});
const routePath = await this.getRoutePath(from, to);
const trade = retro_bridge_factory_1.RetroBridgeFactory.createTrade(fromBlockchain, {
from,
to,
feeInfo,
priceImpact: from.calculatePriceImpactPercent(to),
slippage: options.slippageTolerance,
gasData: null,
quoteSendParams,
hotWalletAddress: retroBridgeQuoteConfig.hot_wallet_address
}, options.providerAddress, routePath, useProxy);
const isDecimalsGtThanMax = this.checkFromAmountDecimals(from);
if (isDecimalsGtThanMax) {
return {
trade,
tradeType: this.type,
error: new max_decimals_error_1.MaxDecimalsError(this.MAX_DECIMAL)
};
}
return {
trade,
tradeType: this.type
};
}
catch (err) {
return {
trade: null,
error: (0, errors_2.parseError)(err),
tradeType: this.type
};
}
}
async getRoutePath(from, toToken) {
return [{ type: 'cross-chain', provider: this.type, path: [from, toToken] }];
}
async getFeeInfo(fromBlockchain, providerAddress, percentFeeToken, useProxy) {
return proxy_cross_chain_evm_trade_1.ProxyCrossChainEvmTrade.getFeeInfo(fromBlockchain, providerAddress, percentFeeToken, useProxy);
}
async checkMinMaxAmount(from, toToken, fromTokenTicker, toTokenTicker) {
const srcChain = this.getBlockchainTicker(from.blockchain);
const dstChain = this.getBlockchainTicker(toToken.blockchain);
const tokenLimits = await retro_bridge_api_service_1.RetroBridgeApiService.getTokenLimits(srcChain, dstChain, fromTokenTicker, toTokenTicker);
const minSendAmount = new bignumber_js_1.default(web3_pure_1.Web3Pure.toWei(tokenLimits.min_send, from.decimals));
const maxSendAmount = new bignumber_js_1.default(web3_pure_1.Web3Pure.toWei(tokenLimits.max_send, from.decimals));
if (from.weiAmount.lt(minSendAmount)) {
throw new errors_1.MinAmountError(new bignumber_js_1.default(tokenLimits.min_send), from.symbol);
}
if (from.weiAmount.gt(maxSendAmount)) {
throw new errors_1.MaxAmountError(new bignumber_js_1.default(tokenLimits.max_send), from.symbol);
}
}
checkFromAmountDecimals(from) {
if (from.decimals > this.MAX_DECIMAL) {
const stringAmount = from.tokenAmount.toFixed();
const amountDecimals = stringAmount.split('.')[1]?.length ?? 0;
if (amountDecimals > this.MAX_DECIMAL) {
return true;
}
}
return false;
}
getBlockchainTicker(blockchain) {
const blockchainTicker = retro_bridge_blockchain_ticker_1.retroBridgeBlockchainTickers[blockchain];
if (!blockchainTicker) {
return blockchain;
}
return blockchainTicker;
}
getEmptyTrade(from, toToken, feeInfo, quoteSendParams, providerAddress, error) {
const to = new tokens_1.PriceTokenAmount({
...toToken.asStruct,
tokenAmount: new bignumber_js_1.default(0)
});
const trade = retro_bridge_factory_1.RetroBridgeFactory.createTrade(from.blockchain, {
from,
feeInfo,
to,
priceImpact: null,
slippage: 0,
gasData: null,
quoteSendParams,
hotWalletAddress: ''
}, providerAddress, [], false);
return {
tradeType: this.type,
trade,
error
};
}
async getFromToTokenTickers(fromToken, toToken) {
const fromChainTicker = this.getBlockchainTicker(fromToken.blockchain);
const toChainTicker = this.getBlockchainTicker(toToken.blockchain);
const { data: tokenList } = await retro_bridge_api_service_1.RetroBridgeApiService.getTokenList(fromChainTicker, toChainTicker);
const fromTokenAddress = this.parseTokenAddress(fromToken.address, fromToken.blockchain);
const toTokenAddress = this.parseTokenAddress(toToken.address, toToken.blockchain);
const from = tokenList.find(token => ((0, blockchain_1.compareAddresses)(token.contract_address, fromTokenAddress) && !token.native) ||
(fromToken.isNative && token.native));
if (!from) {
throw new errors_1.NotSupportedTokensError();
}
const to = from.pairs.find(tokenTo => ((0, blockchain_1.compareAddresses)(tokenTo.contract_address, toTokenAddress) && !tokenTo.native) ||
(toToken.isNative && tokenTo.native));
if (!to) {
throw new errors_1.NotSupportedTokensError();
}
return { fromTokenTicker: from.name, toTokenTicker: to.name };
}
parseTokenAddress(tokenAddress, blockchain) {
const chainType = blockchains_info_1.BlockchainsInfo.getChainType(blockchain);
if (web3_pure_1.Web3Pure[chainType].isNativeAddress(tokenAddress))
return tokenAddress;
if (blockchain === blockchain_name_1.BLOCKCHAIN_NAME.TON) {
return core_1.Address.parseRaw(tokenAddress).toString();
}
return tokenAddress;
}
}
exports.RetroBridgeProvider = RetroBridgeProvider;
//# sourceMappingURL=retro-bridge-provider.js.map