@broxus/js-core
Version:
MobX-based JavaScript Core library
428 lines (427 loc) • 21.1 kB
JavaScript
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;
}
}
}