@broxus/js-bridge-essentials
Version:
Bridge JavaScript Essentials library
220 lines (219 loc) • 11.4 kB
JavaScript
import { getFullContractState, isAddressesEquals, resolveTvmAddress } from '@broxus/js-core';
import { debug } from '@broxus/js-utils';
import { tonAlienProxyV3Contract, tonMergePoolV3Contract, tonMergeRouterContract, } from '../../models/ton-alien-proxy/contracts';
import { TonToken } from '../../models/ton-token';
export class TonAlienProxyV3Utils {
static async getExpectedTokenFeeAddress(connection, proxyAddress, tokenAddress, cachedState) {
const state = cachedState ?? await getFullContractState(connection, proxyAddress);
const result = await tonAlienProxyV3Contract(connection, proxyAddress)
.methods.getExpectedTokenFeeAddress({
_token: resolveTvmAddress(tokenAddress),
answerId: 0,
})
.call({ cachedState: state, responsible: true });
return result.value0;
}
static async getDailyLimits(connection, proxyAddress, tokenAddress, cachedState) {
const state = cachedState ?? await getFullContractState(connection, proxyAddress);
const result = await tonAlienProxyV3Contract(connection, proxyAddress)
.methods.getDailyLimits({
_token: resolveTvmAddress(tokenAddress),
answerId: 0,
})
.call({ cachedState: state, responsible: true });
return {
dailyIncomingVolume: result.value0.dailyIncomingVolume,
dailyOutgoingVolume: result.value0.dailyOutgoingVolume,
dayStartTimestamp: Number(result.value0.dayStartTimestamp),
incomingLimit: result.value0.incomingLimit,
outgoingLimit: result.value0.outgoingLimit,
};
}
static async getTvmDefaultFee(connection, proxyAddress, cachedState) {
const state = cachedState ?? await getFullContractState(connection, proxyAddress);
return tonAlienProxyV3Contract(connection, proxyAddress)
.methods.getTvmDefaultFee({ answerId: 0 })
.call({ cachedState: state, responsible: true });
}
static async getTvmFees(connection, proxyAddress, cachedState) {
const state = cachedState ?? await getFullContractState(connection, proxyAddress);
const result = await tonAlienProxyV3Contract(connection, proxyAddress)
.methods.getTvmFees({ answerId: 0 })
.call({ cachedState: state, responsible: true });
return new Map(result.value0.flat(0).map(([addr, value]) => [addr.toString(), value]));
}
static async getTvmTokenFee(connection, proxyAddress, tokenAddress, cachedState) {
const state = cachedState ?? await getFullContractState(connection, proxyAddress);
return tonAlienProxyV3Contract(connection, proxyAddress)
.methods.getTvmTokenFee({
_token: resolveTvmAddress(tokenAddress),
answerId: 0,
})
.call({ cachedState: state, responsible: true });
}
static async getConfiguration(connection, proxyAddress, cachedState) {
const state = cachedState ?? await getFullContractState(connection, proxyAddress);
return tonAlienProxyV3Contract(connection, proxyAddress)
.methods.getConfiguration({ answerId: 0 })
.call({ cachedState: state, responsible: true });
}
static async getTonEvmConfiguration(connection, proxyAddress, cachedState) {
const result = await TonAlienProxyV3Utils.getConfiguration(connection, proxyAddress, cachedState);
return result.value0.tvmConfiguration;
}
/**
* Derive EVM alien token address in TVM by the given proxy address and EVM token params
* @param {ProviderRpcClient} connection
* @param {Address | string} proxyAddress
* @param {DeriveEvmAlienJettonRootAbiParams} params
* @param {FullContractState} [cachedState] - optional. Full contract state of the alien proxy contract
*/
static async deriveEvmAlienTokenRoot(connection, proxyAddress, params, cachedState) {
const state = cachedState ?? await getFullContractState(connection, proxyAddress);
const result = await tonAlienProxyV3Contract(connection, proxyAddress)
.methods.deriveEvmAlienTokenRoot({
_chainId: params.chainId,
_decimals: params.decimals,
_name: params.name,
_symbol: params.symbol,
_token: params.token,
answerId: 0,
})
.call({ cachedState: state, responsible: true });
return result.value0;
}
/**
* Derive TON alien token address in TON by the given proxy address and TON token params
* @param {ProviderRpcClient} connection
* @param {Address | string} proxyAddress
* @param {DeriveTonAlienJettonRootAbiParams} params
* @param {FullContractState} [cachedState] - optional. Full contract state of the alien proxy contract
*/
static async deriveTonAlienTokenRoot(connection, proxyAddress, params, cachedState) {
const state = cachedState ?? await getFullContractState(connection, proxyAddress);
const result = await tonAlienProxyV3Contract(connection, proxyAddress)
.methods.deriveTvmAlienTokenRoot({
_chainId: params.chainId,
_decimals: params.decimals,
_name: params.name,
_nativeProxyWallet: resolveTvmAddress(params.nativeProxyWallet),
_symbol: params.symbol,
_token: resolveTvmAddress(params.token),
answerId: 0,
})
.call({ cachedState: state, responsible: true });
return result.value0;
}
/**
* Get derive merge router address by the given TVM-like token and proxy addresses
* @param {ProviderRpcClient} connection
* @param {Address | string} proxyAddress
* @param {Address | string} tokenAddress
* @param {FullContractState} [cachedState] - optional. Full contract state of the alien proxy contract
*/
static async deriveMergeRouter(connection, proxyAddress, tokenAddress, cachedState) {
const state = cachedState ?? await getFullContractState(connection, proxyAddress);
const result = await tonAlienProxyV3Contract(connection, proxyAddress)
.methods.deriveMergeRouter({
_token: resolveTvmAddress(tokenAddress),
answerId: 0,
})
.call({ cachedState: state, responsible: true });
return result.router;
}
/**
* Get merge pool address by the given merge router address
* @param {ProviderRpcClient} connection
* @param {Address | string} mergeRouterAddress
* @param {FullContractState} [cachedState] - optional. Full contract state of the merge router contract
*/
static async getMergePoolAddress(connection, mergeRouterAddress, cachedState) {
const state = cachedState ?? await getFullContractState(connection, mergeRouterAddress);
const result = await tonMergeRouterContract(connection, mergeRouterAddress)
.methods.getPool({ answerId: 0 })
.call({ cachedState: state, responsible: true });
return result.value0;
}
static async getMergePoolTokens(connection, mergePoolAddress, cachedState) {
const state = cachedState ?? await getFullContractState(connection, mergePoolAddress);
const result = await tonMergePoolV3Contract(connection, mergePoolAddress)
.methods.getTokens({ answerId: 0 })
.call({ cachedState: state, responsible: true });
return {
canon: result._canon,
tokens: result._tokens.map(([addr, settings]) => [addr, settings]),
};
}
static async getEvmTokenMergeDetails(connection, proxyAddress, tokenAddress, chainId, cachedState) {
try {
const state = cachedState ?? await getFullContractState(connection, proxyAddress);
const mergeRouterAddress = await TonAlienProxyV3Utils.deriveMergeRouter(connection, proxyAddress, tokenAddress, state);
const mergePoolAddress = await TonAlienProxyV3Utils.getMergePoolAddress(connection, mergeRouterAddress);
const mergedTokens = await TonAlienProxyV3Utils.getMergePoolTokens(connection, mergePoolAddress);
const providerState = await connection.getProviderState();
const enabled = mergedTokens.tokens.filter(([, settings]) => settings.enabled);
const promises = enabled.map(async ([address]) => {
try {
const meta = await TonToken.Utils.getOffchainMeta(address.toString(), providerState.networkId);
return {
baseChainId: meta.baseChainId.toString(),
evmTokenAddress: meta.evmTokenAddress,
isMerged: meta.baseChainId.toString() === chainId,
};
}
catch (e) {
return { isMerged: false };
}
});
const results = await Promise.all(promises);
const merged = results.find(e => e.isMerged);
if (!merged?.baseChainId) {
return undefined;
}
return {
baseChainId: merged.baseChainId,
canonicalAddress: mergedTokens.canon,
evmTokenAddress: merged.evmTokenAddress,
mergePoolAddress,
mergeRouterAddress,
tonTokenAddress: resolveTvmAddress(tokenAddress),
};
}
catch (e) {
debug('TonAlienProxyV3.getEvmTokenMergeDetails failed with an error', e);
return undefined;
}
}
static async getTonTokenMergeDetails(connection, proxyAddress, tokenAddress, cachedState) {
try {
const state = cachedState ?? await getFullContractState(connection, proxyAddress);
const tonTokenAddress = resolveTvmAddress(tokenAddress);
const mergeRouterAddress = await TonAlienProxyV3Utils.deriveMergeRouter(connection, proxyAddress, tokenAddress, state);
const mergePoolAddress = await TonAlienProxyV3Utils.getMergePoolAddress(connection, mergeRouterAddress);
const mergedTokens = await TonAlienProxyV3Utils.getMergePoolTokens(connection, mergePoolAddress);
const merged = mergedTokens.tokens.find(([address, settings]) => isAddressesEquals(address, tonTokenAddress) && settings.enabled);
if (!merged) {
return undefined;
}
return {
canonicalAddress: mergedTokens.canon,
mergePoolAddress,
mergeRouterAddress,
tonTokenAddress: resolveTvmAddress(merged[0] ?? tokenAddress),
};
}
catch (e) {
debug('TonAlienProxyV3.getTonTokenMergeDetails failed with an error', e);
return undefined;
}
}
static decodeEvent(connection, proxyAddress, args) {
return tonAlienProxyV3Contract(connection, proxyAddress).decodeEvent(args);
}
static decodeTransaction(connection, proxyAddress, args) {
return tonAlienProxyV3Contract(connection, proxyAddress).decodeTransaction(args);
}
static decodeTransactionEvents(connection, proxyAddress, transaction) {
return tonAlienProxyV3Contract(connection, proxyAddress).decodeTransactionEvents({ transaction });
}
}