UNPKG

@broxus/js-bridge-essentials

Version:

Bridge JavaScript Essentials library

191 lines (190 loc) 9.78 kB
import { getFullContractState, isAddressesEquals, resolveTvmAddress } from '@broxus/js-core'; import { debug } from '@broxus/js-utils'; import { tonAlienProxyV2Contract, tonMergePoolV2Contract, tonMergeRouterContract, } from '../../models/ton-alien-proxy/contracts'; import { TonToken } from '../../models/ton-token'; export class TonAlienProxyV2Utils { static async getExpectedTokenFeeAddress(connection, proxyAddress, tokenAddress, cachedState) { const state = cachedState ?? await getFullContractState(connection, proxyAddress); const result = await tonAlienProxyV2Contract(connection, proxyAddress) .methods.getExpectedTokenFeeAddress({ _token: resolveTvmAddress(tokenAddress), answerId: 0, }) .call({ cachedState: state, responsible: true }); return result.value0; } static async getTvmTokenFee(connection, proxyAddress, tokenAddress, cachedState) { const state = cachedState ?? await getFullContractState(connection, proxyAddress); return tonAlienProxyV2Contract(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 tonAlienProxyV2Contract(connection, proxyAddress) .methods.getConfiguration({ answerId: 0 }) .call({ cachedState: state, responsible: true }); } static async getTonEvmConfiguration(connection, proxyAddress, cachedState) { const result = await TonAlienProxyV2Utils.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 tonAlienProxyV2Contract(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 tonAlienProxyV2Contract(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 tonAlienProxyV2Contract(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 tonMergePoolV2Contract(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 TonAlienProxyV2Utils.deriveMergeRouter(connection, proxyAddress, tokenAddress, state); const mergePoolAddress = await TonAlienProxyV2Utils.getMergePoolAddress(connection, mergeRouterAddress); const mergedTokens = await TonAlienProxyV2Utils.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('TonAlienProxyV2.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 TonAlienProxyV2Utils.deriveMergeRouter(connection, proxyAddress, tokenAddress, state); const mergePoolAddress = await TonAlienProxyV2Utils.getMergePoolAddress(connection, mergeRouterAddress); const mergedTokens = await TonAlienProxyV2Utils.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('TonAlienProxyV2.getTonTokenMergeDetails failed with an error', e); return undefined; } } static decodeEvent(connection, proxyAddress, args) { return tonAlienProxyV2Contract(connection, proxyAddress).decodeEvent(args); } static decodeTransaction(connection, proxyAddress, args) { return tonAlienProxyV2Contract(connection, proxyAddress).decodeTransaction(args); } static decodeTransactionEvents(connection, proxyAddress, transaction) { return tonAlienProxyV2Contract(connection, proxyAddress).decodeTransactionEvents({ transaction }); } }