import {makeAutoObservable, runInAction} from 'mobx' import Bignumber from 'bignumber.js' import {AssetDescriptor, generateLiquidityPoolId} from '@stellar-expert/asset-descriptor' import {adjustPrecision} from '@stellar-expert/formatter' import accountLedgerData from '../../../state/ledger-data/account-ledger-data' import {prepareLiquidityDepositTx} from './liquidity-pool-deposit-tx-builder' import {resolvePoolParams} from '../../../util/liquidity-pool-params-resolver' export default class LiquidityPoolDepositSettings { constructor(network) { this.network = network this.amount = ['', ''] this.asset = ['XLM', 'XLM'] this.poolInfo = {loaded: false} makeAutoObservable(this) } network asset amount slippage = 1 poolInfo reverse = false get poolId() { return generateLiquidityPoolId(this.asset) } get hasSufficientBalance() { return this.asset .map(asset => { const additionalBalance = asset === 'XLM' ? (this.hasPoolTrustline ? 0.6 : 0.1) : 0 return new Bignumber(accountLedgerData.getAvailableBalance(asset, additionalBalance)) }) .every((balance, i) => balance.greaterThanOrEqualTo(this.amount[i] || 0)) } get hasPoolTrustline() { return !!accountLedgerData.balances[this.poolId] } get isValid() { return this.amount[0] > 0 && this.amount[1] > 0 && this.asset[0] != this.asset[1] && this.poolInfo?.loaded && this.hasSufficientBalance } setAsset(asset, index) { this.asset[index] = asset this.amount[index] = '' this.loadPoolInfo() .then(() => this.recalculate(1 - index)) } setAmount(amount, index) { this.amount[index] = amount this.loadPoolInfo() .then(() => this.recalculate(index)) } setSlippage(slippage) { this.slippage = slippage } loadPoolInfo(force = false) { if (this._poolInfoPromise && !force) return this._poolInfoPromise this.poolInfo = {loaded: false} this.reverse = false if (this.asset[0] === this.asset[1]) { this.poolInfo = {loaded: true, invalidPair: true} return Promise.resolve() } this._poolInfoPromise = resolvePoolParams(this.network, this.poolId, true) .then(res => runInAction(() => { this.poolInfo = {loaded: true, parameters: res} if (res && AssetDescriptor.parse(res.reserves[0].asset).toFQAN() !== AssetDescriptor.parse(this.asset[0]).toFQAN()) { this.reverse = true } this._poolInfoPromise = undefined })) return this._poolInfoPromise } recalculate(sourceIndex) { if (!this.poolInfo.parameters) return let {reserves} = this.poolInfo.parameters if (parseFloat(reserves[0].amount) === 0 || parseFloat(reserves[1].amount) === 0) return if (this.reverse) { reserves = reserves.slice().reverse() } const counter = new Bignumber(this.amount[sourceIndex] || 0) .mul(new Bignumber(reserves[1 - sourceIndex].amount)) .div(new Bignumber(reserves[sourceIndex].amount)) this.amount[1 - sourceIndex] = adjustPrecision(counter) } prepareTransaction() { return prepareLiquidityDepositTx(this) } resetOperationAmount() { this.amount = ['', ''] } }