"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getL1TokenAddress = exports.getUsdcSymbol = exports.getTokenInfo = exports.isStablecoin = exports.isBridgedUsdc = exports.getTokenBalance = exports.getCoingeckoTokenIdByAddress = exports.resolveContractFromSymbol = exports.resolveSymbolOnChain = exports.getL2TokenAddresses = exports.fetchTokenInfo = void 0;
var tslib_1 = require("tslib");
var assert_1 = tslib_1.__importDefault(require("assert"));
var ethers_1 = require("ethers");
var constants = tslib_1.__importStar(require("../constants"));
var typechain_1 = require("../typechain");
var NetworkUtils_1 = require("./NetworkUtils");
var TypeGuards_1 = require("./TypeGuards");
var AddressUtils_1 = require("./AddressUtils");
var TOKEN_SYMBOLS_MAP = constants.TOKEN_SYMBOLS_MAP, CHAIN_IDs = constants.CHAIN_IDs, TOKEN_EQUIVALENCE_REMAPPING = constants.TOKEN_EQUIVALENCE_REMAPPING;
function fetchTokenInfo(address, signerOrProvider) {
    return tslib_1.__awaiter(this, void 0, void 0, function () {
        var token, _a, symbol, decimals;
        return tslib_1.__generator(this, function (_b) {
            switch (_b.label) {
                case 0:
                    token = new ethers_1.Contract(address, typechain_1.ERC20__factory.abi, signerOrProvider);
                    return [4, Promise.all([token.symbol(), token.decimals()])];
                case 1:
                    _a = _b.sent(), symbol = _a[0], decimals = _a[1];
                    return [2, { address: AddressUtils_1.EvmAddress.from(address), symbol: symbol, decimals: decimals }];
            }
        });
    });
}
exports.fetchTokenInfo = fetchTokenInfo;
var getL2TokenAddresses = function (l1TokenAddress, l1ChainId) {
    var _a;
    if (l1ChainId === void 0) { l1ChainId = CHAIN_IDs.MAINNET; }
    return (_a = Object.values(TOKEN_SYMBOLS_MAP).find(function (details) {
        return details.addresses[l1ChainId] === l1TokenAddress;
    })) === null || _a === void 0 ? void 0 : _a.addresses;
};
exports.getL2TokenAddresses = getL2TokenAddresses;
function resolveSymbolOnChain(chainId, symbol) {
    var token = TOKEN_SYMBOLS_MAP[symbol];
    if (!(0, TypeGuards_1.isDefined)(token) || !(0, TypeGuards_1.isDefined)(token.addresses[chainId])) {
        var network = (0, NetworkUtils_1.getNetworkName)(chainId);
        throw new Error("Unable to find token ".concat(symbol, " on ").concat(network, " (chain ID ").concat(chainId));
    }
    var decimals = token.decimals, addresses = token.addresses;
    var address = (0, AddressUtils_1.toAddressType)(addresses[chainId], chainId);
    (0, assert_1.default)(address.isEVM() || address.isSVM());
    return { symbol: symbol, decimals: decimals, address: address };
}
exports.resolveSymbolOnChain = resolveSymbolOnChain;
var resolveContractFromSymbol = function (symbol, chainId, tokenMapping) {
    var _a;
    if (tokenMapping === void 0) { tokenMapping = TOKEN_SYMBOLS_MAP; }
    return (_a = Object.values(tokenMapping).find(function (details) {
        return details.symbol.toLowerCase() === symbol.toLowerCase();
    })) === null || _a === void 0 ? void 0 : _a.addresses[Number(chainId)];
};
exports.resolveContractFromSymbol = resolveContractFromSymbol;
function getCoingeckoTokenIdByAddress(address, chainId) {
    var token = getTokenInfo((0, AddressUtils_1.toAddressType)(address, chainId), chainId);
    return TOKEN_SYMBOLS_MAP[token.symbol].coingeckoId;
}
exports.getCoingeckoTokenIdByAddress = getCoingeckoTokenIdByAddress;
function getTokenBalance(address, tokenAddress, signerOrProvider, blockTag) {
    if (blockTag === void 0) { blockTag = "latest"; }
    var token = typechain_1.ERC20__factory.connect(tokenAddress, signerOrProvider);
    return token.balanceOf(address, { blockTag: blockTag });
}
exports.getTokenBalance = getTokenBalance;
function isBridgedUsdc(tokenSymbol) {
    return !!constants.BRIDGED_USDC_SYMBOLS.find(function (bridgedUsdcSymbol) { return bridgedUsdcSymbol.toLowerCase() === tokenSymbol.toLowerCase(); });
}
exports.isBridgedUsdc = isBridgedUsdc;
function isStablecoin(tokenSymbol) {
    return constants.STABLE_COIN_SYMBOLS.some(function (stablecoinSymbol) { return stablecoinSymbol.toLowerCase() === tokenSymbol.toLowerCase(); });
}
exports.isStablecoin = isStablecoin;
function getTokenInfo(l2Token, chainId, tokenMapping) {
    var _a;
    if (tokenMapping === void 0) { tokenMapping = TOKEN_SYMBOLS_MAP; }
    var address = l2Token.toNative();
    var tokenObject = Object.values(tokenMapping).find(function (_a) {
        var addresses = _a.addresses;
        return addresses[chainId] === address;
    });
    if (!tokenObject) {
        throw new Error("Unable to resolve token info for ".concat(address, " on chain ").concat(chainId));
    }
    if ((0, NetworkUtils_1.chainIsL1)(chainId)) {
        var l1TokenSymbol = (_a = TOKEN_EQUIVALENCE_REMAPPING[tokenObject.symbol]) !== null && _a !== void 0 ? _a : tokenObject.symbol;
        tokenObject = tokenMapping[l1TokenSymbol];
    }
    return { address: l2Token, symbol: tokenObject.symbol, decimals: tokenObject.decimals };
}
exports.getTokenInfo = getTokenInfo;
function getUsdcSymbol(l2Token, chainId) {
    var IterableTokenSymbolsMap = TOKEN_SYMBOLS_MAP;
    return ["USDC", "USDbC", "USDC.e"].find(function (token) { var _a, _b; return ((_b = (_a = IterableTokenSymbolsMap[token]) === null || _a === void 0 ? void 0 : _a.addresses) === null || _b === void 0 ? void 0 : _b[chainId]) === l2Token.toNative(); });
}
exports.getUsdcSymbol = getUsdcSymbol;
function getL1TokenAddress(l2TokenAddress, chainId) {
    if ((0, NetworkUtils_1.chainIsL1)(chainId)) {
        (0, assert_1.default)(l2TokenAddress.isEVM());
        return l2TokenAddress;
    }
    var tokenObject = Object.values(TOKEN_SYMBOLS_MAP).find(function (_a) {
        var addresses = _a.addresses;
        return l2TokenAddress.toNative() === addresses[chainId];
    });
    var l1TokenAddress = tokenObject === null || tokenObject === void 0 ? void 0 : tokenObject.addresses[(0, NetworkUtils_1.chainIsProd)(chainId) ? CHAIN_IDs.MAINNET : CHAIN_IDs.SEPOLIA];
    if (!l1TokenAddress) {
        throw new Error("getL1TokenAddress: Unable to resolve l1 token for L2 token ".concat(l2TokenAddress, " on chain ").concat(chainId));
    }
    return AddressUtils_1.EvmAddress.from(l1TokenAddress);
}
exports.getL1TokenAddress = getL1TokenAddress;
//# sourceMappingURL=TokenUtils.js.map