"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.buildConfig = exports.isTransactionIdentifier = exports.resolveWrappedToken = exports.canonicalAddress = exports.isSameToken = exports.isTokenId = exports.nativeTokenId = exports.isNative = void 0;
const sdk_base_1 = require("@wormhole-foundation/sdk-base");
const address_1 = require("./address");
const contracts_1 = require("./contracts");
// Typeguard to check if the token address is the string "native" representing the gas token
// on a given chain
function isNative(thing) {
    return typeof thing === "string" && thing === "native";
}
exports.isNative = isNative;
/**  Utility to create a TokenId with the address set to the string "native" */
function nativeTokenId(chain) {
    return { chain, address: "native" };
}
exports.nativeTokenId = nativeTokenId;
function isTokenId(thing) {
    return (typeof thing === "object" &&
        thing.address !== undefined &&
        thing.chain !== undefined &&
        (0, sdk_base_1.isChain)(thing.chain));
}
exports.isTokenId = isTokenId;
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);
}
exports.isSameToken = isSameToken;
/** Utility function to return the string representation of a ChainAddress or TokenId */
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();
}
exports.canonicalAddress = canonicalAddress;
/**
 * Given a token id, address, or the const string 'native' return
 * a TokenId representing either the token itself or the wrapped version
 */
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 = sdk_base_1.tokens.getNative(network, chain);
        if (!nativeToken)
            throw new Error("Invalid destination token");
        const wrappedKey = nativeToken.wrappedKey;
        const wrappedToken = sdk_base_1.tokens.getTokenByKey(network, chain, wrappedKey);
        if (!wrappedToken)
            throw new Error("Invalid wrapped token key: " + wrappedKey);
        const destNativeWrapped = { chain, address: (0, address_1.toNative)(chain, wrappedToken.address) };
        return [true, destNativeWrapped];
    }
    const tid = { chain, address: tokenAddr };
    return [false, tid];
}
exports.resolveWrappedToken = resolveWrappedToken;
function isTransactionIdentifier(thing) {
    return thing.chain !== undefined && thing.txid !== undefined;
}
exports.isTransactionIdentifier = isTransactionIdentifier;
function buildConfig(n) {
    const cc = sdk_base_1.chains
        .map((c) => {
        const platform = (0, sdk_base_1.chainToPlatform)(c);
        let nativeChainId = "";
        try {
            nativeChainId = sdk_base_1.nativeChainIds.networkChainToNativeChainId.get(n, c);
        }
        catch { }
        const tokenMap = sdk_base_1.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: (0, sdk_base_1.toChainId)(c),
            finalityThreshold: sdk_base_1.finality.finalityThreshold.get(c) ?? 0,
            blockTime: sdk_base_1.finality.blockTime(c),
            contracts: (0, contracts_1.getContracts)(n, c),
            nativeTokenDecimals: sdk_base_1.decimals.nativeDecimals(platform),
            nativeChainId,
            tokenMap,
            wrappedNative,
            explorer: sdk_base_1.explorer.explorerConfigs(n, c),
            rpc: sdk_base_1.rpc.rpcAddress(n, c),
        };
    })
        .reduce((acc, curr) => {
        return { ...acc, [curr.key]: curr };
    }, {});
    return cc;
}
exports.buildConfig = buildConfig;
//# sourceMappingURL=types.js.map