rubic-sdk-next
Version:
Simplify dApp creation
211 lines • 8.9 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.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