/**
 * @packageDocumentation
 *
 * An implementation of a peer id
 *
 * @example
 *
 * ```TypeScript
 * import { peerIdFromString } from '@libp2p/peer-id'
 * const peer = peerIdFromString('12D3KooWKnDdG3iXw9eTFijk3EWSunZcFi54Zka4wmtqtt6rPxc8')
 *
 * console.log(peer.toCID()) // CID(bafzaa...)
 * console.log(peer.toString()) // "12D3K..."
 * ```
 */
import { publicKeyFromMultihash } from '@libp2p/crypto/keys';
import { InvalidCIDError, InvalidMultihashError, InvalidParametersError, UnsupportedKeyTypeError } from '@libp2p/interface';
import { base58btc } from 'multiformats/bases/base58';
import { CID } from 'multiformats/cid';
import * as Digest from 'multiformats/hashes/digest';
import { identity } from 'multiformats/hashes/identity';
import { sha256 } from 'multiformats/hashes/sha2';
import { toString as uint8ArrayToString } from 'uint8arrays/to-string';
import { RSAPeerId as RSAPeerIdClass, Ed25519PeerId as Ed25519PeerIdClass, Secp256k1PeerId as Secp256k1PeerIdClass, URLPeerId as URLPeerIdClass } from './peer-id.js';
// these values are from https://github.com/multiformats/multicodec/blob/master/table.csv
const LIBP2P_KEY_CODE = 0x72;
const TRANSPORT_IPFS_GATEWAY_HTTP_CODE = 0x0920;
export function peerIdFromString(str, decoder) {
    let multihash;
    if (str.charAt(0) === '1' || str.charAt(0) === 'Q') {
        // identity hash ed25519/secp256k1 key or sha2-256 hash of
        // rsa public key - base58btc encoded either way
        multihash = Digest.decode(base58btc.decode(`z${str}`));
    }
    else if (str.startsWith('k51qzi5uqu5') || str.startsWith('kzwfwjn5ji4') || str.startsWith('k2k4r8') || str.startsWith('bafz')) {
        // base36 encoded CIDv1 with libp2p-key and identity hash (for ed25519/secp256k1/rsa) or base32 encoded CIDv1 with libp2p-key and identity hash (for ed25519/secp256k1/rsa)
        return peerIdFromCID(CID.parse(str));
    }
    else {
        if (decoder == null) {
            throw new InvalidParametersError('Please pass a multibase decoder for strings that do not start with "1" or "Q"');
        }
        multihash = Digest.decode(decoder.decode(str));
    }
    return peerIdFromMultihash(multihash);
}
export function peerIdFromPublicKey(publicKey) {
    if (publicKey.type === 'Ed25519') {
        return new Ed25519PeerIdClass({
            multihash: publicKey.toCID().multihash,
            publicKey
        });
    }
    else if (publicKey.type === 'secp256k1') {
        return new Secp256k1PeerIdClass({
            multihash: publicKey.toCID().multihash,
            publicKey
        });
    }
    else if (publicKey.type === 'RSA') {
        return new RSAPeerIdClass({
            multihash: publicKey.toCID().multihash,
            publicKey
        });
    }
    throw new UnsupportedKeyTypeError();
}
export function peerIdFromPrivateKey(privateKey) {
    return peerIdFromPublicKey(privateKey.publicKey);
}
export function peerIdFromMultihash(multihash) {
    if (isSha256Multihash(multihash)) {
        return new RSAPeerIdClass({ multihash });
    }
    else if (isIdentityMultihash(multihash)) {
        try {
            const publicKey = publicKeyFromMultihash(multihash);
            if (publicKey.type === 'Ed25519') {
                return new Ed25519PeerIdClass({ multihash, publicKey });
            }
            else if (publicKey.type === 'secp256k1') {
                return new Secp256k1PeerIdClass({ multihash, publicKey });
            }
        }
        catch (err) {
            // was not Ed or secp key, try URL
            const url = uint8ArrayToString(multihash.digest);
            return new URLPeerIdClass(new URL(url));
        }
    }
    throw new InvalidMultihashError('Supplied PeerID Multihash is invalid');
}
export function peerIdFromCID(cid) {
    if (cid?.multihash == null || cid.version == null || (cid.version === 1 && (cid.code !== LIBP2P_KEY_CODE) && cid.code !== TRANSPORT_IPFS_GATEWAY_HTTP_CODE)) {
        throw new InvalidCIDError('Supplied PeerID CID is invalid');
    }
    if (cid.code === TRANSPORT_IPFS_GATEWAY_HTTP_CODE) {
        const url = uint8ArrayToString(cid.multihash.digest);
        return new URLPeerIdClass(new URL(url));
    }
    return peerIdFromMultihash(cid.multihash);
}
function isIdentityMultihash(multihash) {
    return multihash.code === identity.code;
}
function isSha256Multihash(multihash) {
    return multihash.code === sha256.code;
}
//# sourceMappingURL=index.js.map