@cmdcode/tapscript
Version:
A basic library for working with Tapscript, signatures and Bitcoin transactions.
1,651 lines (1,626 loc) • 408 kB
JavaScript
'use strict';
function number$3(n) {
if (!Number.isSafeInteger(n) || n < 0)
throw new Error(`Wrong positive integer: ${n}`);
}
function bool$3(b) {
if (typeof b !== 'boolean')
throw new Error(`Expected boolean, not ${b}`);
}
function bytes$3(b, ...lengths) {
if (!(b instanceof Uint8Array))
throw new TypeError('Expected Uint8Array');
if (lengths.length > 0 && !lengths.includes(b.length))
throw new TypeError(`Expected Uint8Array of length ${lengths}, not of length=${b.length}`);
}
function hash$4(hash) {
if (typeof hash !== 'function' || typeof hash.create !== 'function')
throw new Error('Hash should be wrapped by utils.wrapConstructor');
number$3(hash.outputLen);
number$3(hash.blockLen);
}
function exists$3(instance, checkFinished = true) {
if (instance.destroyed)
throw new Error('Hash instance has been destroyed');
if (checkFinished && instance.finished)
throw new Error('Hash#digest() has already been called');
}
function output$3(out, instance) {
bytes$3(out);
const min = instance.outputLen;
if (out.length < min) {
throw new Error(`digestInto() expects output buffer of length at least ${min}`);
}
}
const assert$1$2 = {
number: number$3,
bool: bool$3,
bytes: bytes$3,
hash: hash$4,
exists: exists$3,
output: output$3,
};
var assert$2$1 = assert$1$2;
/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */
// Cast array to view
const createView$3 = (arr) => new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
// The rotate right (circular right shift) operation for uint32
const rotr$3 = (word, shift) => (word << (32 - shift)) | (word >>> shift);
// big-endian hardware is rare. Just in case someone still decides to run hashes:
// early-throw an error because we don't support BE yet.
const isLE$3 = new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44;
if (!isLE$3)
throw new Error('Non little-endian hardware is not supported');
Array.from({ length: 256 }, (v, i) => i.toString(16).padStart(2, '0'));
function utf8ToBytes$4(str) {
if (typeof str !== 'string') {
throw new TypeError(`utf8ToBytes expected string, got ${typeof str}`);
}
return new TextEncoder().encode(str);
}
function toBytes$5(data) {
if (typeof data === 'string')
data = utf8ToBytes$4(data);
if (!(data instanceof Uint8Array))
throw new TypeError(`Expected input type is Uint8Array (got ${typeof data})`);
return data;
}
// For runtime check if class implements interface
let Hash$3 = class Hash {
// Safe version that clones internal state
clone() {
return this._cloneInto();
}
};
function wrapConstructor$3(hashConstructor) {
const hashC = (message) => hashConstructor().update(toBytes$5(message)).digest();
const tmp = hashConstructor();
hashC.outputLen = tmp.outputLen;
hashC.blockLen = tmp.blockLen;
hashC.create = () => hashConstructor();
return hashC;
}
// Polyfill for Safari 14
function setBigUint64$3(view, byteOffset, value, isLE) {
if (typeof view.setBigUint64 === 'function')
return view.setBigUint64(byteOffset, value, isLE);
const _32n = BigInt(32);
const _u32_max = BigInt(0xffffffff);
const wh = Number((value >> _32n) & _u32_max);
const wl = Number(value & _u32_max);
const h = isLE ? 4 : 0;
const l = isLE ? 0 : 4;
view.setUint32(byteOffset + h, wh, isLE);
view.setUint32(byteOffset + l, wl, isLE);
}
// Base SHA2 class (RFC 6234)
let SHA2$3 = class SHA2 extends Hash$3 {
constructor(blockLen, outputLen, padOffset, isLE) {
super();
this.blockLen = blockLen;
this.outputLen = outputLen;
this.padOffset = padOffset;
this.isLE = isLE;
this.finished = false;
this.length = 0;
this.pos = 0;
this.destroyed = false;
this.buffer = new Uint8Array(blockLen);
this.view = createView$3(this.buffer);
}
update(data) {
assert$2$1.exists(this);
const { view, buffer, blockLen } = this;
data = toBytes$5(data);
const len = data.length;
for (let pos = 0; pos < len;) {
const take = Math.min(blockLen - this.pos, len - pos);
// Fast path: we have at least one block in input, cast it to view and process
if (take === blockLen) {
const dataView = createView$3(data);
for (; blockLen <= len - pos; pos += blockLen)
this.process(dataView, pos);
continue;
}
buffer.set(data.subarray(pos, pos + take), this.pos);
this.pos += take;
pos += take;
if (this.pos === blockLen) {
this.process(view, 0);
this.pos = 0;
}
}
this.length += data.length;
this.roundClean();
return this;
}
digestInto(out) {
assert$2$1.exists(this);
assert$2$1.output(out, this);
this.finished = true;
// Padding
// We can avoid allocation of buffer for padding completely if it
// was previously not allocated here. But it won't change performance.
const { buffer, view, blockLen, isLE } = this;
let { pos } = this;
// append the bit '1' to the message
buffer[pos++] = 0b10000000;
this.buffer.subarray(pos).fill(0);
// we have less than padOffset left in buffer, so we cannot put length in current block, need process it and pad again
if (this.padOffset > blockLen - pos) {
this.process(view, 0);
pos = 0;
}
// Pad until full block byte with zeros
for (let i = pos; i < blockLen; i++)
buffer[i] = 0;
// Note: sha512 requires length to be 128bit integer, but length in JS will overflow before that
// You need to write around 2 exabytes (u64_max / 8 / (1024**6)) for this to happen.
// So we just write lowest 64 bits of that value.
setBigUint64$3(view, blockLen - 8, BigInt(this.length * 8), isLE);
this.process(view, 0);
const oview = createView$3(out);
const len = this.outputLen;
// NOTE: we do division by 4 later, which should be fused in single op with modulo by JIT
if (len % 4)
throw new Error('_sha2: outputLen should be aligned to 32bit');
const outLen = len / 4;
const state = this.get();
if (outLen > state.length)
throw new Error('_sha2: outputLen bigger than state');
for (let i = 0; i < outLen; i++)
oview.setUint32(4 * i, state[i], isLE);
}
digest() {
const { buffer, outputLen } = this;
this.digestInto(buffer);
const res = buffer.slice(0, outputLen);
this.destroy();
return res;
}
_cloneInto(to) {
to || (to = new this.constructor());
to.set(...this.get());
const { blockLen, buffer, length, finished, destroyed, pos } = this;
to.length = length;
to.pos = pos;
to.finished = finished;
to.destroyed = destroyed;
if (length % blockLen)
to.buffer.set(buffer);
return to;
}
};
// Choice: a ? b : c
const Chi$3 = (a, b, c) => (a & b) ^ (~a & c);
// Majority function, true if any two inpust is true
const Maj$3 = (a, b, c) => (a & b) ^ (a & c) ^ (b & c);
// Round constants:
// first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311)
// prettier-ignore
const SHA256_K$3 = new Uint32Array([
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
]);
// Initial state (first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19):
// prettier-ignore
const IV$3 = new Uint32Array([
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
]);
// Temporary buffer, not used to store anything between runs
// Named this way because it matches specification.
const SHA256_W$3 = new Uint32Array(64);
let SHA256$3 = class SHA256 extends SHA2$3 {
constructor() {
super(64, 32, 8, false);
// We cannot use array here since array allows indexing by variable
// which means optimizer/compiler cannot use registers.
this.A = IV$3[0] | 0;
this.B = IV$3[1] | 0;
this.C = IV$3[2] | 0;
this.D = IV$3[3] | 0;
this.E = IV$3[4] | 0;
this.F = IV$3[5] | 0;
this.G = IV$3[6] | 0;
this.H = IV$3[7] | 0;
}
get() {
const { A, B, C, D, E, F, G, H } = this;
return [A, B, C, D, E, F, G, H];
}
// prettier-ignore
set(A, B, C, D, E, F, G, H) {
this.A = A | 0;
this.B = B | 0;
this.C = C | 0;
this.D = D | 0;
this.E = E | 0;
this.F = F | 0;
this.G = G | 0;
this.H = H | 0;
}
process(view, offset) {
// Extend the first 16 words into the remaining 48 words w[16..63] of the message schedule array
for (let i = 0; i < 16; i++, offset += 4)
SHA256_W$3[i] = view.getUint32(offset, false);
for (let i = 16; i < 64; i++) {
const W15 = SHA256_W$3[i - 15];
const W2 = SHA256_W$3[i - 2];
const s0 = rotr$3(W15, 7) ^ rotr$3(W15, 18) ^ (W15 >>> 3);
const s1 = rotr$3(W2, 17) ^ rotr$3(W2, 19) ^ (W2 >>> 10);
SHA256_W$3[i] = (s1 + SHA256_W$3[i - 7] + s0 + SHA256_W$3[i - 16]) | 0;
}
// Compression function main loop, 64 rounds
let { A, B, C, D, E, F, G, H } = this;
for (let i = 0; i < 64; i++) {
const sigma1 = rotr$3(E, 6) ^ rotr$3(E, 11) ^ rotr$3(E, 25);
const T1 = (H + sigma1 + Chi$3(E, F, G) + SHA256_K$3[i] + SHA256_W$3[i]) | 0;
const sigma0 = rotr$3(A, 2) ^ rotr$3(A, 13) ^ rotr$3(A, 22);
const T2 = (sigma0 + Maj$3(A, B, C)) | 0;
H = G;
G = F;
F = E;
E = (D + T1) | 0;
D = C;
C = B;
B = A;
A = (T1 + T2) | 0;
}
// Add the compressed chunk to the current hash value
A = (A + this.A) | 0;
B = (B + this.B) | 0;
C = (C + this.C) | 0;
D = (D + this.D) | 0;
E = (E + this.E) | 0;
F = (F + this.F) | 0;
G = (G + this.G) | 0;
H = (H + this.H) | 0;
this.set(A, B, C, D, E, F, G, H);
}
roundClean() {
SHA256_W$3.fill(0);
}
destroy() {
this.set(0, 0, 0, 0, 0, 0, 0, 0);
this.buffer.fill(0);
}
};
// Constants from https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf
let SHA224$3 = class SHA224 extends SHA256$3 {
constructor() {
super();
this.A = 0xc1059ed8 | 0;
this.B = 0x367cd507 | 0;
this.C = 0x3070dd17 | 0;
this.D = 0xf70e5939 | 0;
this.E = 0xffc00b31 | 0;
this.F = 0x68581511 | 0;
this.G = 0x64f98fa7 | 0;
this.H = 0xbefa4fa4 | 0;
this.outputLen = 28;
}
};
/**
* SHA2-256 hash function
* @param message - data that would be hashed
*/
const sha256$4 = wrapConstructor$3(() => new SHA256$3());
wrapConstructor$3(() => new SHA224$3());
function within_size$1(data, size) {
if (data.length > size) {
throw new TypeError(`Data is larger than array size: ${data.length} > ${size}`);
}
}
function is_hex$1(hex) {
if (hex.match(/[^a-fA-f0-9]/) !== null) {
throw new TypeError('Invalid characters in hex string: ' + hex);
}
if (hex.length % 2 !== 0) {
throw new Error(`Length of hex string is invalid: ${hex.length}`);
}
}
function is_safe_num$1(num) {
if (num > Number.MAX_SAFE_INTEGER) {
throw new TypeError('Number exceeds safe bounds!');
}
}
const { getRandomValues: getRandomValues$1 } = crypto ?? globalThis.crypto ?? window.crypto;
function random$2(size = 32) {
if (typeof getRandomValues$1 === 'function') {
return crypto.getRandomValues(new Uint8Array(size));
}
throw new Error('Crypto module missing getRandomValues!');
}
function set_buffer$1(data, size, endian = 'be') {
if (size === undefined)
size = data.length;
within_size$1(data, size);
const buffer = new Uint8Array(size).fill(0);
const offset = (endian === 'be') ? 0 : size - data.length;
buffer.set(data, offset);
return buffer;
}
function join_array$1(arr) {
let i, offset = 0;
const size = arr.reduce((len, arr) => len + arr.length, 0);
const buff = new Uint8Array(size);
for (i = 0; i < arr.length; i++) {
const a = arr[i];
buff.set(a, offset);
offset += a.length;
}
return buff;
}
const ec$2$1 = new TextEncoder();
const ALPHABETS$1 = [
{
name: 'base58',
charset: '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
}
];
function getAlphabet$1(name) {
for (const alpha of ALPHABETS$1) {
if (alpha.name === name) {
return alpha.charset;
}
}
throw TypeError('Charset does not exist: ' + name);
}
function encode$1$2(data, charset, padding = false) {
if (typeof data === 'string')
data = ec$2$1.encode(data);
const alphabet = getAlphabet$1(charset);
const len = alphabet.length;
const d = [];
let s = '', i, j = 0, c, n;
for (i = 0; i < data.length; i++) {
j = 0;
c = data[i];
s += (c > 0 || (s.length ^ i) > 0) ? '' : '1';
while (j in d || c > 0) {
n = d[j];
n = n > 0 ? n * 256 + c : c;
c = n / len | 0;
d[j] = n % len;
j++;
}
}
while (j-- > 0) {
s += alphabet[d[j]];
}
return (padding && s.length % 4 > 0)
? s + '='.repeat(4 - s.length % 4)
: s;
}
function decode$1$2(encoded, charset) {
const alphabet = getAlphabet$1(charset);
const len = alphabet.length, d = [], b = [];
encoded = encoded.replace('=', '');
let i, j = 0, c, n;
for (i = 0; i < encoded.length; i++) {
j = 0;
c = alphabet.indexOf(encoded[i]);
if (c < 0) {
throw new Error(`Character range out of bounds: ${c}`);
}
if (!(c > 0 || (b.length ^ i) > 0))
b.push(0);
while (j in d || c > 0) {
n = d[j];
n = n > 0 ? n * len + c : c;
c = n >> 8;
d[j] = n % 256;
j++;
}
}
while (j-- > 0) {
b.push(d[j]);
}
return new Uint8Array(b);
}
function hash256$2(data) {
return sha256$4(sha256$4(data));
}
function addChecksum$1(data) {
const sum = hash256$2(data);
return join_array$1([data, sum.slice(0, 4)]);
}
function checkTheSum$1(data) {
const ret = data.slice(0, -4);
const chk = data.slice(-4);
const sum = hash256$2(ret).slice(0, 4);
if (sum.toString() !== chk.toString()) {
throw new Error('Invalid checksum!');
}
return ret;
}
const BaseX$1 = {
encode: encode$1$2,
decode: decode$1$2
};
const Base58C$1 = {
encode: (data) => {
const withSum = addChecksum$1(data);
return BaseX$1.encode(withSum, 'base58');
},
decode: (data) => {
const decoded = BaseX$1.decode(data, 'base58');
return checkTheSum$1(decoded);
}
};
const CHARSET$1 = 'qpzry9x8gf2tvdw0s3jn54khce6mua7l';
const GENERATOR$1 = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3];
const ENCODINGS$1 = [
{ version: 0, name: 'bech32', const: 1 },
{ version: 1, name: 'bech32m', const: 0x2bc830a3 }
];
function polymod$1(values) {
let chk = 1;
for (let p = 0; p < values.length; ++p) {
const top = chk >> 25;
chk = (chk & 0x1ffffff) << 5 ^ values[p];
for (let i = 0; i < 5; ++i) {
if (((top >> i) & 1) !== 0) {
chk ^= GENERATOR$1[i];
}
}
}
return chk;
}
function hrpExpand$1(hrp) {
const ret = [];
let p;
for (p = 0; p < hrp.length; ++p) {
ret.push(hrp.charCodeAt(p) >> 5);
}
ret.push(0);
for (p = 0; p < hrp.length; ++p) {
ret.push(hrp.charCodeAt(p) & 31);
}
return ret;
}
function verifyChecksum$1(hrp, data, enc) {
const combined = hrpExpand$1(hrp).concat(data);
return polymod$1(combined) === enc.const;
}
function createChecksum$1(hrp, data, enc) {
const values = hrpExpand$1(hrp).concat(data).concat([0, 0, 0, 0, 0, 0]);
const mod = polymod$1(values) ^ enc.const;
const ret = [];
for (let p = 0; p < 6; ++p) {
ret.push((mod >> 5 * (5 - p)) & 31);
}
return ret;
}
function convertBits$1(data, fromBits, toBits, pad = true) {
const ret = [];
let acc = 0;
let bits = 0;
const maxVal = (1 << toBits) - 1;
const maxAcc = (1 << (fromBits + toBits - 1)) - 1;
for (const val of data) {
if (val < 0 || (val >> fromBits) > 0) {
throw new Error('Failed to perform base conversion. Invalid value: ' + String(val));
}
acc = ((acc << fromBits) | val) & maxAcc;
bits += fromBits;
while (bits >= toBits) {
bits -= toBits;
ret.push((acc >> bits) & maxVal);
}
}
if (pad) {
if (bits > 0) {
ret.push((acc << (toBits - bits)) & maxVal);
}
}
else if (bits >= fromBits || ((acc << (toBits - bits)) & maxVal) > 0) {
throw new Error('Failed to perform base conversion. Invalid Size!');
}
return ret;
}
function encode$6(hrp, data, enc) {
const combined = data.concat(createChecksum$1(hrp, data, enc));
let ret = hrp + '1';
for (let p = 0; p < combined.length; ++p) {
ret += CHARSET$1.charAt(combined[p]);
}
return ret;
}
function decode$6(bechstr) {
if (!checkBounds$1(bechstr)) {
throw new Error('Encoded string goes out of bounds!');
}
bechstr = bechstr.toLowerCase();
if (!checkSeparatorPos$1(bechstr)) {
throw new Error('Encoded string has invalid separator!');
}
const data = [];
const pos = bechstr.lastIndexOf('1');
const hrp = bechstr.substring(0, pos);
for (let p = pos + 1; p < bechstr.length; ++p) {
const d = CHARSET$1.indexOf(bechstr.charAt(p));
if (d === -1) {
throw new Error('Character idx out of bounds: ' + String(p));
}
data.push(d);
}
const enc = ENCODINGS$1.find(e => e.version === data[0]) ?? ENCODINGS$1[0];
if (!verifyChecksum$1(hrp, data, enc)) {
throw new Error('Checksum verification failed!');
}
return [hrp, data.slice(0, data.length - 6)];
}
function checkBounds$1(bechstr) {
let p;
let char;
let hasLower = false;
let hasUpper = false;
for (p = 0; p < bechstr.length; ++p) {
char = bechstr.charCodeAt(p);
if (char < 33 || char > 126) {
return false;
}
if (char >= 97 && char <= 122) {
hasLower = true;
}
if (char >= 65 && char <= 90) {
hasUpper = true;
}
}
if (hasLower && hasUpper)
return false;
return true;
}
function checkSeparatorPos$1(bechstr) {
const pos = bechstr.lastIndexOf('1');
return !(pos < 1 ||
pos + 7 > bechstr.length ||
bechstr.length > 90);
}
function b32encode$1(data, hrp = 'bc', version = 0) {
const dat = [version, ...convertBits$1([...data], 8, 5)];
const enc = ENCODINGS$1.find(e => e.version === version) ?? ENCODINGS$1[0];
const str = encode$6(hrp, dat, enc);
b32decode$1(str);
return str;
}
function b32decode$1(str) {
str = str.toLowerCase();
const hrp = str.split('1', 1)[0];
const [hrpgot, data] = decode$6(str);
const decoded = convertBits$1(data.slice(1), 5, 8, false);
const length = decoded.length;
switch (true) {
case (hrp !== hrpgot):
throw new Error('Returned hrp string is invalid.');
case (decoded === null || length < 2 || length > 40):
throw new Error('Decoded string is invalid or out of spec.');
case (data[0] > 16):
throw new Error('Returned version bit is out of range.');
default:
return Uint8Array.from(decoded);
}
}
function getVersion$2(str) {
str = str.toLowerCase();
const [_, data] = decode$6(str);
return data[0];
}
const Bech32$1 = {
encode: b32encode$1,
decode: b32decode$1,
version: getVersion$2
};
const BASE64_MAP$1 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
const B64URL_MAP$1 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';
const ec$1$1 = new TextEncoder();
function b64encode$1(input, urlSafe = false, padding = true) {
if (typeof input === 'string')
input = ec$1$1.encode(input);
const map = urlSafe ? B64URL_MAP$1 : BASE64_MAP$1;
let output = '';
let bits = 0;
let buffer = 0;
for (let i = 0; i < input.length; i++) {
buffer = (buffer << 8) | input[i];
bits += 8;
while (bits >= 6) {
bits -= 6;
output += map[(buffer >> bits) & 0x3f];
}
}
if (bits > 0) {
buffer <<= 6 - bits;
output += map[buffer & 0x3f];
while (bits < 6) {
output += padding ? '=' : '';
bits += 2;
}
}
return output;
}
function b64decode$1(input, urlSafe = false) {
const map = (urlSafe || input.includes('-') || input.includes('_'))
? B64URL_MAP$1.split('')
: BASE64_MAP$1.split('');
input = input.replace(/=+$/, '');
const chars = input.split('');
let bits = 0;
let value = 0;
const bytes = [];
for (let i = 0; i < chars.length; i++) {
const c = chars[i];
const index = map.indexOf(c);
if (index === -1) {
throw new Error('Invalid character: ' + c);
}
bits += 6;
value <<= 6;
value |= index;
if (bits >= 8) {
bits -= 8;
bytes.push((value >>> bits) & 0xff);
}
}
return new Uint8Array(bytes);
}
const Base64$1 = {
encode: b64encode$1,
decode: b64decode$1
};
const B64URL$1 = {
encode: (data) => b64encode$1(data, true, false),
decode: (data) => b64decode$1(data, true)
};
const _0n = BigInt(0);
const _255n$1 = BigInt(255);
const _256n$1 = BigInt(256);
function big_size$1(big) {
if (big <= 0xffn)
return 1;
if (big <= 0xffffn)
return 2;
if (big <= 0xffffffffn)
return 4;
if (big <= 0xffffffffffffffffn)
return 8;
if (big <= 0xffffffffffffffffffffffffffffffffn)
return 16;
if (big <= 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffn) {
return 32;
}
throw new TypeError('Must specify a fixed buffer size for bigints greater than 32 bytes.');
}
function bigToBytes$1(big, size, endian = 'be') {
if (size === undefined)
size = big_size$1(big);
const use_le = (endian === 'le');
const buffer = new ArrayBuffer(size);
const dataView = new DataView(buffer);
let offset = (use_le) ? 0 : size - 1;
while (big > _0n) {
const byte = big & _255n$1;
const num = Number(byte);
if (use_le) {
dataView.setUint8(offset++, num);
}
else {
dataView.setUint8(offset--, num);
}
big = (big - byte) / _256n$1;
}
return new Uint8Array(buffer);
}
function bytesToBig$1(bytes) {
let num = BigInt(0);
for (let i = bytes.length - 1; i >= 0; i--) {
num = (num * _256n$1) + BigInt(bytes[i]);
}
return BigInt(num);
}
function binToBytes$1(binary) {
const bins = binary.split('').map(Number);
if (bins.length % 8 !== 0) {
throw new Error(`Binary array is invalid length: ${binary.length}`);
}
const bytes = new Uint8Array(bins.length / 8);
for (let i = 0, ct = 0; i < bins.length; i += 8, ct++) {
let byte = 0;
for (let j = 0; j < 8; j++) {
byte |= (bins[i + j] << (7 - j));
}
bytes[ct] = byte;
}
return bytes;
}
function bytesToBin$1(bytes) {
const bin = new Array(bytes.length * 8);
let count = 0;
for (const num of bytes) {
if (num > 255) {
throw new Error(`Invalid byte value: ${num}. Byte values must be between 0 and 255.`);
}
for (let i = 7; i >= 0; i--, count++) {
bin[count] = (num >> i) & 1;
}
}
return bin.join('');
}
function num_size$1(num) {
if (num <= 0xFF)
return 1;
if (num <= 0xFFFF)
return 2;
if (num <= 0xFFFFFFFF)
return 4;
throw new TypeError('Numbers larger than 4 bytes must specify a fixed size!');
}
function numToBytes$1(num, size, endian = 'be') {
if (size === undefined)
size = num_size$1(num);
const use_le = (endian === 'le');
const buffer = new ArrayBuffer(size);
const dataView = new DataView(buffer);
let offset = (use_le) ? 0 : size - 1;
while (num > 0) {
const byte = num & 255;
if (use_le) {
dataView.setUint8(offset++, num);
}
else {
dataView.setUint8(offset--, num);
}
num = (num - byte) / 256;
}
return new Uint8Array(buffer);
}
function bytesToNum$1(bytes) {
let num = 0;
for (let i = bytes.length - 1; i >= 0; i--) {
num = (num * 256) + bytes[i];
is_safe_num$1(num);
}
return num;
}
const ec$3 = new TextEncoder();
const dc$1 = new TextDecoder();
function strToBytes$1(str) {
return ec$3.encode(str);
}
function bytesToStr$1(bytes) {
return dc$1.decode(bytes);
}
function hex_size$1(hexstr, size) {
is_hex$1(hexstr);
const len = hexstr.length / 2;
if (size === undefined)
size = len;
if (len > size) {
throw new TypeError(`Hex string is larger than array size: ${len} > ${size}`);
}
return size;
}
function hexToBytes$2(hexstr, size, endian = 'le') {
size = hex_size$1(hexstr, size);
const use_le = (endian === 'le');
const buffer = new ArrayBuffer(size);
const dataView = new DataView(buffer);
let offset = (use_le) ? 0 : size - 1;
for (let i = 0; i < hexstr.length; i += 2) {
const char = hexstr.substring(i, i + 2);
const num = parseInt(char, 16);
if (use_le) {
dataView.setUint8(offset++, num);
}
else {
dataView.setUint8(offset--, num);
}
}
return new Uint8Array(buffer);
}
function bytesToHex$2(bytes) {
let chars = '';
for (let i = 0; i < bytes.length; i++) {
chars += bytes[i].toString(16).padStart(2, '0');
}
return chars;
}
function jsonToBytes$1(obj) {
const str = JSON.stringify(obj, (_, v) => {
return typeof v === 'bigint'
? `${v}n`
: v;
});
return strToBytes$1(str);
}
function buffer$1(data, size, endian) {
if (data instanceof ArrayBuffer) {
return new Uint8Array(data);
}
if (data instanceof Uint8Array) {
return set_buffer$1(data, size, endian);
}
if (typeof data === 'string') {
return hexToBytes$2(data, size, endian);
}
if (typeof data === 'bigint') {
return bigToBytes$1(data, size, endian);
}
if (typeof data === 'number') {
return numToBytes$1(data, size, endian);
}
if (typeof data === 'boolean') {
return Uint8Array.of(data ? 1 : 0);
}
throw TypeError('Unsupported format:' + String(typeof data));
}
let Buff$1 = class Buff extends Uint8Array {
static { this.num = numToBuff$1; }
static { this.big = bigToBuff$1; }
static { this.bin = binToBuff$1; }
static { this.raw = rawToBuff$1; }
static { this.str = strToBuff$1; }
static { this.hex = hexToBuff$1; }
static { this.bytes = bytesToBuff$1; }
static { this.json = jsonToBuff$1; }
static { this.base64 = base64ToBuff$1; }
static { this.b64url = b64urlToBuff$1; }
static { this.bech32 = bech32ToBuff$1; }
static { this.b58chk = b58chkToBuff$1; }
static { this.encode = strToBytes$1; }
static { this.decode = bytesToStr$1; }
static random(size = 32) {
const rand = random$2(size);
return new Buff(rand, size);
}
constructor(data, size, endian) {
const buffer$1$1 = buffer$1(data, size, endian);
super(buffer$1$1);
}
get arr() {
return [...this];
}
get num() {
return this.toNum();
}
get big() {
return this.toBig();
}
get str() {
return this.toStr();
}
get hex() {
return this.toHex();
}
get raw() {
return new Uint8Array(this);
}
get bin() {
return this.toBin();
}
get b58chk() {
return this.tob58chk();
}
get base64() {
return this.toBase64();
}
get b64url() {
return this.toB64url();
}
get digest() {
return this.toHash();
}
get id() {
return this.toHash().hex;
}
get stream() {
return new Stream$1(this);
}
toNum(endian = 'be') {
const bytes = (endian === 'be')
? this.reverse()
: this;
return bytesToNum$1(bytes);
}
toBin() {
return bytesToBin$1(this);
}
toBig(endian = 'be') {
const bytes = (endian === 'be')
? this.reverse()
: this;
return bytesToBig$1(bytes);
}
toHash() {
const digest = sha256$4(this);
return new Buff(digest);
}
toJson() {
const str = bytesToStr$1(this);
return JSON.parse(str);
}
toBech32(hrp, version = 0) {
return Bech32$1.encode(this, hrp, version);
}
toStr() { return bytesToStr$1(this); }
toHex() { return bytesToHex$2(this); }
toBytes() { return new Uint8Array(this); }
tob58chk() { return Base58C$1.encode(this); }
toBase64() { return Base64$1.encode(this); }
toB64url() { return B64URL$1.encode(this); }
prepend(data) {
return Buff.join([Buff.bytes(data), this]);
}
append(data) {
return Buff.join([this, Buff.bytes(data)]);
}
slice(start, end) {
const arr = new Uint8Array(this).slice(start, end);
return new Buff(arr);
}
subarray(begin, end) {
const arr = new Uint8Array(this).subarray(begin, end);
return new Buff(arr);
}
reverse() {
const arr = new Uint8Array(this).reverse();
return new Buff(arr);
}
write(bytes, offset) {
const b = Buff.bytes(bytes);
this.set(b, offset);
}
prefixSize(endian) {
const size = Buff.varInt(this.length, endian);
return Buff.join([size, this]);
}
static from(data) {
return new Buff(Uint8Array.from(data));
}
static of(...args) {
return new Buff(Uint8Array.of(...args));
}
static join(arr) {
const bytes = arr.map(e => Buff.bytes(e));
const joined = join_array$1(bytes);
return new Buff(joined);
}
static varInt(num, endian) {
if (num < 0xFD) {
return Buff.num(num, 1);
}
else if (num < 0x10000) {
return Buff.of(0xFD, ...Buff.num(num, 2, endian));
}
else if (num < 0x100000000) {
return Buff.of(0xFE, ...Buff.num(num, 4, endian));
}
else if (BigInt(num) < 0x10000000000000000n) {
return Buff.of(0xFF, ...Buff.num(num, 8, endian));
}
else {
throw new Error(`Value is too large: ${num}`);
}
}
};
function numToBuff$1(number, size, endian) {
return new Buff$1(number, size, endian);
}
function binToBuff$1(data, size, endian) {
return new Buff$1(binToBytes$1(data), size, endian);
}
function bigToBuff$1(bigint, size, endian) {
return new Buff$1(bigint, size, endian);
}
function rawToBuff$1(data, size, endian) {
return new Buff$1(data, size, endian);
}
function strToBuff$1(data, size, endian) {
return new Buff$1(strToBytes$1(data), size, endian);
}
function hexToBuff$1(data, size, endian) {
return new Buff$1(data, size, endian);
}
function bytesToBuff$1(data, size, endian) {
return new Buff$1(data, size, endian);
}
function jsonToBuff$1(data) {
return new Buff$1(jsonToBytes$1(data));
}
function base64ToBuff$1(data) {
return new Buff$1(Base64$1.decode(data));
}
function b64urlToBuff$1(data) {
return new Buff$1(B64URL$1.decode(data));
}
function bech32ToBuff$1(data) {
return new Buff$1(Bech32$1.decode(data));
}
function b58chkToBuff$1(data) {
return new Buff$1(Base58C$1.decode(data));
}
let Stream$1 = class Stream {
constructor(data) {
this.data = Buff$1.bytes(data);
this.size = this.data.length;
}
peek(size) {
if (size > this.size) {
throw new Error(`Size greater than stream: ${size} > ${this.size}`);
}
return new Buff$1(this.data.slice(0, size));
}
read(size) {
size = size ?? this.readSize();
const chunk = this.peek(size);
this.data = this.data.slice(size);
this.size = this.data.length;
return chunk;
}
readSize(endian) {
const num = this.read(1).num;
switch (true) {
case (num >= 0 && num < 0xFD):
return num;
case (num === 0xFD):
return this.read(2).toNum(endian);
case (num === 0xFE):
return this.read(4).toNum(endian);
case (num === 0xFF):
return this.read(8).toNum(endian);
default:
throw new Error(`Varint is out of range: ${num}`);
}
}
};
function checkSize(input, size) {
const bytes = Buff$1.bytes(input);
if (bytes.length !== size) {
throw new Error(`Invalid input size: ${bytes.hex} !== ${size}`);
}
}
function safeThrow(errorMsg, shouldThrow) {
if (shouldThrow) {
throw new Error(errorMsg);
}
else {
return false;
}
}
function hashTag(tag, ...data) {
const htag = Buff$1.str(tag).digest.raw;
const buff = data.map(e => Buff$1.bytes(e));
return Buff$1.join([htag, htag, Buff$1.join(buff)]).digest;
}
const OPCODE_MAP = {
OP_0: 0,
OP_PUSHDATA1: 76,
OP_PUSHDATA2: 77,
OP_PUSHDATA4: 78,
OP_1NEGATE: 79,
OP_SUCCESS80: 80,
OP_1: 81,
OP_2: 82,
OP_3: 83,
OP_4: 84,
OP_5: 85,
OP_6: 86,
OP_7: 87,
OP_8: 88,
OP_9: 89,
OP_10: 90,
OP_11: 91,
OP_12: 92,
OP_13: 93,
OP_14: 94,
OP_15: 95,
OP_16: 96,
OP_NOP: 97,
OP_SUCCESS98: 98,
OP_IF: 99,
OP_NOTIF: 100,
OP_ELSE: 103,
OP_ENDIF: 104,
OP_VERIFY: 105,
OP_RETURN: 106,
OP_TOALTSTACK: 107,
OP_FROMALTSTACK: 108,
OP_2DROP: 109,
OP_2DUP: 110,
OP_3DUP: 111,
OP_2OVER: 112,
OP_2ROT: 113,
OP_2SWAP: 114,
OP_IFDUP: 115,
OP_DEPTH: 116,
OP_DROP: 117,
OP_DUP: 118,
OP_NIP: 119,
OP_OVER: 120,
OP_PICK: 121,
OP_ROLL: 122,
OP_ROT: 123,
OP_SWAP: 124,
OP_TUCK: 125,
OP_SUCCESS126: 126,
OP_SUCCESS127: 127,
OP_SUCCESS128: 128,
OP_SUCCESS129: 129,
OP_SIZE: 130,
OP_SUCCESS131: 131,
OP_SUCCESS132: 132,
OP_SUCCESS133: 133,
OP_SUCCESS134: 134,
OP_EQUAL: 135,
OP_EQUALVERIFY: 136,
OP_SUCCESS137: 137,
OP_SUCCESS138: 138,
OP_1ADD: 139,
OP_1SUB: 140,
OP_SUCCESS141: 141,
OP_SUCCESS142: 142,
OP_NEGATE: 143,
OP_ABS: 144,
OP_NOT: 145,
OP_0NOTEQUAL: 146,
OP_ADD: 147,
OP_SUB: 148,
OP_SUCCESS149: 149,
OP_SUCCESS150: 150,
OP_SUCCESS151: 151,
OP_SUCCESS152: 152,
OP_SUCCESS153: 153,
OP_BOOLAND: 154,
OP_BOOLOR: 155,
OP_NUMEQUAL: 156,
OP_NUMEQUALVERIFY: 157,
OP_NUMNOTEQUAL: 158,
OP_LESSTHAN: 159,
OP_GREATERTHAN: 160,
OP_LESSTHANOREQUAL: 161,
OP_GREATERTHANOREQUAL: 162,
OP_MIN: 163,
OP_MAX: 164,
OP_WITHIN: 165,
OP_RIPEMD160: 166,
OP_SHA1: 167,
OP_SHA256: 168,
OP_HASH160: 169,
OP_HASH256: 170,
OP_CODESEPARATOR: 171,
OP_CHECKSIG: 172,
OP_CHECKSIGVERIFY: 173,
OP_CHECKMULTISIG: 174,
OP_CHECKMULTISIGVERIFY: 175,
OP_NOP1: 176,
OP_CHECKLOCKTIMEVERIFY: 177,
OP_CHECKSEQUENCEVERIFY: 178,
OP_NOP4: 179,
OP_NOP5: 180,
OP_NOP6: 181,
OP_NOP7: 182,
OP_NOP8: 183,
OP_NOP9: 184,
OP_NOP10: 185,
OP_CHECKSIGADD: 186,
OP_SUCCESS187: 187,
OP_SUCCESS188: 188,
OP_SUCCESS189: 189,
OP_SUCCESS190: 190,
OP_SUCCESS191: 191,
OP_SUCCESS192: 192,
OP_SUCCESS193: 193,
OP_SUCCESS194: 194,
OP_SUCCESS195: 195,
OP_SUCCESS196: 196,
OP_SUCCESS197: 197,
OP_SUCCESS198: 198,
OP_SUCCESS199: 199,
OP_SUCCESS200: 200,
OP_SUCCESS201: 201,
OP_SUCCESS202: 202,
OP_SUCCESS203: 203,
OP_SUCCESS204: 204,
OP_SUCCESS205: 205,
OP_SUCCESS206: 206,
OP_SUCCESS207: 207,
OP_SUCCESS208: 208,
OP_SUCCESS209: 209,
OP_SUCCESS210: 210,
OP_SUCCESS211: 211,
OP_SUCCESS212: 212,
OP_SUCCESS213: 213,
OP_SUCCESS214: 214,
OP_SUCCESS215: 215,
OP_SUCCESS216: 216,
OP_SUCCESS217: 217,
OP_SUCCESS218: 218,
OP_SUCCESS219: 219,
OP_SUCCESS220: 220,
OP_SUCCESS221: 221,
OP_SUCCESS222: 222,
OP_SUCCESS223: 223,
OP_SUCCESS224: 224,
OP_SUCCESS225: 225,
OP_SUCCESS226: 226,
OP_SUCCESS227: 227,
OP_SUCCESS228: 228,
OP_SUCCESS229: 229,
OP_SUCCESS230: 230,
OP_SUCCESS231: 231,
OP_SUCCESS232: 232,
OP_SUCCESS233: 233,
OP_SUCCESS234: 234,
OP_SUCCESS235: 235,
OP_SUCCESS236: 236,
OP_SUCCESS237: 237,
OP_SUCCESS238: 238,
OP_SUCCESS239: 239,
OP_SUCCESS240: 240,
OP_SUCCESS241: 241,
OP_SUCCESS242: 242,
OP_SUCCESS243: 243,
OP_SUCCESS244: 244,
OP_SUCCESS245: 245,
OP_SUCCESS246: 246,
OP_SUCCESS247: 247,
OP_SUCCESS248: 248,
OP_SUCCESS249: 249,
OP_SUCCESS250: 250,
OP_SUCCESS251: 251,
OP_SUCCESS252: 252,
OP_SUCCESS253: 253,
OP_SUCCESS254: 254
};
function getOpLabel(num) {
if (num > 186 && num < 255) {
return 'OP_SUCCESS' + String(num);
}
for (const [k, v] of Object.entries(OPCODE_MAP)) {
if (v === num)
return k;
}
throw new Error('OPCODE not found:' + String(num));
}
function getOpCode(string) {
for (const [k, v] of Object.entries(OPCODE_MAP)) {
if (k === string)
return Number(v);
}
throw new Error('OPCODE not found:' + string);
}
function getWordType(word) {
switch (true) {
case (word === 0):
return 'opcode';
case (word >= 1 && word <= 75):
return 'varint';
case (word === 76):
return 'pushdata1';
case (word === 77):
return 'pushdata2';
case (word === 78):
return 'pushdata4';
case (word <= 254):
return 'opcode';
default:
throw new Error(`Invalid word range: ${word}`);
}
}
function isValidWord(word) {
const MIN_RANGE = 75;
const MAX_RANGE = 254;
const DISABLED_OPCODES = [];
switch (true) {
case (typeof (word) !== 'number'):
return false;
case (word === 0):
return true;
case (DISABLED_OPCODES.includes(word)):
return false;
case (MIN_RANGE < word && word < MAX_RANGE):
return true;
default:
return false;
}
}
function isHex(value) {
return (typeof value === 'string' &&
value.length % 2 === 0 &&
/[0-9a-fA-F]/.test(value));
}
function isBytes$1(value) {
return (isHex(value) || value instanceof Uint8Array);
}
const MAX_WORD_SIZE = 0x208;
function encodeScript(script = [], varint = true) {
let buff = Buff$1.num(0);
if (Array.isArray(script)) {
buff = Buff$1.raw(encodeWords(script));
}
if (isHex(script)) {
buff = Buff$1.hex(script);
}
if (script instanceof Uint8Array) {
buff = Buff$1.raw(script);
}
if (varint) {
buff = buff.prefixSize('le');
}
return buff;
}
function encodeWords(wordArray) {
const words = [];
for (const word of wordArray) {
words.push(encodeWord(word));
}
return (words.length > 0)
? Buff$1.join(words)
: new Uint8Array();
}
function encodeWord(word) {
let buff = new Uint8Array();
if (typeof (word) === 'string') {
if (word.startsWith('OP_')) {
return Buff$1.num(getOpCode(word), 1);
}
else if (isHex(word)) {
buff = Buff$1.hex(word);
}
else {
buff = Buff$1.str(word);
}
}
else {
buff = Buff$1.bytes(word);
}
if (buff.length === 1) {
if (buff[0] !== 0 && buff[0] <= 16) {
buff[0] += 0x50;
return buff;
}
else if (buff[0] > 128 && buff[0] <= 255) {
buff = new Uint8Array([buff[0], 0]);
}
return Buff$1.join([encodeSize(buff.length), buff]);
}
else if (buff.length > MAX_WORD_SIZE) {
const words = splitWord(buff);
return encodeWords(words);
}
else {
return Buff$1.join([encodeSize(buff.length), buff]);
}
}
function encodeSize(size) {
const OP_DATAPUSH1 = Buff$1.num(0x4c, 1);
const OP_DATAPUSH2 = Buff$1.num(0x4d, 1);
switch (true) {
case (size <= 0x4b):
return Buff$1.num(size);
case (size > 0x4b && size < 0x100):
return Buff$1.join([OP_DATAPUSH1, Buff$1.num(size, 1, 'le')]);
case (size >= 0x100 && size <= MAX_WORD_SIZE):
return Buff$1.join([OP_DATAPUSH2, Buff$1.num(size, 2, 'le')]);
default:
throw new Error('Invalid word size:' + size.toString());
}
}
function splitWord(word) {
const words = [];
const buff = new Stream$1(word);
while (buff.size > MAX_WORD_SIZE) {
words.push(buff.read(MAX_WORD_SIZE));
}
words.push(buff.read(buff.size));
return words;
}
function decodeScript(script, varint = false) {
let buff = Buff$1.bytes(script);
if (varint) {
const stream = buff.stream;
const len = stream.readSize('le');
buff = buff.slice(1);
if (buff.length !== len) {
throw new Error(`Varint does not match stream size: ${len} !== ${buff.length}`);
}
}
return decodeWords(buff);
}
function decodeWords(words) {
const stream = new Stream$1(words);
const stack = [];
const stackSize = stream.size;
let word;
let wordType;
let wordSize;
let count = 0;
while (count < stackSize) {
word = stream.read(1).num;
wordType = getWordType(word);
count++;
switch (wordType) {
case 'varint':
stack.push(stream.read(word).hex);
count += word;
break;
case 'pushdata1':
wordSize = stream.read(1).reverse().num;
stack.push(stream.read(wordSize).hex);
count += wordSize + 1;
break;
case 'pushdata2':
wordSize = stream.read(2).reverse().num;
stack.push(stream.read(wordSize).hex);
count += wordSize + 2;
break;
case 'pushdata4':
wordSize = stream.read(4).reverse().num;
stack.push(stream.read(wordSize).hex);
count += wordSize + 4;
break;
case 'opcode':
if (!isValidWord(word)) {
throw new Error(`Invalid OPCODE: ${word}`);
}
stack.push(getOpLabel(word));
break;
default:
throw new Error(`Word type undefined: ${word}`);
}
}
return stack;
}
function toAsm(script, varint) {
if (Array.isArray(script)) {
script = encodeScript(script, varint);
}
if (script instanceof Uint8Array ||
isHex(script)) {
return decodeScript(script, varint);
}
throw new Error('Invalid format: ' + String(typeof script));
}
function toBytes$4(script, varint) {
if (script instanceof Uint8Array ||
isHex(script)) {
script = decodeScript(script, varint);
}
if (Array.isArray(script)) {
return encodeScript(script, varint);
}
throw new Error('Invalid format: ' + String(typeof script));
}
function toParam(script) {
if (!Array.isArray(script)) {
return Buff$1.bytes(script);
}
throw new Error('Invalid format: ' + String(typeof script));
}
const FmtScript = {
toAsm,
toBytes: toBytes$4,
toParam
};
const Script = {
encode: encodeScript,
decode: decodeScript,
fmt: FmtScript
};
function number$2(n) {
if (!Number.isSafeInteger(n) || n < 0)
throw new Error(`Wrong positive integer: ${n}`);
}
function bool$2(b) {
if (typeof b !== 'boolean')
throw new Error(`Expected boolean, not ${b}`);
}
function bytes$2(b, ...lengths) {
if (!(b instanceof Uint8Array))
throw new TypeError('Expected Uint8Array');
if (lengths.length > 0 && !lengths.includes(b.length))
throw new TypeError(`Expected Uint8Array of length ${lengths}, not of length=${b.length}`);
}
function hash$3(hash) {
if (typeof hash !== 'function' || typeof hash.create !== 'function')
throw new Error('Hash should be wrapped by utils.wrapConstructor');
number$2(hash.outputLen);
number$2(hash.blockLen);
}
function exists$2(instance, checkFinished = true) {
if (instance.destroyed)
throw new Error('Hash instance has been destroyed');
if (checkFinished && instance.finished)
throw new Error('Hash#digest() has already been called');
}
function output$2(out, instance) {
bytes$2(out);
const min = instance.outputLen;
if (out.length < min) {
throw new Error(`digestInto() expects output buffer of length at least ${min}`);
}
}
const assert$3 = {
number: number$2,
bool: bool$2,
bytes: bytes$2,
hash: hash$3,
exists: exists$2,
output: output$2,
};
var assert$4 = assert$3;
const crypto$1 = typeof globalThis === 'object' && 'crypto' in globalThis ? globalThis.crypto : undefined;
/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */
// We use `globalThis.crypto`, but node.js versions earlier than v19 don't
// declare it in global scope. For node.js, package.json#exports field mapping
// rewrites import from `crypto` to `cryptoNode`, which imports native module.
// Makes the utils un-importable in browsers without a bundler.
// Once node.js 18 is deprecated, we can just drop the import.
// Cast array to view
const createView$2 = (arr) => new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
// The rotate right (circular right shift) operation for uint32
const rotr$2 = (word, shift) => (word << (32 - shift)) | (word >>> shift);
// big-endian hardware is rare. Just in case someone still decides to run hashes:
// early-throw an error because we don't support BE yet.
const isLE$2 = new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44;
if (!isLE$2)
throw new Error('Non little-endian hardware is not supported');
Array.from({ length: 256 }, (v, i) => i.toString(16).padStart(2, '0'));
function utf8ToBytes$3(str) {
if (typeof str !== 'string') {
throw new TypeError(`utf8ToBytes expected string, got ${typeof str}`);
}
return new TextEncoder().encode(str);
}
function toBytes$2(data) {
if (typeof data === 'string')
data = utf8ToBytes$3(data);
if (!(data instanceof Uint8Array))
throw new TypeError(`Expected input type is Uint8Array (got ${typeof data})`);
return data;
}
/**
* Concats Uint8Array-s into one; like `Buffer.concat([buf1, buf2])`
* @example concatBytes(buf1, buf2)
*/
function concatBytes$1(...arrays) {
if (!arrays.every((a) => a instanceof Uint8Array))
throw new Error('Uint8Array list expected');
if (arrays.length === 1)
return arrays[0];
const length = arrays.reduce((a, arr) => a + arr.length, 0);
const result = new Uint8Array(length);
for (let i = 0, pad = 0; i < arrays.length; i++) {
const arr = arrays[i];
result.set(arr, pad);
pad += arr.length;
}
return result;
}
// For runtime check if class implements interface
let Hash$2 = class Hash {
// Safe version that clones internal state
clone() {
return this._cloneInto();
}
};
function wrapConstructor$2(hashConstructor) {
const hashC = (message) => hashConstructor().update(toBytes$2(message)).digest();
const tmp = hashConstructor();
hashC.outputLen = tmp.outputLen;
hashC.blockLen = tmp.blockLen;
hashC.create = () => hashConstructor();
return hashC;
}
/**
* Secure PRNG. Uses `globalThis.crypto` or node.js crypto module.
*/
function randomBytes(bytesLength = 32) {
if (crypto$1 && typeof