UNPKG

rubic-sdk-next

Version:
211 lines 8.9 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.CrossChainTrade = void 0; const bignumber_js_1 = __importDefault(require("bignumber.js")); const errors_1 = require("../../../../../common/errors"); const updated_rates_error_1 = require("../../../../../common/errors/cross-chain/updated-rates-error"); const trade_expired_error_1 = require("../../../../../common/errors/swap/trade-expired.error"); const native_tokens_1 = require("../../../../../common/tokens/constants/native-tokens"); const blockchain_name_1 = require("../../../../../core/blockchain/models/blockchain-name"); const web3_pure_1 = require("../../../../../core/blockchain/web3-pure/web3-pure"); const injector_1 = require("../../../../../core/injector/injector"); const check_address_1 = require("../../../../common/utils/check-address"); /** * Abstract class for all cross-chain providers' trades. */ class CrossChainTrade { get uniqueInfo() { return this._uniqueInfo; } get httpClient() { return injector_1.Injector.httpClient; } get fromWeb3Public() { return injector_1.Injector.web3PublicService.getWeb3Public(this.from.blockchain); } get web3Private() { return injector_1.Injector.web3PrivateService.getWeb3PrivateByBlockchain(this.from.blockchain); } get walletAddress() { return this._apiFromAddress ?? this.web3Private.address; } get networkFee() { return new bignumber_js_1.default(this.feeInfo.rubicProxy?.fixedFee?.amount || 0).plus(this.feeInfo.provider?.cryptoFee?.amount || 0); } get platformFee() { return new bignumber_js_1.default(this.feeInfo.rubicProxy?.platformFee?.percent || 0).plus(this.feeInfo.provider?.platformFee?.percent || 0); } get amountToCheck() { return this.to.stringWeiAmount; } get needAuthWallet() { return false; } set apiFromAddress(value) { this._apiFromAddress = value; } constructor(providerAddress, routePath, apiQuote, apiResponse) { this.providerAddress = providerAddress; this.routePath = routePath; this.apiQuote = apiQuote; this.apiResponse = apiResponse; this.lastTransactionConfig = null; this._uniqueInfo = {}; /** * Promotions array. */ this.promotions = []; this._apiFromAddress = null; this.useProxy = apiResponse.useRubicContract; this.contractSpender = apiResponse.transaction.approvalAddress; this.rubicId = apiResponse.id; } /** * Returns true, if allowance is not enough. */ async needApprove() { return false; } /** * Sends approve transaction with connected wallet. * @param options Transaction options. * @param checkNeedApprove If true, first allowance is checked. * @param amount Amount of tokens in approval window in spending cap field */ async approve(_options, _checkNeedApprove, _amount) { return undefined; } checkAmountChange(newWeiAmount, oldWeiAmount) { const oldAmount = new bignumber_js_1.default(oldWeiAmount); const newAmount = new bignumber_js_1.default(newWeiAmount); const changePercent = 0.5; const acceptablePercentPriceChange = new bignumber_js_1.default(changePercent).dividedBy(100); const amountPlusPercent = oldAmount.multipliedBy(acceptablePercentPriceChange.plus(1)); const amountMinusPercent = oldAmount.multipliedBy(new bignumber_js_1.default(1).minus(acceptablePercentPriceChange)); const shouldThrowError = newAmount.lt(amountMinusPercent) || newAmount.gt(amountPlusPercent); if (shouldThrowError) { throw new updated_rates_error_1.UpdatedRatesError(oldWeiAmount, newWeiAmount); } } async checkTradeErrors() { this.checkWalletConnected(); await Promise.all([ this.checkBlockchainCorrect(), this.checkUserBalance(), this.checkBlockchainRequirements() ]); } checkWalletConnected() { if (!this.walletAddress) { throw new errors_1.WalletNotConnectedError(); } } async checkBlockchainRequirements() { if (this.to.blockchain === blockchain_name_1.BLOCKCHAIN_NAME.SEI && !this.to.isNative && this.walletAddress) { const web3 = injector_1.Injector.web3PublicService.getWeb3Public(blockchain_name_1.BLOCKCHAIN_NAME.SEI); const transactionCount = await web3.getTransactionCount(this.walletAddress); const balance = await web3.getBalance(this.walletAddress, this.to.address); if (new bignumber_js_1.default(balance).eq(0) && transactionCount === 0) { return true; } } return false; } async checkBlockchainCorrect() { await this.web3Private.checkBlockchainCorrect(this.from.blockchain); } async checkUserBalance() { await this.fromWeb3Public.checkBalance(this.from, this.from.tokenAmount, this.walletAddress); } async checkFromAddress(fromAddress, isRequired = false, crossChainType) { if (!fromAddress) { if (isRequired) { throw new errors_1.RubicSdkError(`'fromAddress' is required option`); } return; } const isAddressCorrectValue = await (0, check_address_1.isAddressCorrect)(fromAddress, this.from.blockchain, crossChainType); if (!isAddressCorrectValue) { throw new errors_1.WrongFromAddressError(); } } async checkReceiverAddress(receiverAddress, isRequired = false, crossChainType) { if (!receiverAddress) { if (isRequired) { throw new errors_1.RubicSdkError(`'receiverAddress' is required option`); } return; } const isAddressCorrectValue = await (0, check_address_1.isAddressCorrect)(receiverAddress, this.to.blockchain, crossChainType); if (!isAddressCorrectValue) { throw new errors_1.WrongReceiverAddressError(); } } /** * Calculates value for swap transaction. * @param providerValue Value, returned from cross-chain provider. Not '0' if from is native or provider has extranative */ getSwapValue(providerValue) { const nativeToken = native_tokens_1.nativeTokensList[this.from.blockchain]; const fixedFeeValue = web3_pure_1.Web3Pure.toWei(this.feeInfo.rubicProxy?.fixedFee?.amount || 0, nativeToken.decimals); let fromValue; if (this.from.isNative) { if (providerValue) { fromValue = new bignumber_js_1.default(providerValue).dividedBy(1 - (this.feeInfo.rubicProxy?.platformFee?.percent || 0) / 100); } else { fromValue = this.from.weiAmount; } } else { fromValue = new bignumber_js_1.default(providerValue || 0); } // 100 / 0.98 return new bignumber_js_1.default(fromValue).plus(fixedFeeValue).toFixed(0, 0); } getUsdPrice(providerFeeToken) { let feeSum = new bignumber_js_1.default(0); const providerFee = this.feeInfo.provider?.cryptoFee; if (providerFee) { feeSum = feeSum.plus(providerFee.amount.multipliedBy(providerFeeToken || providerFee.token.price)); } return this.to.price.multipliedBy(this.to.tokenAmount).minus(feeSum); } async setTransactionConfig(skipAmountChangeCheck, useCacheData, testMode, receiverAddress, refundAddress) { if (this.lastTransactionConfig && useCacheData) { return this.lastTransactionConfig; } const { config, amount } = await this.getTransactionConfigAndAmount(testMode, receiverAddress, refundAddress); this.lastTransactionConfig = config; setTimeout(() => { this.lastTransactionConfig = null; }, 15000); if (!skipAmountChangeCheck) { this.checkAmountChange(amount, this.amountToCheck); } return config; } async fetchSwapData(body) { try { const res = await injector_1.Injector.rubicApiService.fetchSwapData(body); return res; } catch (err) { if (err instanceof trade_expired_error_1.TradeExpiredError) { return this.refetchTrade(body); } throw err; } } refetchTrade(body) { return injector_1.Injector.rubicApiService.fetchBestSwapData({ ...body, preferredProvider: this.type }); } } exports.CrossChainTrade = CrossChainTrade; //# sourceMappingURL=cross-chain-trade.js.map