UNPKG

@broxus/js-core

Version:

MobX-based JavaScript Core library

428 lines (427 loc) 21.1 kB
import { dexStablePoolContract, dexStablePoolV22Contract } from '../../models/dex-stable-pool/contracts'; import { TvmToken } from '../../models/tvm-token'; import { getFullContractState, getRandomInt, resolveTvmAddress } from '../../utils'; export class DexStablePoolUtils { static async getDetails(connection, poolAddress, cachedState) { const state = cachedState ?? await getFullContractState(connection, poolAddress); const [balances, roots, _wallets, isActive] = await Promise.all([ DexStablePoolUtils.getBalances(connection, poolAddress, state), DexStablePoolUtils.getTokenRoots(connection, poolAddress, state), DexStablePoolUtils.getTokenWallets(connection, poolAddress, state), DexStablePoolUtils.isActive(connection, poolAddress, state), ]); const [lpToken, lpWallet, [...tokens], [...wallets]] = await Promise.all([ TvmToken.create(connection, roots.lp, { sync: true }), TvmToken.Wallet.create(connection, { address: _wallets.lp }, { sync: true }), Promise.all(roots.tokens.map(address => TvmToken.create(connection, address, { sync: true }))), Promise.all(_wallets.tokens.map(address => TvmToken.Wallet.create(connection, { address }, { sync: true }))), ]); return { address: resolveTvmAddress(poolAddress), balances, contractState: state, isActive, lpToken, lpWallet, tokens, wallets, }; } static async getBalances(connection, poolAddress, cachedState) { const state = cachedState ?? await getFullContractState(connection, poolAddress); const [roots, balances] = await Promise.all([ DexStablePoolUtils.getTokenRoots(connection, poolAddress, state), dexStablePoolContract(connection, poolAddress) .methods.getBalances({ answerId: 0 }) .call({ cachedState: state, responsible: true }), ]); const result = new Map([ [roots.lp.toString(), balances.value0.lp_supply], ]); roots.tokens.forEach((token, idx) => { result.set(token.toString(), balances.value0.balances[idx]); }); return result; } static async getVirtualPrice(connection, poolAddress, cachedState) { const state = cachedState ?? await getFullContractState(connection, poolAddress); const result = await dexStablePoolContract(connection, poolAddress) .methods.getVirtualPrice({ answerId: 0 }) .call({ cachedState: state, responsible: true }); return result.value0; } static async getDepositPriceImpact(connection, poolAddress, params, cachedState) { const state = cachedState ?? await getFullContractState(connection, poolAddress); const result = await dexStablePoolContract(connection, poolAddress) .methods.getDepositPriceImpact({ amount: params.amount, price_amount: params.priceAmount, spent_token_root: resolveTvmAddress(params.spentTokenAddress), }) .call({ cachedState: state }); return result.value0; } static async getWithdrawalPriceImpact(connection, poolAddress, params, cachedState) { const state = cachedState ?? await getFullContractState(connection, poolAddress); const result = await dexStablePoolContract(connection, poolAddress) .methods.getWithdrawalPriceImpact({ amount: params.amount, price_amount: params.priceAmount, receive_token_root: resolveTvmAddress(params.receiveTokenAddress), }) .call({ cachedState: state }); return result.value0; } static async getFeeParams(connection, poolAddress, cachedState) { const state = cachedState ?? await getFullContractState(connection, poolAddress); const result = await dexStablePoolContract(connection, poolAddress) .methods.getFeeParams({ answerId: 0 }) .call({ cachedState: state, responsible: true }); return { beneficiaryAddress: result.value0.beneficiary, beneficiaryNumerator: Number(result.value0.beneficiary_numerator), denominator: Number(result.value0.denominator), numerator: Number(result.value0.pool_numerator), threshold: result.value0.threshold, }; } static async getRoot(connection, poolAddress, cachedState) { const state = cachedState ?? await getFullContractState(connection, poolAddress); const result = await dexStablePoolContract(connection, poolAddress) .methods.getRoot({ answerId: 0 }) .call({ cachedState: state, responsible: true }); return result.dex_root; } static async getVault(connection, poolAddress, cachedState) { const state = cachedState ?? await getFullContractState(connection, poolAddress); const result = await dexStablePoolContract(connection, poolAddress) .methods.getVault({ answerId: 0 }) .call({ cachedState: state, responsible: true }); return result.value0; } static async isActive(connection, poolAddress, cachedState) { const state = cachedState ?? await getFullContractState(connection, poolAddress); const result = await dexStablePoolContract(connection, poolAddress) .methods.isActive({ answerId: 0 }) .call({ cachedState: state, responsible: true }); return result.value0; } static async getTokenRoots(connection, poolAddress, cachedState) { const state = cachedState ?? await getFullContractState(connection, poolAddress); const results = await dexStablePoolContract(connection, poolAddress) .methods.getTokenRoots({ answerId: 0 }) .call({ cachedState: state, responsible: true }); return { lp: results.lp, tokens: results.roots }; } static async getTokenWallets(connection, poolAddress, cachedState) { const state = cachedState ?? await getFullContractState(connection, poolAddress); const results = await dexStablePoolContract(connection, poolAddress) .methods.getTokenWallets({ answerId: 0 }) .call({ cachedState: state, responsible: true }); return { lp: results.lp, tokens: results.token_wallets }; } static async buildExchangePayload(connection, poolAddress, params, cachedState) { const state = cachedState ?? await getFullContractState(connection, poolAddress); const _params = { cancel_payload: params.cancelPayload ?? null, deploy_wallet_grams: params.deployWalletGrams || 0, expected_amount: params.expectedAmount, id: params.callId ?? getRandomInt(), outcoming: resolveTvmAddress(params.outcoming), recipient: resolveTvmAddress(params.recipient), referrer: resolveTvmAddress(params.referrer), success_payload: params.successPayload ?? null, toNative: params.toNative ?? null, }; try { const result = await dexStablePoolContract(connection, poolAddress) .methods.buildExchangePayload(_params) .call({ cachedState: state }); return result.value0; } catch { const result = await dexStablePoolV22Contract(connection, poolAddress) .methods.buildExchangePayload(_params) .call({ cachedState: state }); return result.value0; } } static async buildDepositLiquidityPayload(connection, poolAddress, params, cachedState) { const state = cachedState ?? await getFullContractState(connection, poolAddress); const _params = { cancel_payload: params.cancelPayload ?? null, deploy_wallet_grams: params.deployWalletGrams || 0, expected_amount: params.expectedAmount, id: params.callId ?? getRandomInt(), recipient: resolveTvmAddress(params.recipient), referrer: resolveTvmAddress(params.referrer), success_payload: params.successPayload ?? null, }; try { const result = await dexStablePoolContract(connection, poolAddress) .methods.buildDepositLiquidityPayload(_params) .call({ cachedState: state }); return result.value0; } catch { const result = await dexStablePoolV22Contract(connection, poolAddress) .methods.buildDepositLiquidityPayload(_params) .call({ cachedState: state }); return result.value0; } } static async buildWithdrawLiquidityPayload(connection, poolAddress, params, cachedState) { const state = cachedState ?? await getFullContractState(connection, poolAddress); const _params = { cancel_payload: params.cancelPayload ?? null, deploy_wallet_grams: params.deployWalletGrams || 0, expected_amounts: params.expectedAmounts, id: params.callId ?? getRandomInt(), recipient: resolveTvmAddress(params.recipient), referrer: resolveTvmAddress(params.referrer), success_payload: params.successPayload ?? null, }; try { const result = await dexStablePoolContract(connection, poolAddress) .methods.buildWithdrawLiquidityPayload({ ..._params, to_native: params.toNative ?? null, }) .call({ cachedState: state }); return result.value0; } catch { const result = await dexStablePoolV22Contract(connection, poolAddress) .methods.buildWithdrawLiquidityPayload(_params) .call({ cachedState: state }); return result.value0; } } static async buildWithdrawLiquidityOneCoinPayload(connection, poolAddress, params, cachedState) { const state = cachedState ?? await getFullContractState(connection, poolAddress); const _params = { cancel_payload: params.cancelPayload ?? null, deploy_wallet_grams: params.deployWalletGrams || 0, expected_amount: params.expectedAmount, id: params.callId ?? getRandomInt(), outcoming: resolveTvmAddress(params.outcoming), recipient: resolveTvmAddress(params.recipient), referrer: resolveTvmAddress(params.referrer), success_payload: params.successPayload ?? null, to_native: params.toNative ?? null, }; try { const result = await dexStablePoolContract(connection, poolAddress) .methods.buildWithdrawLiquidityOneCoinPayload(_params) .call({ cachedState: state }); return result.value0; } catch { const result = await dexStablePoolV22Contract(connection, poolAddress) .methods.buildWithdrawLiquidityOneCoinPayload(_params) .call({ cachedState: state }); return result.value0; } } static async expectedDepositLiquidityV2(connection, poolAddress, params, cachedState) { const state = cachedState ?? await getFullContractState(connection, poolAddress); try { const result = await dexStablePoolContract(connection, poolAddress) .methods.expectedDepositLiquidityV2({ amounts: params.amounts, answerId: 0 }) .call({ cachedState: state, responsible: true }); return { amounts: result.value0.amounts, differences: result.value0.differences, invariant: result.value0.invariant, lpReward: result.value0.lp_reward, oldBalances: result.value0.old_balances, poolFees: result.value0.pool_fees, resultBalances: result.value0.result_balances, sell: result.value0.sell, }; } catch { const result = await dexStablePoolV22Contract(connection, poolAddress) .methods.expectedDepositLiquidityV2({ amounts: params.amounts, answerId: 0 }) .call({ cachedState: state, responsible: true }); return { amounts: result.value0.amounts, differences: result.value0.differences, invariant: result.value0.invariant, lpReward: result.value0.lp_reward, oldBalances: result.value0.old_balances, poolFees: result.value0.pool_fees, resultBalances: result.value0.result_balances, sell: result.value0.sell, }; } } static async expectedDepositLiquidityOneCoin(connection, poolAddress, params, cachedState) { const state = cachedState ?? await getFullContractState(connection, poolAddress); try { const result = await dexStablePoolContract(connection, poolAddress) .methods.expectedDepositLiquidityOneCoin({ amount: params.amount, answerId: 0, spent_token_root: resolveTvmAddress(params.spentTokenAddress), }) .call({ cachedState: state, responsible: true }); return { amounts: result.value0.amounts, differences: result.value0.differences, invariant: result.value0.invariant, lpReward: result.value0.lp_reward, oldBalances: result.value0.old_balances, poolFees: result.value0.pool_fees, resultBalances: result.value0.result_balances, sell: result.value0.sell, }; } catch { const result = await dexStablePoolV22Contract(connection, poolAddress) .methods.expectedDepositLiquidityOneCoin({ amount: params.amount, answerId: 0, spent_token_root: resolveTvmAddress(params.spentTokenAddress), }) .call({ cachedState: state, responsible: true }); return { amounts: result.value0.amounts, differences: result.value0.differences, invariant: result.value0.invariant, lpReward: result.value0.lp_reward, oldBalances: result.value0.old_balances, poolFees: result.value0.pool_fees, resultBalances: result.value0.result_balances, sell: result.value0.sell, }; } } static async expectedDepositSpendAmount(connection, poolAddress, params, cachedState) { const state = cachedState ?? await getFullContractState(connection, poolAddress); try { const result = await dexStablePoolContract(connection, poolAddress) .methods.expectedDepositSpendAmount({ answerId: 0, lp_amount: params.lpAmount, spent_token_root: resolveTvmAddress(params.spentTokenAddress), }) .call({ cachedState: state, responsible: true }); return { expectedFee: result.expected_fee, tokensAmount: result.tokens_amount }; } catch { const result = await dexStablePoolV22Contract(connection, poolAddress) .methods.expectedDepositSpendAmount({ answerId: 0, lp_amount: params.lpAmount, spent_token_root: resolveTvmAddress(params.spentTokenAddress), }) .call({ cachedState: state, responsible: true }); return { expectedFee: result.expected_fee, tokensAmount: result.tokens_amount }; } } static async expectedExchange(connection, poolAddress, params, cachedState) { const state = cachedState ?? await getFullContractState(connection, poolAddress); try { const result = await dexStablePoolContract(connection, poolAddress) .methods.expectedExchange({ amount: params.amount, answerId: 0, receive_token_root: resolveTvmAddress(params.receiveTokenAddress), spent_token_root: resolveTvmAddress(params.spentTokenAddress), }) .call({ cachedState: state, responsible: true }); return { expectedAmount: result.expected_amount, expectedFee: result.expected_fee }; } catch { const result = await dexStablePoolV22Contract(connection, poolAddress) .methods.expectedExchange({ amount: params.amount, answerId: 0, receive_token_root: resolveTvmAddress(params.receiveTokenAddress), spent_token_root: resolveTvmAddress(params.spentTokenAddress), }) .call({ cachedState: state, responsible: true }); return { expectedAmount: result.expected_amount, expectedFee: result.expected_fee }; } } static async expectedOneCoinWithdrawalSpendAmount(connection, poolAddress, params, cachedState) { const state = cachedState ?? await getFullContractState(connection, poolAddress); try { const result = await dexStablePoolContract(connection, poolAddress) .methods.expectedOneCoinWithdrawalSpendAmount({ answerId: 0, receive_amount: params.receiveAmount, receive_token_root: resolveTvmAddress(params.receiveTokenAddress), }) .call({ cachedState: state, responsible: true }); return { expectedFee: result.expected_fee, lp: result.lp }; } catch { const result = await dexStablePoolV22Contract(connection, poolAddress) .methods.expectedOneCoinWithdrawalSpendAmount({ answerId: 0, receive_amount: params.receiveAmount, receive_token_root: resolveTvmAddress(params.receiveTokenAddress), }) .call({ cachedState: state, responsible: true }); return { expectedFee: result.expected_fee, lp: result.lp }; } } static async expectedWithdrawLiquidity(connection, poolAddress, amount, cachedState) { const state = cachedState ?? await getFullContractState(connection, poolAddress); try { const result = await dexStablePoolContract(connection, poolAddress) .methods.expectedWithdrawLiquidity({ answerId: 0, lp_amount: amount }) .call({ cachedState: state, responsible: true }); return { amounts: result.value0.amounts, differences: result.value0.differences, invariant: result.value0.invariant, lpAmount: result.value0.lp_amount, oldBalances: result.value0.old_balances, poolFees: result.value0.pool_fees, resultBalances: result.value0.result_balances, sell: result.value0.sell, }; } catch (e) { const result = await dexStablePoolV22Contract(connection, poolAddress) .methods.expectedWithdrawLiquidity({ answerId: 0, lp_amount: amount }) .call({ cachedState: state, responsible: true }); return { amounts: result.value0.amounts, differences: result.value0.differences, invariant: result.value0.invariant, lpAmount: result.value0.lp_amount, oldBalances: result.value0.old_balances, poolFees: result.value0.pool_fees, resultBalances: result.value0.result_balances, sell: result.value0.sell, }; } } static async expectedWithdrawLiquidityOneCoin(connection, poolAddress, params, cachedState) { const state = cachedState ?? await getFullContractState(connection, poolAddress); try { const result = await dexStablePoolContract(connection, poolAddress) .methods.expectedWithdrawLiquidityOneCoin({ answerId: 0, lp_amount: params.amount, outcoming: resolveTvmAddress(params.outcoming), }) .call({ cachedState: state, responsible: true }); return result.value0; } catch { const result = await dexStablePoolV22Contract(connection, poolAddress) .methods.expectedWithdrawLiquidityOneCoin({ answerId: 0, lp_amount: params.amount, outcoming: resolveTvmAddress(params.outcoming), }) .call({ cachedState: state, responsible: true }); return result.value0; } } }