import cardanoNativeTokens from "./data/cardanoNative";
import { findCryptoCurrencyById, getCryptoCurrencyById } from "./currencies";
import jettonTokens from "./data/ton-jetton";
import { tokens as sepoliaTokens } from "./data/evm/11155111";
import stellarTokens from "./data/stellar";
import vechainTokens from "./data/vip180";
import esdttokens from "./data/esdt";
import asatokens from "./data/asa";
import { tokens as polygonTokens } from "./data/evm/137";
import { tokens as sonicTokens } from "./data/evm/146";
import trc10tokens from "./data/trc10";
import trc20tokens from "./data/trc20";
import { tokens as mainnetTokens } from "./data/evm/1";
import { tokens as bnbTokens } from "./data/evm/56";
import filecoinTokens from "./data/filecoin-erc20";
import spltokens from "./data/spl";
import aptCoinTokens from "./data/apt_coin";
import aptFATokens from "./data/apt_fungible_asset";
import { getEnv } from "@ledgerhq/live-env";
const emptyArray = [];
const tokensArray = [];
const tokensArrayWithDelisted = [];
const tokensByCryptoCurrency = {};
const tokensByCryptoCurrencyWithDelisted = {};
const tokensById = {};
const tokensByTicker = {};
const tokensByAddress = {};
const tokensByCurrencyAddress = {};
const tokenListHashes = new Set();
// Ethereum mainnet tokens
addTokens(mainnetTokens.map(convertERC20));
// Ethereum Sepolia testnet tokens
addTokens(sepoliaTokens.map(convertERC20));
// Polygon tokens
addTokens(polygonTokens.map(convertERC20));
// Binance Smart Chain tokens
addTokens(bnbTokens.map(convertERC20));
// Tron tokens
addTokens(trc10tokens.map(convertTRONTokens("trc10")));
addTokens(trc20tokens.map(convertTRONTokens("trc20")));
// Algoland tokens
addTokens(asatokens.map(convertAlgorandASATokens));
// MultiversX tokens
addTokens(esdttokens.map(convertMultiversXESDTTokens));
// Cardano tokens
addTokens(cardanoNativeTokens.map(convertCardanoNativeTokens));
// Stellar tokens
addTokens(stellarTokens.map(convertStellarTokens));
// VeChain tokens
addTokens(vechainTokens.map(convertVechainToken));
// Ton tokens
addTokens(jettonTokens.map(convertJettonToken));
// Filecoin tokens
addTokens(filecoinTokens.map(convertERC20));
// Solana tokens
addTokens(spltokens.map(convertSplTokens));
// Sonic
addTokens(sonicTokens.map(convertERC20));
if (getEnv("APTOS_ENABLE_TOKENS")) {
    // Aptos Legacy Coin tokens
    addTokens(aptCoinTokens.map(convertAptCoinTokens));
    // Aptos fungible assets tokens
    addTokens(aptFATokens.map(convertAptFaTokens));
}
const defaultTokenListOptions = {
    withDelisted: false,
};
export function createTokenHash(token) {
    return token
        ? `${token.id}${token.contractAddress}${token.delisted}${token.ticker}${token.ledgerSignature}`
        : "";
}
/**
 * Only for jest purpose, clean object to be empty
 * @param obj
 */
const __clearObject = (obj) => {
    for (const key in obj) {
        delete obj[key];
    }
};
/**
 * Only for jest purpose, clear all the init list
 */
export function __clearAllLists() {
    tokensArray.length = 0;
    tokensArrayWithDelisted.length = 0;
    __clearObject(tokensByCryptoCurrency);
    __clearObject(tokensByCryptoCurrencyWithDelisted);
    __clearObject(tokensById);
    __clearObject(tokensByTicker);
    __clearObject(tokensByAddress);
    __clearObject(tokensByCurrencyAddress);
    tokenListHashes.clear();
}
/**
 *
 */
export function listTokens(options) {
    const { withDelisted } = { ...defaultTokenListOptions, ...options };
    return withDelisted ? tokensArrayWithDelisted : tokensArray;
}
/**
 *
 */
export function listTokensForCryptoCurrency(currency, options) {
    const { withDelisted } = { ...defaultTokenListOptions, ...options };
    if (withDelisted) {
        return tokensByCryptoCurrencyWithDelisted[currency.id] || emptyArray;
    }
    return tokensByCryptoCurrency[currency.id] || emptyArray;
}
/**
 *
 */
export function listTokenTypesForCryptoCurrency(currency) {
    return listTokensForCryptoCurrency(currency).reduce((acc, cur) => {
        const tokenType = cur.tokenType.replace("_", " ");
        if (acc.indexOf(tokenType) < 0) {
            return [...acc, tokenType];
        }
        return acc;
    }, []);
}
/**
 *
 */
export function findTokenByTicker(ticker) {
    return tokensByTicker[ticker];
}
/**
 *
 */
export function findTokenById(id) {
    return tokensById[id];
}
let deprecatedDisplayed = false;
export function findTokenByAddress(address) {
    if (!deprecatedDisplayed) {
        deprecatedDisplayed = true;
        console.warn("findTokenByAddress is deprecated. use findTokenByAddressInCurrency");
    }
    return tokensByAddress[address.toLowerCase()];
}
export function findTokenByAddressInCurrency(address, currencyId) {
    return tokensByCurrencyAddress[currencyId + ":" + address.toLowerCase()];
}
/**
 *
 */
export const hasTokenId = (id) => id in tokensById;
/**
 *
 */
export function getTokenById(id) {
    const currency = findTokenById(id);
    if (!currency) {
        throw new Error(`token with id "${id}" not found`);
    }
    return currency;
}
function removeTokenFromArray(array, tokenId) {
    if (array && array.length > 0) {
        const index = array.findIndex(currentToken => currentToken && currentToken.id === tokenId);
        if (index === -1)
            return array;
        return array.splice(index, 1);
    }
}
function removeTokenFromRecord(record, key) {
    tokenListHashes.delete(record[key]);
    delete record[key];
}
/**
 * Delete previous token entry to all array
 * @param token
 */
function removeTokenFromAllLists(token) {
    const { id, contractAddress, parentCurrency, ticker } = token;
    const lowCaseContract = contractAddress.toLowerCase();
    removeTokenFromRecord(tokensById, id);
    removeTokenFromRecord(tokensByCurrencyAddress, parentCurrency.id + ":" + lowCaseContract);
    removeTokenFromRecord(tokensByAddress, lowCaseContract);
    removeTokenFromRecord(tokensByTicker, ticker);
    removeTokenFromArray(tokensArray, id);
    removeTokenFromArray(tokensArrayWithDelisted, id);
    removeTokenFromArray(tokensByCryptoCurrency[parentCurrency.id], id);
    removeTokenFromArray(tokensByCryptoCurrencyWithDelisted[parentCurrency.id], id);
}
export function addTokens(list) {
    list.forEach(token => {
        if (!token)
            return;
        const tokenHash = createTokenHash(token);
        if (tokenListHashes.has(tokenHash))
            return;
        /**
         * We clean all the reference of an existing token, if an hash doesn't  match.
         * Like this we can update any change from a already added token coming from Dynamic CAL
         * and maintain it up to date without having to release a new version of LLD or LLM
         */
        const { id, contractAddress, parentCurrency, delisted, ticker } = token;
        if (tokensById[id])
            removeTokenFromAllLists(token);
        const lowCaseContract = contractAddress.toLowerCase();
        if (!delisted)
            tokensArray.push(token);
        tokensArrayWithDelisted.push(token);
        tokensById[id] = token;
        if (!tokensByTicker[ticker]) {
            tokensByTicker[ticker] = token;
        }
        tokensByAddress[lowCaseContract] = token;
        tokensByCurrencyAddress[parentCurrency.id + ":" + lowCaseContract] = token;
        if (!(parentCurrency.id in tokensByCryptoCurrency)) {
            tokensByCryptoCurrency[parentCurrency.id] = [];
        }
        if (!(parentCurrency.id in tokensByCryptoCurrencyWithDelisted)) {
            tokensByCryptoCurrencyWithDelisted[parentCurrency.id] = [];
        }
        if (!delisted)
            tokensByCryptoCurrency[parentCurrency.id].push(token);
        tokensByCryptoCurrencyWithDelisted[parentCurrency.id].push(token);
        tokenListHashes.add(tokenHash);
    });
}
export function convertERC20([parentCurrencyId, token, ticker, magnitude, name, ledgerSignature, contractAddress, disableCountervalue, delisted,]) {
    const parentCurrency = findCryptoCurrencyById(parentCurrencyId);
    if (!parentCurrency) {
        return;
    }
    const tokenType = parentCurrencyId === "bsc" ? "bep20" : "erc20";
    return {
        type: "TokenCurrency",
        id: `${parentCurrencyId}/${tokenType}/${token}`,
        ledgerSignature,
        contractAddress,
        parentCurrency,
        tokenType,
        name,
        ticker,
        delisted,
        disableCountervalue: !!parentCurrency.isTestnetFor || !!disableCountervalue,
        units: [
            {
                name,
                code: ticker,
                magnitude,
            },
        ],
    };
}
function convertAlgorandASATokens([id, abbr, name, contractAddress, precision,]) {
    const parentCurrency = getCryptoCurrencyById("algorand");
    return {
        type: "TokenCurrency",
        id: `algorand/asa/${id}`,
        contractAddress,
        parentCurrency,
        tokenType: "asa",
        name,
        ticker: abbr,
        disableCountervalue: false,
        units: [
            {
                name,
                code: abbr,
                magnitude: precision,
            },
        ],
    };
}
function convertVechainToken([tokenIdenfitier, ticker, name, contractAddress, precision,]) {
    return {
        type: "TokenCurrency",
        id: `vechain/vip180/${tokenIdenfitier}`,
        contractAddress: contractAddress,
        parentCurrency: getCryptoCurrencyById("vechain"),
        tokenType: "vip180",
        name,
        ticker,
        disableCountervalue: false,
        units: [
            {
                name,
                code: ticker,
                magnitude: precision,
            },
        ],
    };
}
function convertTRONTokens(type) {
    return ([id, abbr, name, contractAddress, precision, delisted, ledgerSignature]) => {
        const parentCurrency = getCryptoCurrencyById("tron");
        return {
            type: "TokenCurrency",
            id: `tron/${type}/${id}`,
            contractAddress,
            parentCurrency,
            tokenType: type,
            name,
            ticker: abbr,
            delisted,
            disableCountervalue: false,
            ledgerSignature,
            units: [
                {
                    name,
                    code: abbr,
                    magnitude: precision,
                },
            ],
        };
    };
}
function convertMultiversXESDTTokens([ticker, identifier, decimals, signature, name,]) {
    const MULTIVERSX_ESDT_CONTRACT = "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u";
    // const parentCurrency = getCryptoCurrencyById("multiversx");
    const parentCurrency = getCryptoCurrencyById("elrond");
    return {
        type: "TokenCurrency",
        id: `multiversx/esdt/${identifier}`,
        contractAddress: MULTIVERSX_ESDT_CONTRACT,
        ledgerSignature: signature,
        parentCurrency,
        tokenType: "esdt",
        disableCountervalue: false,
        name,
        ticker,
        units: [
            {
                name,
                code: name,
                magnitude: decimals,
            },
        ],
    };
}
export function convertSplTokens([id, network, name, symbol, address, decimals,]) {
    return {
        type: "TokenCurrency",
        id,
        contractAddress: address,
        parentCurrency: getCryptoCurrencyById(network),
        name,
        tokenType: "spl",
        ticker: symbol,
        disableCountervalue: false,
        units: [
            {
                name,
                code: symbol,
                magnitude: decimals,
            },
        ],
    };
}
function convertAptosTokens(tokenType, [id, ticker, name, address, decimals, delisted]) {
    return {
        type: "TokenCurrency",
        id,
        contractAddress: address,
        parentCurrency: getCryptoCurrencyById("aptos"),
        name,
        tokenType,
        ticker,
        disableCountervalue: false,
        delisted,
        units: [
            {
                name,
                code: ticker,
                magnitude: decimals,
            },
        ],
    };
}
function convertAptCoinTokens(token) {
    return convertAptosTokens("coin", token);
}
function convertAptFaTokens(token) {
    return convertAptosTokens("fungible_asset", token);
}
function convertCardanoNativeTokens([parentCurrencyId, policyId, assetName, name, ticker, decimals, delisted,]) {
    const assetId = policyId + assetName;
    const parentCurrency = getCryptoCurrencyById(parentCurrencyId);
    if (!parentCurrency) {
        return;
    }
    return {
        type: "TokenCurrency",
        id: `${parentCurrencyId}/native/${assetId}`,
        // Tracking and accounting of native tokens is natively supported by cardano ledger.
        // As there's no contract for native tokens, using unique assetId in place of contractAddress
        contractAddress: assetId,
        parentCurrency,
        tokenType: "native",
        name,
        ticker,
        delisted,
        disableCountervalue: false,
        units: [
            {
                name,
                code: ticker,
                magnitude: decimals,
            },
        ],
    };
}
function convertStellarTokens([assetCode, assetIssuer, assetType, name, precision,]) {
    const parentCurrency = getCryptoCurrencyById("stellar");
    // FIXME: to be discussed with CAL service as values are Uppercase IRL
    return {
        type: "TokenCurrency",
        id: `stellar/asset/${assetCode.toUpperCase()}:${assetIssuer.toUpperCase()}`,
        contractAddress: assetIssuer.toUpperCase(),
        parentCurrency,
        tokenType: assetType,
        name,
        ticker: assetCode,
        disableCountervalue: false,
        units: [
            {
                name,
                code: assetCode,
                magnitude: precision,
            },
        ],
    };
}
export function convertJettonToken([address, name, ticker, magnitude, delisted]) {
    const parentCurrency = findCryptoCurrencyById("ton");
    if (!parentCurrency) {
        return;
    }
    return {
        type: "TokenCurrency",
        id: "ton/jetton/" + address.toLocaleLowerCase(),
        contractAddress: address,
        parentCurrency,
        tokenType: "jetton",
        name,
        ticker,
        delisted,
        disableCountervalue: false,
        units: [
            {
                name,
                code: ticker,
                magnitude,
            },
        ],
    };
}
//# sourceMappingURL=tokens.js.map