import { chainToPlatform, chains, decimals, explorer, finality, isChain, nativeChainIds, rpc, toChainId, tokens, } from "@wormhole-foundation/sdk-base";
import { toNative } from "./address";
import { getContracts } from "./contracts";
// Typeguard to check if the token address is the string "native" representing the gas token
// on a given chain
export function isNative(thing) {
    return typeof thing === "string" && thing === "native";
}
/**  Utility to create a TokenId with the address set to the string "native" */
export function nativeTokenId(chain) {
    return { chain, address: "native" };
}
export function isTokenId(thing) {
    return (typeof thing === "object" &&
        thing.address !== undefined &&
        thing.chain !== undefined &&
        isChain(thing.chain));
}
export function isSameToken(a, b) {
    if (a.chain !== b.chain)
        return false;
    if (isNative(a.address) && isNative(b.address))
        return true;
    return canonicalAddress(a) === canonicalAddress(b);
}
/** Utility function to return the string representation of a ChainAddress or TokenId */
export function canonicalAddress(ca) {
    if (isTokenId(ca) && isNative(ca.address))
        return ca.address;
    // @ts-ignore -- `toNative` will eval to 'never' until platforms are registered
    return ca.address.toNative(ca.chain).toString();
}
/**
 * Given a token id, address, or the const string 'native' return
 * a TokenId representing either the token itself or the wrapped version
 */
export function resolveWrappedToken(network, chain, token) {
    let tokenAddr;
    if (isTokenId(token)) {
        if (!isNative(token.address))
            return [false, token];
        tokenAddr = token.address;
    }
    else {
        tokenAddr = token;
    }
    if (isNative(tokenAddr)) {
        const nativeToken = tokens.getNative(network, chain);
        if (!nativeToken)
            throw new Error("Invalid destination token");
        const wrappedKey = nativeToken.wrappedKey;
        const wrappedToken = tokens.getTokenByKey(network, chain, wrappedKey);
        if (!wrappedToken)
            throw new Error("Invalid wrapped token key: " + wrappedKey);
        const destNativeWrapped = { chain, address: toNative(chain, wrappedToken.address) };
        return [true, destNativeWrapped];
    }
    const tid = { chain, address: tokenAddr };
    return [false, tid];
}
export function isTransactionIdentifier(thing) {
    return thing.chain !== undefined && thing.txid !== undefined;
}
export function buildConfig(n) {
    const cc = chains
        .map((c) => {
        const platform = chainToPlatform(c);
        let nativeChainId = "";
        try {
            nativeChainId = nativeChainIds.networkChainToNativeChainId.get(n, c);
        }
        catch { }
        const tokenMap = tokens.getTokenMap(n, c);
        const nativeToken = tokenMap
            ? Object.values(tokenMap).find((token) => isNative(token.address) && token.wrappedKey)
            : undefined;
        const wrappedNative = nativeToken ? tokenMap[nativeToken.wrappedKey] : undefined;
        return {
            key: c,
            platform,
            network: n,
            chainId: toChainId(c),
            finalityThreshold: finality.finalityThreshold.get(c) ?? 0,
            blockTime: finality.blockTime(c),
            contracts: getContracts(n, c),
            nativeTokenDecimals: decimals.nativeDecimals(platform),
            nativeChainId,
            tokenMap,
            wrappedNative,
            explorer: explorer.explorerConfigs(n, c),
            rpc: rpc.rpcAddress(n, c),
        };
    })
        .reduce((acc, curr) => {
        return { ...acc, [curr.key]: curr };
    }, {});
    return cc;
}
//# sourceMappingURL=types.js.map