/**
 * @packageDocumentation
 *
 * An implementation of a peer id
 *
 * @example
 *
 * ```TypeScript
 * import { peerIdFromString } from '@libp2p/peer-id'
 * const peer = peerIdFromString('k51qzi5uqu5dkwkqm42v9j9kqcam2jiuvloi16g72i4i4amoo2m8u3ol3mqu6s')
 *
 * console.log(peer.toCID()) // CID(bafzaa...)
 * console.log(peer.toString()) // "12D3K..."
 * ```
 */
import { peerIdSymbol } from '@libp2p/interface';
import { base58btc } from 'multiformats/bases/base58';
import { CID } from 'multiformats/cid';
import { identity } from 'multiformats/hashes/identity';
import { equals as uint8ArrayEquals } from 'uint8arrays/equals';
import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string';
import { toString as uint8ArrayToString } from 'uint8arrays/to-string';
const inspect = Symbol.for('nodejs.util.inspect.custom');
// these values are from https://github.com/multiformats/multicodec/blob/master/table.csv
const LIBP2P_KEY_CODE = 0x72;
class PeerIdImpl {
    type;
    multihash;
    publicKey;
    string;
    constructor(init) {
        this.type = init.type;
        this.multihash = init.multihash;
        // mark string cache as non-enumerable
        Object.defineProperty(this, 'string', {
            enumerable: false,
            writable: true
        });
    }
    get [Symbol.toStringTag]() {
        return `PeerId(${this.toString()})`;
    }
    [peerIdSymbol] = true;
    toString() {
        if (this.string == null) {
            this.string = base58btc.encode(this.multihash.bytes).slice(1);
        }
        return this.string;
    }
    toMultihash() {
        return this.multihash;
    }
    // return self-describing String representation
    // in default format from RFC 0001: https://github.com/libp2p/specs/pull/209
    toCID() {
        return CID.createV1(LIBP2P_KEY_CODE, this.multihash);
    }
    toJSON() {
        return this.toString();
    }
    /**
     * Checks the equality of `this` peer against a given PeerId
     */
    equals(id) {
        if (id == null) {
            return false;
        }
        if (id instanceof Uint8Array) {
            return uint8ArrayEquals(this.multihash.bytes, id);
        }
        else if (typeof id === 'string') {
            return this.toString() === id;
        }
        else if (id?.toMultihash()?.bytes != null) {
            return uint8ArrayEquals(this.multihash.bytes, id.toMultihash().bytes);
        }
        else {
            throw new Error('not valid Id');
        }
    }
    /**
     * Returns PeerId as a human-readable string
     * https://nodejs.org/api/util.html#utilinspectcustom
     *
     * @example
     * ```TypeScript
     * import { peerIdFromString } from '@libp2p/peer-id'
     *
     * console.info(peerIdFromString('QmFoo'))
     * // 'PeerId(QmFoo)'
     * ```
     */
    [inspect]() {
        return `PeerId(${this.toString()})`;
    }
}
export class RSAPeerId extends PeerIdImpl {
    type = 'RSA';
    publicKey;
    constructor(init) {
        super({ ...init, type: 'RSA' });
        this.publicKey = init.publicKey;
    }
}
export class Ed25519PeerId extends PeerIdImpl {
    type = 'Ed25519';
    publicKey;
    constructor(init) {
        super({ ...init, type: 'Ed25519' });
        this.publicKey = init.publicKey;
    }
}
export class Secp256k1PeerId extends PeerIdImpl {
    type = 'secp256k1';
    publicKey;
    constructor(init) {
        super({ ...init, type: 'secp256k1' });
        this.publicKey = init.publicKey;
    }
}
// these values are from https://github.com/multiformats/multicodec/blob/master/table.csv
const TRANSPORT_IPFS_GATEWAY_HTTP_CODE = 0x0920;
export class URLPeerId {
    type = 'url';
    multihash;
    publicKey;
    url;
    constructor(url) {
        this.url = url.toString();
        this.multihash = identity.digest(uint8ArrayFromString(this.url));
    }
    [inspect]() {
        return `PeerId(${this.url})`;
    }
    [peerIdSymbol] = true;
    toString() {
        return this.toCID().toString();
    }
    toMultihash() {
        return this.multihash;
    }
    toCID() {
        return CID.createV1(TRANSPORT_IPFS_GATEWAY_HTTP_CODE, this.toMultihash());
    }
    toJSON() {
        return this.toString();
    }
    equals(other) {
        if (other == null) {
            return false;
        }
        if (other instanceof Uint8Array) {
            other = uint8ArrayToString(other);
        }
        return other.toString() === this.toString();
    }
}
//# sourceMappingURL=peer-id.js.map