/*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) */
function isBytes(a) {
    // Plain `instanceof Uint8Array` is too strict for some Buffer / proxy / cross-realm cases. The
    // fallback still requires a real ArrayBuffer view, so plain JSON-deserialized
    // `{ constructor: ... }` spoofing is rejected. `BYTES_PER_ELEMENT === 1` keeps the
    // fallback on byte-oriented views.
    return (a instanceof Uint8Array ||
        (ArrayBuffer.isView(a) &&
            a.constructor.name === 'Uint8Array' &&
            'BYTES_PER_ELEMENT' in a &&
            a.BYTES_PER_ELEMENT === 1));
}
/** Asserts something is Uint8Array. */
function abytes(b) {
    if (!isBytes(b))
        throw new TypeError('Uint8Array expected');
}
function isArrayOf(isString, arr) {
    if (!Array.isArray(arr))
        return false;
    if (arr.length === 0)
        return true;
    if (isString) {
        return arr.every((item) => typeof item === 'string');
    }
    else {
        return arr.every((item) => Number.isSafeInteger(item));
    }
}
function afn(input) {
    if (typeof input !== 'function')
        throw new TypeError('function expected');
    return true;
}
function astr(label, input) {
    if (typeof input !== 'string')
        throw new TypeError(`${label}: string expected`);
    return true;
}
function anumber(n) {
    if (typeof n !== 'number')
        throw new TypeError(`number expected, got ${typeof n}`);
    if (!Number.isSafeInteger(n))
        throw new RangeError(`invalid integer: ${n}`);
}
function aArr(input) {
    if (!Array.isArray(input))
        throw new TypeError('array expected');
}
function astrArr(label, input) {
    if (!isArrayOf(true, input))
        throw new TypeError(`${label}: array of strings expected`);
}
function anumArr(label, input) {
    if (!isArrayOf(false, input))
        throw new TypeError(`${label}: array of numbers expected`);
}
/**
 * @__NO_SIDE_EFFECTS__
 */
function chain(...args) {
    const id = (a) => a;
    // Wrap call in closure so JIT can inline calls
    const wrap = (a, b) => (c) => a(b(c));
    // Construct chain of args[-1].encode(args[-2].encode([...]))
    const encode = args.map((x) => x.encode).reduceRight(wrap, id);
    // Construct chain of args[0].decode(args[1].decode(...))
    const decode = args.map((x) => x.decode).reduce(wrap, id);
    return { encode, decode };
}
/**
 * Encodes integer radix representation to array of strings using alphabet and back.
 * Could also be array of strings.
 * @__NO_SIDE_EFFECTS__
 */
function alphabet(letters) {
    // mapping 1 to "b"
    const lettersA = typeof letters === 'string' ? letters.split('') : letters;
    const len = lettersA.length;
    astrArr('alphabet', lettersA);
    // mapping "b" to 1
    const indexes = new Map(lettersA.map((l, i) => [l, i]));
    return {
        encode: (digits) => {
            aArr(digits);
            return digits.map((i) => {
                if (!Number.isSafeInteger(i) || i < 0 || i >= len)
                    throw new Error(`alphabet.encode: digit index outside alphabet "${i}". Allowed: ${letters}`);
                return lettersA[i];
            });
        },
        decode: (input) => {
            aArr(input);
            return input.map((letter) => {
                astr('alphabet.decode', letter);
                const i = indexes.get(letter);
                if (i === undefined)
                    throw new Error(`Unknown letter: "${letter}". Allowed: ${letters}`);
                return i;
            });
        },
    };
}
/**
 * @__NO_SIDE_EFFECTS__
 */
function join(separator = '') {
    astr('join', separator);
    // join('') is only lossless when each chunk is already unambiguous, such as single-symbol alphabets.
    // Multi-character tokens need a separator that cannot appear inside the chunks.
    return {
        encode: (from) => {
            astrArr('join.decode', from);
            return from.join(separator);
        },
        decode: (to) => {
            astr('join.decode', to);
            return to.split(separator);
        },
    };
}
/**
 * Pad strings array so it has integer number of bits
 * @__NO_SIDE_EFFECTS__
 */
function padding(bits, chr = '=') {
    anumber(bits);
    astr('padding', chr);
    return {
        encode(data) {
            astrArr('padding.encode', data);
            // Mutates the intermediate token array in place while appending pad chars.
            // utils.padding callers that need to preserve their input should pass a copy.
            while ((data.length * bits) % 8)
                data.push(chr);
            return data;
        },
        decode(input) {
            astrArr('padding.decode', input);
            let end = input.length;
            if ((end * bits) % 8)
                throw new Error('padding: invalid, string should have whole number of bytes');
            for (; end > 0 && input[end - 1] === chr; end--) {
                const last = end - 1;
                const byte = last * bits;
                if (byte % 8 === 0)
                    throw new Error('padding: invalid, string has too much padding');
            }
            return input.slice(0, end);
        },
    };
}
/**
 * @__NO_SIDE_EFFECTS__
 */
function normalize(fn) {
    afn(fn);
    return { encode: (from) => from, decode: (to) => fn(to) };
}
/**
 * Slow: O(n^2) time complexity
 */
function convertRadix(data, from, to) {
    // base 1 is impossible
    if (from < 2)
        throw new RangeError(`convertRadix: invalid from=${from}, base cannot be less than 2`);
    if (to < 2)
        throw new RangeError(`convertRadix: invalid to=${to}, base cannot be less than 2`);
    aArr(data);
    if (!data.length)
        return [];
    let pos = 0;
    const res = [];
    const digits = Array.from(data, (d) => {
        anumber(d);
        if (d < 0 || d >= from)
            throw new Error(`invalid integer: ${d}`);
        return d;
    });
    const dlen = digits.length;
    while (true) {
        let carry = 0;
        let done = true;
        for (let i = pos; i < dlen; i++) {
            const digit = digits[i];
            const fromCarry = from * carry;
            const digitBase = fromCarry + digit;
            if (!Number.isSafeInteger(digitBase) ||
                fromCarry / from !== carry ||
                digitBase - digit !== fromCarry) {
                throw new Error('convertRadix: carry overflow');
            }
            const div = digitBase / to;
            carry = digitBase % to;
            const rounded = Math.floor(div);
            digits[i] = rounded;
            if (!Number.isSafeInteger(rounded) || rounded * to + carry !== digitBase)
                throw new Error('convertRadix: carry overflow');
            if (!done)
                continue;
            else if (!rounded)
                pos = i;
            else
                done = false;
        }
        res.push(carry);
        if (done)
            break;
    }
    // Preserve explicit leading zero digits so callers like base58 keep zero-prefix semantics.
    for (let i = 0; i < data.length - 1 && data[i] === 0; i++)
        res.push(0);
    return res.reverse();
}
const gcd = (a, b) => (b === 0 ? a : gcd(b, a % b));
// Maximum carry width before the `pos` cycle repeats.
// Residues advance in gcd(from, to) steps, so the largest pre-drain width is from + (to - gcd).
const radix2carry = /* @__NO_SIDE_EFFECTS__ */ (from, to) => from + (to - gcd(from, to));
const powers = /* @__PURE__ */ (() => {
    let res = [];
    for (let i = 0; i < 40; i++)
        res.push(2 ** i);
    return res;
})();
/**
 * Implemented with numbers, because BigInt is 5x slower
 */
function convertRadix2(data, from, to, padding) {
    aArr(data);
    if (from <= 0 || from > 32)
        throw new RangeError(`convertRadix2: wrong from=${from}`);
    if (to <= 0 || to > 32)
        throw new RangeError(`convertRadix2: wrong to=${to}`);
    if (radix2carry(from, to) > 32) {
        throw new Error(`convertRadix2: carry overflow from=${from} to=${to} carryBits=${radix2carry(from, to)}`);
    }
    let carry = 0;
    let pos = 0; // bitwise position in current element
    const max = powers[from];
    const mask = powers[to] - 1;
    const res = [];
    for (const n of data) {
        anumber(n);
        if (n >= max)
            throw new Error(`convertRadix2: invalid data word=${n} from=${from}`);
        carry = (carry << from) | n;
        if (pos + from > 32)
            throw new Error(`convertRadix2: carry overflow pos=${pos} from=${from}`);
        pos += from;
        for (; pos >= to; pos -= to)
            res.push(((carry >> (pos - to)) & mask) >>> 0);
        const pow = powers[pos];
        if (pow === undefined)
            throw new Error('invalid carry');
        carry &= pow - 1; // clean carry, otherwise it will cause overflow
    }
    carry = (carry << (to - pos)) & mask;
    // Canonical decode paths reject leftover whole input words and non-zero pad bits.
    // For Bech32 5->8 regrouping, this is the "4 bits or less, all zeroes" tail rule.
    if (!padding && pos >= from)
        throw new Error('Excess padding');
    if (!padding && carry > 0)
        throw new Error(`Non-zero padding: ${carry}`);
    if (padding && pos > 0)
        res.push(carry >>> 0);
    return res;
}
/**
 * @__NO_SIDE_EFFECTS__
 */
function radix(num) {
    anumber(num);
    const _256 = 2 ** 8;
    // Base-range and carry-overflow checks live in convertRadix so encode/decode reject unsupported bases symmetrically.
    return {
        encode: (bytes) => {
            if (!isBytes(bytes))
                throw new TypeError('radix.encode input should be Uint8Array');
            return convertRadix(Array.from(bytes), _256, num);
        },
        decode: (digits) => {
            anumArr('radix.decode', digits);
            return Uint8Array.from(convertRadix(digits, num, _256));
        },
    };
}
/**
 * If both bases are power of same number (like `2**8 <-> 2**64`),
 * there is a linear algorithm. For now we have implementation for power-of-two bases only.
 * @__NO_SIDE_EFFECTS__
 */
function radix2(bits, revPadding = false) {
    anumber(bits);
    if (bits <= 0 || bits > 32)
        throw new RangeError('radix2: bits should be in (0..32]');
    if (radix2carry(8, bits) > 32 || radix2carry(bits, 8) > 32)
        throw new RangeError('radix2: carry overflow');
    // revPadding flips which direction allows a partial zero tail.
    // Default pads 8->bits and rejects extra bits on bits->8; `true` does the opposite.
    return {
        encode: (bytes) => {
            if (!isBytes(bytes))
                throw new TypeError('radix2.encode input should be Uint8Array');
            return convertRadix2(Array.from(bytes), 8, bits, !revPadding);
        },
        decode: (digits) => {
            anumArr('radix2.decode', digits);
            return Uint8Array.from(convertRadix2(digits, bits, 8, revPadding));
        },
    };
}
function unsafeWrapper(fn) {
    afn(fn);
    return function (...args) {
        // Only for *Unsafe APIs that intentionally collapse validation failures to `undefined`.
        // Do not wrap code that needs to preserve exception details.
        try {
            return fn.apply(null, args);
        }
        catch (e) { }
    };
}
function checksum(len, fn) {
    anumber(len);
    // Reject degenerate zero-byte checksums up front so callers don't accidentally
    // build a no-op checksum stage.
    if (len <= 0)
        throw new RangeError(`checksum length must be positive: ${len}`);
    afn(fn);
    const _fn = fn;
    // Uses the first `len` bytes of fn(data) in both directions.
    // Current call sites rely on `len > 0` and checksum functions that return at least that many bytes.
    return {
        encode(data) {
            if (!isBytes(data))
                throw new TypeError('checksum.encode: input should be Uint8Array');
            const sum = _fn(data).slice(0, len);
            const res = new Uint8Array(data.length + len);
            res.set(data);
            res.set(sum, data.length);
            return res;
        },
        decode(data) {
            if (!isBytes(data))
                throw new TypeError('checksum.decode: input should be Uint8Array');
            const payload = data.slice(0, -len);
            const oldChecksum = data.slice(-len);
            const newChecksum = _fn(payload).slice(0, len);
            for (let i = 0; i < len; i++)
                if (newChecksum[i] !== oldChecksum[i])
                    throw new Error('Invalid checksum');
            return payload;
        },
    };
}
// prettier-ignore
/**
 * Low-level building blocks used by the exported codecs.
 * @example
 * Build a radix-32 coder from the low-level helpers.
 * ```ts
 * import { utils } from '@scure/base';
 * utils.radix2(5).encode(Uint8Array.from([1, 2, 3]));
 * ```
 */
export const utils = /* @__PURE__ */ Object.freeze({
    alphabet, chain, checksum, convertRadix, convertRadix2, radix, radix2, join, padding,
});
// RFC 4648 aka RFC 3548
// ---------------------
/**
 * base16 encoding from RFC 4648.
 * This codec uses RFC 4648 Table 5's uppercase alphabet directly.
 * RFC 4648 §8 calls base16 "case-insensitive hex encoding", but we intentionally do not case-fold decode input here.
 * Use `hex` for case-insensitive hex decoding.
 * @example
 * ```js
 * base16.encode(Uint8Array.from([0x12, 0xab]));
 * // => '12AB'
 * ```
 */
export const base16 = /* @__PURE__ */ Object.freeze(chain(radix2(4), alphabet('0123456789ABCDEF'), join('')));
/**
 * base32 encoding from RFC 4648. Has padding.
 * RFC 4648 §6 Table 3 uses uppercase letters, and RFC 4648 §3.4 allows applications to choose
 * upper- or lowercase alphabets. We keep the published uppercase table and do not case-fold decode input.
 * Use `base32nopad` for unpadded version.
 * Also check out `base32hex`, `base32hexnopad`, `base32crockford`.
 * @example
 * ```js
 * base32.encode(Uint8Array.from([0x12, 0xab]));
 * // => 'CKVQ===='
 * base32.decode('CKVQ====');
 * // => Uint8Array.from([0x12, 0xab])
 * ```
 */
export const base32 = /* @__PURE__ */ Object.freeze(chain(radix2(5), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'), padding(5), join('')));
/**
 * base32 encoding from RFC 4648. No padding.
 * This variant inherits RFC 4648 base32's uppercase table and intentionally does not case-fold decode input.
 * Use `base32` for padded version.
 * Also check out `base32hex`, `base32hexnopad`, `base32crockford`.
 * @example
 * ```js
 * base32nopad.encode(Uint8Array.from([0x12, 0xab]));
 * // => 'CKVQ'
 * base32nopad.decode('CKVQ');
 * // => Uint8Array.from([0x12, 0xab])
 * ```
 */
export const base32nopad = /* @__PURE__ */ Object.freeze(chain(radix2(5), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'), join('')));
/**
 * base32 encoding from RFC 4648. Padded. Compared to ordinary `base32`, slightly different alphabet.
 * RFC 4648 §7 Table 4 uses uppercase letters, and we intentionally keep that table without case-folding decode input.
 * Use `base32hexnopad` for unpadded version.
 * @example
 * ```js
 * base32hex.encode(Uint8Array.from([0x12, 0xab]));
 * // => '2ALG===='
 * base32hex.decode('2ALG====');
 * // => Uint8Array.from([0x12, 0xab])
 * ```
 */
export const base32hex = /* @__PURE__ */ Object.freeze(chain(radix2(5), alphabet('0123456789ABCDEFGHIJKLMNOPQRSTUV'), padding(5), join('')));
/**
 * base32 encoding from RFC 4648. No padding. Compared to ordinary `base32`, slightly different alphabet.
 * This variant inherits RFC 4648 base32hex's uppercase table and intentionally does not case-fold decode input.
 * Use `base32hex` for padded version.
 * @example
 * ```js
 * base32hexnopad.encode(Uint8Array.from([0x12, 0xab]));
 * // => '2ALG'
 * base32hexnopad.decode('2ALG');
 * // => Uint8Array.from([0x12, 0xab])
 * ```
 */
export const base32hexnopad = /* @__PURE__ */ Object.freeze(chain(radix2(5), alphabet('0123456789ABCDEFGHIJKLMNOPQRSTUV'), join('')));
/**
 * base32 encoding from RFC 4648. Doug Crockford's version.
 * See {@link https://www.crockford.com/base32.html | Douglas Crockford's Base32}.
 * @example
 * ```js
 * base32crockford.encode(Uint8Array.from([0x12, 0xab]));
 * // => '2ANG'
 * base32crockford.decode('2ANG');
 * // => Uint8Array.from([0x12, 0xab])
 * ```
 */
export const base32crockford = /* @__PURE__ */ Object.freeze(chain(radix2(5), alphabet('0123456789ABCDEFGHJKMNPQRSTVWXYZ'), join(''), normalize((s) => s.toUpperCase().replace(/O/g, '0').replace(/[IL]/g, '1'))));
// Built-in base64 conversion https://caniuse.com/mdn-javascript_builtins_uint8array_frombase64
// Require both directions before taking the native fast path, so base64/base64url don't mix native and JS behavior.
// prettier-ignore
const hasBase64Builtin = /* @__PURE__ */ (() => typeof Uint8Array.from([]).toBase64 === 'function' &&
    typeof Uint8Array.fromBase64 === 'function')();
// Native `Uint8Array.fromBase64()` accepts these ASCII whitespace chars.
// Reject them first so the native base64 path still follows RFC 4648 §3.3.
// ASCII whitespace is U+0009 TAB, U+000A LF, U+000C FF, U+000D CR, or U+0020 SPACE
const ASCII_WHITESPACE = /[\t\n\f\r ]/;
const decodeBase64Builtin = (s, isUrl) => {
    astr('base64', s);
    const alphabet = isUrl ? 'base64url' : 'base64';
    // Per spec, .fromBase64 already throws on any other non-alphabet symbols except ASCII whitespace
    // And checking just for whitespace makes decoding about 3x faster than a full range check.
    // lastChunkHandling: 'strict' rejects loose tails and non-zero pad bits so native decoding stays canonical.
    if (s.length > 0 && ASCII_WHITESPACE.test(s))
        throw new Error('invalid base64');
    return Uint8Array.fromBase64(s, { alphabet, lastChunkHandling: 'strict' });
};
/**
 * base64 from RFC 4648. Padded.
 * Use `base64nopad` for unpadded version.
 * Also check out `base64url`, `base64urlnopad`.
 * Falls back to built-in function, when available.
 * @example
 * ```js
 * base64.encode(Uint8Array.from([0x12, 0xab]));
 * // => 'Eqs='
 * base64.decode('Eqs=');
 * // => Uint8Array.from([0x12, 0xab])
 * ```
 */
// prettier-ignore
export const base64 = /* @__PURE__ */ Object.freeze(hasBase64Builtin ? {
    encode(b) { abytes(b); return b.toBase64(); },
    decode(s) { return decodeBase64Builtin(s, false); },
} : chain(radix2(6), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'), padding(6), join('')));
/**
 * base64 from RFC 4648. No padding.
 * Use `base64` for padded version.
 * @example
 * ```js
 * base64nopad.encode(Uint8Array.from([0x12, 0xab]));
 * // => 'Eqs'
 * base64nopad.decode('Eqs');
 * // => Uint8Array.from([0x12, 0xab])
 * ```
 */
export const base64nopad = /* @__PURE__ */ Object.freeze(chain(radix2(6), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'), join('')));
/**
 * base64 from RFC 4648, using URL-safe alphabet. Padded.
 * Use `base64urlnopad` for unpadded version.
 * Falls back to built-in function, when available.
 * @example
 * ```js
 * base64url.encode(Uint8Array.from([0x12, 0xab]));
 * // => 'Eqs='
 * base64url.decode('Eqs=');
 * // => Uint8Array.from([0x12, 0xab])
 * ```
 */
// prettier-ignore
export const base64url = /* @__PURE__ */ Object.freeze(hasBase64Builtin ? {
    encode(b) { abytes(b); return b.toBase64({ alphabet: 'base64url' }); },
    decode(s) { return decodeBase64Builtin(s, true); },
} : chain(radix2(6), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'), padding(6), join('')));
/**
 * base64 from RFC 4648, using URL-safe alphabet. No padding.
 * Use `base64url` for padded version.
 * @example
 * ```js
 * base64urlnopad.encode(Uint8Array.from([0x12, 0xab]));
 * // => 'Eqs'
 * base64urlnopad.decode('Eqs');
 * // => Uint8Array.from([0x12, 0xab])
 * ```
 */
export const base64urlnopad = /* @__PURE__ */ Object.freeze(chain(radix2(6), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'), join('')));
// base58 code
// -----------
const genBase58 = /* @__NO_SIDE_EFFECTS__ */ (abc) => chain(radix(58), alphabet(abc), join(''));
/**
 * base58: base64 without ambigous characters +, /, 0, O, I, l.
 * Quadratic (O(n^2)) - so, can't be used on large inputs.
 * @example
 * ```js
 * const text = base58.encode(Uint8Array.from([0, 1, 2]));
 * base58.decode(text);
 * // => Uint8Array.from([0, 1, 2])
 * ```
 */
export const base58 = /* @__PURE__ */ Object.freeze(genBase58('123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'));
/**
 * base58: flickr version. Check out `base58`.
 * @example
 * Round-trip bytes with the Flickr alphabet.
 * ```ts
 * const text = base58flickr.encode(Uint8Array.from([0, 1, 2]));
 * base58flickr.decode(text);
 * ```
 */
export const base58flickr = /* @__PURE__ */ Object.freeze(genBase58('123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ'));
/**
 * base58: XRP version. Check out `base58`.
 * @example
 * Round-trip bytes with the XRP alphabet.
 * ```ts
 * const text = base58xrp.encode(Uint8Array.from([0, 1, 2]));
 * base58xrp.decode(text);
 * ```
 */
export const base58xrp = /* @__PURE__ */ Object.freeze(genBase58('rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz'));
// Data len (index) -> encoded block len.
// Monero pads each 1..8-byte block to this fixed base58 width so decode can recover the tail length.
const XMR_BLOCK_LEN = [0, 2, 3, 5, 6, 7, 9, 10, 11];
/**
 * base58: XMR version. Check out `base58`.
 * Done in 8-byte blocks (which equals 11 chars in decoding). Last (non-full) block padded with '1' to size in XMR_BLOCK_LEN.
 * Block encoding significantly reduces quadratic complexity of base58.
 * @example
 * Round-trip bytes with the Monero block codec.
 * ```ts
 * const text = base58xmr.encode(Uint8Array.from([0, 1, 2]));
 * base58xmr.decode(text);
 * ```
 */
export const base58xmr = /* @__PURE__ */ Object.freeze({
    encode(data) {
        abytes(data);
        let res = '';
        for (let i = 0; i < data.length; i += 8) {
            const block = data.subarray(i, i + 8);
            res += base58.encode(block).padStart(XMR_BLOCK_LEN[block.length], '1');
        }
        return res;
    },
    decode(str) {
        astr('base58xmr.decode', str);
        let res = [];
        for (let i = 0; i < str.length; i += 11) {
            const slice = str.slice(i, i + 11);
            const blockLen = XMR_BLOCK_LEN.indexOf(slice.length);
            const block = base58.decode(slice);
            for (let j = 0; j < block.length - blockLen; j++) {
                if (block[j] !== 0)
                    throw new Error('base58xmr: wrong padding');
            }
            res = res.concat(Array.from(block.slice(block.length - blockLen)));
        }
        return Uint8Array.from(res);
    },
});
/**
 * Method, which creates base58check encoder.
 * Requires function, calculating sha256.
 * Callers must include any version bytes in `data`; this helper only applies the
 * 4-byte double-SHA256 checksum used by Bitcoin Base58Check.
 * @param sha256 - Function used to calculate the checksum hash.
 * @returns base58check codec using 4 checksum bytes.
 * @throws On wrong argument types. {@link TypeError}
 * @example
 * Create a base58check codec from a SHA-256 implementation.
 * ```ts
 * import { createBase58check } from '@scure/base';
 * import { sha256 } from '@noble/hashes/sha2.js';
 * const coder = createBase58check(sha256);
 * coder.encode(Uint8Array.from([1, 2, 3]));
 * ```
 */
export const createBase58check = (sha256) => {
    // Validate the hash function at construction time so wrong inputs fail before returning a coder.
    afn(sha256);
    const _sha256 = sha256;
    return chain(checksum(4, (data) => _sha256(_sha256(data))), base58);
};
/**
 * Use `createBase58check` instead.
 * @deprecated Use {@link createBase58check} instead.
 * Callers must include any version bytes in `data`; this alias keeps the same
 * 4-byte double-SHA256 checksum behavior as `createBase58check`.
 * @param sha256 - Function used to calculate the checksum hash.
 * @returns base58check codec using 4 checksum bytes.
 * @example
 * Create a base58check codec with the deprecated alias.
 * ```ts
 * import { base58check } from '@scure/base';
 * import { sha256 } from '@noble/hashes/sha2.js';
 * const coder = base58check(sha256);
 * coder.encode(Uint8Array.from([1, 2, 3]));
 * ```
 */
export const base58check = createBase58check;
// BIP 173 character table: data values 0..31 map to `qpzry9x8gf2tvdw0s3jn54khce6mua7l`.
const BECH_ALPHABET = chain(alphabet('qpzry9x8gf2tvdw0s3jn54khce6mua7l'), join(''));
// BIP 173 `bech32_polymod` GEN coefficients.
const POLYMOD_GENERATORS = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3];
// BIP 173 step split: this applies the polymod state transition before callers xor in the next 5-bit value.
function bech32Polymod(pre) {
    const b = pre >> 25;
    let chk = (pre & 0x1ffffff) << 5;
    for (let i = 0; i < POLYMOD_GENERATORS.length; i++) {
        if (((b >> i) & 1) === 1)
            chk ^= POLYMOD_GENERATORS[i];
    }
    return chk;
}
function bechChecksum(prefix, words, encodingConst = 1) {
    const len = prefix.length;
    let chk = 1;
    for (let i = 0; i < len; i++) {
        const c = prefix.charCodeAt(i);
        if (c < 33 || c > 126)
            throw new Error(`Invalid prefix (${prefix})`);
        chk = bech32Polymod(chk) ^ (c >> 5);
    }
    chk = bech32Polymod(chk);
    for (let i = 0; i < len; i++)
        chk = bech32Polymod(chk) ^ (prefix.charCodeAt(i) & 0x1f);
    for (let v of words)
        chk = bech32Polymod(chk) ^ v;
    for (let i = 0; i < 6; i++)
        chk = bech32Polymod(chk);
    // BIP 173/BIP 350: xor the final checksum constant, then emit the 30-bit state as six 5-bit symbols.
    chk ^= encodingConst;
    return BECH_ALPHABET.encode(convertRadix2([chk % powers[30]], 30, 5, false));
}
/**
 * @__NO_SIDE_EFFECTS__
 */
function genBech32(encoding) {
    // BIP 173 uses final xor constant 1; BIP 350 swaps in 0x2bc830a3 for Bech32m.
    const ENCODING_CONST = encoding === 'bech32' ? 1 : 0x2bc830a3;
    const _words = radix2(5);
    const fromWords = _words.decode;
    const toWords = _words.encode;
    const fromWordsUnsafe = unsafeWrapper(fromWords);
    function encode(prefix, words, limit = 90) {
        astr('bech32.encode prefix', prefix);
        if (isBytes(words))
            words = Array.from(words);
        anumArr('bech32.encode', words);
        const plen = prefix.length;
        if (plen === 0)
            throw new TypeError(`Invalid prefix length ${plen}`);
        // Total output is hrp + `1` separator + payload words + 6 checksum chars.
        const actualLength = plen + 7 + words.length;
        if (limit !== false && actualLength > limit)
            throw new TypeError(`Length ${actualLength} exceeds limit ${limit}`);
        const lowered = prefix.toLowerCase();
        const sum = bechChecksum(lowered, words, ENCODING_CONST);
        return `${lowered}1${BECH_ALPHABET.encode(words)}${sum}`;
    }
    function decode(str, limit = 90) {
        astr('bech32.decode input', str);
        const slen = str.length;
        // Minimum length is 1-char hrp + `1` separator + 6-char checksum.
        if (slen < 8 || (limit !== false && slen > limit))
            throw new TypeError(`invalid string length: ${slen} (${str}). Expected (8..${limit})`);
        // don't allow mixed case
        const lowered = str.toLowerCase();
        if (str !== lowered && str !== str.toUpperCase())
            throw new Error(`String must be lowercase or uppercase`);
        const sepIndex = lowered.lastIndexOf('1');
        if (sepIndex === 0 || sepIndex === -1)
            throw new Error(`Letter "1" must be present between prefix and data only`);
        const prefix = lowered.slice(0, sepIndex);
        const data = lowered.slice(sepIndex + 1);
        if (data.length < 6)
            throw new Error('Data must be at least 6 characters long');
        const words = BECH_ALPHABET.decode(data).slice(0, -6);
        const sum = bechChecksum(prefix, words, ENCODING_CONST);
        if (!data.endsWith(sum))
            throw new Error(`Invalid checksum in ${str}: expected "${sum}"`);
        return { prefix, words };
    }
    const decodeUnsafe = unsafeWrapper(decode);
    function decodeToBytes(str) {
        // Keep the byte helper unbounded; callers that need the default BIP 173 length cap should use decode(str).
        const { prefix, words } = decode(str, false);
        return {
            prefix,
            words,
            bytes: fromWords(words),
        };
    }
    function encodeFromBytes(prefix, bytes) {
        // Keep the convenience wrapper on encode()'s default 90-char cap; custom limits should call encode(prefix, toWords(bytes), limit).
        return encode(prefix, toWords(bytes));
    }
    return {
        encode,
        decode,
        encodeFromBytes,
        decodeToBytes,
        decodeUnsafe,
        fromWords,
        fromWordsUnsafe,
        toWords,
    };
}
/**
 * bech32 from BIP 173. Operates on words.
 * For high-level helpers, check out {@link https://github.com/paulmillr/scure-btc-signer | scure-btc-signer}.
 * @example
 * Convert bytes to words, encode them, then decode back.
 * ```ts
 * const words = bech32.toWords(Uint8Array.from([1, 2, 3]));
 * const text = bech32.encode('bc', words);
 * bech32.decode(text);
 * ```
 */
export const bech32 = /* @__PURE__ */ Object.freeze(genBech32('bech32'));
/**
 * bech32m from BIP 350. Operates on words.
 * It was to mitigate `bech32` weaknesses.
 * For high-level helpers, check out {@link https://github.com/paulmillr/scure-btc-signer | scure-btc-signer}.
 * @example
 * Convert bytes to words, encode them with bech32m, then decode back.
 * ```ts
 * const words = bech32m.toWords(Uint8Array.from([1, 2, 3]));
 * const text = bech32m.encode('bc', words);
 * bech32m.decode(text);
 * ```
 */
export const bech32m = /* @__PURE__ */ Object.freeze(genBech32('bech32m'));
/**
 * ASCII-to-byte decoder. Rejects non-ASCII text and bytes instead of doing UTF-8 replacement.
 * Method names follow `BytesCoder`, so `encode(bytes)` returns a string and `decode(string)` returns bytes.
 * @example
 * ```js
 * const b = ascii.decode("ABC"); // => new Uint8Array([ 65, 66, 67 ])
 * const str = ascii.encode(b); // "ABC"
 * ```
 */
export const ascii = /* @__PURE__ */ Object.freeze({
    encode(data) {
        abytes(data);
        let res = '';
        for (let i = 0; i < data.length; i++) {
            const byte = data[i];
            // ASCII is 7-bit; reject bytes outside 0x00..0x7f instead of silently widening to
            // Latin-1/UTF-8.
            if (byte > 127)
                throw new RangeError(`bytes contain non-ASCII byte ${byte} at position ${i}`);
            res += String.fromCharCode(byte);
        }
        return res;
    },
    decode(str) {
        if (typeof str !== 'string')
            throw new TypeError('ascii string expected, got ' + typeof str);
        const res = new Uint8Array(str.length);
        for (let i = 0; i < str.length; i++) {
            // Indexed access is much faster than Uint8Array.from(str, mapFn) here and keeps
            // exact error positions.
            const charCode = str.charCodeAt(i);
            if (charCode > 127) {
                throw new RangeError(`string contains non-ASCII character "${str[i]}" with code ${charCode} at position ${i}`);
            }
            res[i] = charCode;
        }
        return res;
    },
});
const _isWellFormedShim = (str) => {
    // encodeURI rejects malformed UTF-16, giving a compact fallback that matches native
    // isWellFormed on our tests/fuzz corpus.
    try {
        return encodeURI(str) !== null;
    }
    catch {
        return false;
    }
};
const _isWellFormed = /* @__PURE__ */ (() => 
// Pick the native check once so utf8.decode doesn't re-probe String.prototype on every call.
typeof ''.isWellFormed === 'function'
    ? (str) => str.isWellFormed()
    : _isWellFormedShim)();
// This fallback stays small because strict UTF-8 only needs fatal decoding plus well-formed
// UTF-16 checks, not the replacement, streaming, or legacy-encoding behavior of full platform
// text codecs.
const utf8Fallback = /* @__PURE__ */ Object.freeze({
    encode(data) {
        abytes(data);
        let res = '';
        for (let i = 0; i < data.length;) {
            const a = data[i++];
            if (a < 0b1000_0000) {
                res += String.fromCharCode(a);
                continue;
            }
            if (a < 0b1100_0010 || i >= data.length)
                throw new TypeError(`invalid utf8 at byte ${i - 1}`);
            const b = data[i++];
            if ((b & 0b1100_0000) !== 0b1000_0000)
                throw new TypeError(`invalid utf8 at byte ${i - 1}`);
            let cp = ((a & 0b0001_1111) << 6) | (b & 0b0011_1111);
            if (a >= 0b1110_0000) {
                if (i >= data.length)
                    throw new TypeError(`invalid utf8 at byte ${i - 1}`);
                const c = data[i++];
                if ((c & 0b1100_0000) !== 0b1000_0000 ||
                    (a === 0b1110_0000 && b < 0b1010_0000) ||
                    (a === 0xed && b >= 0b1010_0000))
                    throw new TypeError(`invalid utf8 at byte ${i - 1}`);
                cp = ((a & 0b0000_1111) << 12) | ((b & 0b0011_1111) << 6) | (c & 0b0011_1111);
                if (a >= 0b1111_0000) {
                    if (i >= data.length)
                        throw new TypeError(`invalid utf8 at byte ${i - 1}`);
                    const d = data[i++];
                    if (a > 0b1111_0100 ||
                        (d & 0b1100_0000) !== 0b1000_0000 ||
                        (a === 0b1111_0000 && b < 0b1001_0000) ||
                        (a === 0b1111_0100 && b >= 0b1001_0000))
                        throw new TypeError(`invalid utf8 at byte ${i - 1}`);
                    cp =
                        ((a & 7) << 18) |
                            ((b & 0b0011_1111) << 12) |
                            ((c & 0b0011_1111) << 6) |
                            (d & 0b0011_1111);
                }
            }
            if (cp < 0x10000)
                res += String.fromCharCode(cp);
            else {
                cp -= 0x10000;
                res += String.fromCharCode((cp >> 10) + 0xd800, (cp & 0x3ff) + 0xdc00);
            }
        }
        return res;
    },
    decode(str) {
        astr('utf8', str);
        if (!_isWellFormed(str))
            throw new TypeError('utf8 expected well-formed string');
        // Direct Uint8Array writes are much faster than number[] + Uint8Array.from on Hermes and
        // large Node inputs.
        const res = new Uint8Array(str.length * 3);
        let pos = 0;
        for (let i = 0; i < str.length; i++) {
            let c = str.charCodeAt(i);
            if (c < 0b1000_0000) {
                res[pos++] = c;
                continue;
            }
            if (c >= 0xd800 && c <= 0xdfff) {
                const d = str.charCodeAt(++i);
                c = 0x10000 + ((c - 0xd800) << 10) + d - 0xdc00;
            }
            if (c >= 0x10000) {
                res[pos++] = (c >> 18) | 0b1111_0000;
                res[pos++] = ((c >> 12) & 0b0011_1111) | 0b1000_0000;
            }
            else if (c >= 0x800)
                res[pos++] = (c >> 12) | 0b1110_0000;
            else
                res[pos++] = (c >> 6) | 0b1100_0000;
            if (c >= 0x800)
                res[pos++] = ((c >> 6) & 0b0011_1111) | 0b1000_0000;
            res[pos++] = (c & 0b0011_1111) | 0b1000_0000;
        }
        return res.subarray(0, pos);
    },
});
/**
 * Strict UTF-8-to-byte decoder. Uses built-in TextDecoder / TextEncoder when available.
 * Method names follow `BytesCoder`, so `encode(bytes)` returns a string and
 * `decode(string)` returns bytes.
 * `encode(bytes)` requires Uint8Array input, preserves an explicit leading BOM, and
 *   throws on invalid UTF-8 bytes.
 * `decode(string)` requires a primitive string and throws on malformed UTF-16 strings with
 *   lone surrogates.
 * @example
 * ```js
 * const b = utf8.decode("hey"); // => new Uint8Array([ 104, 101, 121 ])
 * const str = utf8.encode(b); // "hey"
 * ```
 */
export const utf8 = /* @__PURE__ */ (() => {
    let _utf8Encoder;
    let _utf8Decoder;
    const utf8Builtin = {
        // ignoreBOM preserves an explicit leading U+FEFF;
        // fatal rejects invalid UTF-8 bytes instead of replacing them.
        encode(data) {
            abytes(data);
            return (_utf8Decoder || (_utf8Decoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }))).decode(data);
        },
        decode(str) {
            astr('utf8', str);
            if (!_isWellFormed(str))
                throw new TypeError('utf8 expected well-formed string');
            return (_utf8Encoder || (_utf8Encoder = new TextEncoder())).encode(str);
        },
    };
    return Object.freeze({
        // Select each direction once at module init, since
        // TextEncoder and TextDecoder can exist independently.
        encode: typeof TextDecoder === 'function' ? utf8Builtin.encode : utf8Fallback.encode,
        decode: typeof TextEncoder === 'function' ? utf8Builtin.decode : utf8Fallback.decode,
    });
})();
// Keep fallback parity probes behind a test-only export until runtime fallback behavior is decided.
export const __TESTS = /* @__PURE__ */ Object.freeze({
    utf8Fallback: utf8Fallback,
    _isWellFormedShim: _isWellFormedShim,
});
// Built-in hex conversion https://caniuse.com/mdn-javascript_builtins_uint8array_fromhex
// prettier-ignore
const hasHexBuiltin = /* @__PURE__ */ (() => 
// Require both directions before enabling the native hex path so encode/decode stay symmetric.
typeof Uint8Array.from([]).toHex === 'function' &&
    typeof Uint8Array.fromHex === 'function')();
// prettier-ignore
const hexBuiltin = {
    // Keep local type guards so the native path preserves library-level input errors.
    // Native toHex emits lowercase hex, matching the fallback alphabet and Node's hex strings.
    encode(data) { abytes(data); return data.toHex(); },
    // Native fromHex accepts either hex case and rejects odd-length / non-hex syntax.
    decode(s) { astr('hex', s); return Uint8Array.fromHex(s); },
};
/**
 * hex string decoder. Uses built-in function, when available.
 * Lowercase codec; unlike `base16`, this variant accepts either hex case and emits lowercase.
 * @example
 * ```js
 * const b = hex.decode("0102ff"); // => new Uint8Array([ 1, 2, 255 ])
 * const str = hex.encode(b); // "0102ff"
 * ```
 */
export const hex = /* @__PURE__ */ Object.freeze(hasHexBuiltin
    ? hexBuiltin
    : chain(radix2(4), alphabet('0123456789abcdef'), join(''), normalize((s) => {
        if (typeof s !== 'string' || s.length % 2 !== 0)
            throw new TypeError(`hex.decode: expected string, got ${typeof s} with length ${s.length}`);
        return s.toLowerCase();
    })));
// prettier-ignore
// Keep this registry aligned with CoderType/coderTypeError; only byte<->string codecs belong here.
const CODERS = {
    utf8, hex, base16, base32, base64, base64url, base58, base58xmr
};
const coderTypeError = 'Invalid encoding type. Available types: utf8, hex, base16, base32, base64, base64url, base58, base58xmr';
/**
 * Encodes bytes with one of the built-in codecs.
 * @deprecated Use the codec directly, for example `hex.encode(bytes)`.
 * @param type - Codec name.
 * @param bytes - Bytes to encode.
 * @returns Encoded string.
 * @throws On wrong argument types. {@link TypeError}
 * @example
 * ```ts
 * bytesToString('hex', Uint8Array.from([1, 2, 255]));
 * ```
 */
export const bytesToString = (type, bytes) => {
    if (typeof type !== 'string' || !CODERS.hasOwnProperty(type))
        throw new TypeError(coderTypeError);
    if (!isBytes(bytes))
        throw new TypeError('bytesToString() expects Uint8Array');
    return CODERS[type].encode(bytes);
};
/**
 * Alias for `bytesToString`.
 * @deprecated Use {@link bytesToString} or the codec directly instead.
 * @param type - Codec name.
 * @param bytes - Bytes to encode.
 * @returns Encoded string.
 * @example
 * ```ts
 * str('hex', Uint8Array.from([1, 2, 255]));
 * ```
 */
export const str = bytesToString; // as in python, but for bytes only
/**
 * Decodes a string with one of the built-in codecs.
 * @deprecated Use the codec directly, for example `hex.decode(text)`.
 * @param type - Codec name.
 * @param str - Encoded string.
 * @returns Decoded bytes.
 * @throws On wrong argument types. {@link TypeError}
 * @example
 * ```ts
 * stringToBytes('hex', '0102ff');
 * ```
 */
export const stringToBytes = (type, str) => {
    // Match bytesToString's selector validation so hostile `toString()` coercions can't leak custom errors.
    if (typeof type !== 'string' || !CODERS.hasOwnProperty(type))
        throw new TypeError(coderTypeError);
    if (typeof str !== 'string')
        throw new TypeError('stringToBytes() expects string');
    return CODERS[type].decode(str);
};
/**
 * Alias for `stringToBytes`.
 * @deprecated Use {@link stringToBytes} or the codec directly instead.
 * @param type - Codec name.
 * @param str - Encoded string.
 * @returns Decoded bytes.
 * @example
 * ```ts
 * bytes('hex', '0102ff');
 * ```
 */
export const bytes = stringToBytes;
//# sourceMappingURL=index.js.map