"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.TokenInfoManager = exports.NATIVE_TOKENS = void 0;
const constants_1 = require("@ethersproject/constants");
const handler_1 = require("../erc20/handler");
const subgraph_1 = require("../erc20/subgraph");
exports.NATIVE_TOKENS = {
    1: {
        // Ethereum Mainnet
        name: "Ether",
        decimals: 18,
        symbol: "ETH"
    },
    11155111: {
        // Ethereum Sepolia
        name: "Ether",
        decimals: 18,
        symbol: "ETH"
    },
    8453: {
        // Base
        name: "Ether",
        decimals: 18,
        symbol: "ETH"
    },
    42161: {
        // Arbitrum
        name: "Ether",
        decimals: 18,
        symbol: "ETH"
    },
    10: {
        // Base
        name: "Ether",
        decimals: 18,
        symbol: "ETH"
    },
    84532: {
        // Base Sepolia
        name: "Ether",
        decimals: 18,
        symbol: "ETH"
    },
    11155420: {
        // Optimism Sepolia
        name: "Ether",
        decimals: 18,
        symbol: "ETH"
    },
    421614: {
        // Arbitrum Sepolia
        name: "Ether",
        decimals: 18,
        symbol: "ETH"
    },
    137: {
        // Polygon Mainnet
        name: "MATIC",
        decimals: 18,
        symbol: "MATIC"
    },
    80002: {
        // Polygon Amoy
        name: "MATIC",
        decimals: 18,
        symbol: "MATIC"
    },
    1234: {
        // Private Node
        name: "Ether",
        decimals: 18,
        symbol: "ETH"
    },
    31337: {
        // Local Hardhat
        name: "Ether",
        decimals: 18,
        symbol: "ETH"
    }
};
class TokenInfoManager {
    constructor(chainId, web3Lib, subgraphUrl) {
        if (!exports.NATIVE_TOKENS[chainId]) {
            throw new Error(`Unexpected chainId value '${chainId}'`);
        }
        if (!TokenInfoManager.TokenInfos.has(chainId)) {
            const tokenInfos = new Map();
            tokenInfos.set(constants_1.AddressZero, exports.NATIVE_TOKENS[chainId]);
            TokenInfoManager.TokenInfos.set(chainId, tokenInfos);
        }
        if (!TokenInfoManager.mapInitialized.has(chainId)) {
            TokenInfoManager.mapInitialized.set(chainId, false);
        }
        if (!TokenInfoManager.InvalidAddresses.has(chainId)) {
            TokenInfoManager.InvalidAddresses.set(chainId, new Set());
        }
        this._web3Lib = web3Lib;
        this._subgraphUrl = subgraphUrl;
        this._chainId = chainId;
    }
    getExchangeTokenInfo(tokenAddress) {
        return __awaiter(this, void 0, void 0, function* () {
            yield this.ensureInitialized();
            const tokenInfos = TokenInfoManager.TokenInfos.get(this._chainId);
            const invalidAddressesSet = TokenInfoManager.InvalidAddresses.get(this._chainId);
            const key = tokenAddress.toLowerCase();
            if (!tokenInfos.has(key) && !invalidAddressesSet.has(key)) {
                const args = {
                    web3Lib: this._web3Lib,
                    contractAddress: tokenAddress
                };
                try {
                    const [decimals, name, symbol] = yield Promise.all([
                        (0, handler_1.getDecimals)(args),
                        (0, handler_1.getName)(args),
                        (0, handler_1.getSymbol)(args)
                    ]);
                    tokenInfos.set(key, {
                        decimals,
                        name,
                        symbol
                    });
                }
                catch (error) {
                    invalidAddressesSet.add(key);
                }
            }
            return tokenInfos.get(key);
        });
    }
    ensureInitialized() {
        return __awaiter(this, void 0, void 0, function* () {
            const isInitialized = TokenInfoManager.mapInitialized.get(this._chainId);
            if (!isInitialized) {
                // Be sure we are initializing the map only one time per chainId
                TokenInfoManager.mapInitialized.set(this._chainId, true);
                const tokenInfos = TokenInfoManager.TokenInfos.get(this._chainId);
                // Get all tokens from subgraph
                const tokens = yield (0, subgraph_1.getExchangeTokens)(this._subgraphUrl);
                for (const token of tokens) {
                    tokenInfos.set(token.address.toLowerCase(), {
                        decimals: parseInt(token.decimals),
                        name: token.name,
                        symbol: token.symbol
                    });
                }
            }
        });
    }
}
exports.TokenInfoManager = TokenInfoManager;
TokenInfoManager.TokenInfos = new Map();
TokenInfoManager.mapInitialized = new Map();
TokenInfoManager.InvalidAddresses = new Map();
//# sourceMappingURL=tokenInfoManager.js.map