@broxus/js-bridge-essentials
Version:
Bridge JavaScript Essentials library
89 lines (88 loc) • 4.03 kB
JavaScript
import { Endpoint, resolveTvmAddress } from '@broxus/js-core';
import { debug, throwException } from '@broxus/js-utils';
import { BigNumber } from 'bignumber.js';
import { TonTokenRootAbi } from '../../models/ton-token/abi';
import { TonChains } from '../../types';
import { resolveTonAddress } from '../../utils';
export class TonTokenUtils {
static endpoints = {
[TonChains.Mainnet]: 'https://ton-tokens-meta.chainconnect.com',
[TonChains.Testnet]: 'https://ton-testnet-tokens-meta.chainconnect.com',
};
static async getOffchainDetails(address, chainId) {
const endpoint = new Endpoint('token/:address', chainId != null
? TonTokenUtils.endpoints[chainId]
: (TonTokenUtils.endpoints[TonChains.Mainnet] ?? TonTokenUtils.endpoints[TonChains.Mainnet]));
const details = await endpoint.fetch({ address: resolveTonAddress(address).toRawString() });
if (!details.symbol) {
throw new Error('Details does not contains symbol');
}
if (!details.decimals) {
throw new Error('Details does not contains decimals');
}
if (!details.name) {
throw new Error('Details does not contains name');
}
return {
address: resolveTonAddress(address),
decimals: Number(details.decimals),
logoURI: details.imageUrl ?? undefined,
name: details.name,
symbol: details.symbol,
};
}
static async getOffchainMeta(address, chainId) {
const endpoint = new Endpoint('token/:address', chainId != null
? TonTokenUtils.endpoints[chainId]
: (TonTokenUtils.endpoints[TonChains.Mainnet] ?? TonTokenUtils.endpoints[TonChains.Mainnet]));
const details = await endpoint.fetch({
address: resolveTonAddress(address).toRawString(),
});
if (!details.meta) {
throw new Error('Details does not contains meta');
}
if (!details.meta.decimals) {
throw new Error('Meta does not contains decimals');
}
return {
baseChainId: details.meta.chainId,
baseToken: details.meta.baseToken,
decimals: details.meta.decimals,
evmTokenAddress: `0x${BigNumber(details.meta.baseToken).toString(16).padStart(40, '0')}`,
name: details.meta.name,
symbol: details.meta.symbol,
};
}
static async walletOf(connection, params, cachedState) {
const tokenRawAddress = resolveTonAddress(params.tokenAddress).toRawString();
const ownerRawAddress = resolveTonAddress(params.ownerAddress).toRawString();
try {
// @ts-ignore Support for everscale-inpage-provider with runGetter (legacy)
const result = await connection.runGetter({
address: resolveTvmAddress(tokenRawAddress),
cachedState,
inputData: {
walletOwner: resolveTvmAddress(ownerRawAddress),
},
inputStructure: [{ name: 'walletOwner', type: 'address' }],
method: 'get_wallet_address',
outputStructure: [{ name: 'value0', type: 'address' }],
});
if (!result.output?.value0) {
throwException('Wallet not found');
}
return resolveTonAddress(result.output.value0.toString());
}
catch (e) {
debug('runGetter call failed with an error. Fallback to contract getter call');
const contract = new connection.Contract(TonTokenRootAbi, resolveTvmAddress(tokenRawAddress));
// @ts-ignore Support for everscale-inpage-provider with getters
const result = await contract.getters
.get_wallet_address({
walletOwner: resolveTvmAddress(ownerRawAddress),
})
.run({ cachedState });
return resolveTonAddress(result.value0.toString());
}
}
}