UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

4,558 lines 168 kB
import { c as isRecord } from "./record-coerce-DItp3I4t.js";
import { c as resolveUserPath } from "./home-dir-BPhrG-aM.js";
import { $n as uuid, Nn as record, Rn as string, Tn as object, dn as literal, wn as number } from "./schemas-zxit8y5H.js";
import "./string-coerce-runtime-GQa0ehRA.js";
import "./account-resolution-CN-KM82K.js";
import { A as hexToBytes$1, B as equalBytes, C as aexists$1, D as bytesToHex$1, E as aoutput, F as aoutput32, G as swap8IfBE, H as isAligned32, I as bytesToHex$2, J as u8, K as u32, L as clean, M as randomBytes$2, N as abytes$1, O as clean$1, P as aexists, R as copyBytes$1, S as abytes$2, T as anumber$1, U as isLE, V as getOutput, W as swap32IfBE, X as wrapCipher, Y as utf8ToBytes, Z as wrapMacConstructor, _ as decodeUtf8, b as sha256, g as base64url, h as base64, j as isBytes$1, k as concatBytes$1, p as canonicalBytes, q as u64Lengths, r as normalizeReefTarget, v as fromBase64, w as ahash, x as sha512, y as fromBase64url, z as createView } from "./config-schema-DGoCUvrP.js";
import { i as matchesReefPeerIdentity, n as ReefPeerIdentitySchema, o as sameReefPeerIdentity, r as ReefPeerTrustSchema, t as ReefAutonomySchema } from "./friend-types-DBQVddbp.js";
import path from "node:path";
import fs from "node:fs/promises";
import os from "node:os";
import { createHash, randomUUID } from "node:crypto";
import { setTimeout } from "node:timers/promises";
//#region node_modules/.pnpm/@noble+ciphers@2.3.0/node_modules/@noble/ciphers/_polyval.js
/**
* GHash from AES-GCM and its little-endian "mirror image" Polyval from AES-SIV.
*
* Implemented in terms of GHash with conversion function for keys
* GCM GHASH from
* {@link https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf | NIST SP800-38d},
* SIV from
* {@link https://www.rfc-editor.org/rfc/rfc8452 | RFC 8452}.
*
* GHASH   modulo: x^128 + x^7   + x^2   + x     + 1
* POLYVAL modulo: x^128 + x^127 + x^126 + x^121 + 1
*
* @module
*/
const BLOCK_SIZE$1 = 16;
const ZEROS16 = /* @__PURE__ */ new Uint8Array(16);
const ZEROS32 = /* @__PURE__ */ u32(ZEROS16);
const POLY$1 = 225;
const mul2$1 = (s0, s1, s2, s3) => {
	const hiBit = s3 & 1;
	return {
		s3: s2 << 31 | s3 >>> 1,
		s2: s1 << 31 | s2 >>> 1,
		s1: s0 << 31 | s1 >>> 1,
		s0: s0 >>> 1 ^ POLY$1 << 24 & -(hiBit & 1)
	};
};
const swapLE = (n) => (n >>> 0 & 255) << 24 | (n >>> 8 & 255) << 16 | (n >>> 16 & 255) << 8 | n >>> 24 & 255 | 0;
const estimateWindow = (bytes) => {
	if (bytes > 65536) return 8;
	if (bytes > 1024) return 4;
	return 2;
};
/**
* Incremental GHASH state for AES-GCM.
* @param key - 16-byte GHASH key.
* @param expectedLength - Expected message length for table sizing.
* Chunking is segment-based, not hash-streaming: every `update()` call is zero-padded
* to the next 16-byte boundary before it is absorbed. This matches the internal AES/GCM
* use where AAD, payload, and length block are separate padded segments.
* @example
* Feeds one ciphertext block into an incremental GHASH state with a fresh hash key.
*
* ```ts
* import { GHASH } from '@noble/ciphers/_polyval.js';
* import { randomBytes } from '@noble/ciphers/utils.js';
* const key = randomBytes(16);
* const mac = new GHASH(key);
* mac.update(new Uint8Array(16));
* mac.digest();
* ```
*/
var GHASH = class {
	blockLen = BLOCK_SIZE$1;
	outputLen = BLOCK_SIZE$1;
	s0 = 0;
	s1 = 0;
	s2 = 0;
	s3 = 0;
	finished = false;
	destroyed = false;
	t;
	W;
	windowSize;
	constructor(key, expectedLength) {
		abytes$1(key, 16, "key");
		key = copyBytes$1(key);
		const kView = createView(key);
		let k0 = kView.getUint32(0, false);
		let k1 = kView.getUint32(4, false);
		let k2 = kView.getUint32(8, false);
		let k3 = kView.getUint32(12, false);
		const doubles = [];
		for (let i = 0; i < 128; i++) {
			doubles.push({
				s0: swapLE(k0),
				s1: swapLE(k1),
				s2: swapLE(k2),
				s3: swapLE(k3)
			});
			({s0: k0, s1: k1, s2: k2, s3: k3} = mul2$1(k0, k1, k2, k3));
		}
		const W = estimateWindow(expectedLength || 1024);
		if (![
			1,
			2,
			4,
			8
		].includes(W)) throw new Error("ghash: invalid window size, expected 2, 4 or 8");
		this.W = W;
		const windows = 128 / W;
		const windowSize = this.windowSize = 2 ** W;
		const items = [];
		for (let w = 0; w < windows; w++) for (let byte = 0; byte < windowSize; byte++) {
			let s0 = 0, s1 = 0, s2 = 0, s3 = 0;
			for (let j = 0; j < W; j++) {
				if (!(byte >>> W - j - 1 & 1)) continue;
				const { s0: d0, s1: d1, s2: d2, s3: d3 } = doubles[W * w + j];
				s0 ^= d0, s1 ^= d1, s2 ^= d2, s3 ^= d3;
			}
			items.push({
				s0,
				s1,
				s2,
				s3
			});
		}
		this.t = items;
	}
	_updateBlock(s0, s1, s2, s3) {
		s0 ^= this.s0, s1 ^= this.s1, s2 ^= this.s2, s3 ^= this.s3;
		const { W, t, windowSize } = this;
		let o0 = 0, o1 = 0, o2 = 0, o3 = 0;
		const mask = (1 << W) - 1;
		let w = 0;
		for (const num of [
			s0,
			s1,
			s2,
			s3
		]) for (let bytePos = 0; bytePos < 4; bytePos++) {
			const byte = num >>> 8 * bytePos & 255;
			for (let bitPos = 8 / W - 1; bitPos >= 0; bitPos--) {
				const bit = byte >>> W * bitPos & mask;
				const { s0: e0, s1: e1, s2: e2, s3: e3 } = t[w * windowSize + bit];
				o0 ^= e0, o1 ^= e1, o2 ^= e2, o3 ^= e3;
				w += 1;
			}
		}
		this.s0 = o0;
		this.s1 = o1;
		this.s2 = o2;
		this.s3 = o3;
	}
	update(data) {
		aexists(this);
		abytes$1(data);
		data = copyBytes$1(data);
		const b32 = u32(data);
		const blocks = Math.floor(data.length / BLOCK_SIZE$1);
		const left = data.length % BLOCK_SIZE$1;
		for (let i = 0; i < blocks; i++) this._updateBlock(swap8IfBE(b32[i * 4 + 0]), swap8IfBE(b32[i * 4 + 1]), swap8IfBE(b32[i * 4 + 2]), swap8IfBE(b32[i * 4 + 3]));
		if (left) {
			ZEROS16.set(data.subarray(blocks * BLOCK_SIZE$1));
			this._updateBlock(swap8IfBE(ZEROS32[0]), swap8IfBE(ZEROS32[1]), swap8IfBE(ZEROS32[2]), swap8IfBE(ZEROS32[3]));
			clean(ZEROS32);
		}
		return this;
	}
	destroy() {
		this.destroyed = true;
		const { t } = this;
		for (const elm of t) elm.s0 = 0, elm.s1 = 0, elm.s2 = 0, elm.s3 = 0;
	}
	digestInto(out) {
		aexists(this);
		aoutput32(out, this);
		this.finished = true;
		const { s0, s1, s2, s3 } = this;
		const o32 = u32(out);
		o32[0] = s0;
		o32[1] = s1;
		o32[2] = s2;
		o32[3] = s3;
		if (!isLE) swap32IfBE(o32.subarray(0, BLOCK_SIZE$1 / 4));
	}
	digest() {
		const res = new Uint8Array(BLOCK_SIZE$1);
		this.digestInto(res);
		this.destroy();
		return res;
	}
};
/**
* GHash MAC for AES-GCM.
* @param msg - Message bytes to authenticate.
* @param key - 16-byte GHASH key.
* @returns 16-byte authentication tag.
* @example
* Authenticates a short message with GHASH and a fresh hash key.
*
* ```ts
* import { ghash } from '@noble/ciphers/_polyval.js';
* import { randomBytes } from '@noble/ciphers/utils.js';
* const key = randomBytes(16);
* ghash(new Uint8Array(), key);
* ```
*/
const ghash = /* @__PURE__ */ wrapMacConstructor(16, (key, expectedLength) => new GHASH(key, expectedLength), (msg) => [msg.length]);
//#endregion
//#region node_modules/.pnpm/@noble+ciphers@2.3.0/node_modules/@noble/ciphers/aes.js
/**
* {@link https://en.wikipedia.org/wiki/Advanced_Encryption_Standard | AES}
* a.k.a. Advanced Encryption Standard
* is a variant of Rijndael block cipher, standardized by NIST in 2001.
* We provide the fastest available pure JS implementation.
*
* `cipher = encrypt(block, key)`
*
* Data is split into 128-bit blocks.
* Encrypted in 10/12/14 rounds (128/192/256 bits). In every round:
* 1. **S-box**, table substitution
* 2. **Shift rows**, cyclic shift left of all rows of data array
* 3. **Mix columns**, multiplying every column by fixed polynomial
* 4. **Add round key**, round_key xor i-th column of array
*
* Check out
* {@link https://csrc.nist.gov/files/pubs/fips/197/final/docs/fips-197.pdf | FIPS-197},
* {@link https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38G.pdf | NIST 800-38G},
* and {@link https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/aes-development/rijndael-ammended.pdf | original proposal}.
* @module
*/
const BLOCK_SIZE = 16;
const BLOCK_SIZE32 = 4;
const EMPTY_BLOCK = /* @__PURE__ */ new Uint8Array(BLOCK_SIZE);
const POLY = 283;
function validateKeyLength(key) {
	if (![
		16,
		24,
		32
	].includes(key.length)) throw new Error("\"aes key\" expected Uint8Array of length 16/24/32, got length=" + key.length);
}
function mul2(n) {
	return n << 1 ^ POLY & -(n >> 7);
}
function mul(a, b) {
	let res = 0;
	for (; b > 0; b >>= 1) {
		res ^= a & -(b & 1);
		a = mul2(a);
	}
	return res;
}
const sbox = /* @__PURE__ */ (() => {
	const t = /* @__PURE__ */ new Uint8Array(256);
	for (let i = 0, x = 1; i < 256; i++, x ^= mul2(x)) t[i] = x;
	const box = /* @__PURE__ */ new Uint8Array(256);
	box[0] = 99;
	for (let i = 0; i < 255; i++) {
		let x = t[255 - i];
		x |= x << 8;
		box[t[i]] = (x ^ x >> 4 ^ x >> 5 ^ x >> 6 ^ x >> 7 ^ 99) & 255;
	}
	clean(t);
	return box;
})();
const rotr32_8 = (n) => n << 24 | n >>> 8;
const rotl32_8 = (n) => n << 8 | n >>> 24;
function genTtable(sbox, fn) {
	if (sbox.length !== 256) throw new Error("wrong sbox length");
	const T0 = (/* @__PURE__ */ new Uint32Array(256)).map((_, j) => fn(sbox[j]));
	const T1 = T0.map(rotl32_8);
	const T2 = T1.map(rotl32_8);
	const T3 = T2.map(rotl32_8);
	const T01 = /* @__PURE__ */ new Uint32Array(65536);
	const T23 = /* @__PURE__ */ new Uint32Array(65536);
	const sbox2 = /* @__PURE__ */ new Uint16Array(65536);
	for (let i = 0; i < 256; i++) for (let j = 0; j < 256; j++) {
		const idx = i * 256 + j;
		T01[idx] = T0[i] ^ T1[j];
		T23[idx] = T2[i] ^ T3[j];
		sbox2[idx] = sbox[i] << 8 | sbox[j];
	}
	return {
		sbox,
		sbox2,
		T0,
		T1,
		T2,
		T3,
		T01,
		T23
	};
}
const tableEncoding = /* @__PURE__ */ genTtable(sbox, (s) => mul(s, 3) << 24 | s << 16 | s << 8 | mul(s, 2));
const xPowers = /* @__PURE__ */ (() => {
	const p = /* @__PURE__ */ new Uint8Array(16);
	for (let i = 0, x = 1; i < 16; i++, x = mul2(x)) p[i] = x;
	return p;
})();
/** Forward AES key expansion used across ECB/CBC/CTR/GCM/CMAC/KW-style paths. */
function expandKeyLE(key) {
	abytes$1(key);
	const len = key.length;
	validateKeyLength(key);
	const { sbox2 } = tableEncoding;
	const toClean = [];
	if (!isLE || !isAligned32(key)) toClean.push(key = copyBytes$1(key));
	const k32 = swap32IfBE(u32(key));
	const Nk = k32.length;
	const subByte = (n) => applySbox(sbox2, n, n, n, n);
	const xk = new Uint32Array(len + 28);
	xk.set(k32);
	for (let i = Nk; i < xk.length; i++) {
		let t = xk[i - 1];
		if (i % Nk === 0) t = subByte(rotr32_8(t)) ^ xPowers[i / Nk - 1];
		else if (Nk > 6 && i % Nk === 4) t = subByte(t);
		xk[i] = xk[i - Nk] ^ t;
	}
	clean(...toClean);
	return xk;
}
function apply0123(T01, T23, s0, s1, s2, s3) {
	return T01[s0 << 8 & 65280 | s1 >>> 8 & 255] ^ T23[s2 >>> 8 & 65280 | s3 >>> 24 & 255];
}
function applySbox(sbox2, s0, s1, s2, s3) {
	return sbox2[s0 & 255 | s1 & 65280] | sbox2[s2 >>> 16 & 255 | s3 >>> 16 & 65280] << 16;
}
function encrypt(xk, s0, s1, s2, s3) {
	const { sbox2, T01, T23 } = tableEncoding;
	let k = 0;
	s0 ^= xk[k++], s1 ^= xk[k++], s2 ^= xk[k++], s3 ^= xk[k++];
	const rounds = xk.length / 4 - 2;
	for (let i = 0; i < rounds; i++) {
		const t0 = xk[k++] ^ apply0123(T01, T23, s0, s1, s2, s3);
		const t1 = xk[k++] ^ apply0123(T01, T23, s1, s2, s3, s0);
		const t2 = xk[k++] ^ apply0123(T01, T23, s2, s3, s0, s1);
		const t3 = xk[k++] ^ apply0123(T01, T23, s3, s0, s1, s2);
		s0 = t0, s1 = t1, s2 = t2, s3 = t3;
	}
	return {
		s0: xk[k++] ^ applySbox(sbox2, s0, s1, s2, s3),
		s1: xk[k++] ^ applySbox(sbox2, s1, s2, s3, s0),
		s2: xk[k++] ^ applySbox(sbox2, s2, s3, s0, s1),
		s3: xk[k++] ^ applySbox(sbox2, s3, s0, s1, s2)
	};
}
function ctr32(xk, isLE, nonce, src, dst) {
	abytes$1(nonce, BLOCK_SIZE, "nonce");
	abytes$1(src);
	dst = getOutput(src.length, dst);
	const ctr = nonce;
	const c32 = u32(ctr);
	const view = createView(ctr);
	const src32 = u32(src);
	const dst32 = u32(dst);
	const ctrPos = isLE ? 0 : 12;
	const srcLen = src.length;
	let ctrNum = view.getUint32(ctrPos, isLE);
	for (let i = 0; i + 4 <= src32.length; i += 4) {
		const { s0, s1, s2, s3 } = encrypt(xk, swap8IfBE(c32[0]), swap8IfBE(c32[1]), swap8IfBE(c32[2]), swap8IfBE(c32[3]));
		dst32[i + 0] = src32[i + 0] ^ swap8IfBE(s0);
		dst32[i + 1] = src32[i + 1] ^ swap8IfBE(s1);
		dst32[i + 2] = src32[i + 2] ^ swap8IfBE(s2);
		dst32[i + 3] = src32[i + 3] ^ swap8IfBE(s3);
		ctrNum = ctrNum + 1 >>> 0;
		view.setUint32(ctrPos, ctrNum, isLE);
	}
	const start = BLOCK_SIZE * Math.floor(src32.length / BLOCK_SIZE32);
	if (start < srcLen) {
		const { s0, s1, s2, s3 } = encrypt(xk, swap8IfBE(c32[0]), swap8IfBE(c32[1]), swap8IfBE(c32[2]), swap8IfBE(c32[3]));
		const b32 = new Uint32Array([
			s0,
			s1,
			s2,
			s3
		]);
		swap32IfBE(b32);
		const buf = u8(b32);
		for (let i = start, pos = 0; i < srcLen; i++, pos++) dst[i] = src[i] ^ buf[pos];
		clean(b32);
	}
	return dst;
}
function computeTag(fn, isLE, key, data, AAD) {
	const aadLength = AAD ? AAD.length : 0;
	const h = fn.create(key, data.length + aadLength);
	if (AAD) h.update(AAD);
	const num = u64Lengths(8 * data.length, 8 * aadLength, isLE);
	h.update(data);
	h.update(num);
	const res = h.digest();
	clean(num);
	return res;
}
/**
* **GCM** (Galois/Counter Mode): Combines CTR mode with polynomial MAC. Efficient and widely used.
* Not perfect:
* a) conservative key wear-out is `2**32` (4B) msgs.
* b) key wear-out under random nonces is even smaller: `2**23` (8M) messages for `2**-50` chance.
* c) MAC can be forged: see Poly1305 documentation.
* @param key - AES key bytes.
* @param nonce - Nonce bytes (12 recommended, minimum 8; other lengths use GHASH J0 derivation).
* @param AAD - Additional authenticated data.
* @returns AEAD cipher instance with a fixed 16-byte tag.
* @example
* Encrypts and authenticates plaintext with a fresh key and 12-byte nonce.
*
* ```ts
* import { gcm } from '@noble/ciphers/aes.js';
* import { randomBytes } from '@noble/ciphers/utils.js';
* const key = randomBytes(16);
* const nonce = randomBytes(12);
* const aad = new TextEncoder().encode('session metadata');
* const cipher = gcm(key, nonce, aad);
* cipher.encrypt(new Uint8Array([1, 2, 3]));
* ```
*/
const gcm = /* @__PURE__ */ wrapCipher({
	blockSize: 16,
	nonceLength: 12,
	tagLength: 16,
	withAAD: true,
	varSizeNonce: true
}, function aesgcm(key, nonce, AAD) {
	if (nonce.length < 8) throw new Error("aes/gcm: invalid nonce length");
	const tagLength = 16;
	function _computeTag(authKey, tagMask, data) {
		const tag = computeTag(ghash, false, authKey, data, AAD);
		for (let i = 0; i < tagMask.length; i++) tag[i] ^= tagMask[i];
		return tag;
	}
	function deriveKeys() {
		const xk = expandKeyLE(key);
		const authKey = EMPTY_BLOCK.slice();
		const counter = EMPTY_BLOCK.slice();
		ctr32(xk, false, counter, counter, authKey);
		if (nonce.length === 12) counter.set(nonce);
		else {
			const nonceLen = EMPTY_BLOCK.slice();
			createView(nonceLen).setBigUint64(8, BigInt(nonce.length * 8), false);
			const g = ghash.create(authKey).update(nonce).update(nonceLen);
			g.digestInto(counter);
			g.destroy();
		}
		return {
			xk,
			authKey,
			counter,
			tagMask: ctr32(xk, false, counter, EMPTY_BLOCK)
		};
	}
	return {
		encrypt(plaintext) {
			const { xk, authKey, counter, tagMask } = deriveKeys();
			const out = new Uint8Array(plaintext.length + tagLength);
			const toClean = [
				xk,
				authKey,
				counter,
				tagMask
			];
			if (!isAligned32(plaintext)) toClean.push(plaintext = copyBytes$1(plaintext));
			ctr32(xk, false, counter, plaintext, out.subarray(0, plaintext.length));
			const tag = _computeTag(authKey, tagMask, out.subarray(0, out.length - tagLength));
			toClean.push(tag);
			out.set(tag, plaintext.length);
			clean(...toClean);
			return out;
		},
		decrypt(ciphertext) {
			const { xk, authKey, counter, tagMask } = deriveKeys();
			const toClean = [
				xk,
				authKey,
				tagMask,
				counter
			];
			if (!isAligned32(ciphertext)) toClean.push(ciphertext = copyBytes$1(ciphertext));
			const data = ciphertext.subarray(0, -16);
			const passedTag = ciphertext.subarray(-16);
			const tag = _computeTag(authKey, tagMask, data);
			toClean.push(tag);
			if (!equalBytes(tag, passedTag)) {
				clean(...toClean);
				throw new Error("aes-gcm: invalid tag");
			}
			const out = ctr32(xk, false, counter, data);
			clean(...toClean);
			return out;
		}
	};
});
//#endregion
//#region node_modules/.pnpm/@noble+curves@2.3.0/node_modules/@noble/curves/utils.js
/**
* Hex, bytes and number utilities.
* @module
*/
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
/**
* Validates that a value is an array, optionally validating each element.
* @param item - Value to validate.
* @param title - Label included in thrown errors.
* @param inner - Optional per-element validator, called with the element and its label.
* @returns The validated array.
* @example
* Validate an array of points before batch processing.
*
* ```ts
* aarray([1n, 2n], 'scalars');
* ```
*/
function aarray(item, title, inner = () => {}) {
	if (!Array.isArray(item)) throw new TypeError(`"${title}" expected array, got type=${typeof item}`);
	for (let i = 0; i < item.length; i++) inner(item[i], `${title}[${i}]`);
	return item;
}
/**
* Validates that a value is a byte array.
* @param value - Value to validate.
* @param length - Optional exact byte length.
* @param title - Optional field name.
* @returns Original byte array.
* @example
* Reject non-byte input before passing data into curve code.
*
* ```ts
* abytes(new Uint8Array(1));
* ```
*/
const abytes = (value, length, title) => abytes$2(value, length, title);
/**
* Validates that a value is a non-negative safe integer.
* @param n - Value to validate.
* @param title - Optional field name.
* @returns The validated number.
* @example
* Validate a numeric length before allocating buffers.
*
* ```ts
* anumber(1);
* ```
*/
const anumber = anumber$1;
/**
* Asserts something is a plain object-ish value, not null or array.
* @param value - Value to validate.
* @param title - Label included in thrown errors.
* @returns The validated object.
* @throws On wrong argument types. {@link TypeError}
* @example
* Validate an options object before checking fields.
*
* ```ts
* aobject({ flag: true });
* ```
*/
function aobject(value, title = "object") {
	if (value === null || typeof value !== "object" || Array.isArray(value)) throw new TypeError(title === "object" ? "expected valid options object" : `"${title}" expected object, got type=${typeof value}`);
	return value;
}
/**
* Asserts something is a function.
* @param value - Value to validate.
* @param title - Label included in thrown errors.
* @returns The validated function.
* @throws On wrong argument types. {@link TypeError}
* @example
* Validate a required method before calling it.
*
* ```ts
* afunction(() => true, 'predicate');
* ```
*/
function afunction(value, title) {
	if (typeof value !== "function") throw new TypeError(`"${title}" is invalid: expected function, got ${typeof value}`);
	return value;
}
/**
* Encodes bytes as lowercase hex.
* @param bytes - Bytes to encode.
* @returns Lowercase hex string.
* @example
* Serialize bytes as hex for logging or fixtures.
*
* ```ts
* bytesToHex(Uint8Array.of(1, 2, 3));
* ```
*/
const bytesToHex = bytesToHex$1;
/**
* Concatenates byte arrays.
* @param arrays - Byte arrays to join.
* @returns Concatenated bytes.
* @example
* Join domain-separated chunks into one buffer.
*
* ```ts
* concatBytes(Uint8Array.of(1), Uint8Array.of(2));
* ```
*/
const concatBytes = (...arrays) => concatBytes$1(...arrays);
/**
* Decodes lowercase or uppercase hex into bytes.
* @param hex - Hex string to decode.
* @returns Decoded bytes.
* @example
* Parse fixture hex into bytes before hashing.
*
* ```ts
* hexToBytes('0102');
* ```
*/
const hexToBytes = (hex) => hexToBytes$1(hex);
/**
* Checks whether a value is a Uint8Array.
* @param a - Value to inspect.
* @returns `true` when `a` is a Uint8Array.
* @example
* Branch on byte input before decoding it.
*
* ```ts
* isBytes(new Uint8Array(1));
* ```
*/
const isBytes = isBytes$1;
/**
* Reads random bytes from the platform CSPRNG.
* @param bytesLength - Number of random bytes to read.
* @returns Fresh random bytes.
* @example
* Generate a random seed for a keypair.
*
* ```ts
* randomBytes(2);
* ```
*/
const randomBytes$1 = (bytesLength) => randomBytes$2(bytesLength);
const _0n$5 = /* @__PURE__ */ BigInt(0);
const _1n$5 = /* @__PURE__ */ BigInt(1);
const atitle = (title) => title ? `"${title}" ` : "";
/**
* Validates that a flag is boolean.
* @param value - Value to validate.
* @param title - Optional field name.
* @returns Original value.
* @throws On wrong argument types. {@link TypeError}
* @example
* Reject non-boolean option flags early.
*
* ```ts
* abool(true);
* ```
*/
function abool(value, title = "") {
	if (typeof value !== "boolean") throw new TypeError(atitle(title) + "expected boolean, got type=" + typeof value);
	return value;
}
/**
* Validates that a value is a non-negative bigint or safe integer.
* @param n - Value to validate.
* @returns The same validated value.
* @throws On wrong argument ranges or values. {@link RangeError}
* @example
* Validate one integer-like value before serializing it.
*
* ```ts
* abignumber(1n);
* ```
*/
function abignumber(n) {
	if (typeof n === "bigint") {
		if (!isPosBig(n)) throw new RangeError("positive bigint expected, got " + n);
	} else anumber(n);
	return n;
}
/**
* Validates that a value is a safe integer.
* @param value - Integer to validate.
* @param title - Optional field name.
* @throws On wrong argument types. {@link TypeError}
* @throws On wrong argument ranges or values. {@link RangeError}
* @example
* Validate a window size before scalar arithmetic uses it.
*
* ```ts
* asafenumber(1);
* ```
*/
function asafenumber(value, title = "") {
	if (typeof value !== "number") {
		const prefix = title && `"${title}" `;
		throw new TypeError(prefix + "expected number, got type=" + typeof value);
	}
	if (!Number.isSafeInteger(value)) {
		const prefix = title && `"${title}" `;
		throw new RangeError(prefix + "expected safe integer, got " + value);
	}
}
/**
* Parses a big-endian hex string into bigint.
* Accepts odd-length hex through the native `BigInt('0x' + hex)` parser and currently surfaces the
* same native `SyntaxError` for malformed hex instead of wrapping it in a library-specific error.
* @param hex - Hex string without `0x`.
* @returns Parsed bigint value.
* @throws On wrong argument types. {@link TypeError}
* @example
* Parse a scalar from fixture hex.
*
* ```ts
* hexToNumber('ff');
* ```
*/
function hexToNumber(hex) {
	if (typeof hex !== "string") throw new TypeError("hex string expected, got " + typeof hex);
	return hex === "" ? _0n$5 : BigInt("0x" + hex);
}
/**
* Parses big-endian bytes into bigint.
* @param bytes - Bytes in big-endian order.
* @returns Parsed bigint value.
* @throws On wrong argument types. {@link TypeError}
* @example
* Read a scalar encoded in network byte order.
*
* ```ts
* bytesToNumberBE(Uint8Array.of(1, 0));
* ```
*/
function bytesToNumberBE(bytes) {
	return hexToNumber(bytesToHex$1(bytes));
}
/**
* Parses little-endian bytes into bigint.
* @param bytes - Bytes in little-endian order.
* @returns Parsed bigint value.
* @throws On wrong argument types. {@link TypeError}
* @example
* Read a scalar encoded in little-endian form.
*
* ```ts
* bytesToNumberLE(Uint8Array.of(1, 0));
* ```
*/
function bytesToNumberLE(bytes) {
	return hexToNumber(bytesToHex$1(copyBytes(abytes$2(bytes)).reverse()));
}
/**
* Encodes a bigint into fixed-length big-endian bytes.
* @param n - Number to encode.
* @param len - Output length in bytes. Must be greater than zero.
* @returns Big-endian byte array.
* @throws On wrong argument ranges or values. {@link RangeError}
* @throws If a documented runtime validation or state check fails. {@link Error}
* @example
* Serialize a scalar into a 32-byte field element.
*
* ```ts
* numberToBytesBE(255n, 2);
* ```
*/
function numberToBytesBE(n, len) {
	anumber$1(len);
	if (len === 0) throw new Error("zero output length is invalid");
	n = abignumber(n);
	const expectedLen = len * 2;
	const hex = n.toString(16);
	if (hex.length > expectedLen) throw new RangeError("number is too large");
	return hexToBytes$1(hex.padStart(expectedLen, "0"));
}
/**
* Encodes a bigint into fixed-length little-endian bytes.
* @param n - Number to encode.
* @param len - Output length in bytes.
* @returns Little-endian byte array.
* @throws On wrong argument ranges or values. {@link RangeError}
* @throws If a documented runtime validation or state check fails. {@link Error}
* @example
* Serialize a scalar for little-endian protocols.
*
* ```ts
* numberToBytesLE(255n, 2);
* ```
*/
function numberToBytesLE(n, len) {
	return numberToBytesBE(n, len).reverse();
}
/**
* Copies Uint8Array. We can't use u8a.slice(), because u8a can be Buffer,
* and Buffer#slice creates mutable copy. Never use Buffers!
* @param bytes - Bytes to copy.
* @returns Detached copy.
* @example
* Make an isolated copy before mutating serialized bytes.
*
* ```ts
* copyBytes(Uint8Array.of(1, 2, 3));
* ```
*/
function copyBytes(bytes) {
	return Uint8Array.from(abytes(bytes));
}
/**
* Checks whether n is non-negative bigint. Historical name.
* @param n - candidate value
* @returns `true` when the value is bigint and 0 or larger
* @example
* Check a candidate scalar before range validation.
*
* ```ts
* isPosBig(2n);
* ```
*/
function isPosBig(n) {
	return typeof n === "bigint" && _0n$5 <= n;
}
/**
* Checks whether a bigint lies inside a half-open range.
* @param n - Candidate value.
* @param min - Inclusive lower bound.
* @param max - Exclusive upper bound.
* @returns `true` when the value is inside the range.
* @example
* Check whether a candidate scalar fits the field order.
*
* ```ts
* inRange(2n, 1n, 3n);
* ```
*/
function inRange(n, min, max) {
	return isPosBig(n) && isPosBig(min) && isPosBig(max) && min <= n && n < max;
}
/**
* Asserts `min <= n < max`. NOTE: upper bound is exclusive.
* @param title - Value label for error messages.
* @param n - Candidate value.
* @param min - Inclusive lower bound.
* @param max - Exclusive upper bound.
* Wrong-type inputs are not separated from out-of-range values here: they still flow through the
* shared `RangeError` path because this is only a throwing wrapper around `inRange(...)`.
* @throws On wrong argument ranges or values. {@link RangeError}
* @example
* Assert that a bigint stays within one half-open range.
*
* ```ts
* aInRange('x', 2n, 1n, 256n);
* ```
*/
function aInRange(title, n, min, max) {
	if (!inRange(n, min, max)) throw new RangeError("expected valid " + title + ": " + min + " <= n < " + max + ", got " + n);
}
/**
* Calculates amount of bits in a bigint.
* Same as `n.toString(2).length`
* TODO: merge with nLength in modular
* @param n - Value to inspect.
* @returns Bit length.
* @throws If the value is negative. {@link Error}
* @example
* Measure the bit length of a scalar before serialization.
*
* ```ts
* bitLen(8n);
* ```
*/
function bitLen(n) {
	if (n < _0n$5) throw new Error("expected non-negative bigint, got " + n);
	return n === _0n$5 ? 0 : n.toString(2).length;
}
/**
* Calculate mask for N bits. Not using ** operator with bigints because of old engines.
* Same as BigInt(`0b${Array(i).fill('1').join('')}`)
* @param n - Number of bits. Negative widths are currently passed through to raw bigint shift
*   semantics and therefore produce `-1n`.
* @returns Bitmask value.
* @example
* Calculate mask for N bits.
*
* ```ts
* bitMask(4);
* ```
*/
const bitMask = (n) => {
	asafenumber(n, "n");
	return (_1n$5 << BigInt(n)) - _1n$5;
};
/**
* Validates declared required and optional field types on a plain object.
* Extra keys are intentionally ignored because many callers validate only the subset they use from
* richer option bags or runtime objects.
* This walks field schemas and formats detailed errors, so avoid it on hot paths; use direct
* one-line guards such as `aobject()`, `afunction()`, `abool()`, or `asafenumber()` instead.
* @param object - Object to validate.
* @param fields - Required field types.
* @param optFields - Optional field types.
* @param title - Object label included in thrown errors.
* @throws On wrong argument types. {@link TypeError}
* @example
* Check user options before building a curve helper.
*
* ```ts
* validateObject({ flag: true }, { flag: 'boolean' });
* ```
*/
function validateObject(object, fields = {}, optFields = {}, title = "object") {
	aobject(object, title);
	aobject(fields, "fields");
	aobject(optFields, "optFields");
	function checkField(fieldName, expectedType, isOpt) {
		const label = title === "object" ? `param "${String(fieldName)}"` : `"${title}.${String(fieldName)}"`;
		const val = object[fieldName];
		if (!Object.hasOwn(object, fieldName) && (isOpt ? val !== void 0 : expectedType !== "function")) throw new TypeError(`${label} is invalid: expected own property`);
		if (isOpt && val === void 0) return;
		const current = typeof val;
		if (current !== expectedType || val === null) throw new TypeError(`${label} is invalid: expected ${expectedType}, got ${current}`);
	}
	const iter = (f, isOpt) => Object.entries(f).forEach(([k, v]) => checkField(k, v, isOpt));
	iter(fields, false);
	iter(optFields, true);
}
//#endregion
//#region node_modules/.pnpm/@noble+curves@2.3.0/node_modules/@noble/curves/abstract/modular.js
/**
* Utils for modular division and fields.
* Field over 11 is a finite (Galois) field is integer number operations `mod 11`.
* There is no division: it is replaced by modular multiplicative inverse.
* @module
*/
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
const _0n$4 = /* @__PURE__ */ BigInt(0);
const _1n$4 = /* @__PURE__ */ BigInt(1);
const _2n$3 = /* @__PURE__ */ BigInt(2);
const _3n$1 = /* @__PURE__ */ BigInt(3);
const _4n$2 = /* @__PURE__ */ BigInt(4);
const _5n$1 = /* @__PURE__ */ BigInt(5);
const _7n = /* @__PURE__ */ BigInt(7);
const _8n$2 = /* @__PURE__ */ BigInt(8);
const _9n = /* @__PURE__ */ BigInt(9);
const _15n = /* @__PURE__ */ BigInt(15);
const _16n = /* @__PURE__ */ BigInt(16);
const POW_WINDOWED_MIN = /* @__PURE__ */ BigInt("0x10000000000000000");
/**
* @param a - Dividend value.
* @param b - Positive modulus.
* @returns Reduced value in `[0, b)` only when `b` is positive.
* @throws If the modulus is not positive. {@link Error}
* @example
* Normalize a bigint into one field residue.
*
* ```ts
* mod(-1n, 5n);
* ```
*/
function mod(a, b) {
	if (b <= _0n$4) throw new Error("mod: expected positive modulus, got " + b);
	const result = a % b;
	return result >= _0n$4 ? result : b + result;
}
/**
* Efficiently raise num to a power with modular reduction.
* Unsafe in some contexts: uses ladder, so can expose bigint bits.
* Low-level helper: callers that need canonical residues must pass a valid `num` for the chosen
* modulus instead of relying on the `power===0/1` fast paths to normalize it.
* @param num - Base value.
* @param power - Exponent value.
* @param modulo - Reduction modulus.
* @returns Modular exponentiation result.
* @throws If the modulus or exponent is invalid. {@link Error}
* @example
* Raise one bigint to a modular power.
*
* ```ts
* pow(2n, 6n, 11n) // 64n % 11n == 9n
* ```
*/
function pow(num, power, modulo) {
	if (modulo <= _1n$4) throw new Error("pow: expected modulus > 1, got " + modulo);
	if (typeof power !== "bigint") throw new TypeError("invalid exponent: expected bigint, got " + typeof power);
	if (power < _0n$4) throw new Error("invalid exponent, negatives unsupported");
	if (power === _0n$4) return _1n$4;
	if (power === _1n$4) return num;
	let d = num % modulo;
	if (d < _0n$4) d += modulo;
	if (power < POW_WINDOWED_MIN) {
		let p = _1n$4;
		while (power > _0n$4) {
			if (power & _1n$4) p = p * d % modulo;
			d = d * d % modulo;
			power >>= _1n$4;
		}
		return p;
	}
	const digits = [];
	while (power > _0n$4) {
		digits.push(Number(power & _15n));
		power >>= _4n$2;
	}
	const table = new Array(16);
	table[0] = _1n$4;
	table[1] = d;
	for (let i = 2; i < 16; i++) table[i] = table[i - 1] * d % modulo;
	let p = table[digits[digits.length - 1]];
	for (let w = digits.length - 2; w >= 0; w--) {
		p = p * p % modulo;
		p = p * p % modulo;
		p = p * p % modulo;
		p = p * p % modulo;
		const digit = digits[w];
		if (digit !== 0) p = p * table[digit] % modulo;
	}
	return p;
}
/**
* Does `x^(2^power)` mod p. `pow2(30, 4)` == `30^(2^4)`.
* Low-level helper: callers that need canonical residues must pass a valid `x` for the chosen
* modulus; the `power===0` fast path intentionally returns the input unchanged.
* @param x - Base value.
* @param power - Number of squarings.
* @param modulo - Reduction modulus.
* @returns Repeated-squaring result.
* @throws If the exponent is negative. {@link Error}
* @example
* Apply repeated squaring inside one field.
*
* ```ts
* pow2(3n, 2n, 11n);
* ```
*/
function pow2(x, power, modulo) {
	if (modulo <= _1n$4) throw new Error("pow2: expected modulus > 1, got " + modulo);
	if (power < _0n$4) throw new Error("pow2: expected non-negative exponent, got " + power);
	let res = x;
	while (power-- > _0n$4) {
		res *= res;
		res %= modulo;
	}
	return res;
}
/**
* Inverses number over modulo.
* Implemented using the {@link https://brilliant.org/wiki/extended-euclidean-algorithm/ | extended Euclidean algorithm}.
* @param number - Value to invert.
* @param modulo - Modulus greater than 1.
* @returns Multiplicative inverse.
* @throws If the modulus is invalid or the inverse does not exist. {@link Error}
* @example
* Compute one modular inverse with the extended Euclidean algorithm.
*
* ```ts
* invert(3n, 11n);
* ```
*/
function invert(number, modulo) {
	if (number === _0n$4) throw new Error("invert: expected non-zero number");
	if (modulo <= _1n$4) throw new Error("invert: expected modulus > 1, got " + modulo);
	let a = mod(number, modulo);
	let b = modulo;
	let x = _0n$4, u = _1n$4;
	while (a !== _0n$4) {
		const q = b / a;
		const r = b - a * q;
		const m = x - u * q;
		b = a, a = r, x = u, u = m;
	}
	if (b !== _1n$4) throw new Error("invert: does not exist");
	return mod(x, modulo);
}
function assertIsSquare(Fp, root, n) {
	const F = Fp;
	if (!F.eql(F.sqr(root), n)) throw new Error("Cannot find square root");
}
function aoddModulus(order, fnName) {
	if ((order & _1n$4) === _0n$4) throw new Error(fnName + ": expected odd modulus, got " + order);
}
function sqrt3mod4(Fp, n) {
	const F = Fp;
	const p1div4 = (F.ORDER + _1n$4) / _4n$2;
	const root = F.pow(n, p1div4);
	assertIsSquare(F, root, n);
	return root;
}
function sqrt5mod8(Fp, n) {
	const F = Fp;
	const p5div8 = (F.ORDER - _5n$1) / _8n$2;
	const n2 = F.mul(n, _2n$3);
	const v = F.pow(n2, p5div8);
	const nv = F.mul(n, v);
	const i = F.mul(F.mul(nv, _2n$3), v);
	const root = F.mul(nv, F.sub(i, F.ONE));
	assertIsSquare(F, root, n);
	return root;
}
function sqrt9mod16(P) {
	const Fp_ = Field(P);
	const tn = tonelliShanks(P);
	const c1 = tn(Fp_, Fp_.neg(Fp_.ONE));
	const c2 = tn(Fp_, c1);
	const c3 = tn(Fp_, Fp_.neg(c1));
	const c4 = (P + _7n) / _16n;
	return ((Fp, n) => {
		const F = Fp;
		let tv1 = F.pow(n, c4);
		let tv2 = F.mul(tv1, c1);
		const tv3 = F.mul(tv1, c2);
		const tv4 = F.mul(tv1, c3);
		const e1 = F.eql(F.sqr(tv2), n);
		const e2 = F.eql(F.sqr(tv3), n);
		tv1 = F.cmov(tv1, tv2, e1);
		tv2 = F.cmov(tv4, tv3, e2);
		const e3 = F.eql(F.sqr(tv2), n);
		const root = F.cmov(tv1, tv2, e3);
		assertIsSquare(F, root, n);
		return root;
	});
}
/**
* Tonelli-Shanks square root search algorithm.
* This implementation is variable-time: it searches data-dependently for the first non-residue `Z`
* and for the smallest `i` in the main loop, unlike RFC 9380 Appendix I.4's constant-time shape.
* 1. {@link https://eprint.iacr.org/2012/685.pdf | eprint 2012/685}, page 12
* 2. Square Roots from 1; 24, 51, 10 to Dan Shanks
* @param P - field order
* @returns function that takes field Fp (created from P) and number n
* @throws If the field is too small, non-prime, or the square root does not exist. {@link Error}
* @example
* Construct a square-root helper for primes that need Tonelli-Shanks.
*
* ```ts
* import { Field, tonelliShanks } from '@noble/curves/abstract/modular.js';
* const Fp = Field(17n);
* const sqrt = tonelliShanks(17n)(Fp, 4n);
* ```
*/
function tonelliShanks(P) {
	if (P < _3n$1) throw new Error("sqrt is not defined for small field");
	aoddModulus(P, "tonelliShanks");
	let Q = P - _1n$4;
	let S = 0;
	while (Q % _2n$3 === _0n$4) {
		Q /= _2n$3;
		S++;
	}
	let Z = _2n$3;
	const _Fp = Field(P);
	while (FpLegendre(_Fp, Z) === 1) if (Z++ > 1e3) throw new Error("Cannot find square root: probably non-prime P");
	if (S === 1) return sqrt3mod4;
	let cc = _Fp.pow(Z, Q);
	const Q1div2 = (Q + _1n$4) / _2n$3;
	return function tonelliSlow(Fp, n) {
		const F = Fp;
		if (F.is0(n)) return n;
		if (FpLegendre(F, n) !== 1) throw new Error("Cannot find square root");
		let M = S;
		let c = F.mul(F.ONE, cc);
		let t = F.pow(n, Q);
		let R = F.pow(n, Q1div2);
		while (!F.eql(t, F.ONE)) {
			if (F.is0(t)) throw new Error("Cannot find square root: probably non-prime P");
			let i = 1;
			let t_tmp = F.sqr(t);
			while (!F.eql(t_tmp, F.ONE)) {
				i++;
				t_tmp = F.sqr(t_tmp);
				if (i === M) throw new Error("Cannot find square root");
			}
			const exponent = _1n$4 << BigInt(M - i - 1);
			const b = F.pow(c, exponent);
			M = i;
			c = F.sqr(b);
			t = F.mul(t, c);
			R = F.mul(R, b);
		}
		return R;
	};
}
/**
* Square root for a finite field. Will try optimized versions first:
*
* 1. P ≡ 3 (mod 4)
* 2. P ≡ 5 (mod 8)
* 3. P ≡ 9 (mod 16)
* 4. Tonelli-Shanks algorithm
*
* Different algorithms can give different roots, it is up to user to decide which one they want.
* For example there is FpSqrtOdd/FpSqrtEven to choose a root by oddness
* (used for hash-to-curve).
* @param P - Field order.
* @returns Square-root helper. The generic fallback inherits Tonelli-Shanks' variable-time
*   behavior and this selector assumes prime-field-style integer moduli.
* @throws If the field is unsupported or the square root does not exist. {@link Error}
* @example
* Choose the square-root helper appropriate for one field modulus.
*
* ```ts
* import { Field, FpSqrt } from '@noble/curves/abstract/modular.js';
* const Fp = Field(17n);
* const sqrt = FpSqrt(17n)(Fp, 4n);
* ```
*/
function FpSqrt(P) {
	aoddModulus(P, "Fp.sqrt");
	if (P % _4n$2 === _3n$1) return sqrt3mod4;
	if (P % _8n$2 === _5n$1) return sqrt5mod8;
	if (P % _16n === _9n) return sqrt9mod16(P);
	return tonelliShanks(P);
}
/**
* @param num - Value to inspect.
* @param modulo - Field modulus.
* @returns `true` when the least-significant little-endian bit is set.
* @throws If the modulus is invalid for `mod(...)`. {@link Error}
* @example
* Inspect the low bit used by little-endian sign conventions.
*
* ```ts
* isNegativeLE(3n, 11n);
* ```
*/
const isNegativeLE = (num, modulo) => (mod(num, modulo) & _1n$4) === _1n$4;
const FIELD_FIELDS = [
	"create",
	"isValid",
	"is0",
	"neg",
	"inv",
	"sqrt",
	"sqr",
	"eql",
	"add",
	"sub",
	"mul",
	"pow",
	"div",
	"addN",
	"subN",
	"mulN",
	"sqrN"
];
/**
* @param field - Field implementation.
* @returns Validated field. This only checks the arithmetic subset needed by generic helpers; it
*   does not guarantee full runtime-method coverage for serialization, batching, `cmov`, or
*   field-specific extras beyond positive `BYTES` / `BITS`.
* @throws If the field shape or numeric metadata are invalid. {@link Error}
* @example
* Check that a field implementation exposes the operations curve code expects.
*
* ```ts
* import { Field, validateField } from '@noble/curves/abstract/modular.js';
* const Fp = validateField(Field(17n));
* ```
*/
function validateField(field) {
	aobject(field, "field");
	if (typeof field.ORDER !== "bigint") throw new TypeError("param \"ORDER\" is invalid: expected bigint, got " + typeof field.ORDER);
	asafenumber(field.BYTES, "BYTES");
	asafenumber(field.BITS, "BITS");
	for (const name of FIELD_FIELDS) afunction(field[name], "field." + name);
	if (field.BYTES < 1 || field.BITS < 1) throw new Error("invalid field: expected BYTES/BITS > 0");
	if (field.ORDER <= _1n$4) throw new Error("invalid field: expected ORDER > 1, got " + field.ORDER);
	return field;
}
function FpInvertBatch(Fp, nums, passZero = false) {
	validateField(Fp);
	aarray(nums, "nums");
	abool(passZero, "passZero");
	const F = Fp;
	const inverted = new Array(nums.length).fill(passZero ? F.ZERO : void 0);
	const multipliedAcc = nums.reduce((acc, num, i) => {
		if (F.is0(num)) return acc;
		inverted[i] = acc;
		return F.mul(acc, num);
	}, F.ONE);
	const invertedAcc = F.inv(multipliedAcc);
	nums.reduceRight((acc, num, i) => {
		if (F.is0(num)) return acc;
		inverted[i] = F.mul(acc, inverted[i]);
		return F.mul(acc, num);
	}, invertedAcc);
	return inverted;
}
/**
* Legendre symbol.
* Legendre constant is used to calculate Legendre symbol (a | p)
* which denotes the value of a^((p-1)/2) (mod p).
*
* * (a | p) ≡ 1    if a is a square (mod p), quadratic residue
* * (a | p) ≡ -1   if a is not a square (mod p), quadratic non residue
* * (a | p) ≡ 0    if a ≡ 0 (mod p)
* @param Fp - Field implementation.
* @param n - Value to inspect.
* @returns Legendre symbol.
* @throws If the powered value does not match a valid Legendre symbol. {@link Error}
* @example
* Compute the Legendre symbol of one field element.
*
* ```ts
* import { Field, FpLegendre } from '@noble/curves/abstract/modular.js';
* const Fp = Field(17n);
* const symbol = FpLegendre(Fp, 4n);
* ```
*/
function FpLegendre(Fp, n) {
	validateField(Fp);
	const F = Fp;
	aoddModulus(F.ORDER, "FpLegendre");
	const p1mod2 = (F.ORDER - _1n$4) / _2n$3;
	const powered = F.pow(n, p1mod2);
	const yes = F.eql(powered, F.ONE);
	const zero = F.eql(powered, F.ZERO);
	const no = F.eql(powered, F.neg(F.ONE));
	if (!yes && !zero && !no) throw new Error("invalid Legendre symbol result");
	return yes ? 1 : zero ? 0 : -1;
}
/**
* @param n - Curve order. Callers are expected to pass a positive order.
* @param nBitLength - Optional cached bit length. Callers are expected to pass a positive cached
*   value when overriding the derived bit length.
* @returns Byte and bit lengths.
* @throws If the order or cached bit length is invalid. {@link Error}
* @example
* Measure the encoding sizes needed for one modulus.
*
* ```ts
* nLength(255n);
* ```
*/
function nLength(n, nBitLength) {
	if (nBitLength !== void 0) anumber(nBitLength);
	if (n <= _0n$4) throw new Error("invalid n length: expected positive n, got " + n);
	if (nBitLength !== void 0 && nBitLength < 1) throw new Error("invalid n length: expected positive bit length, got " + nBitLength);
	const bits = bitLen(n);
	if (nBitLength !== void 0 && nBitLength < bits) throw new Error(`invalid n length: expected nBitLength (${nBitLength}) >= bitLen(n) (${bits})`);
	const _nBitLength = nBitLength !== void 0 ? nBitLength : bits;
	return {
		nBitLength: _nBitLength,
		nByteLength: Math.ceil(_nBitLength / 8)
	};
}
const FIELD_SQRT = /* @__PURE__ */ new WeakMap();
var _Field = class {
	ORDER;
	BITS;
	BYTES;
	isLE;
	ZERO = _0n$4;
	ONE = _1n$4;
	_lengths;
	_mod;
	constructor(ORDER, opts = {}) {
		if (ORDER <= _1n$4) throw new Error("invalid field: expected ORDER > 1, got " + ORDER);
		let _nbitLength = void 0;
		this.isLE = false;
		if (opts != null && typeof opts === "object") {
			if (typeof opts.BITS === "number") _nbitLength = opts.BITS;
			if (typeof opts.sqrt === "function") Object.defineProperty(this, "sqrt", {
				value: opts.sqrt,
				enumerable: true
			});
			if (typeof opts.isLE === "boolean") this.isLE = opts.isLE;
			if (opts.allowedLengths) this._lengths = Object.freeze(opts.allowedLengths.slice());
			if (typeof opts.modFromBytes === "boolean") this._mod = opts.modFromBytes;
		}
		const { nBitLength, nByteLength } = nLength(ORDER, _nbitLength);
		if (nByteLength > 2048) throw new Error("invalid field: expected ORDER of <= 2048 bytes");
		this.ORDER = ORDER;
		this.BITS = nBitLength;
		this.BYTES = nByteLength;
		Object.freeze(this);
	}
	create(num) {
		return mod(num, this.ORDER);
	}
	isValid(num) {
		if (typeof num !== "bigint") throw new TypeError("invalid field element: expected bigint, got " + typeof num);
		return _0n$4 <= num && num < this.ORDER;
	}
	is0(num) {
		return num === _0n$4;
	}
	isValidNot0(num) {
		return !this.is0(num) && this.isValid(num);
	}
	isOdd(num) {
		return (num & _1n$4) === _1n$4;
	}
	neg(num) {
		return mod(-num, this.ORDER);
	}
	eql(lhs, rhs) {
		return lhs === rhs;
	}
	sqr(num) {
		return mod(num * num, this.ORDER);
	}
	add(lhs, rhs) {
		return mod(lhs + rhs, this.ORDER);
	}
	sub(lhs, rhs) {
		return mod(lhs - rhs, this.ORDER);
	}
	mul(lhs, rhs) {
		return mod(lhs * rhs, this.ORDER);
	}
	pow(num, power) {
		return pow(num, power, this.ORDER);
	}
	div(lhs, rhs) {
		return mod(lhs * invert(rhs, this.ORDER), this.ORDER);
	}
	sqrN(num) {
		return num * num;
	}
	addN(lhs, rhs) {
		return lhs + rhs;
	}
	subN(lhs, rhs) {
		return lhs - rhs;
	}
	mulN(lhs, rhs) {
		return lhs * rhs;
	}
	inv(num) {
		return invert(num, this.ORDER);
	}
	sqrt(num) {
		let sqrt = FIELD_SQRT.get(this);
		if (!sqrt) FIELD_SQRT.set(this, sqrt = FpSqrt(this.ORDER));
		return sqrt(this, num);
	}
	toBytes(num) {
		return this.isLE ? numberToBytesLE(num, this.BYTES) : numberToBytesBE(num, this.BYTES);
	}
	fromBytes(bytes, skipValidation = false) {
		abytes(bytes);
		const { _lengths: allowedLengths, BYTES, isLE, ORDER, _mod: modFromBytes } = this;
		if (allowedLengths) {
			if (bytes.length < 1 || !allowedLengths.includes(bytes.length) || bytes.length > BYTES) throw new Error("Field.fromBytes: expected " + allowedLengths + " bytes, got " + bytes.length);
			const padded = new Uint8Array(BYTES);
			padded.set(bytes, isLE ? 0 : padded.length - bytes.length);
			bytes = padded;
		}
		if (bytes.length !== BYTES) throw new Error("Field.fromBytes: expected " + BYTES + " bytes, got " + bytes.length);
		let scalar = isLE ? bytesToNumberLE(bytes) : bytesToNumberBE(bytes);
		if (modFromBytes) scalar = mod(scalar, ORDER);
		if (!skipValidation) {
			if (!this.isValid(scalar)) throw new Error("invalid field element: outside of range 0..ORDER");
		}
		return scalar;
	}
	invertBatch(lst) {
		return FpInvertBatch(this, lst, true);
	}
	cmov(a, b, condition) {
		abool(condition, "condition");
		return condition ? b : a;
	}
};
/**
* Creates a finite field. Major performance optimizations:
* * 1. Denormalized operations like mulN instead of mul.
* * 2. Identical object shape: never add or remove keys.
* * 3. Frozen stable object shape; the lazy sqrt cache lives in a module-level `WeakMap`.
* Fragile: always run a benchmark on a change.
* Security note: operations and low-level serializers like `toBytes` don't check `isValid` for
* all elements for performance and protocol-flexibility reasons; callers are responsible for
* supplying valid elements when they need canonical field behavior.
* This is low-level code, please make sure you know what you're doing.
*
* Note about field properties:
* * CHARACTERISTIC p = prime number, number of elements in main subgroup.
* * ORDER q = similar to cofactor in curves, may be composite `q = p^m`.
*
* @param ORDER - field order, probably prime, or could be composite
* @param opts - Field options such as bit length or endianness. See {@link FieldOpts}.
* @returns Frozen field instance with a stable object shape. This wrapper forwards `opts` straight
*   into `_Field`, so it inherits `_Field`'s assumptions about cached sizes and `allowedLengths`.
* @example
* Construct one prime field with optional overrides.
*
* ```ts
* Field(11n);
* ```
*/
function Field(ORDER, opts = {}) {
	Object.freeze(_Field.prototype);
	return new _Field(ORDER, opts);
}
//#endregion
//#region node_modules/.pnpm/@noble+curves@2.3.0/node_modules/@noble/curves/abstract/curve.js
/**
* Methods for elliptic curve multiplication by scalars.
* Contains wNAF-based ScalarMultiplier, pippenger.
* @module
*/
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
const _0n$3 = /* @__PURE__ */ BigInt(0);
const _1n$3 = /* @__PURE__ */ BigInt(1);
const _4n$1 = /* @__PURE__ */ BigInt(4);
const BLIND_BYTES = 16;
const BLIND_BITS = 128;
const FW_WINDOW = 5;
const TABLE_BYTES_MAX = /* @__PURE__ */ (() => 2 ** 31)();
/**
* Validates the static surface of a point constructor.
* This is only a cheap sanity check for the constructor hooks and fields consumed by generic
* factories; it does not certify `BASE`/`ZERO` semantics or prove the curve implementation itself.
* @param Point - Runtime point constructor.
* @throws On missing constructor hooks or malformed field metadata. {@link TypeError}
* @example
* Check that one point constructor exposes the static hooks generic helpers need.
*
* ```ts
* import { ed25519 } from '@noble/curves/ed25519.js';
* import { validatePointCons } from '@noble/curves/abstract/curve.js';
* validatePointCons(ed25519.Point);
* ```
*/
function validatePointCons(Point) {
	const pc = Point;
	if (typeof pc !== "function") throw new TypeError("\"Point\" expected constructor, got type=" + typeof Point);
	afunction(pc.fromAffine, "Point.fromAffine");
	afunction(pc.fromBytes, "Point.fromBytes");
	afunction(pc.fromHex, "Point.fromHex");
	aobject(pc.BASE, "Point.BASE");
	aobject(pc.ZERO, "Point.ZERO");
	validateField(pc.Fp);
	validateField(pc.Fn);
}
/**
* Takes a bunch of Projective Points but executes only one
* inversion on all of them. Inversion is very slow operation,
* so this improves performance massively.
* Optimization: converts a list of projective points to a list of identical points with Z=1.
* Input points are left unchanged; the normalized points are returned as fresh instances.
* @param c - Point constructor.
* @param points - Projective points.
* @returns Fresh projective points reconstructed from normalized affine coordinates.
* @example
* Batch-normalize projective points with a single shared inversion.
*
* ```ts
* import { normalizeZ } from '@noble/curves/abstract/curve.js';
* import { p256 } from '@noble/curves/nist.js';
* const points = normalizeZ(p256.Point, [p256.Point.BASE, p256.Point.BASE.double()]);
* ```
*/
function normalizeZ(c, points) {
	validatePointCons(c);
	validateMSMPoints(points, c);
	const invertedZs = FpInvertBatch(c.Fp, points.map((p) => p.Z));
	return points.map((p, i) => c.fromAffine(p.toAffine(invertedZs[i])));
}
function validateW(W, bits, min = 1) {
	if (!Number.isSafeInteger(W) || W < min || W > bits) throw new Error("invalid window size, expected [" + min + ".." + bits + "], got W=" + W);
}
function validateTableBytes(numPoints, fpBytes) {
	const bytes = numPoints * (4 * fpBytes + 128);
	if (bytes > TABLE_BYTES_MAX) throw new Error("invalid window size: table would need ~" + Math.ceil(bytes / 2 ** 20) + " MiB, max " + TABLE_BYTES_MAX / 2 ** 20 + " MiB");
}
/**
* Probes an RNG once, at construction time: returns `undefined` when it is unavailable —
* throws or returns malformed bytes — so callers can downgrade to their unblinded /
* deterministic constant-time fallback. Blinding is defense-in-depth (DPA/template
* hardening), not a correctness or key-secrecy requirement, so availability-based
* downgrade is acceptable.
*
* The downgrade decision is deliberately static. After a successful probe the RNG becomes
* part of the trusted contract: later misbehavior must fail closed in per-call validation
* (throw), never downgrade — a dynamic fallback would let a tampered RNG silently strip
* blinding on demand. A probe can only ever classify broken environments, not adversarial
* RNGs: a stateful RNG can always behave while probed and misbehave later.
* @param randomBytes - RNG to probe, or `undefined` when the environment provides none.
* @param length - Byte length requested from the probe call.
* @returns The RNG when the probe produced `length` valid bytes; `undefined` otherwise.
* @example
* Probe an RNG once before enabling scalar blinding.
*
* ```ts
* import { probeRandomBytes } from '@noble/curves/abstract/curve.js';
* import { randomBytes } from '@noble/hashes/utils.js';
* const rng = probeRandomBytes(randomBytes, 16);
* ```
*/
function probeRandomBytes(randomBytes, length) {
	if (randomBytes === void 0) return void 0;
	afunction(randomBytes, "randomBytes");
	try {
		const probe = randomBytes(length);
		if (!isBytes(probe) || probe.length !== length) return void 0;
	} catch {
		return;
	}
	return randomBytes;
}
function validateMSMPoints(points, c) {
	aarray(points, "points");
	points.forEach((p, i) => {
		if (!(p instanceof c)) throw new Error("invalid point at index " + i);
	});
}
function validateMSMScalars(scalars, field, maxScalar) {
	if (!Array.isArray(scalars)) throw new Error("array of scalars expected");
	scalars.forEach((s, i) => {
		if (!(maxScalar === void 0 ? field.isValid(s) : isPosBig(s) && s < maxScalar)) throw new Error("invalid scalar at index " + i);
	});
}
const pointWindowSizes = /* @__PURE__ */ new WeakMap();
function getWindowSize(P) {
	return pointWindowSizes.get(P) || 1;
}
/** Table of odd multiples [1P, 3P, ..., (2⋅size−1)P]; width-W wNAF uses size = 2^(W−2). */
function oddMultiples(p, size) {
	const dbl = p.double();
	const t = [p];
	for (let j = 1; j < size; j++) t.push(t[j - 1].add(dbl));
	return t;
}
/**
* Width-W wNAF signed-digit recoding (W >= 2), LSB-first: digits are 0 or odd with
* |digit| < 2^(W−1); nonzero density ~1/(W+1) (a nonzero digit is followed by W−1 zeros).
*/
function wnafDigits(n, W) {
	const size = 2 ** W;
	const half = size / 2;
	const mask = BigInt(size - 1);
	const d = [];
	while (n > _0n$3) {
		let w = 0;
		if (n & _1n$3) {
			w = Number(n & mask);
			if (w >= half) w -= size;
			n -= BigInt(w);
		}
		d.push(w);
		n >>= _1n$3;
	}
	return d;
}
/**
* Fixed-position signed-window recoding for precomputed wNAF: `n = Σ digits[w]⋅2^(w⋅W)` with
* digits in `[−2^(W−1)+1, 2^(W−1)]`. Digit count is fixed by `windows` (callers reserve one
* extra window for the final carry), so recoding length does not depend on the scalar.
*/
function signedWindowDigits(n, W, windows) {
	const size = 2 ** W;
	const half = size / 2;
	const mask = BigInt(size - 1);
	const shiftBy = BigInt(W);
	const d = [];
	for (let w = 0; w < windows; w++) {
		let v = Number(n & mask);
		n >>= shiftBy;
		if (v > half) {
			v -= size;
			n += _1n$3;
		}
		d.push(v);
	}
	if (n !== _0n$3) throw new Error("invalid wnaf");
	return d;
}
/**
* Shared vartime walk over per-scalar wNAF digit streams: one doubling of a single shared
* accumulator per bit position of the longest recoding, one signed table addition per
* nonzero digit. `tables[i]` must hold the odd multiples of the i-th point.
*/
function wnafWalk(zero, tables, digits) {
	let max = 0;
	for (const d of digits) max = Math.max(max, d.length);
	let acc = zero;
	for (let bit = max - 1; bit >= 0; bit--) {
		if (bit !== max - 1) acc = acc.double();
		for (let i = 0; i < digits.length; i++) {
			const w = digits[i][bit];
			if (w) {
				const item = tables[i][Math.abs(w) - 1 >> 1];
				acc = acc.add(w < 0 ? item.negate() : item);
			}
		}
	}
	return acc;
}
/**
* Elliptic curve multiplication of Point by scalar.
* Routes between cached-table, fixed-window, and one-shot wNAF paths; entry points validate
* their own scalars (`mulCT`/`mulCTBlinded`: `1 <= s < Fn.ORDER`; `mulUnsafe`: up to the
* `Fn.ORDER^4` DoS cap via {@link mulAddUnsafe}).
* Table generation is expensive and happens on first call of `multiply()`
* (or eagerly via `precompute(W, false)`). By default, `BASE` point is precomputed.
*
* Cached algorithm is signed fixed-window wNAF:
* - table stores, for every window w, the multiples `[1..2^(W−1)]⋅2^(w⋅W)⋅P` — all doublings
*   are baked in, so a multiplication is exactly one table addition per window
* - window count is fixed (`ceil(bits/W) + 1`), so the point-operation count is scalar-independent
*   (basis of the constant-time path)
* - for a 256-bit curve and W=6: 44⋅32 = 1408 table points, 44 additions per multiply
* - secret scalars are additionally blinded (see {@link ScalarMultiplier.mulCTBlinded}), which
*   widens tables by 128 bits
* @param Point - Point constructor.
* @param randomBytes - RNG used for scalar blinding; required by the blinded secret path.
* @example
* Elliptic curve multiplication of Point by scalar.
*
* ```ts
* import { ScalarMultiplier } from '@noble/curves/abstract/curve.js';
* import { p256 } from '@noble/curves/nist.js';
* const mul = new ScalarMultiplier(p256.Point);
* ```
*/
var ScalarMultiplier = class {
	Point;
	BASE;
	ZERO;
	randomBytes;
	wnafPrecomputes = /* @__PURE__ */ new WeakMap();
	baseCanBeBlinded;
	bits;
	constructor(Point, randomBytes) {
		validatePointCons(Point);
		this.randomBytes = probeRandomBytes(randomBytes, BLIND_BYTES);
		this.Point = Point;
		this.BASE = Point.BASE;
		this.ZERO = Point.ZERO;
		this.bits = Point.Fn.BITS;
	}
	/**
	* Creates a signed fixed-window wNAF precomputation table: for every window w, the
	* multiples `[1..2^(W−1)]⋅2^(w⋅W)⋅P`, flattened. All doublings are baked into the table,
	* so cached multiplication is additions-only. `windows = ceil(bits/W) + 1`: the extra
	* window absorbs the final carry of signed-digit recoding.
	* For a 256-bit curve and W=6, the table is 44⋅32 = 1408 points.
	* @param point - Point instance
	* @param W - window size
	* @param bits - scalar bitlength the table must cover
	*/
	buildWnafTable(point, W, bits) {
		const windows = Math.ceil(bits / W) + 1;
		const half = 2 ** (W - 1);
		const comp = [];
		let base = point;
		for (let w = 0; w < windows; w++) {
			let acc = base;
			for (let i = 0; i < half; i++) {
				comp.push(acc);
				acc = acc.add(base);
			}
			base = comp[comp.length - 1].double();
		}
		return {
			W,
			bits,
			windows,
			comp
		};
	}
	/**
	* Implements ec multiplication using precomputed signed fixed-window wNAF tables.
	* Constant-time: fixed window count with one table addition per window — zero digits feed
	* the fake accumulator — and no doublings; the lookup scans the whole window slice.
	* Scalar bounds are validated by the public entry points ({@link ScalarMultiplier.mulCT},
	* {@link ScalarMultiplier.mulCTBlinded}, {@link ScalarMultiplier.mulUnsafe});
	* signedWindowDigits throws if `n` exceeds the table.
	* @returns real and fake (for const-time) points
	*/
	wnafCachedCT(precomputes, n) {
		const { W, windows, comp } = precomputes;
		const half = 2 ** (W - 1);
		const digits = signedWindowDigits(n, W, windows);
		let p = this.ZERO;
		let f = this.BASE;
		for (let w = 0; w < windows; w++) {
			const digit = digits[w];
			const start = w * half;
			const idx = Math.abs(digit) - 1;
			let sel = comp[start];
			for (let i = 1; i < half; i++) sel = i === idx ? comp[start + i] : sel;
			const neg = sel.negate();
			if (digit === 0) f = f.add(comp[start]);
			else p = p.add(digit < 0 ? neg : sel);
		}
		return {
			p,
			f
		};
	}
	getWnafPrecomputes(W, point, bits, transform) {
		let entries = this.wnafPrecomputes.get(point);
		let comp = entries?.find((entry) => entry.W === W && entry.bits === bits);
		if (!comp) {
			comp = this.buildWnafTable(point, W, bits);
			if (typeof transform === "function") comp = {
				...comp,
				comp: transform(comp.comp)
			};
			if (!entries) {
				entries = [];
				this.wnafPrecomputes.set(point, entries);
			}
			entries.push(comp);
		}
		return comp;
	}
	assertPoint(point) {
		if (!(point instanceof this.Point)) throw new TypeError("\"point\" expected Point instance, got type=" + typeof point);
	}
	validateMulInput(point, scalar) {
		this.assertPoint(point);
		if (!inRange(scalar, _1n$3, this.Point.Fn.ORDER)) throw new Error("invalid scalar");
	}
	runCT(point, n, bits, transform) {
		const W = getWindowSize(point);
		if (W === 1) return this.fixedWindowCT(point, n, bits);
		return this.wnafCachedCT(this.getWnafPrecomputes(W, point, bits, transform), n);
	}
	mulCT(point, scalar, transform) {
		this.validateMulInput(point, scalar);
		return this.runCT(point, scalar, this.bits, transform);
	}
	mulCTBlinded(point, scalar, transform) {
		this.validateMulInput(point, scalar);
		if (this.randomBytes === void 0) throw new Error("randomBytes is required for scalar blinding");
		const bits = this.Point.Fn.BITS + BLIND_BITS;
		const blind = this.randomBytes(BLIND_BYTES);
		if (!isBytes(blind) || blind.length !== BLIND_BYTES) throw new Error("randomBytes returned invalid byte array");
		blind[0] = blind[0] & 63 | 128;
		const n = scalar + bytesToNumberBE(blind) * this.Point.Fn.ORDER;
		return this.runCT(point, n, bits, transform);
	}
	/**
	* Constant-time multiplication `n*point` for an un-precomputed point, via a small fixed window.
	* A cached wNAF table only pays off when reused; a flat 2^FW_WINDOW table (`size-1` adds) is
	* far cheaper to build for a single use. The point-operation sequence is independent of `n`:
	* build the table, then per window exactly FW_WINDOW doublings, a data-oblivious scan over
	* every table entry, and one addition (adds the identity when the window digit is 0 — never
	* skipped).
	*
	* `n` must be `< 2^bits`. Assumes complete addition (adding the identity costs the same as any
	* add), which holds for the Weierstrass/Edwards point types used here. The table is left in
	* projective form (no normalizeZ): normalizing this small a table costs more than the
	* mixed-add savings it would buy for a single multiply.
	* @returns real point `p`; `f` duplicates it only to match {@link wnafCachedCT}'s return shape
	* (this path needs no fake accumulator — its op-count is already scalar-independent).
	*/
	fixedWindowCT(point, n, bits) {
		const W = FW_WINDOW;
		const size = 32;
		const mask = bitMask(W);
		const table = new Array(size);
		table[0] = this.ZERO;
		for (let i = 1; i < size; i++) table[i] = table[i - 1].add(point);
		const windows = Math.ceil(bits / W);
		let acc = this.ZERO;
		for (let window = windows - 1; window >= 0; window--) {
			if (window !== windows - 1) for (let d = 0; d < W; d++) acc = acc.double();
			const digit = Number(n >> BigInt(window * W) & mask);
			let sel = table[0];
			for (let i = 1; i < size; i++) sel = i === digit ? table[i] : sel;
			acc = acc.add(sel);
		}
		return {
			p: acc,
			f: acc
		};
	}
	shouldBlind(point, cofactor) {
		if (this.randomBytes === void 0) return false;
		if (cofactor === _1n$3) return true;
		if (point !== this.BASE) return false;
		if (this.baseCanBeBlinded === void 0) this.baseCanBeBlinded = this.mulUnsafe(this.BASE, this.Point.Fn.ORDER).is0();
		return this.baseCanBeBlinded;
	}
	mulSecret(point, scalar, cofactor, transform) {
		return this.shouldBlind(point, cofactor) ? this.mulCTBlinded(point, scalar, transform) : this.mulCT(point, scalar, transform);
	}
	mulUnsafe(point, scalar, transform) {
		this.assertPoint(point);
		if (!isPosBig(scalar)) throw new Error("invalid scalar");
		const W = getWindowSize(point);
		if (W === 1 || scalar >= this.Point.Fn.ORDER) return mulAddUnsafe(this.Point, [point], [scalar], true);
		const precomputes = this.getWnafPrecomputes(W, point, this.bits, transform);
		return this.wnafCachedCT(precomputes, scalar).p;
	}
	setWindowSize(point, W) {
		this.assertPoint(point);
		validateW(W, this.bits);
		validateTableBytes((Math.ceil((this.bits + BLIND_BITS) / W) + 1) * 2 ** (W - 1), this.Point.Fp.BYTES);
		pointWindowSizes.set(point, W);
		this.wnafPrecomputes.delete(point);
	}
	hasWindowSize(point) {
		return getWindowSize(point) !== 1;
	}
};
/**
* Combined multi-scalar multiplication `Σ scalars[i]⋅points[i]` via interleaved width-4 wNAF
* (Strauss–Shamir). Every input gets its own table of odd multiples `[1P, 3P, 5P, 7P]` and
* signed-digit recoding, but all walks share one doubling chain, so total cost is
* `~bits` doublings + `L⋅bits/5` additions instead of `L⋅bits` doublings for separate
* multiplications. Intended for the 2-4 point shapes of signature verification
* (`R = u1⋅G + u2⋅P`); use {@link pippenger} for larger batches.
*
* Not constant-time: only for public inputs. Scalars must satisfy `0 <= s < Fn.ORDER`;
* fold negative signs into the points before calling.
* @param c - Point constructor.
* @param points - Array of curve points.
* @param scalars - Array of non-negative scalars, same length as points.
* @param allowOversized - Replace the `s < Fn.ORDER` scalar check with a `Fn.ORDER^4` DoS cap.
*   Off by default. For scalars that must NOT be reduced mod ORDER: torsion checks
*   (`Fn.ORDER⋅P ≟ O`) and cofactor-clearing multiples. Walk length grows with `bitLen(s)`.
* @returns Combined multiplication result; identity for empty input.
* @throws If the point set or scalar set is invalid. {@link Error}
* @example
* Combined multi-scalar multiplication via Strauss–Shamir.
*
* ```ts
* import { mulAddUnsafe } from '@noble/curves/abstract/curve.js';
* import { p256 } from '@noble/curves/nist.js';
* const G = p256.Point.BASE;
* const R = mulAddUnsafe(p256.Point, [G, G.double()], [2n, 3n]); // 2⋅G + 3⋅(2⋅G)
* ```
*/
function mulAddUnsafe(c, points, scalars, allowOversized = false) {
	validatePointCons(c);
	validateMSMPoints(points, c);
	abool(allowOversized, "allowOversized");
	validateMSMScalars(scalars, c.Fn, allowOversized ? c.Fn.ORDER ** _4n$1 : void 0);
	if (points.length !== scalars.length) throw new Error("arrays of points and scalars must have equal length");
	const tables = points.map((p) => oddMultiples(p, 4));
	const digits = scalars.map((n) => wnafDigits(n, 4));
	return wnafWalk(c.ZERO, tables, digits);
}
function createField(order, field, isLE) {
	if (field) {
		if (field.ORDER !== order) throw new Error("Field.ORDER must match order: Fp == p, Fn == n");
		validateField(field);
		return field;
	} else return Field(order, { isLE });
}
/**
* Validates basic CURVE shape and field membership, then creates fields.
* This does not prove that the generator is on-curve, that subgroup/order data are consistent, or
* that the curve equation itself is otherwise sane.
* @param type - Curve family.
* @param CURVE - Curve parameters.
* @param curveOpts - Optional field overrides. See {@link FpFn}:
*   - `Fp` (optional): Optional base-field override.
*   - `Fn` (optional): Optional scalar-field override.
* @param FpFnLE - Whether field encoding is little-endian.
* @returns Frozen curve parameters and fields.
* @throws If the curve parameters or field overrides are invalid. {@link Error}
* @example
* Build curve fields from raw constants before constructing a curve instance.
*
* ```ts
* const curve = createCurveFields('weierstrass', {
*   p: 17n,
*   n: 19n,
*   h: 1n,
*   a: 2n,
*   b: 2n,
*   Gx: 5n,
*   Gy: 1n,
* });
* ```
*/
function createCurveFields(type, CURVE, curveOpts = {}, FpFnLE) {
	if (type !== "weierstrass" && type !== "edwards") throw new Error("expected curve type \"weierstrass\" or \"edwards\"");
	if (FpFnLE === void 0) FpFnLE = type === "edwards";
	if (!CURVE || typeof CURVE !== "object") throw new Error(`expected valid ${type} CURVE object`);
	validateObject(curveOpts);
	for (const p of [
		"p",
		"n",
		"h"
	]) {
		const val = CURVE[p];
		if (!(isPosBig(val) && val !== _0n$3)) throw new Error(`CURVE.${p} must be positive bigint`);
	}
	const Fp = createField(CURVE.p, curveOpts.Fp, FpFnLE);
	const Fn = createField(CURVE.n, curveOpts.Fn, FpFnLE);
	const params = [
		"Gx",
		"Gy",
		"a",
		type === "weierstrass" ? "b" : "d"
	];
	for (const p of params) if (!Fp.isValid(CURVE[p])) throw new Error(`CURVE.${p} must be valid field element of CURVE.Fp`);
	CURVE = Object.freeze(Object.assign({}, CURVE));
	return {
		CURVE,
		Fp,
		Fn
	};
}
/**
* @param randomSecretKey - Secret-key generator.
* @param getPublicKey - Public-key derivation helper.
* @returns Keypair generator.
* @example
* Build a `keygen()` helper from existing secret-key and public-key primitives.
*
* ```ts
* import { createKeygen } from '@noble/curves/abstract/curve.js';
* import { p256 } from '@noble/curves/nist.js';
* const keygen = createKeygen(p256.utils.randomSecretKey, p256.getPublicKey);
* const pair = keygen();
* ```
*/
function createKeygen(randomSecretKey, getPublicKey) {
	return function keygen(seed) {
		const secretKey = randomSecretKey(seed);
		return {
			secretKey,
			publicKey: getPublicKey(secretKey)
		};
	};
}
//#endregion
//#region node_modules/.pnpm/@noble+curves@2.3.0/node_modules/@noble/curves/abstract/edwards.js
/**
* Twisted Edwards curve. The formula is: ax² + y² = 1 + dx²y².
* For design rationale of types / exports, see weierstrass module documentation.
* Untwisted Edwards curves exist, but they aren't used in real-world protocols.
* @module
*/
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
const _0n$2 = /* @__PURE__ */ BigInt(0);
const _1n$2 = /* @__PURE__ */ BigInt(1);
const _2n$2 = /* @__PURE__ */ BigInt(2);
const _4n = /* @__PURE__ */ BigInt(4);
const _8n$1 = /* @__PURE__ */ BigInt(8);
function isEdValidXY(Fp, CURVE, x, y) {
	const x2 = Fp.sqr(x);
	const y2 = Fp.sqr(y);
	const left = Fp.add(Fp.mul(CURVE.a, x2), y2);
	const right = Fp.add(Fp.ONE, Fp.mul(CURVE.d, Fp.mul(x2, y2)));
	return Fp.eql(left, right);
}
/**
* @param params - Curve parameters. See {@link EdwardsOpts}.
* @param extraOpts - Optional helpers and overrides. See {@link EdwardsExtraOpts}.
* @returns Edwards point constructor. Generator validation here only checks
*   that `(Gx, Gy)` satisfies the affine Edwards equation.
*   RFC 8032 base-point constraints like `B != (0,1)` and `[L]B = 0`
*   are left to the caller's chosen parameters, since eager subgroup
*   validation here adds about 10-15ms to heavyweight imports like ed448.
*   The returned constructor also eagerly marks `Point.BASE` for W=6
*   precompute caching. Some code paths still assume
*   `Fp.BYTES === Fn.BYTES`, so mismatched byte lengths are not fully audited here.
* @throws If the curve parameters or Edwards overrides are invalid. {@link Error}
* @example
* ```ts
* import { edwards } from '@noble/curves/abstract/edwards.js';
* import { jubjub } from '@noble/curves/misc.js';
* // Build a point constructor from explicit curve parameters, then use its base point.
* const Point = edwards(jubjub.Point.CURVE());
* Point.BASE.toHex();
* ```
*/
function edwards(params, extraOpts = {}) {
	validateObject(extraOpts, {}, {}, "extraOpts");
	const opts = extraOpts;
	const validated = createCurveFields("edwards", params, opts, opts.FpFnLE);
	const { Fp, Fn } = validated;
	let CURVE = validated.CURVE;
	const { h: cofactor } = CURVE;
	if (FpLegendre(Fp, CURVE.a) !== 1) throw new Error("edwards: CURVE.a must be a square in Fp for complete addition formulas");
	if (FpLegendre(Fp, CURVE.d) !== -1) throw new Error("edwards: CURVE.d must be a non-square in Fp for complete addition formulas");
	validateObject(opts, {}, {
		uvRatio: "function",
		randomBytes: "function"
	});
	const randomBytes = opts.randomBytes === void 0 ? randomBytes$1 : opts.randomBytes;
	const MASK = _2n$2 << BigInt(Fp.BYTES * 8) - _1n$2;
	function isOdd(n) {
		if (!Fp.isOdd) throw new Error("Field does not have .isOdd()");
		return Fp.isOdd(n);
	}
	const uvRatio = opts.uvRatio === void 0 ? (u, v) => {
		try {
			return {
				isValid: true,
				value: Fp.sqrt(Fp.div(u, v))
			};
		} catch (e) {
			return {
				isValid: false,
				value: _0n$2
			};
		}
	} : opts.uvRatio;
	if (!isEdValidXY(Fp, CURVE, CURVE.Gx, CURVE.Gy)) throw new Error("bad curve params: generator point");
	const mulA = Fp.eql(CURVE.a, Fp.neg(Fp.ONE)) ? (x) => Fp.neg(x) : Fp.eql(CURVE.a, Fp.ONE) ? (x) => x : (x) => Fp.mul(CURVE.a, x);
	/**
	* Asserts coordinate is valid: 0 <= n < MASK.
	* Coordinates >= Fp.ORDER are allowed for zip215.
	*/
	function acoord(title, n, banZero = false) {
		const min = banZero ? _1n$2 : _0n$2;
		aInRange("coordinate " + title, n, min, MASK);
		return n;
	}
	function aedpoint(other) {
		if (!(other instanceof Point)) throw new Error("EdwardsPoint expected");
	}
	class Point {
		static BASE = new Point(CURVE.Gx, CURVE.Gy, Fp.ONE, Fp.mul(CURVE.Gx, CURVE.Gy));
		static ZERO = new Point(Fp.ZERO, Fp.ONE, Fp.ONE, Fp.ZERO);
		static Fp = Fp;
		static Fn = Fn;
		X;
		Y;
		Z;
		T;
		constructor(X, Y, Z, T) {
			this.X = acoord("x", X);
			this.Y = acoord("y", Y);
			this.Z = acoord("z", Z, true);
			this.T = acoord("t", T);
			Object.freeze(this);
		}
		static CURVE() {
			return CURVE;
		}
		/**
		* Create one extended Edwards point from affine coordinates.
		* Does NOT validate that the point is on-curve or torsion-free.
		* Use `.assertValidity()` on adversarial inputs.
		*/
		static fromAffine(p) {
			if (p instanceof Point) throw new Error("extended point not allowed");
			const { x, y } = p || {};
			acoord("x", x);
			acoord("y", y);
			return new Point(x, y, Fp.ONE, Fp.mul(x, y));
		}
		static fromBytes(bytes, zip215 = false) {
			const len = Fp.BYTES;
			const { a, d } = CURVE;
			bytes = copyBytes(abytes(bytes, len, "point"));
			abool(zip215, "zip215");
			const normed = copyBytes(bytes);
			const lastByte = bytes[len - 1];
			normed[len - 1] = lastByte & -129;
			const y = bytesToNumberLE(normed);
			const max = zip215 ? MASK : Fp.ORDER;
			aInRange("point.y", y, _0n$2, max);
			const y2 = Fp.sqr(y);
			const u = Fp.sub(y2, Fp.ONE);
			const v = Fp.sub(Fp.mulN(d, y2), a);
			let { isValid, value: x } = uvRatio(u, v);
			if (!isValid) throw new Error("bad point: invalid y coordinate");
			const isXOdd = isOdd(x);
			const isLastByteOdd = (lastByte & 128) !== 0;
			if (!zip215 && Fp.is0(x) && isLastByteOdd) throw new Error("bad point: x=0 and x_0=1");
			if (isLastByteOdd !== isXOdd) x = Fp.neg(x);
			return Point.fromAffine({
				x,
				y
			});
		}
		static fromHex(hex, zip215 = false) {
			return Point.fromBytes(hexToBytes(hex), zip215);
		}
		get x() {
			return this.toAffine().x;
		}
		get y() {
			return this.toAffine().y;
		}
		precompute(windowSize = 6, isLazy = true) {
			wnaf.setWindowSize(this, windowSize);
			if (!isLazy) this.multiply(_2n$2);
			return this;
		}
		assertValidity() {
			const p = this;
			const { a, d } = CURVE;
			if (p.is0()) throw new Error("bad point: ZERO");
			const { X, Y, Z, T } = p;
			const X2 = Fp.sqr(X);
			const Y2 = Fp.sqr(Y);
			const Z2 = Fp.sqr(Z);
			const Z4 = Fp.sqr(Z2);
			const aX2 = Fp.mul(X2, a);
			const left = Fp.mul(Fp.add(aX2, Y2), Z2);
			const right = Fp.add(Z4, Fp.mul(d, Fp.mul(X2, Y2)));
			if (!Fp.eql(left, right)) throw new Error("bad point: equation left != right (1)");
			const XY = Fp.mul(X, Y);
			const ZT = Fp.mul(Z, T);
			if (!Fp.eql(XY, ZT)) throw new Error("bad point: equation left != right (2)");
		}
		equals(other) {
			aedpoint(other);
			const { X: X1, Y: Y1, Z: Z1 } = this;
			const { X: X2, Y: Y2, Z: Z2 } = other;
			const X1Z2 = Fp.mul(X1, Z2);
			const X2Z1 = Fp.mul(X2, Z1);
			const Y1Z2 = Fp.mul(Y1, Z2);
			const Y2Z1 = Fp.mul(Y2, Z1);
			return Fp.eql(X1Z2, X2Z1) && Fp.eql(Y1Z2, Y2Z1);
		}
		is0() {
			return this.equals(Point.ZERO);
		}
		negate() {
			return new Point(Fp.neg(this.X), this.Y, this.Z, Fp.neg(this.T));
		}
		double() {
			const { X: X1, Y: Y1, Z: Z1 } = this;
			const A = Fp.sqr(X1);
			const B = Fp.sqr(Y1);
			const C = Fp.mul(Fp.sqr(Z1), _2n$2);
			const D = mulA(A);
			const x1y1 = Fp.addN(X1, Y1);
			const E = Fp.sub(Fp.subN(Fp.sqr(x1y1), A), B);
			const G = Fp.addN(D, B);
			const F = Fp.subN(G, C);
			const H = Fp.subN(D, B);
			const X3 = Fp.mul(E, F);
			const Y3 = Fp.mul(G, H);
			const T3 = Fp.mul(E, H);
			const Z3 = Fp.mul(F, G);
			return new Point(X3, Y3, Z3, T3);
		}
		add(other) {
			aedpoint(other);
			const { d } = CURVE;
			const { X: X1, Y: Y1, Z: Z1, T: T1 } = this;
			const { X: X2, Y: Y2, Z: Z2, T: T2 } = other;
			const A = Fp.mul(X1, X2);
			const B = Fp.mul(Y1, Y2);
			const C = Fp.mul(Fp.mulN(T1, d), T2);
			const D = Fp.mul(Z1, Z2);
			const E = Fp.sub(Fp.subN(Fp.mulN(Fp.addN(X1, Y1), Fp.addN(X2, Y2)), A), B);
			const F = Fp.subN(D, C);
			const G = Fp.addN(D, C);
			const H = Fp.sub(B, mulA(A));
			const X3 = Fp.mul(E, F);
			const Y3 = Fp.mul(G, H);
			const T3 = Fp.mul(E, H);
			const Z3 = Fp.mul(F, G);
			return new Point(X3, Y3, Z3, T3);
		}
		subtract(other) {
			aedpoint(other);
			return this.add(other.negate());
		}
		multiply(scalar) {
			if (!Fn.isValidNot0(scalar)) throw new RangeError("invalid scalar: expected 1 <= sc < curve.n");
			const { p, f } = wnaf.mulSecret(this, scalar, cofactor, normalize);
			return normalize([p, f])[0];
		}
		multiplyUnsafe(scalar) {
			if (!Fn.isValid(scalar)) throw new RangeError("invalid scalar: expected 0 <= sc < curve.n");
			if (scalar === _0n$2) return Point.ZERO;
			if (this.is0() || scalar === _1n$2) return this;
			return wnaf.mulUnsafe(this, scalar, normalize);
		}
		isSmallOrder() {
			return this.clearCofactor().is0();
		}
		isTorsionFree() {
			return wnaf.mulUnsafe(this, CURVE.n).is0();
		}
		toAffine(invertedZ) {
			const p = this;
			let iz = invertedZ;
			if (iz != null && typeof iz !== "bigint") throw new TypeError("\"invertedZ\" expected bigint, got type=" + typeof iz);
			const { X, Y, Z } = p;
			const is0 = p.is0();
			if (iz == null) iz = is0 ? Fp.create(_8n$1) : Fp.inv(Z);
			const x = Fp.mul(X, iz);
			const y = Fp.mul(Y, iz);
			const zz = Fp.mul(Z, iz);
			if (is0) return {
				x: Fp.ZERO,
				y: Fp.ONE
			};
			if (!Fp.eql(zz, Fp.ONE)) throw new Error("invZ was invalid");
			return {
				x,
				y
			};
		}
		clearCofactor() {
			if (cofactor === _1n$2) return this;
			if (cofactor === _2n$2) return this.double();
			if (cofactor === _4n) return this.double().double();
			if (cofactor === _8n$1) return this.double().double().double();
			return this.multiplyUnsafe(cofactor);
		}
		toBytes() {
			const { x, y } = this.toAffine();
			const bytes = Fp.toBytes(y);
			bytes[bytes.length - 1] |= isOdd(x) ? 128 : 0;
			return bytes;
		}
		toHex() {
			return bytesToHex(this.toBytes());
		}
		toString() {
			return `<Point ${this.is0() ? "ZERO" : this.toHex()}>`;
		}
	}
	const normalize = (points) => normalizeZ(Point, points);
	const wnaf = new ScalarMultiplier(Point, randomBytes);
	if (wnaf.bits >= 6) Point.BASE.precompute(6);
	Object.freeze(Point.prototype);
	Object.freeze(Point);
	return Point;
}
/**
* Initializes EdDSA signatures over given Edwards curve.
* @param Point - Edwards point constructor.
* @param cHash - Hash function.
* @param eddsaOpts - Optional signature helpers. See {@link EdDSAOpts}.
* @returns EdDSA helper namespace.
* @throws If the hash function, options, or derived point operations are invalid. {@link Error}
* @example
* Initializes EdDSA signatures over given Edwards curve.
*
* ```ts
* import { eddsa } from '@noble/curves/abstract/edwards.js';
* import { jubjub } from '@noble/curves/misc.js';
* import { sha512 } from '@noble/hashes/sha2.js';
* const sigs = eddsa(jubjub.Point, sha512);
* const { secretKey, publicKey } = sigs.keygen();
* const msg = new TextEncoder().encode('hello noble');
* const sig = sigs.sign(msg, secretKey);
* const isValid = sigs.verify(sig, msg, publicKey);
* ```
*/
function eddsa(Point, cHash, eddsaOpts = {}) {
	validatePointCons(Point);
	if (typeof cHash !== "function") throw new Error("\"hash\" function param is required");
	const hash = cHash;
	const opts = eddsaOpts;
	validateObject(opts, {}, {
		adjustScalarBytes: "function",
		randomBytes: "function",
		domain: "function",
		prehash: "function",
		zip215: "boolean",
		mapToCurve: "function",
		toMontgomery: "function",
		toMontgomerySecret: "function"
	});
	const { prehash } = opts;
	const { BASE, Fp, Fn } = Point;
	const outputLen = hash.outputLen;
	const expectedLen = 2 * Fp.BYTES;
	if (outputLen !== void 0) {
		asafenumber(outputLen, "hash.outputLen");
		if (outputLen !== expectedLen) throw new Error(`hash.outputLen must be ${expectedLen}, got ${outputLen}`);
	}
	const randomBytes = opts.randomBytes === void 0 ? randomBytes$1 : opts.randomBytes;
	const toMontgomery = opts.toMontgomery;
	const toMontgomerySecret = opts.toMontgomerySecret;
	const adjustScalarBytes = opts.adjustScalarBytes === void 0 ? (bytes) => bytes : opts.adjustScalarBytes;
	const domain = opts.domain === void 0 ? (data, ctx, phflag) => {
		abool(phflag, "phflag");
		if (ctx.length || phflag) throw new Error("Contexts/pre-hash are not supported");
		return data;
	} : opts.domain;
	function modN_LE(hash) {
		return Fn.create(bytesToNumberLE(hash));
	}
	function getPrivateScalar(key) {
		const len = lengths.secretKey;
		abytes(key, lengths.secretKey, "secretKey");
		const hashed = abytes(hash(key), 2 * len, "hashedSecretKey");
		const head = adjustScalarBytes(hashed.slice(0, len));
		return {
			head,
			prefix: hashed.slice(len, 2 * len),
			scalar: modN_LE(head)
		};
	}
	/** Convenience method that creates public key from scalar. RFC8032 5.1.5
	* Also exposes the derived scalar/prefix tuple and point form reused by sign().
	*/
	function getExtendedPublicKey(secretKey) {
		const { head, prefix, scalar } = getPrivateScalar(secretKey);
		const point = BASE.multiply(scalar);
		return {
			head,
			prefix,
			scalar,
			point,
			pointBytes: point.toBytes()
		};
	}
	/** Calculates EdDSA pub key. RFC8032 5.1.5. */
	function getPublicKey(secretKey) {
		return getExtendedPublicKey(secretKey).pointBytes;
	}
	function hashDomainToScalar(context = Uint8Array.of(), ...msgs) {
		const msg = concatBytes(...msgs);
		return modN_LE(hash(domain(msg, abytes(context, void 0, "context"), !!prehash)));
	}
	/** Signs message with secret key. RFC8032 5.1.6 */
	function sign(msg, secretKey, options = {}) {
		validateObject(options, {}, {}, "options");
		msg = abytes(msg, void 0, "message");
		if (prehash) msg = prehash(msg);
		const { prefix, scalar, pointBytes } = getExtendedPublicKey(secretKey);
		const r = hashDomainToScalar(options.context, prefix, msg);
		const R = BASE.multiply(r).toBytes();
		const k = hashDomainToScalar(options.context, R, pointBytes, msg);
		const s = Fn.create(r + k * scalar);
		if (!Fn.isValid(s)) throw new Error("sign failed: invalid s");
		const rs = concatBytes(R, Fn.toBytes(s));
		return abytes(rs, lengths.signature, "result");
	}
	const verifyOpts = { zip215: opts.zip215 };
	/**
	* Verifies EdDSA signature against message and public key. RFC 8032 §§5.1.7 and 5.2.7.
	* A cofactored verification equation is checked.
	*/
	function verify(sig, msg, publicKey, options = verifyOpts) {
		validateObject(options);
		const { context } = options;
		const zip215 = options.zip215 === void 0 ? !!verifyOpts.zip215 : options.zip215;
		const len = lengths.signature;
		sig = abytes(sig, len, "signature");
		msg = abytes(msg, void 0, "message");
		publicKey = abytes(publicKey, lengths.publicKey, "publicKey");
		if (zip215 !== void 0) abool(zip215, "zip215");
		if (prehash) msg = prehash(msg);
		const mid = len / 2;
		const r = sig.subarray(0, mid);
		const s = bytesToNumberLE(sig.subarray(mid, len));
		let A, R, SB;
		try {
			A = Point.fromBytes(publicKey, zip215);
			R = Point.fromBytes(r, zip215);
			SB = BASE.multiplyUnsafe(s);
		} catch (error) {
			return false;
		}
		if (!zip215 && A.isSmallOrder()) return false;
		const k = hashDomainToScalar(context, r, publicKey, msg);
		return R.add(A.multiplyUnsafe(k)).subtract(SB).clearCofactor().is0();
	}
	const _size = Fp.BYTES;
	const lengths = {
		secretKey: _size,
		publicKey: _size,
		signature: 2 * _size,
		seed: _size
	};
	function randomSecretKey(seed) {
		seed = seed === void 0 ? randomBytes(lengths.seed) : seed;
		return abytes(seed, lengths.seed, "seed");
	}
	function isValidSecretKey(key) {
		return isBytes(key) && key.length === lengths.secretKey;
	}
	function isValidPublicKey(key, zip215) {
		try {
			return !!Point.fromBytes(key, zip215 === void 0 ? verifyOpts.zip215 : zip215);
		} catch (error) {
			return false;
		}
	}
	const utils = {
		getExtendedPublicKey,
		randomSecretKey,
		isValidSecretKey,
		isValidPublicKey,
		/** Converts an Edwards public key to a companion Montgomery public key. */
		toMontgomery(publicKey) {
			if (toMontgomery === void 0) throw new Error("Montgomery conversion is not supported for this curve");
			return toMontgomery(Point.fromBytes(publicKey));
		},
		toMontgomerySecret(secretKey) {
			if (toMontgomerySecret === void 0) throw new Error("Montgomery conversion is not supported for this curve");
			return toMontgomerySecret(secretKey);
		}
	};
	Object.freeze(lengths);
	Object.freeze(utils);
	return Object.freeze({
		keygen: createKeygen(randomSecretKey, getPublicKey),
		getPublicKey,
		sign,
		verify,
		utils,
		Point,
		lengths
	});
}
//#endregion
//#region node_modules/.pnpm/@noble+curves@2.3.0/node_modules/@noble/curves/abstract/montgomery.js
/**
* Montgomery curve methods. It's not really whole montgomery curve,
* just bunch of very specific methods for X25519 / X448 from
* [RFC 7748](https://www.rfc-editor.org/rfc/rfc7748)
* @module
*/
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
const _0n$1 = /* @__PURE__ */ BigInt(0);
const _1n$1 = /* @__PURE__ */ BigInt(1);
const _2n$1 = /* @__PURE__ */ BigInt(2);
/**
* Selector for cswap(): `P` to keep, `P + 1` to swap, chosen by the low bit of `swap`.
* Higher bits are ignored, and `swap` is passed in whole rather than as a {0n, 1n} bit on
* purpose: `P + (swap & _1n)` would short-circuit the addition whenever the bit is clear, which
* is the very leak this construction avoids, one round-trip further down. Subtracting `swap`
* with its low bit cleared keeps every operand full-width instead.
* @param P - Field modulus.
* @param swap - Value whose low bit selects; ignored above that bit.
* @returns `P` when the low bit is clear, `P + 1` when it is set.
*/
function cmask(P, swap) {
	return P + swap - (swap >> _1n$1 << _1n$1);
}
/**
* Swap two field elements when `mask` is `P + 1`, keep them when it is `P`:
*
*   d    = 6P + x_3 - x_2
*   x_2' = d * mask + x_2   (mod P)      x_3' = (x_2 + x_3) - x_2'
*
* The extra `6P * mask` vanishes modulo P, so `mask === P` leaves x_2 and `mask === P + 1`
* leaves x_3. Without the offset, the reduction dividend changes sign with input order and crosses
* BigInt limb boundaries; those classes measured differently on the tested Node/V8 build. For
* canonical inputs, the deliberately left-associative `offset + x_3 - x_2` is between 5P and 7P,
* keeping the dividend positive and in one word-count band for both RFC fields and masks. Six is
* the smallest coefficient `c` for which the shared offset `cP` has that property.
*
* This reduced the tested sign/size timing ratios, but JavaScript BigInt has no constant-time
* contract and the contents of the multiply and remainder still vary. Valid ladder states can
* contain genuine zero coordinates; this construction does not mask those value-shape effects.
* Computing `x_3'` independently as `((6P + x_2 - x_3) * mask + x_3) % P` is more symmetric.
* On the tested Node/V8 build, it reduced the timing difference between keeping `(0, v)` and
* swapping `(v, 0)`—both return `(0, v)`—from about 10%/13% for X25519/X448 to about 3%.
* Successful calls cannot reach that zero-in-the-first-output case. For the case they can reach,
* swapping `(0, v)` and keeping `(v, 0)` both return `(v, 0)`; the difference instead grew from
* about 0.7%/1.1% to 2.7%/2.8%. The extra multiply/remainder also made public
* `getSharedSecret()` about 16% slower. The retained one-remainder form measured about 2.5%
* slower than the prior helper for public X25519 `getSharedSecret()` in the same environment.
* x_3' falls out of the sum, which a swap leaves invariant: no second multiply or reduction is
* needed. Bind `6P` once per field so production and the timing regression exercise the same
* configured helper without paying for the multiplication in every ladder round.
*
* The returned function is called twice per ladder round, so it validates nothing. Both elements
* MUST already be reduced mod P; unreduced input silently corrupts the kept-side output.
* @param P - Field modulus.
* @returns A field-bound swap function taking mask, x_2, and x_3.
*/
function cswap(P) {
	const offset = BigInt(6) * P;
	return (mask, x_2, x_3) => {
		const sum = x_2 + x_3;
		const a = ((offset + x_3 - x_2) * mask + x_2) % P;
		return {
			x_2: a,
			x_3: sum - a
		};
	};
}
function validateOpts(curve) {
	validateObject(curve, {
		P: "bigint",
		type: "string",
		adjustScalarBytes: "function",
		powPminus2: "function"
	}, {
		randomBytes: "function",
		scalarMultBase: "function"
	});
	return Object.freeze({ ...curve });
}
/**
* @param curveDef - Montgomery curve definition.
* @returns ECDH helper namespace.
* @throws If the curve definition or derived shared point is invalid. {@link Error}
* @example
* Build an X25519 helper from curve parameters, then derive one public key.
*
* ```ts
* import { montgomery } from '@noble/curves/abstract/montgomery.js';
* const P = 2n ** 255n - 19n;
* const mod = (num: bigint) => {
*   const out = num % P;
*   return out >= 0n ? out : out + P;
* };
* const pow = (num: bigint, power: bigint) => {
*   let res = 1n;
*   for (; power > 0n; power >>= 1n) {
*     if (power & 1n) res = mod(res * num);
*     num = mod(num * num);
*   }
*   return res;
* };
* const x25519 = montgomery({
*   P,
*   type: 'x25519',
*   adjustScalarBytes(bytes: Uint8Array) {
*     bytes[0] &= 248;
*     bytes[31] &= 127;
*     bytes[31] |= 64;
*     return bytes;
*   },
*   powPminus2(x) {
*     return pow(x, P - 2n);
*   },
* });
* const publicKey = x25519.getPublicKey(new Uint8Array(32).fill(1));
* ```
*/
function montgomery(curveDef) {
	const CURVE = validateOpts(curveDef);
	const { P, type, adjustScalarBytes, powPminus2, randomBytes: rand } = CURVE;
	const mulBaseHook = CURVE.scalarMultBase;
	const is25519 = type === "x25519";
	if (!is25519 && type !== "x448") throw new Error("invalid type");
	const randomBytes_ = rand === void 0 ? randomBytes$1 : rand;
	const montgomeryBits = is25519 ? 255 : 448;
	const swap = cswap(P);
	const fieldLen = is25519 ? 32 : 56;
	const Gu = is25519 ? BigInt(9) : BigInt(5);
	const a24 = is25519 ? BigInt(121665) : BigInt(39081);
	const minScalar = is25519 ? _2n$1 ** BigInt(254) : _2n$1 ** BigInt(447);
	const maxScalar = minScalar + (is25519 ? BigInt(8) * (_2n$1 ** BigInt(251) - _1n$1) : BigInt(4) * (_2n$1 ** BigInt(445) - _1n$1)) + _1n$1;
	const modP = (n) => mod(n, P);
	const GuBytes = encodeU(Gu);
	function encodeU(u) {
		return numberToBytesLE(modP(u), fieldLen);
	}
	function decodeU(u) {
		const _u = copyBytes(abytes(u, fieldLen, "uCoordinate"));
		if (is25519) _u[31] &= 127;
		return modP(bytesToNumberLE(_u));
	}
	function decodeScalar(scalar) {
		return bytesToNumberLE(adjustScalarBytes(copyBytes(abytes(scalar, fieldLen, "scalar"))));
	}
	/**
	* u coordinates whose order divides the cofactor, on the curve and on its quadratic twist -
	* the ladder sends every one of them to zero. Same blocklist libsodium and post-CVE-2017-0379
	* Libgcrypt carry. decodeU() reduces mod P first, so the non-canonical encodings P and P + 1
	* collapse onto 0 and 1, and `type` admits no curve beyond these two, so both lists are total.
	*
	* Complete by construction: x-only doubling sends u to (u^2 - 1)^2 / 4u(u^2 + a*u + 1). Order 4
	* therefore needs (u^2 - 1)^2 === 0, i.e. u = +-1; order 2 needs u(u^2 + a*u + 1) === 0, and
	* a^2 - 4 is a non-residue on both curves, leaving u = 0. curve448 stops there (cofactor 4);
	* curve25519 (cofactor 8) adds the two order-8 roots below. Cross-checked by clearing the
	* cofactor with those same doublings over 200k random u: no sixth value exists.
	*/
	const lowOrderU = new Set(is25519 ? [
		_0n$1,
		_1n$1,
		P - _1n$1,
		BigInt("325606250916557431795983626356110631294008115727848805560023387167927233504"),
		BigInt("39382357235489614581723060781553021112529911719440698176882885853963445705823")
	] : [
		_0n$1,
		_1n$1,
		P - _1n$1
	]);
	function scalarMult(scalar, u) {
		const pointU = decodeU(u);
		if (lowOrderU.has(pointU)) throw new Error("invalid private or public key received");
		const pu = montgomeryLadder(pointU, decodeScalar(scalar));
		if (pu === _0n$1) throw new Error("invalid private or public key received");
		return encodeU(pu);
	}
	function scalarMultBase(scalar) {
		if (mulBaseHook === void 0) return scalarMult(scalar, GuBytes);
		const k = decodeScalar(scalar);
		aInRange("scalar", k, minScalar, maxScalar);
		const pu = modP(mulBaseHook(k));
		if (pu === _0n$1) throw new Error("invalid private or public key received");
		return encodeU(pu);
	}
	const getPublicKey = scalarMultBase;
	const getSharedSecret = scalarMult;
	/**
	* Montgomery x-only multiplication ladder for the selected X25519/X448 curve.
	* @param pointU - decoded Montgomery u coordinate for the selected curve
	* @param scalar - decoded clamped scalar by which the point is multiplied
	* @returns resulting Montgomery u coordinate for the selected curve
	*/
	function montgomeryLadder(u, scalar) {
		aInRange("u", u, _0n$1, P);
		aInRange("scalar", scalar, minScalar, maxScalar);
		const k = scalar;
		const x_1 = u;
		let x_2 = _1n$1;
		let z_2 = _0n$1;
		let x_3 = u;
		let z_3 = _1n$1;
		const kx = k ^ k >> _1n$1;
		for (let t = BigInt(montgomeryBits - 1); t >= _0n$1; t--) {
			const mask = cmask(P, kx >> t);
			({x_2, x_3} = swap(mask, x_2, x_3));
			({x_2: z_2, x_3: z_3} = swap(mask, z_2, z_3));
			const A = x_2 + z_2;
			const AA = modP(A * A);
			const B = x_2 - z_2;
			const BB = modP(B * B);
			const E = AA - BB;
			const C = x_3 + z_3;
			const D = x_3 - z_3;
			const DA = modP(D * A);
			const CB = modP(C * B);
			const dacb = DA + CB;
			const da_cb = DA - CB;
			x_3 = modP(dacb * dacb);
			z_3 = modP(x_1 * modP(da_cb * da_cb));
			x_2 = modP(AA * BB);
			z_2 = modP(E * (AA + modP(a24 * E)));
		}
		const mask = cmask(P, k);
		({x_2, x_3} = swap(mask, x_2, x_3));
		({x_2: z_2, x_3: z_3} = swap(mask, z_2, z_3));
		const z2 = powPminus2(z_2);
		return modP(x_2 * z2);
	}
	const lengths = {
		secretKey: fieldLen,
		publicKey: fieldLen,
		seed: fieldLen
	};
	const randomSecretKey = (seed) => {
		seed = seed === void 0 ? randomBytes_(fieldLen) : seed;
		abytes(seed, lengths.seed, "seed");
		return seed;
	};
	const utils = { randomSecretKey };
	Object.freeze(lengths);
	Object.freeze(utils);
	return Object.freeze({
		keygen: createKeygen(randomSecretKey, getPublicKey),
		getSharedSecret,
		getPublicKey,
		scalarMult,
		scalarMultBase,
		utils,
		GuBytes: GuBytes.slice(),
		lengths
	});
}
//#endregion
//#region node_modules/.pnpm/@noble+curves@2.3.0/node_modules/@noble/curves/ed25519.js
/**
* ed25519 Twisted Edwards curve with following addons:
* - X25519 ECDH
* - Ristretto cofactor elimination
* - Elligator hash-to-group / point indistinguishability
* @module
*/
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
const _0n = /* @__PURE__ */ BigInt(0);
const _1n = /* @__PURE__ */ BigInt(1);
const _2n = /* @__PURE__ */ BigInt(2);
const _3n = /* @__PURE__ */ BigInt(3);
const _5n = /* @__PURE__ */ BigInt(5);
const _8n = /* @__PURE__ */ BigInt(8);
const ed25519_CURVE_p = /* @__PURE__ */ BigInt("0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed");
const ed25519_CURVE = /* @__PURE__ */ (() => ({
	p: ed25519_CURVE_p,
	n: BigInt("0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed"),
	h: _8n,
	a: BigInt("0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec"),
	d: BigInt("0x52036cee2b6ffe738cc740797779e89800700a4d4141d8ab75eb4dca135978a3"),
	Gx: BigInt("0x216936d3cd6e53fec0a4e231fdd6dc5c692cc7609525a7b2c9562d608f25d51a"),
	Gy: BigInt("0x6666666666666666666666666666666666666666666666666666666666666658")
}))();
function ed25519_pow_2_252_3(x) {
	const _10n = BigInt(10), _20n = BigInt(20), _40n = BigInt(40), _80n = BigInt(80);
	const P = ed25519_CURVE_p;
	const b2 = x * x % P * x % P;
	const b5 = pow2(pow2(b2, _2n, P) * b2 % P, _1n, P) * x % P;
	const b10 = pow2(b5, _5n, P) * b5 % P;
	const b20 = pow2(b10, _10n, P) * b10 % P;
	const b40 = pow2(b20, _20n, P) * b20 % P;
	const b80 = pow2(b40, _40n, P) * b40 % P;
	return {
		pow_p_5_8: pow2(pow2(pow2(pow2(b80, _80n, P) * b80 % P, _80n, P) * b80 % P, _10n, P) * b10 % P, _2n, P) * x % P,
		b2
	};
}
function adjustScalarBytes(bytes) {
	bytes[0] &= 248;
	bytes[31] &= 127;
	bytes[31] |= 64;
	return bytes;
}
const ED25519_SQRT_M1 = /* @__PURE__ */ BigInt("19681161376707505956807079304988542015446066515923890162744021073123829784752");
function uvRatio(u, v) {
	const P = ed25519_CURVE_p;
	const v3 = mod(v * v * v, P);
	const pow = ed25519_pow_2_252_3(u * mod(v3 * v3 * v, P)).pow_p_5_8;
	let x = mod(u * v3 * pow, P);
	const vx2 = mod(v * x * x, P);
	const root1 = x;
	const root2 = mod(x * ED25519_SQRT_M1, P);
	const useRoot1 = vx2 === u;
	const useRoot2 = vx2 === mod(-u, P);
	const noRoot = vx2 === mod(-u * ED25519_SQRT_M1, P);
	if (useRoot1) x = root1;
	if (useRoot2 || noRoot) x = root2;
	if (isNegativeLE(x, P)) x = mod(-x, P);
	return {
		isValid: useRoot1 || useRoot2,
		value: x
	};
}
const ed25519_Point = /* @__PURE__ */ edwards(ed25519_CURVE, { uvRatio });
const Fp = /* @__PURE__ */ (() => ed25519_Point.Fp)();
function toMontgomery(point) {
	const { y } = point;
	return Fp.toBytes(Fp.div(_1n + y, _1n - y));
}
function toMontgomerySecret(secretKey) {
	const size = ed25519_Point.Fp.BYTES;
	abytes$2(secretKey, size);
	return adjustScalarBytes(sha512(secretKey.subarray(0, size))).subarray(0, size);
}
function ed(opts) {
	return eddsa(ed25519_Point, sha512, Object.assign({
		adjustScalarBytes,
		toMontgomery,
		toMontgomerySecret,
		zip215: true
	}, opts));
}
/**
* ed25519 curve with EdDSA signatures.
* Seeded `keygen(seed)` / `utils.randomSecretKey(seed)` reuse the provided
* 32-byte seed buffer instead of copying it.
* @example
* Generate one Ed25519 keypair, sign a message, and verify it.
*
* ```js
* import { ed25519 } from '@noble/curves/ed25519.js';
* const { secretKey, publicKey } = ed25519.keygen();
* // const publicKey = ed25519.getPublicKey(secretKey);
* const msg = new TextEncoder().encode('hello noble');
* const sig = ed25519.sign(msg, secretKey);
* const isValid = ed25519.verify(sig, msg, publicKey); // ZIP215
* // RFC8032 / FIPS 186-5
* const isValid2 = ed25519.verify(sig, msg, publicKey, { zip215: false });
* ```
*/
const ed25519 = /* @__PURE__ */ ed({});
/**
* ECDH using curve25519 aka x25519.
* `getSharedSecret()` rejects low-order peer inputs by default, and seeded
* `keygen(seed)` reuses the provided 32-byte seed buffer instead of copying it.
* @example
* Derive one shared secret between two X25519 peers.
*
* ```js
* import { x25519 } from '@noble/curves/ed25519.js';
* const alice = x25519.keygen();
* const bob = x25519.keygen();
* const alicePublic = x25519.getPublicKey(alice.secretKey);
* const shared = x25519.getSharedSecret(alice.secretKey, bob.publicKey);
* ```
*/
const x25519 = /* @__PURE__ */ (() => {
	const P = ed25519_CURVE_p;
	const powPminus2 = (x) => {
		const { pow_p_5_8, b2 } = ed25519_pow_2_252_3(x);
		return mod(pow2(pow_p_5_8, _3n, P) * b2, P);
	};
	return montgomery({
		P,
		type: "x25519",
		powPminus2,
		adjustScalarBytes,
		scalarMultBase: (k) => {
			const kn = mod(k, ed25519_Point.Fn.ORDER);
			if (kn === _0n) return _0n;
			const p = ed25519_Point.BASE.multiply(kn);
			return mod((p.Z + p.Y) * powPminus2(mod(p.Z - p.Y, P)), P);
		}
	});
})();
//#endregion
//#region extensions/reef/protocol/audit.ts
function appendAudit(store, type, payload, ts) {
	return store.appendEvent(type, payload, ts);
}
async function appendInboxRead(store, ids, ts) {
	return appendAudit(store, "read", { ids }, ts);
}
function verifyChain(entries, expected) {
	if (expected?.length !== void 0 && entries.length !== expected.length) return false;
	return verifyChainSegment(entries, {
		previousHash: "",
		previousSeq: 0,
		...expected?.head === void 0 ? {} : { head: expected.head }
	});
}
function verifyChainSegment(entries, expected) {
	let previous = expected.previousHash;
	for (let index = 0; index < entries.length; index++) {
		const entry = entries[index];
		if (entry.event.seq !== expected.previousSeq + index + 1 || entry.prevHash !== previous || entry.entryHash !== hashEntry(previous, entry.event)) return false;
		previous = entry.entryHash;
	}
	return expected.head === void 0 || previous === expected.head;
}
function createAuditEntry(type, payload, ts, auditKey, head, rng = randomBytes$2) {
	if (typeof type !== "string" || type.length === 0 || !Number.isSafeInteger(ts) || ts < 0) throw new Error("invalid audit event");
	const event = {
		seq: head.seq + 1,
		ts,
		type,
		payload: encryptSensitive(payload, validateAuditKey(auditKey), rng)
	};
	return {
		event,
		prevHash: head.hash,
		entryHash: hashEntry(head.hash, event)
	};
}
function encryptSensitive(value, key, rng) {
	if (Array.isArray(value)) return value.map((child) => encryptSensitive(child, key, rng));
	if (value !== null && typeof value === "object") {
		const output = {};
		for (const [field, child] of Object.entries(value)) if ((field === "text" || field === "reason") && typeof child === "string") {
			const nonce = rng(12);
			if (nonce.length !== 12) throw new Error("invalid audit nonce");
			const ciphertext = gcm(key, nonce).encrypt(utf8ToBytes(child));
			output[field] = { enc: base64(concatBytes$1(nonce, ciphertext)) };
		} else output[field] = encryptSensitive(child, key, rng);
		return output;
	}
	return value;
}
function hashEntry(previous, event) {
	const previousBytes = previous === "" ? /* @__PURE__ */ new Uint8Array() : fromHex(previous);
	const eventBytes = canonicalBytes(event);
	return bytesToHex$2(sha256(concatBytes$1(previousBytes, eventBytes)));
}
function validateAuditKey(key) {
	if (!(key instanceof Uint8Array) || key.length !== 32) throw new Error("audit key must be 32 bytes");
	return key;
}
function fromHex(value) {
	if (!/^[0-9a-f]{64}$/.test(value)) throw new Error("invalid audit hash");
	return Uint8Array.from(value.match(/../g), (part) => Number.parseInt(part, 16));
}
//#endregion
//#region node_modules/.pnpm/@noble+hashes@2.3.0/node_modules/@noble/hashes/hmac.js
/**
* HMAC: RFC2104 message authentication code.
* @module
*/
/**
* Internal class for HMAC.
* Accepts any byte key, although RFC 2104 §3 recommends keys at least
* `HashLen` bytes long.
*/
var _HMAC = class {
	oHash;
	iHash;
	blockLen;
	outputLen;
	canXOF = false;
	finished = false;
	destroyed = false;
	constructor(hash, key) {
		ahash(hash);
		abytes$2(key, void 0, "key");
		this.iHash = hash.create();
		if (typeof this.iHash.update !== "function") throw new Error("expected Hash instance");
		this.blockLen = this.iHash.blockLen;
		this.outputLen = this.iHash.outputLen;
		const blockLen = this.blockLen;
		const pad = new Uint8Array(blockLen);
		pad.set(key.length > blockLen ? hash.create().update(key).digest() : key);
		for (let i = 0; i < pad.length; i++) pad[i] ^= 54;
		this.iHash.update(pad);
		this.oHash = hash.create();
		for (let i = 0; i < pad.length; i++) pad[i] ^= 106;
		this.oHash.update(pad);
		clean$1(pad);
	}
	update(buf) {
		aexists$1(this);
		this.iHash.update(buf);
		return this;
	}
	digestInto(out) {
		aexists$1(this);
		aoutput(out, this);
		this.finished = true;
		const buf = out.subarray(0, this.outputLen);
		this.iHash.digestInto(buf);
		this.oHash.update(buf);
		this.oHash.digestInto(buf);
		this.destroy();
	}
	digest() {
		const out = new Uint8Array(this.oHash.outputLen);
		this.digestInto(out);
		return out;
	}
	_cloneInto(to) {
		to ||= Object.create(Object.getPrototypeOf(this), {});
		const { oHash, iHash, finished, destroyed, blockLen, outputLen, canXOF } = this;
		to = to;
		to.finished = finished;
		to.destroyed = destroyed;
		to.blockLen = blockLen;
		to.outputLen = outputLen;
		to.canXOF = canXOF;
		to.oHash = oHash._cloneInto(to.oHash);
		to.iHash = iHash._cloneInto(to.iHash);
		return to;
	}
	clone() {
		return this._cloneInto();
	}
	destroy() {
		this.destroyed = true;
		this.oHash.destroy();
		this.iHash.destroy();
	}
};
const hmac = /* @__PURE__ */ (() => {
	const hmac_ = ((hash, key, message) => new _HMAC(hash, key).update(message).digest());
	hmac_.create = (hash, key) => new _HMAC(hash, key);
	return hmac_;
})();
//#endregion
//#region node_modules/.pnpm/@noble+hashes@2.3.0/node_modules/@noble/hashes/hkdf.js
/**
* HKDF (RFC 5869): extract + expand in one step.
* See {@link https://soatok.blog/2021/11/17/understanding-hkdf/}.
* @module
*/
const HKDF_COUNTER = /* @__PURE__ */ Uint8Array.of(0);
const EMPTY_BUFFER = /* @__PURE__ */ Uint8Array.of();
/**
* HKDF-expand from the spec. The most important part. `HKDF-Expand(PRK, info, L) -> OKM`
* @param hash - hash function that would be used (e.g. sha256)
* @param prk - a pseudorandom key of at least HashLen octets
*   (usually, the output from the extract step)
* @param info - optional context and application specific information (can be a zero-length string)
* @param length - length of output keying material in bytes.
*   RFC 5869 §2.3 allows `0..255*HashLen`, so `0` returns an empty OKM.
* @param _recycled - Internal destroyed extract hashes owned by the combined `hkdf()` call.
* @returns Output keying material with the requested length.
* @throws If the requested output length exceeds the HKDF limit
*   for the selected hash. {@link Error}
* @example
* Run the HKDF expand step.
* ```ts
* import { expand } from '@noble/hashes/hkdf.js';
* import { sha256 } from '@noble/hashes/sha2.js';
* expand(sha256, new Uint8Array(32), new Uint8Array([1, 2, 3]), 16);
* ```
*/
function expand(hash, prk, info, length = 32, _recycled) {
	ahash(hash);
	anumber$1(length, "length");
	abytes$2(prk, void 0, "prk");
	const olen = hash.outputLen;
	if (prk.length < olen) throw new Error("\"prk\" must be at least HashLen octets");
	if (length > 255 * olen) throw new Error("Length must be <= 255*HashLen");
	const blocks = Math.ceil(length / olen);
	if (info === void 0) info = EMPTY_BUFFER;
	else abytes$2(info, void 0, "info");
	if (!blocks) {
		if (_recycled) clean$1(prk);
		return /* @__PURE__ */ new Uint8Array();
	}
	const okm = _recycled && blocks === 1 ? prk : new Uint8Array(blocks * olen);
	const { iHash, oHash } = hmac.create(hash, prk);
	const T = _recycled ? prk : new Uint8Array(olen);
	const worker = blocks > 1 ? _recycled?.iHash || hash.create() : void 0;
	for (let counter = 0; counter < blocks - 1; counter++) {
		HKDF_COUNTER[0] = counter + 1;
		const iWork = iHash._cloneInto(worker);
		if (counter) iWork.update(T);
		iWork.update(info).update(HKDF_COUNTER).digestInto(T);
		oHash._cloneInto(worker).update(T).digestInto(T);
		okm.set(T, olen * counter);
	}
	HKDF_COUNTER[0] = blocks;
	if (blocks > 1) iHash.update(T);
	iHash.update(info).update(HKDF_COUNTER).digestInto(T);
	oHash.update(T).digestInto(T);
	okm.set(T, olen * (blocks - 1));
	iHash.destroy();
	oHash.destroy();
	worker?.destroy();
	if (T !== okm) clean$1(T);
	clean$1(HKDF_COUNTER);
	if (length === okm.length) return okm;
	const res = okm.slice(0, length);
	clean$1(okm);
	return res;
}
/**
* HKDF (RFC 5869): derive keys from an initial input.
* Combines hkdf_extract + hkdf_expand in one step
* @param hash - hash function that would be used (e.g. sha256)
* @param ikm - input keying material, the initial key
* @param salt - optional salt value (a non-secret random value)
* @param info - optional context and application specific information bytes
* @param length - length of output keying material in bytes.
*   RFC 5869 §2.3 allows `0..255*HashLen`, so `0` returns an empty OKM.
* @returns Output keying material derived from the input key.
* @throws If the requested output length exceeds the HKDF limit
*   for the selected hash. {@link Error}
* @example
* HKDF (RFC 5869): derive keys from an initial input.
* ```ts
* import { hkdf } from '@noble/hashes/hkdf.js';
* import { sha256 } from '@noble/hashes/sha2.js';
* import { randomBytes, utf8ToBytes } from '@noble/hashes/utils.js';
* const inputKey = randomBytes(32);
* const salt = randomBytes(32);
* const info = utf8ToBytes('application-key');
* const okm = hkdf(sha256, inputKey, salt, info, 32);
* ```
*/
const hkdf = (hash, ikm, salt, info, length) => {
	ahash(hash);
	if (salt === void 0) salt = new Uint8Array(hash.outputLen);
	const HMAC = hmac.create(hash, salt).update(ikm);
	return expand(hash, HMAC.digest(), info, length, HMAC);
};
//#endregion
//#region extensions/reef/protocol/identity.ts
function generateIdentity() {
	const signing = ed25519.keygen();
	const encryption = x25519.keygen();
	return {
		signing: {
			publicKey: base64url(signing.publicKey),
			secretKey: base64url(signing.secretKey)
		},
		encryption: {
			publicKey: base64url(encryption.publicKey),
			secretKey: base64url(encryption.secretKey)
		}
	};
}
function signDeviceRequest(input, signingSecretKey) {
	if (!/^[A-Z]+$/.test(input.method) || !input.path.startsWith("/") || !Number.isSafeInteger(input.ts) || input.ts < 0 || !/^[0-9a-f]{64}$/.test(input.bodySha256)) throw new Error("invalid device request signature input");
	return base64url(ed25519.sign(canonicalBytes(input), fromBase64url(signingSecretKey)));
}
function fingerprint(ed25519PublicKey, x25519PublicKey) {
	const material = x25519PublicKey ? canonicalBytes({
		ed25519: ed25519PublicKey,
		x25519: x25519PublicKey
	}) : fromBase64url(ed25519PublicKey);
	return bytesToHex$2(sha256(material)).match(/.{1,4}/g).join(" ");
}
function formatHandleEpoch(handle, keyEpoch) {
	if (!/^[a-z0-9](?:[a-z0-9_-]{0,62})$/i.test(handle) || !Number.isSafeInteger(keyEpoch) || keyEpoch < 1) throw new Error("invalid handle or key epoch");
	return `${handle}#${keyEpoch}`;
}
function parseHandleEpoch(value) {
	const match = /^([a-z0-9](?:[a-z0-9_-]{0,62}))#([1-9][0-9]*)$/i.exec(value);
	if (!match) throw new Error("invalid handle#key_epoch");
	const keyEpoch = Number(match[2]);
	if (!Number.isSafeInteger(keyEpoch)) throw new Error("invalid key epoch");
	return {
		handle: match[1],
		keyEpoch
	};
}
//#endregion
//#region extensions/reef/protocol/envelope.ts
var ProtocolError = class extends Error {
	constructor(code, message = code) {
		super(message);
		this.code = code;
		this.name = "ProtocolError";
	}
};
var BadSignatureError = class extends ProtocolError {
	constructor(message) {
		super("bad_signature", message);
		this.name = "BadSignatureError";
	}
};
var NotPinnedError = class extends ProtocolError {
	constructor(message) {
		super("not_pinned", message);
		this.name = "NotPinnedError";
	}
};
var WrongRecipientError = class extends ProtocolError {
	constructor(message) {
		super("wrong_recipient", message);
		this.name = "WrongRecipientError";
	}
};
var ExpiredError = class extends ProtocolError {
	constructor(message) {
		super("expired", message);
		this.name = "ExpiredError";
	}
};
var ReplayedError = class extends ProtocolError {
	constructor(message) {
		super("replayed", message);
		this.name = "ReplayedError";
	}
};
var TooLargeError = class extends ProtocolError {
	constructor(message) {
		super("too_large", message);
		this.name = "TooLargeError";
	}
};
var MalformedError = class extends ProtocolError {
	constructor(message) {
		super("malformed", message);
		this.name = "MalformedError";
	}
};
const REEF_MAX_PLAINTEXT_BYTES = 32768;
const MAX_CIPHERTEXT_BASE64 = 44752;
const MAX_ENVELOPE_BYTES = 49152;
const HKDF_INFO = utf8ToBytes("reef-v1");
const ULID_PATTERN = /^[0-7][0-9A-HJKMNP-TV-Z]{25}$/;
function seal(options) {
	validateEnvelopeMetadata(options.id, options.from, options.to, options.ts ?? Math.floor(Date.now() / 1e3));
	validateMessageBody(options.body);
	const plaintext = canonicalBytes(options.body);
	if (plaintext.length > 32768) throw new TooLargeError();
	const ephemeral = x25519.keygen((options.rng ?? randomBytes$2)(32));
	const shared = x25519.getSharedSecret(ephemeral.secretKey, decodeKey(options.recipientEncryptionPublicKey));
	const key = hkdf(sha256, shared, void 0, HKDF_INFO, 32);
	const nonce = (options.rng ?? randomBytes$2)(12);
	if (nonce.length !== 12) throw new MalformedError("rng returned invalid nonce");
	const unsigned = {
		v: 1,
		id: options.id,
		from: options.from,
		to: options.to,
		ts: options.ts ?? Math.floor(Date.now() / 1e3),
		epk: base64(ephemeral.publicKey),
		n: base64(nonce),
		ct: base64(gcm(key, nonce).encrypt(plaintext))
	};
	return {
		...unsigned,
		sig: base64(ed25519.sign(canonicalBytes(unsigned), decodeKey(options.senderSigningSecretKey)))
	};
}
async function openClaimed(options) {
	const envelope = validateEnvelope(options.envelope);
	if (!options.senderSigningPublicKey) throw new NotPinnedError();
	const { sig, ...unsigned } = envelope;
	let validSignature = false;
	try {
		validSignature = ed25519.verify(fromBase64(sig), canonicalBytes(unsigned), decodeKey(options.senderSigningPublicKey));
	} catch {}
	if (!validSignature) throw new BadSignatureError();
	if (envelope.v !== 1) throw new MalformedError();
	validateEnvelopeMetadata(envelope.id, envelope.from, envelope.to, envelope.ts);
	if (envelope.to !== options.self) throw new WrongRecipientError();
	const peer = parseHandleEpoch(envelope.from).handle;
	const hash = bytesToHex$2(sha256(canonicalBytes(envelope)));
	const claim = await options.replayStore.claim(peer, envelope.id, hash);
	if (claim === "mismatch") throw new ReplayedError("replay id binding mismatch");
	if (claim === "in_flight") throw new ReplayedError("in flight");
	if (claim === "duplicate") {
		const completed = await options.replayStore.completed(peer, envelope.id);
		if (completed === void 0) return { claim };
		return completed.body === void 0 ? {
			claim,
			receipt: completed.receipt
		} : {
			claim,
			receipt: completed.receipt,
			body: completed.body
		};
	}
	try {
		const now = options.now ?? Math.floor(Date.now() / 1e3);
		const maxAge = options.maxAgeSeconds ?? 2592e3;
		const maxFutureSkew = options.maxFutureSkewSeconds ?? 300;
		if (envelope.ts > now + maxFutureSkew || envelope.ts < now - maxAge) throw new ExpiredError();
		const shared = x25519.getSharedSecret(decodeKey(options.recipientEncryptionSecretKey), fromBase64(envelope.epk));
		const key = hkdf(sha256, shared, void 0, HKDF_INFO, 32);
		const plaintext = gcm(key, fromBase64(envelope.n)).decrypt(fromBase64(envelope.ct));
		if (plaintext.length > 32768) throw new TooLargeError();
		const body = JSON.parse(decodeUtf8(plaintext));
		validateMessageBody(body);
		return {
			claim: "new",
			body,
			envelopeHash: hash
		};
	} catch (error) {
		await options.replayStore.release(peer, envelope.id);
		if (error instanceof ProtocolError) throw error;
		throw new MalformedError();
	}
}
function bodyHash(body) {
	return bytesToHex$2(sha256(canonicalBytes(body)));
}
function decodeKey(value) {
	const key = fromBase64url(value);
	if (key.length !== 32) throw new MalformedError("invalid key length");
	return key;
}
function validateEnvelopeMetadata(id, from, to, ts) {
	if (!ULID_PATTERN.test(id) || !Number.isSafeInteger(ts) || ts < 0) throw new MalformedError("invalid envelope metadata");
	try {
		parseHandleEpoch(from);
		parseHandleEpoch(to);
	} catch {
		throw new MalformedError("invalid envelope peer");
	}
}
function validateMessageBody(value) {
	if (!isExactObject(value, [
		"text",
		"replyTo",
		"thread"
	])) throw new MalformedError("invalid body");
	if (typeof value.text !== "string" || value.replyTo !== void 0 && typeof value.replyTo !== "string" || value.thread !== void 0 && typeof value.thread !== "string") throw new MalformedError("invalid body");
	if (value.replyTo !== void 0 && !ULID_PATTERN.test(value.replyTo) || value.thread !== void 0 && !ULID_PATTERN.test(value.thread)) throw new MalformedError("invalid body identifier");
	for (const field of [
		value.text,
		value.replyTo,
		value.thread
	]) if (field !== void 0 && decodeUtf8(utf8ToBytes(field)) !== field) throw new MalformedError("invalid UTF-8 body");
}
function validateEnvelope(value) {
	if (!isExactObject(value, [
		"v",
		"id",
		"from",
		"to",
		"ts",
		"epk",
		"n",
		"ct",
		"sig"
	])) throw new MalformedError();
	if (typeof value.v !== "number" || typeof value.id !== "string" || typeof value.from !== "string" || typeof value.to !== "string" || !Number.isSafeInteger(value.ts) || typeof value.epk !== "string" || typeof value.n !== "string" || typeof value.ct !== "string" || typeof value.sig !== "string") throw new MalformedError();
	if (value.id.length !== 26) throw new MalformedError("invalid envelope id length");
	if (value.from.length > 80 || value.to.length > 80 || value.epk.length > 46 || value.n.length > 18 || value.sig.length > 90 || value.ct.length > MAX_CIPHERTEXT_BASE64) throw new TooLargeError();
	try {
		if (fromBase64(value.epk).length !== 32 || fromBase64(value.n).length !== 12 || fromBase64(value.sig).length !== 64) throw new Error();
		fromBase64(value.ct);
	} catch {
		throw new MalformedError();
	}
	if (canonicalBytes(value).length > MAX_ENVELOPE_BYTES) throw new TooLargeError();
	return value;
}
function isExactObject(value, keys) {
	if (value === null || typeof value !== "object" || Array.isArray(value)) return false;
	return Object.keys(value).every((key) => keys.includes(key)) && keys.every((key) => key in value || ["replyTo", "thread"].includes(key));
}
//#endregion
//#region extensions/reef/src/audit-state.ts
const REEF_AUDIT_NAMESPACE = "audit";
const REEF_AUDIT_HEAD_NAMESPACE = "audit-head";
const REEF_AUDIT_HEAD_KEY = "head";
const REEF_AUDIT_MAX_ENTRIES = 3e4;
const REEF_AUDIT_STORE_MAX_ENTRIES = 30001;
const REEF_AUDIT_MIGRATION_NAMESPACE = "audit-migration";
const REEF_AUDIT_MIGRATION_KEY = "audit-jsonl";
const REEF_AUDIT_APPEND_LEASE_MS = 3e4;
const REEF_AUDIT_APPEND_RETRY_MS = 25;
const REEF_AUDIT_APPEND_ATTEMPTS = 120;
function reefAuditEntryKey(entryHash) {
	return `entry:${entryHash}`;
}
function parseReefAuditHead(value) {
	if (value === void 0) return {
		kind: "head",
		hash: "",
		seq: 0,
		oldestHash: ""
	};
	if (value.kind !== "head" || typeof value.hash !== "string" || !Number.isSafeInteger(value.seq) || value.seq < 0 || value.seq === 0 !== (value.hash === "") || typeof value.oldestHash !== "string" || value.seq === 0 !== (value.oldestHash === "") || value.garbageEntryKey !== void 0 && (typeof value.garbageEntryKey !== "string" || value.garbageEntryKey.length === 0) || value.pending !== void 0 && (typeof value.pending.owner !== "string" || value.pending.owner.length === 0 || !Number.isSafeInteger(value.pending.expiresAt) || value.pending.expiresAt <= 0 || value.pending.entryKey !== void 0 && (typeof value.pending.entryKey !== "string" || value.pending.entryKey.length === 0))) throw new Error("invalid Reef audit head");
	return value;
}
function parseAuditEntryRecord(value) {
	if (!value || value.kind !== "entry") throw new Error("missing Reef audit entry");
	return value.entry;
}
function parseAuditStateRecord(value) {
	parseAuditEntryRecord(value);
	if (value?.nextHash !== void 0 && (typeof value.nextHash !== "string" || value.nextHash.length === 0)) throw new Error("invalid Reef audit next pointer");
	return value;
}
var ReefSqliteAuditStore = class {
	#auditKey;
	#rng;
	#maxEntries;
	#store;
	#headStore;
	constructor(runtime, auditKey, rng = randomBytes$2, maxEntries = REEF_AUDIT_MAX_ENTRIES) {
		if (auditKey.length !== 32) throw new Error("audit key must be 32 bytes");
		this.#auditKey = auditKey.slice();
		this.#rng = rng;
		this.#maxEntries = maxEntries;
		if (runtime.state.openSyncKeyedStore({
			namespace: "audit-migration",
			maxEntries: 1,
			overflowPolicy: "reject-new"
		}).lookup("audit-jsonl")) throw new Error("Reef audit migration is incomplete; repair audit.jsonl and rerun openclaw doctor --fix");
		this.#store = runtime.state.openSyncKeyedStore({
			namespace: REEF_AUDIT_NAMESPACE,
			maxEntries: maxEntries + 1,
			overflowPolicy: "reject-new"
		});
		this.#headStore = runtime.state.openSyncKeyedStore({
			namespace: REEF_AUDIT_HEAD_NAMESPACE,
			maxEntries: 1,
			overflowPolicy: "reject-new"
		});
	}
	async appendEvent(type, payload, ts = Math.floor(Date.now() / 1e3)) {
		const update = this.#headStore.update;
		const updateEntry = this.#store.update;
		if (!update || !updateEntry) throw new Error("Reef audit state requires atomic plugin-state updates");
		const owner = randomUUID();
		for (let attempt = 0; attempt < REEF_AUDIT_APPEND_ATTEMPTS; attempt++) {
			let acquired = false;
			let staleEntryKey;
			let head = {
				kind: "head",
				hash: "",
				seq: 0,
				oldestHash: ""
			};
			update(REEF_AUDIT_HEAD_KEY, (current) => {
				const latest = parseReefAuditHead(current);
				if (latest.pending && latest.pending.expiresAt > Date.now()) return latest;
				acquired = true;
				staleEntryKey = latest.pending?.entryKey;
				head = {
					kind: "head",
					hash: latest.hash,
					seq: latest.seq,
					oldestHash: latest.oldestHash,
					...latest.garbageEntryKey ? { garbageEntryKey: latest.garbageEntryKey } : {}
				};
				return {
					...head,
					pending: {
						owner,
						expiresAt: Date.now() + REEF_AUDIT_APPEND_LEASE_MS,
						...staleEntryKey ? { entryKey: staleEntryKey } : {}
					}
				};
			});
			if (!acquired) {
				await setTimeout(REEF_AUDIT_APPEND_RETRY_MS);
				continue;
			}
			let entryKey;
			let entryHash;
			let inserted = false;
			let staleCleanupComplete = !staleEntryKey;
			try {
				if (staleEntryKey) {
					if (!staleEntryKey.startsWith("entry:") || staleEntryKey.length === 6) throw new Error("invalid Reef audit staged entry key");
					const staleEntryHash = staleEntryKey.slice(6);
					if (head.hash) updateEntry(reefAuditEntryKey(head.hash), (current) => {
						const previous = parseAuditStateRecord(current);
						if (previous.nextHash !== staleEntryHash) return previous;
						const { nextHash: _nextHash, ...unlinked } = previous;
						return unlinked;
					});
					this.#store.delete(staleEntryKey);
					update(REEF_AUDIT_HEAD_KEY, (current) => {
						const latest = parseReefAuditHead(current);
						if (latest.pending?.owner !== owner || latest.pending.entryKey !== staleEntryKey) return latest;
						return {
							...latest,
							pending: {
								owner,
								expiresAt: latest.pending.expiresAt
							}
						};
					});
					staleCleanupComplete = true;
					staleEntryKey = void 0;
				}
				if (head.garbageEntryKey) {
					this.#store.delete(head.garbageEntryKey);
					update(REEF_AUDIT_HEAD_KEY, (current) => {
						const latest = parseReefAuditHead(current);
						if (latest.pending?.owner !== owner) return latest;
						const { garbageEntryKey: _garbageEntryKey, ...cleaned } = latest;
						return cleaned;
					});
					const { garbageEntryKey: _garbageEntryKey, ...cleanedHead } = head;
					head = cleanedHead;
				}
				const entry = createAuditEntry(type, payload, ts, this.#auditKey, head, this.#rng);
				entryHash = entry.entryHash;
				entryKey = reefAuditEntryKey(entry.entryHash);
				let staged = false;
				update(REEF_AUDIT_HEAD_KEY, (current) => {
					const latest = parseReefAuditHead(current);
					if (latest.hash !== head.hash || latest.seq !== head.seq || latest.pending?.owner !== owner) return latest;
					staged = true;
					return {
						...latest,
						pending: {
							...latest.pending,
							entryKey
						}
					};
				});
				if (!staged) throw new Error("Reef audit append lease was lost before staging");
				inserted = this.#store.registerIfAbsent(entryKey, {
					kind: "entry",
					entry
				});
				if (!inserted) throw new Error("Reef audit entry already exists before head advancement");
				if (head.hash) updateEntry(reefAuditEntryKey(head.hash), (current) => {
					const previous = parseAuditStateRecord(current);
					if (previous.entry.entryHash !== head.hash) throw new Error("Reef audit head entry differs before linking append");
					if (parseReefAuditHead(this.#headStore.lookup("head")).pending?.owner !== owner) throw new Error("Reef audit append lease was lost before linking");
					const replacesStaleLink = previous.nextHash !== void 0 && staleEntryKey === reefAuditEntryKey(previous.nextHash);
					if (previous.nextHash === entry.entryHash) return previous;
					if (previous.nextHash !== void 0 && !replacesStaleLink) throw new Error("Reef audit head already links a committed successor");
					return {
						...previous,
						nextHash: entry.entryHash
					};
				});
				let oldestHash = head.seq === 0 ? entry.entryHash : head.oldestHash;
				let garbageEntryKey;
				if (head.seq >= this.#maxEntries) {
					const oldest = parseAuditStateRecord(this.#store.lookup(reefAuditEntryKey(head.oldestHash)));
					if (!oldest.nextHash) throw new Error("Reef audit retention pointer is missing");
					oldestHash = oldest.nextHash;
					garbageEntryKey = reefAuditEntryKey(head.oldestHash);
				}
				let advanced = false;
				update(REEF_AUDIT_HEAD_KEY, (current) => {
					const latest = parseReefAuditHead(current);
					if (latest.hash !== head.hash || latest.seq !== head.seq || latest.pending?.owner !== owner || latest.pending.entryKey !== entryKey) return latest;
					advanced = true;
					return {
						kind: "head",
						hash: entry.entryHash,
						seq: entry.event.seq,
						oldestHash,
						...garbageEntryKey ? { garbageEntryKey } : {}
					};
				});
				if (!advanced) throw new Error("Reef audit append lease was lost before commit");
				if (garbageEntryKey) try {
					this.#store.delete(garbageEntryKey);
					update(REEF_AUDIT_HEAD_KEY, (current) => {
						const latest = parseReefAuditHead(current);
						if (latest.hash !== entry.entryHash || latest.garbageEntryKey !== garbageEntryKey) return latest;
						const { garbageEntryKey: _garbageEntryKey, ...cleaned } = latest;
						return cleaned;
					});
				} catch {}
				return structuredClone(entry);
			} catch (error) {
				const latestHead = parseReefAuditHead(this.#headStore.lookup(REEF_AUDIT_HEAD_KEY));
				const entryOwnedElsewhere = entryKey !== void 0 && (latestHead.hash === entryHash && latestHead.seq === head.seq + 1 || latestHead.pending?.owner !== owner && latestHead.pending?.entryKey === entryKey);
				if (inserted && entryKey && !entryOwnedElsewhere) this.#store.delete(entryKey);
				if (entryKey && head.hash && !entryOwnedElsewhere) updateEntry(reefAuditEntryKey(head.hash), (current) => {
					const previous = parseAuditStateRecord(current);
					if (previous.nextHash !== entryHash) return previous;
					const { nextHash: _nextHash, ...unlinked } = previous;
					return unlinked;
				});
				update(REEF_AUDIT_HEAD_KEY, (current) => {
					const latest = parseReefAuditHead(current);
					if (latest.pending?.owner !== owner) return latest;
					if (!staleCleanupComplete && staleEntryKey) return {
						...latest,
						pending: {
							owner,
							expiresAt: Math.max(1, Date.now() - 1),
							entryKey: staleEntryKey
						}
					};
					const { pending: _pending, ...committed } = latest;
					return committed;
				});
				throw error;
			}
		}
		throw new Error("Reef audit append contention exceeded retry budget");
	}
	async entries() {
		const head = parseReefAuditHead(this.#headStore.lookup(REEF_AUDIT_HEAD_KEY));
		if (head.seq === 0) return [];
		const reversed = [];
		let hash = head.hash;
		for (let seq = head.seq; seq > 0 && reversed.length < this.#maxEntries; seq--) {
			const record = this.#store.lookup(reefAuditEntryKey(hash));
			if (!record) break;
			const entry = parseAuditEntryRecord(record);
			if (entry.entryHash !== hash || entry.event.seq !== seq) throw new Error("invalid Reef audit chain state");
			reversed.push(entry);
			hash = entry.prevHash;
		}
		const expectedEntries = Math.min(head.seq, this.#maxEntries);
		if (reversed.length !== expectedEntries) throw new Error("Reef audit chain is shorter than its committed retention window");
		const entries = reversed.toReversed();
		const first = entries[0];
		if (!first || !verifyChainSegment(entries, {
			previousHash: first.prevHash,
			previousSeq: first.event.seq - 1,
			head: head.hash
		})) throw new Error("invalid Reef audit chain state");
		return structuredClone(entries);
	}
};
function openReefAuditStore(runtime, auditKey, maxEntries) {
	return new ReefSqliteAuditStore(runtime, auditKey, randomBytes$2, maxEntries);
}
//#endregion
//#region extensions/reef/src/registration-state.ts
const REEF_REGISTRATION_NAMESPACE = "registration";
const REEF_REGISTRATION_IDENTITY_KEY = "identity";
const REEF_REGISTRATION_SESSION_KEY = "setup-session";
const REEF_IDENTITY_RESERVATION_MS = 6e5;
function openRegistrationStore(runtime) {
	return runtime.state.openSyncKeyedStore({
		namespace: REEF_REGISTRATION_NAMESPACE,
		maxEntries: 2,
		overflowPolicy: "reject-new"
	});
}
function parseReefIdentityBinding(value) {
	if (!value || typeof value !== "object") return;
	const parsed = value;
	if (parsed.kind === "pending") return;
	return typeof parsed.handle === "string" && parsed.handle.length > 0 && typeof parsed.relayUrl === "string" && parsed.relayUrl.length > 0 ? {
		handle: parsed.handle,
		relayUrl: parsed.relayUrl
	} : void 0;
}
function parseReefIdentityPendingRecord(value) {
	if (!value || typeof value !== "object") return;
	const parsed = value;
	return parsed.kind === "pending" && typeof parsed.handle === "string" && parsed.handle.length > 0 && typeof parsed.relayUrl === "string" && parsed.relayUrl.length > 0 && typeof parsed.owner === "string" && parsed.owner.length > 0 && Number.isSafeInteger(parsed.expiresAt) && (parsed.expiresAt ?? 0) > 0 ? {
		kind: "pending",
		handle: parsed.handle,
		relayUrl: parsed.relayUrl,
		owner: parsed.owner,
		expiresAt: parsed.expiresAt
	} : void 0;
}
function reefIdentityConflict(binding) {
	return /* @__PURE__ */ new Error(`This OpenClaw state already holds the Reef identity @${binding.handle} on ${binding.relayUrl}. Re-register the same handle and relay.`);
}
function parseReefSetupSession(value) {
	if (!value || typeof value !== "object") return;
	const parsed = value;
	return typeof parsed.session === "string" && parsed.session.length > 0 && typeof parsed.relayUrl === "string" && parsed.relayUrl.length > 0 && typeof parsed.email === "string" && parsed.email.length > 0 ? {
		session: parsed.session,
		relayUrl: parsed.relayUrl,
		email: parsed.email
	} : void 0;
}
function loadReefIdentityBinding(runtime) {
	return parseReefIdentityBinding(openRegistrationStore(runtime).lookup(REEF_REGISTRATION_IDENTITY_KEY));
}
function assertReefIdentityBinding(runtime, binding) {
	const existing = loadReefIdentityBinding(runtime);
	if (!existing) throw new Error("Reef identity binding is missing; run openclaw doctor --fix or register this claw");
	if (existing.handle !== binding.handle || existing.relayUrl !== binding.relayUrl) throw reefIdentityConflict(existing);
}
function reserveReefIdentityBinding(runtime, binding) {
	const parsed = parseReefIdentityBinding(binding);
	if (!parsed) throw new Error("invalid Reef identity binding");
	const update = openRegistrationStore(runtime).update;
	if (!update) throw new Error("Reef identity reservation requires atomic plugin-state updates");
	let reservation;
	let conflict;
	update(REEF_REGISTRATION_IDENTITY_KEY, (current) => {
		const existing = parseReefIdentityBinding(current);
		if (existing) {
			if (existing.handle !== parsed.handle || existing.relayUrl !== parsed.relayUrl) conflict = existing;
			else reservation = { binding: parsed };
			return existing;
		}
		const pending = parseReefIdentityPendingRecord(current);
		if (pending) {
			const sameBinding = pending.handle === parsed.handle && pending.relayUrl === parsed.relayUrl;
			if (pending.expiresAt > Date.now() || !sameBinding) {
				conflict = pending;
				return pending;
			}
		}
		const owner = randomUUID();
		reservation = {
			binding: parsed,
			owner
		};
		return {
			kind: "pending",
			...parsed,
			owner,
			expiresAt: Date.now() + REEF_IDENTITY_RESERVATION_MS
		};
	});
	if (conflict) throw reefIdentityConflict(conflict);
	return reservation;
}
function finalizeReefIdentityBinding(runtime, reservation) {
	if (!reservation.owner) return;
	const update = openRegistrationStore(runtime).update;
	if (!update) throw new Error("Reef identity reservation requires atomic plugin-state updates");
	let finalized = false;
	update(REEF_REGISTRATION_IDENTITY_KEY, (current) => {
		const existing = parseReefIdentityBinding(current);
		if (existing?.handle === reservation.binding.handle && existing.relayUrl === reservation.binding.relayUrl) {
			finalized = true;
			return existing;
		}
		if (parseReefIdentityPendingRecord(current)?.owner !== reservation.owner) return current;
		finalized = true;
		return reservation.binding;
	});
	if (!finalized) throw new Error("Reef identity reservation was replaced before registration completed");
}
function releaseReefIdentityReservation(runtime, reservation) {
	if (!reservation.owner) return;
	const deleteIf = openRegistrationStore(runtime).deleteIf;
	if (!deleteIf) throw new Error("Reef identity reservation requires atomic plugin-state updates");
	deleteIf(REEF_REGISTRATION_IDENTITY_KEY, (current) => parseReefIdentityPendingRecord(current)?.owner === reservation.owner);
}
function loadReefSetupSession(runtime) {
	return parseReefSetupSession(openRegistrationStore(runtime).lookup(REEF_REGISTRATION_SESSION_KEY));
}
function saveReefSetupSession(runtime, session) {
	const parsed = parseReefSetupSession(session);
	if (!parsed) throw new Error("invalid Reef setup session");
	openRegistrationStore(runtime).register(REEF_REGISTRATION_SESSION_KEY, parsed);
}
function clearReefSetupSession(runtime) {
	openRegistrationStore(runtime).delete(REEF_REGISTRATION_SESSION_KEY);
}
//#endregion
//#region extensions/reef/src/state.ts
const REEF_KEYS_NAMESPACE = "identity";
const REEF_KEYS_KEY = "keys";
const REEF_KEYS_MIGRATION_NAMESPACE = "identity-migration";
const REEF_KEYS_MIGRATION_KEY = "keys-json";
const REEF_DURABLE_MIGRATION_NAMESPACE = "durable-migration";
const REEF_DURABLE_MIGRATION_KEY = "legacy-files";
const REEF_REPLAY_NAMESPACE = "replay";
const REEF_REPLAY_MAX_ENTRIES = 3e3;
const REEF_REPLAY_TTL_MS = 26784e5;
const REEF_REVIEWS_NAMESPACE = "reviews";
const REEF_REVIEWS_MAX_ENTRIES = 2e3;
const REEF_DELIVERED_NAMESPACE = "delivered";
const REEF_DELIVERED_MAX_ENTRIES = 5e3;
const REEF_DELIVERED_TTL_MS = REEF_REPLAY_TTL_MS;
const REEF_INBOX_CURSOR_NAMESPACE = "inbox-cursor";
const REEF_INBOX_CURSOR_KEY = "current";
const REEF_INBOX_CURSOR_MAX_ENTRIES = 1;
const REEF_REPLAY_CLAIM_LEASE_MS = 3e5;
function parseReefKeys(value) {
	if (!value || typeof value !== "object") throw new Error("invalid Reef keys");
	const keys = value;
	if (fromBase64url(keys.signing?.publicKey ?? "").length !== 32 || fromBase64url(keys.signing?.secretKey ?? "").length !== 32 || fromBase64url(keys.encryption?.publicKey ?? "").length !== 32 || fromBase64url(keys.encryption?.secretKey ?? "").length !== 32 || fromBase64url(keys.auditKey ?? "").length !== 32 || fromBase64url(keys.replayKey ?? "").length !== 32 || !Number.isSafeInteger(keys.keyEpoch) || keys.keyEpoch < 1) throw new Error("invalid Reef keys");
	return structuredClone(keys);
}
function openKeysStore(runtime) {
	return runtime.state.openSyncKeyedStore({
		namespace: REEF_KEYS_NAMESPACE,
		maxEntries: 1,
		overflowPolicy: "reject-new"
	});
}
function assertReefIdentityMigrationComplete(runtime) {
	if (runtime.state.openSyncKeyedStore({
		namespace: "durable-migration",
		maxEntries: 1,
		overflowPolicy: "reject-new"
	}).lookup("legacy-files")) throw new Error("Reef durable state migration is incomplete; repair the legacy state files and rerun openclaw doctor --fix");
	if (runtime.state.openSyncKeyedStore({
		namespace: "identity-migration",
		maxEntries: 1,
		overflowPolicy: "reject-new"
	}).lookup("keys-json")) throw new Error("Reef identity migration is incomplete; repair the legacy identity files and rerun openclaw doctor --fix");
}
async function generateAndStoreKeys(runtime) {
	assertReefIdentityMigrationComplete(runtime);
	const binding = loadReefIdentityBinding(runtime);
	if (binding) throw new Error(`Reef identity @${binding.handle} on ${binding.relayUrl} has no canonical keys; restore the original keys before registration`);
	const identity = generateIdentity();
	const random = (length) => crypto.getRandomValues(new Uint8Array(length));
	const keys = {
		...identity,
		auditKey: base64url(random(32)),
		replayKey: base64url(random(32)),
		keyEpoch: 1
	};
	if (!openKeysStore(runtime).registerIfAbsent("keys", keys)) throw new Error("Reef keys already exist in plugin state");
	return keys;
}
async function loadKeys(runtime) {
	assertReefIdentityMigrationComplete(runtime);
	const value = openKeysStore(runtime).lookup(REEF_KEYS_KEY);
	if (!value) {
		const error = /* @__PURE__ */ new Error("Reef keys are missing from plugin state");
		error.code = "ENOENT";
		throw error;
	}
	return parseReefKeys(value);
}
function reefReplayStoreKey(peer, id) {
	return `binding:${createHash("sha256").update(JSON.stringify([peer, id])).digest("hex")}`;
}
function parseReplayRecord(value) {
	if (!value) return;
	if (typeof value.peer !== "string" || typeof value.id !== "string" || typeof value.envelopeHash !== "string" || ![
		"available",
		"in_flight",
		"completed",
		"consumed"
	].includes(value.state) || value.state === "in_flight" && (typeof value.claimOwner !== "string" || value.claimOwner.length === 0 || !Number.isSafeInteger(value.claimExpiresAt) || (value.claimExpiresAt ?? 0) <= 0)) throw new Error("invalid Reef replay state");
	return value;
}
function encryptReplayBody(body, key, rng) {
	validateMessageBody(body);
	const nonce = rng(12);
	if (nonce.length !== 12) throw new Error("replay body rng returned invalid nonce");
	return { enc: base64(concatBytes$1(nonce, gcm(key, nonce).encrypt(canonicalBytes(body)))) };
}
function decryptReplayBody(body, key) {
	const packed = fromBase64(body.enc);
	if (packed.length < 28) throw new Error("invalid encrypted replay body");
	const value = JSON.parse(decodeUtf8(gcm(key, packed.slice(0, 12)).decrypt(packed.slice(12))));
	validateMessageBody(value);
	return value;
}
function validateReplayCompletion(receipt, body) {
	if (receipt.status === "accepted" !== (body !== void 0)) throw new Error("accepted replay completion requires body; rejected completion forbids body");
}
var ReefSqliteReplayStore = class {
	#bodyKey;
	#rng;
	#store;
	#claimOwners = /* @__PURE__ */ new Map();
	constructor(runtime, bodyKey, rng = randomBytes$2, maxEntries = REEF_REPLAY_MAX_ENTRIES) {
		if (bodyKey.length !== 32) throw new Error("replay body key must be 32 bytes");
		this.#bodyKey = bodyKey.slice();
		this.#rng = rng;
		this.#store = runtime.state.openSyncKeyedStore({
			namespace: REEF_REPLAY_NAMESPACE,
			maxEntries,
			overflowPolicy: "reject-new",
			defaultTtlMs: REEF_REPLAY_TTL_MS
		});
	}
	#update(peer, id, updateValue) {
		const update = this.#store.update;
		if (!update) throw new Error("Reef replay state requires atomic plugin-state updates");
		return update(reefReplayStoreKey(peer, id), (current) => updateValue(parseReplayRecord(current)));
	}
	async claim(peer, id, envelopeHash) {
		const key = reefReplayStoreKey(peer, id);
		let result = "new";
		const owner = randomUUID();
		const claimExpiresAt = Date.now() + REEF_REPLAY_CLAIM_LEASE_MS;
		this.#update(peer, id, (existing) => {
			if (!existing) return {
				peer,
				id,
				envelopeHash,
				state: "in_flight",
				claimOwner: owner,
				claimExpiresAt
			};
			if (existing.peer !== peer || existing.id !== id || existing.envelopeHash !== envelopeHash) {
				result = "mismatch";
				return existing;
			}
			if (existing.state === "completed" || existing.state === "consumed") {
				result = "duplicate";
				return existing;
			}
			if (existing.state === "in_flight" && (existing.claimExpiresAt ?? 0) > Date.now()) {
				result = "in_flight";
				return existing;
			}
			return {
				...existing,
				state: "in_flight",
				claimOwner: owner,
				claimExpiresAt
			};
		});
		if (result === "new") this.#claimOwners.set(key, owner);
		return result;
	}
	async refresh(peer, id) {
		const key = reefReplayStoreKey(peer, id);
		const owner = this.#claimOwners.get(key);
		let refreshed = false;
		if (owner) this.#update(peer, id, (existing) => {
			if (existing?.state !== "in_flight" || existing.claimOwner !== owner) return existing;
			refreshed = true;
			return {
				...existing,
				claimExpiresAt: Date.now() + REEF_REPLAY_CLAIM_LEASE_MS
			};
		});
		if (!refreshed) {
			this.#claimOwners.delete(key);
			throw new Error("replay claim is not in flight");
		}
	}
	async complete(peer, id, receipt, body) {
		if (receipt.id !== id) throw new Error("receipt id does not match replay claim");
		validateReplayCompletion(receipt, body);
		const key = reefReplayStoreKey(peer, id);
		const owner = this.#claimOwners.get(key);
		let completed = false;
		this.#update(peer, id, (existing) => {
			if (existing?.state !== "in_flight" || existing.claimOwner !== owner) return existing;
			completed = true;
			const { claimOwner: _claimOwner, claimExpiresAt: _claimExpiresAt, ...rest } = existing;
			return {
				...rest,
				state: "completed",
				receipt: structuredClone(receipt),
				...body ? { body: encryptReplayBody(body, this.#bodyKey, this.#rng) } : {}
			};
		});
		if (!completed) throw new Error("replay claim is not in flight");
		this.#claimOwners.delete(key);
	}
	async consume(peer, id) {
		const key = reefReplayStoreKey(peer, id);
		const owner = this.#claimOwners.get(key);
		let consumed = false;
		this.#update(peer, id, (existing) => {
			if (existing?.state !== "in_flight" || existing.claimOwner !== owner) return existing;
			consumed = true;
			const { receipt: _receipt, body: _body, claimOwner: _claimOwner, claimExpiresAt: _claimExpiresAt, ...rest } = existing;
			return {
				...rest,
				state: "consumed"
			};
		});
		if (!consumed) throw new Error("replay claim is not in flight");
		this.#claimOwners.delete(key);
	}
	async release(peer, id) {
		const key = reefReplayStoreKey(peer, id);
		const owner = this.#claimOwners.get(key);
		this.#update(peer, id, (existing) => existing?.state === "in_flight" && existing.claimOwner === owner ? {
			peer: existing.peer,
			id: existing.id,
			envelopeHash: existing.envelopeHash,
			state: "available"
		} : existing);
		this.#claimOwners.delete(key);
	}
	async completed(peer, id) {
		const existing = parseReplayRecord(this.#store.lookup(reefReplayStoreKey(peer, id)));
		if (existing?.peer !== peer || existing.id !== id || existing.state !== "completed" || !existing.receipt) return;
		return existing.body ? {
			receipt: structuredClone(existing.receipt),
			body: decryptReplayBody(existing.body, this.#bodyKey)
		} : { receipt: structuredClone(existing.receipt) };
	}
};
var ReviewApprovalStore = class {
	#store;
	#maxEntries;
	constructor(runtime, maxEntries = REEF_REVIEWS_MAX_ENTRIES, authoritySignal) {
		this.authoritySignal = authoritySignal;
		this.#maxEntries = maxEntries;
		this.#store = runtime.state.openSyncKeyedStore({
			namespace: REEF_REVIEWS_NAMESPACE,
			maxEntries,
			overflowPolicy: "reject-new"
		});
	}
	#makeRoomForPendingReview() {
		const deleteIf = this.#store.deleteIf;
		if (!deleteIf) throw new Error("Reef review retention requires atomic plugin-state deleteIf");
		while (true) {
			const entries = this.#store.entries();
			if (entries.length < this.#maxEntries) return;
			const completed = entries.filter((entry) => entry.value.approved !== void 0).toSorted((left, right) => left.createdAt - right.createdAt)[0];
			if (!completed) throw new Error("Reef pending review capacity is exhausted");
			deleteIf(completed.key, (current) => current.approved !== void 0);
		}
	}
	async request(review) {
		this.authoritySignal?.throwIfAborted();
		const current = this.#store.lookup(review.approvalDigest);
		if (current?.approved !== void 0) return {
			approved: current.approved,
			approvalDigest: review.approvalDigest
		};
		if (!current) this.#makeRoomForPendingReview();
		this.#store.registerIfAbsent(review.approvalDigest, { review: structuredClone(review) });
		const persisted = this.#store.lookup(review.approvalDigest);
		if (!persisted) throw new Error("Failed persisting Reef pending review");
		return persisted?.approved === void 0 ? void 0 : {
			approved: persisted.approved,
			approvalDigest: review.approvalDigest
		};
	}
	async lookupDecision(approvalDigest) {
		this.authoritySignal?.throwIfAborted();
		const current = this.#store.lookup(approvalDigest);
		if (!current) return "none";
		return current.approved === void 0 ? "pending" : { approved: current.approved };
	}
	async decide(digest, approved) {
		const update = this.#store.update;
		if (!update) throw new Error("Reef review state requires atomic plugin-state updates");
		let decided;
		this.authoritySignal?.throwIfAborted();
		update(digest, (current) => {
			if (!current) return;
			decided = structuredClone(current.review);
			return {
				...current,
				approved
			};
		});
		return decided;
	}
	async list() {
		this.authoritySignal?.throwIfAborted();
		return this.#store.entries().filter((entry) => entry.value.approved === void 0).map((entry) => structuredClone(entry.value.review));
	}
};
var ReefDeliveredStore = class {
	#store;
	constructor(runtime, maxEntries = REEF_DELIVERED_MAX_ENTRIES) {
		this.#store = runtime.state.openSyncKeyedStore({
			namespace: REEF_DELIVERED_NAMESPACE,
			maxEntries,
			overflowPolicy: "reject-new",
			defaultTtlMs: REEF_DELIVERED_TTL_MS
		});
	}
	async has(id) {
		return this.#store.lookup(id)?.id === id;
	}
	async add(id) {
		if (this.#store.lookup(id)?.id === id) return;
		if (!this.#store.registerIfAbsent(id, { id }) && this.#store.lookup(id)?.id !== id) throw new Error("Failed persisting Reef delivered marker");
	}
};
function parseReefInboxCursorRecord(value) {
	if (!value || typeof value !== "object") return;
	const record = value;
	return typeof record.handle === "string" && record.handle.length > 0 && typeof record.relayUrl === "string" && record.relayUrl.length > 0 && Number.isSafeInteger(record.cursor) && (record.cursor ?? -1) >= 0 ? {
		handle: record.handle,
		relayUrl: record.relayUrl,
		cursor: record.cursor
	} : void 0;
}
/** Durable relay progress for the single Reef identity bound to this state DB. */
var ReefInboxCursorStore = class {
	#store;
	constructor(runtime, binding) {
		this.binding = binding;
		this.#store = runtime.state.openSyncKeyedStore({
			namespace: REEF_INBOX_CURSOR_NAMESPACE,
			maxEntries: REEF_INBOX_CURSOR_MAX_ENTRIES,
			overflowPolicy: "reject-new"
		});
	}
	load() {
		const value = this.#store.lookup(REEF_INBOX_CURSOR_KEY);
		if (value === void 0) return 0;
		return this.#requireBoundRecord(value).cursor;
	}
	advance(cursor) {
		if (!Number.isSafeInteger(cursor) || cursor < 0) throw new Error("invalid Reef inbox cursor");
		const update = this.#store.update;
		if (!update) throw new Error("Reef inbox cursor requires atomic plugin-state updates");
		update(REEF_INBOX_CURSOR_KEY, (current) => {
			if (current === void 0) return {
				...this.binding,
				cursor
			};
			const existing = this.#requireBoundRecord(current);
			return cursor > existing.cursor ? {
				...existing,
				cursor
			} : existing;
		});
		const persisted = this.#store.lookup(REEF_INBOX_CURSOR_KEY);
		if (!persisted || this.#requireBoundRecord(persisted).cursor < cursor) throw new Error("failed persisting Reef inbox cursor");
	}
	#requireBoundRecord(value) {
		const record = parseReefInboxCursorRecord(value);
		if (!record) throw new Error("invalid Reef inbox cursor state");
		if (record.handle !== this.binding.handle || record.relayUrl !== this.binding.relayUrl) throw new Error("Reef inbox cursor belongs to a different identity");
		return record;
	}
};
function openStores$1(runtime, keys, options = {}) {
	assertReefIdentityMigrationComplete(runtime);
	return {
		audit: openReefAuditStore(runtime, fromBase64url(keys.auditKey), options.auditMaxEntries),
		replay: new ReefSqliteReplayStore(runtime, fromBase64url(keys.replayKey), randomBytes$2, options.replayMaxEntries),
		reviews: new ReviewApprovalStore(runtime, void 0, options.authoritySignal),
		delivered: new ReefDeliveredStore(runtime, options.deliveredMaxEntries)
	};
}
//#endregion
//#region extensions/reef/src/trust-store.ts
const REEF_TRUST_STORE_MAX_ENTRIES = 4096;
const REEF_TRUST_STORE_NAMESPACE = "peer-state";
const REEF_OUTBOUND_DELIVERY_STORE_NAMESPACE = "outbound-deliveries";
const REEF_OUTBOUND_DELIVERY_MAX_ENTRIES = 32768;
const REEF_OUTBOUND_DELIVERY_TTL_MS = 52704e5;
const REEF_PAIRING_APPROVAL_PREFIX = "reef-approval-v1:";
const SHA256_HEX_PATTERN = /^[a-f0-9]{64}$/;
const MESSAGE_ID_PATTERN = /^[0-7][0-9A-HJKMNP-TV-Z]{25}$/;
const ReefOutboundRequestSchema = record(uuid(), number().int().nonnegative());
const ReefRejectionNoticeStateSchema = object({
	lastRejectionAt: number().int().nonnegative(),
	lastResendAt: number().int().nonnegative().optional()
}).strict();
const ReefOutboundRejectionSchema = object({
	category: string().min(1).max(64).optional(),
	notice: ReefRejectionNoticeStateSchema.optional()
}).strict();
const ReefOutboundDeliveryBindingSchema = object({
	bodyHash: string().regex(SHA256_HEX_PATTERN),
	textHash: string().regex(SHA256_HEX_PATTERN).optional(),
	recipient: ReefPeerIdentitySchema
}).strict();
const ReefOutboundDeliverySchema = ReefOutboundDeliveryBindingSchema.extend({
	resendDisabled: literal(true).optional(),
	rejection: ReefOutboundRejectionSchema.optional(),
	sentAt: number().int().positive().optional(),
	overdueNotifiedAt: number().int().positive().optional()
}).strict();
const ReefPeerStateSchema = object({
	revision: number().int().nonnegative(),
	trust: ReefPeerTrustSchema.optional(),
	outboundRequests: ReefOutboundRequestSchema.optional(),
	rejectionNotice: ReefRejectionNoticeStateSchema.optional()
}).strict();
function requirePeer(raw) {
	const peer = normalizeReefTarget(raw);
	if (!peer) throw new Error(`Invalid Reef peer handle: ${raw}`);
	return peer;
}
function resolveReefIdentityScope(config) {
	if (!config.handle) throw new Error("Reef handle is required before opening peer trust state");
	return createHash("sha256").update(`${new URL(config.relayUrl).origin}\n${config.handle}`).digest("hex");
}
function resolveReefTrustStoreKey(config, peer) {
	return `${resolveReefIdentityScope(config)}:${requirePeer(peer)}`;
}
function resolvePairingKeyDigest(friend, trustRevision) {
	return createHash("sha256").update(`${friend.peer}\n${friend.key_epoch}\n${trustRevision}\n${friend.ed25519_pub}\n${friend.x25519_pub}`).digest("hex");
}
function isReefPairingApprovalToken(raw) {
	return raw.trim().startsWith(REEF_PAIRING_APPROVAL_PREFIX);
}
function openStores(openStore) {
	return {
		peers: openStore({
			namespace: REEF_TRUST_STORE_NAMESPACE,
			maxEntries: REEF_TRUST_STORE_MAX_ENTRIES,
			overflowPolicy: "reject-new"
		}),
		deliveries: openStore({
			namespace: REEF_OUTBOUND_DELIVERY_STORE_NAMESPACE,
			maxEntries: REEF_OUTBOUND_DELIVERY_MAX_ENTRIES,
			overflowPolicy: "reject-new",
			defaultTtlMs: REEF_OUTBOUND_DELIVERY_TTL_MS
		})
	};
}
/** Canonical local Reef authorization state for one relay identity. */
var ReefTrustStore = class {
	#identityScope;
	#prefix;
	constructor(stores, config) {
		this.stores = stores;
		this.#identityScope = resolveReefIdentityScope(config);
		this.#prefix = `${this.#identityScope}:`;
	}
	snapshot(peer) {
		const value = this.stores.peers.lookup(this.#key(peer));
		return value === void 0 ? { revision: 0 } : ReefPeerStateSchema.parse(value);
	}
	get(peer) {
		return this.snapshot(peer).trust;
	}
	list() {
		return this.stores.peers.entries().filter((entry) => entry.key.startsWith(this.#prefix)).flatMap((entry) => {
			const state = ReefPeerStateSchema.parse(entry.value);
			return state.trust ? [{
				peer: requirePeer(entry.key.slice(this.#prefix.length)),
				trust: state.trust
			}] : [];
		}).toSorted((left, right) => left.peer === right.peer ? 0 : left.peer < right.peer ? -1 : 1);
	}
	set(peer, trust) {
		const parsedTrust = ReefPeerTrustSchema.parse(trust);
		this.#requireUpdate()(this.#key(peer), (value) => {
			const current = this.#parseState(value);
			return {
				...current,
				revision: current.revision + 1,
				trust: parsedTrust
			};
		});
	}
	remove(peer) {
		return this.#requireUpdate()(this.#key(peer), (value) => {
			return { revision: this.#parseState(value).revision + 1 };
		});
	}
	setAutonomy(peer, autonomy) {
		const normalizedAutonomy = ReefAutonomySchema.parse(autonomy);
		const key = this.#key(peer);
		if (!this.#requireUpdate()(key, (value) => {
			const current = this.#parseState(value);
			if (!current.trust) return;
			return {
				...current,
				trust: {
					...current.trust,
					autonomy: normalizedAutonomy
				}
			};
		})) throw new Error(`Reef peer @${requirePeer(peer)} is not locally trusted`);
	}
	markSafetyNumberChanged(peer, expectedRevision) {
		return this.#requireUpdate()(this.#key(peer), (value) => {
			const current = this.#parseState(value);
			if (current.revision !== expectedRevision || !current.trust) return;
			return {
				...current,
				revision: current.revision + 1,
				trust: {
					...current.trust,
					safetyNumberChanged: true
				}
			};
		});
	}
	commitPeerTrust(friend, options, approvedAt = Date.now()) {
		const peer = requirePeer(friend.peer);
		return this.#requireUpdate()(this.#key(peer), (value) => {
			const current = this.#parseState(value);
			if (current.revision !== options.expectedRevision || options.expectedOutboundRequestId !== void 0 && current.outboundRequests?.[options.expectedOutboundRequestId] === void 0) return;
			return {
				revision: current.revision + 1,
				trust: {
					autonomy: current.trust?.autonomy ?? "bounded",
					ed25519PublicKey: friend.ed25519_pub,
					x25519PublicKey: friend.x25519_pub,
					keyEpoch: friend.key_epoch,
					safetyNumberChanged: false,
					approvedAt
				},
				...current.rejectionNotice ? { rejectionNotice: current.rejectionNotice } : {}
			};
		});
	}
	createPairingApproval(friend, trustRevision = this.snapshot(friend.peer).revision) {
		return `${REEF_PAIRING_APPROVAL_PREFIX}${this.#identityScope}:${requirePeer(friend.peer)}:${friend.key_epoch}:${trustRevision}:${resolvePairingKeyDigest(friend, trustRevision)}`;
	}
	parsePairingApproval(raw) {
		const parts = raw.trim().split(":");
		if (parts.length !== 6 || `${parts[0]}:` !== REEF_PAIRING_APPROVAL_PREFIX) return;
		const [, identityScope, rawPeer, rawKeyEpoch, rawTrustRevision, keyDigest] = parts;
		const peer = rawPeer ? normalizeReefTarget(rawPeer) : void 0;
		const keyEpoch = Number(rawKeyEpoch);
		const trustRevision = Number(rawTrustRevision);
		if (identityScope !== this.#identityScope || !peer || peer !== rawPeer || !Number.isSafeInteger(keyEpoch) || keyEpoch < 1 || String(keyEpoch) !== rawKeyEpoch || !Number.isSafeInteger(trustRevision) || trustRevision < 0 || String(trustRevision) !== rawTrustRevision || !keyDigest || !SHA256_HEX_PATTERN.test(keyDigest)) return;
		return {
			peer,
			keyEpoch,
			trustRevision
		};
	}
	matchesPairingApproval(raw, friend) {
		return raw.trim() === this.createPairingApproval(friend);
	}
	recordOutboundRequest(peer, requestedAt = Date.now()) {
		const requestId = randomUUID();
		if (!this.#requireUpdate()(this.#key(peer), (value) => {
			const current = this.#parseState(value);
			return {
				...current,
				outboundRequests: {
					...current.outboundRequests,
					[requestId]: requestedAt
				}
			};
		})) throw new Error(`Failed to persist outbound Reef request for @${requirePeer(peer)}`);
		return requestId;
	}
	hasOutboundRequest(peer) {
		return Object.keys(this.snapshot(peer).outboundRequests ?? {}).length > 0;
	}
	outboundRequestStatus(peer, requestId) {
		const current = this.snapshot(peer);
		if (current.outboundRequests?.[requestId] !== void 0) return "current";
		return current.trust || this.#hasOutboundRequests(current) ? "superseded" : "revoked";
	}
	removeOutboundRequest(peer, requestId) {
		return this.#requireUpdate()(this.#key(peer), (value) => {
			const current = this.#parseState(value);
			if (!this.#hasOutboundRequests(current)) return;
			if (requestId === void 0) {
				const { outboundRequests: _removed, ...next } = current;
				return next;
			}
			if (current.outboundRequests?.[requestId] === void 0) return;
			const { [requestId]: _removed, ...remaining } = current.outboundRequests;
			if (Object.keys(remaining).length === 0) {
				const { outboundRequests: _allRemoved, ...next } = current;
				return next;
			}
			return {
				...current,
				outboundRequests: remaining
			};
		});
	}
	recordOutboundDelivery(peer, id, binding, options = {}) {
		const key = this.#deliveryKey(peer, id);
		const value = ReefOutboundDeliverySchema.parse({
			...binding,
			...options,
			sentAt: Date.now()
		});
		if (!this.stores.deliveries.registerIfAbsent(key, value)) throw new Error(`Duplicate outbound Reef delivery id ${id}`);
	}
	/**
	* Sends that never produced any receipt. Rejections have their own notice
	* path, and each delivery is reported overdue at most once.
	*/
	overdueOutboundDeliveries(olderThanMs, now = Date.now()) {
		return this.stores.deliveries.entries().filter((entry) => entry.key.startsWith(this.#prefix)).flatMap((entry) => {
			const parsed = ReefOutboundDeliverySchema.safeParse(entry.value);
			if (!parsed.success || parsed.data.rejection || parsed.data.overdueNotifiedAt !== void 0 || parsed.data.sentAt === void 0 || parsed.data.sentAt + olderThanMs > now) return [];
			const separator = entry.key.lastIndexOf(":");
			const peer = requirePeer(entry.key.slice(this.#prefix.length, separator));
			const id = entry.key.slice(separator + 1);
			if (!MESSAGE_ID_PATTERN.test(id) || !matchesReefPeerIdentity(this.get(peer), parsed.data.recipient)) return [];
			return [{
				peer,
				id,
				sentAt: parsed.data.sentAt
			}];
		});
	}
	markOutboundDeliveryOverdueNotified(peer, id) {
		const update = this.stores.deliveries.update;
		if (!update) throw new Error("Reef outbound delivery state requires atomic plugin-state updates");
		return update(this.#deliveryKey(peer, id), (value) => {
			const parsed = ReefOutboundDeliverySchema.safeParse(value);
			if (!parsed.success || parsed.data.rejection || parsed.data.overdueNotifiedAt !== void 0) return;
			return {
				...parsed.data,
				overdueNotifiedAt: Date.now()
			};
		});
	}
	outboundDelivery(peer, id) {
		const value = this.stores.deliveries.lookup(this.#deliveryKey(peer, id));
		return value === void 0 ? void 0 : ReefOutboundDeliverySchema.parse(value);
	}
	consumeOutboundDelivery(peer, id, binding) {
		const expected = this.#parseDeliveryBinding(binding);
		const deleteIf = this.stores.deliveries.deleteIf;
		if (!deleteIf) throw new Error("Reef outbound delivery state requires atomic plugin-state deletion");
		return deleteIf(this.#deliveryKey(peer, id), (current) => {
			const parsed = ReefOutboundDeliverySchema.safeParse(current);
			return parsed.success && this.#matchesDeliveryBinding(parsed.data, expected) && parsed.data.rejection === void 0;
		});
	}
	discardOutboundDelivery(peer, id, binding) {
		const expected = this.#parseDeliveryBinding(binding);
		const deleteIf = this.stores.deliveries.deleteIf;
		if (!deleteIf) throw new Error("Reef outbound delivery state requires atomic plugin-state deletion");
		return deleteIf(this.#deliveryKey(peer, id), (current) => {
			const parsed = ReefOutboundDeliverySchema.safeParse(current);
			return parsed.success && this.#matchesDeliveryBinding(parsed.data, expected);
		});
	}
	recordOutboundRejection(peer, id, binding, category) {
		const key = this.#deliveryKey(peer, id);
		const expected = this.#parseDeliveryBinding(binding);
		const current = this.outboundDelivery(peer, id);
		if (!current || !this.#matchesDeliveryBinding(current, expected)) return false;
		if (current.rejection) return true;
		const update = this.stores.deliveries.update;
		if (!update) throw new Error("Reef outbound delivery state requires atomic plugin-state updates");
		return update(key, (value) => {
			const parsed = ReefOutboundDeliverySchema.safeParse(value);
			if (!parsed.success || !this.#matchesDeliveryBinding(parsed.data, expected)) return;
			if (parsed.data.rejection) return parsed.data;
			const rejection = ReefOutboundRejectionSchema.parse({
				...category ? { category } : {},
				...parsed.data.resendDisabled ? { notice: { lastRejectionAt: Date.now() } } : {}
			});
			return {
				...parsed.data,
				rejection
			};
		});
	}
	pendingOutboundRejections() {
		return this.stores.deliveries.entries().filter((entry) => entry.key.startsWith(this.#prefix)).flatMap((entry) => {
			const delivery = ReefOutboundDeliverySchema.parse(entry.value);
			if (!delivery.rejection) return [];
			const separator = entry.key.lastIndexOf(":");
			const peer = requirePeer(entry.key.slice(this.#prefix.length, separator));
			const id = entry.key.slice(separator + 1);
			if (!MESSAGE_ID_PATTERN.test(id) || !matchesReefPeerIdentity(this.get(peer), delivery.recipient)) return [];
			return [{
				id,
				peer,
				recipient: delivery.recipient,
				...delivery.textHash ? { textHash: delivery.textHash } : {},
				...delivery.rejection.category ? { category: delivery.rejection.category } : {},
				...delivery.rejection.notice ? { reservedNotice: delivery.rejection.notice } : {}
			}];
		}).toSorted((left, right) => left.id === right.id ? 0 : left.id < right.id ? -1 : 1);
	}
	reserveOutboundRejectionNotice(peer, id, recipient, state) {
		const update = this.stores.deliveries.update;
		if (!update) throw new Error("Reef outbound delivery state requires atomic plugin-state updates");
		const expectedRecipient = ReefPeerIdentitySchema.parse(recipient);
		if (!matchesReefPeerIdentity(this.get(peer), expectedRecipient)) throw new Error(`Reef peer @${requirePeer(peer)} changed keys before rejection recovery`);
		const noticeState = ReefRejectionNoticeStateSchema.parse(state);
		let outcome;
		if (!update(this.#deliveryKey(peer, id), (value) => {
			const parsed = ReefOutboundDeliverySchema.safeParse(value);
			if (!parsed.success || !parsed.data.rejection || !sameReefPeerIdentity(parsed.data.recipient, expectedRecipient)) return;
			if (parsed.data.rejection.notice) {
				outcome = {
					kind: "existing",
					state: parsed.data.rejection.notice
				};
				return parsed.data;
			}
			outcome = { kind: "reserved" };
			return {
				...parsed.data,
				rejection: {
					...parsed.data.rejection,
					notice: noticeState
				}
			};
		}) || !outcome) throw new Error(`Reef rejection ${id} lost its durable delivery state`);
		return outcome;
	}
	completeOutboundRejection(peer, id, state) {
		const noticeState = ReefRejectionNoticeStateSchema.parse(state);
		this.#requireUpdate()(this.#key(peer), (value) => {
			const current = this.#parseState(value);
			const previous = current.rejectionNotice;
			const hasResendAt = previous?.lastResendAt !== void 0 || noticeState.lastResendAt !== void 0;
			return {
				...current,
				rejectionNotice: {
					lastRejectionAt: Math.max(previous?.lastRejectionAt ?? 0, noticeState.lastRejectionAt),
					...hasResendAt ? { lastResendAt: Math.max(previous?.lastResendAt ?? 0, noticeState.lastResendAt ?? 0) } : {}
				}
			};
		});
		const key = this.#deliveryKey(peer, id);
		const deleteIf = this.stores.deliveries.deleteIf;
		if (!deleteIf) throw new Error("Reef outbound delivery state requires atomic plugin-state deletion");
		return deleteIf(key, (value) => {
			const parsed = ReefOutboundDeliverySchema.safeParse(value);
			return parsed.success && parsed.data.rejection?.notice !== void 0;
		}) || this.stores.deliveries.lookup(key) === void 0;
	}
	rejectionNoticeState(peer) {
		return this.snapshot(peer).rejectionNotice;
	}
	#key(peer) {
		return `${this.#prefix}${requirePeer(peer)}`;
	}
	#deliveryKey(peer, id) {
		if (!MESSAGE_ID_PATTERN.test(id)) throw new Error(`Invalid Reef delivery id: ${id}`);
		return `${this.#prefix}${requirePeer(peer)}:${id}`;
	}
	#parseState(value) {
		return value === void 0 ? { revision: 0 } : ReefPeerStateSchema.parse(value);
	}
	#parseDeliveryBinding(binding) {
		return ReefOutboundDeliveryBindingSchema.parse({
			bodyHash: binding.bodyHash,
			...binding.textHash ? { textHash: binding.textHash } : {},
			recipient: binding.recipient
		});
	}
	#matchesDeliveryBinding(current, expected) {
		return current.bodyHash === expected.bodyHash && current.textHash === expected.textHash && sameReefPeerIdentity(current.recipient, expected.recipient);
	}
	#hasOutboundRequests(state) {
		return Object.keys(state.outboundRequests ?? {}).length > 0;
	}
	#requireUpdate() {
		const update = this.stores.peers.update;
		if (!update) throw new Error("Reef peer trust requires atomic plugin-state updates");
		return update;
	}
};
function openReefTrustStore(runtime, config) {
	return new ReefTrustStore(openStores(runtime.state.openSyncKeyedStore), config);
}
//#endregion
//#region extensions/reef/src/doctor-state-paths.ts
const REEF_DURABLE_LEGACY_FILENAMES = [
	"keys.json",
	"identity.json",
	"setup-session.json",
	"audit.jsonl",
	"replay.jsonl",
	"reviews.json",
	"delivered.json"
];
function resolveLegacyReefStateDir(params) {
	const reef = params.config.channels?.reef;
	const configured = isRecord(reef) && typeof reef.stateDir === "string" ? reef.stateDir : null;
	const defaultDir = resolveDefaultLegacyReefStateDir(params.homeDir);
	const configuredDir = configured ? resolveUserPath(configured, params.env) : null;
	if (configuredDir) return configuredDir;
	const relativeToActiveState = path.relative(path.resolve(params.stateDir), defaultDir);
	return relativeToActiveState === "" || !relativeToActiveState.startsWith(`..${path.sep}`) && relativeToActiveState !== ".." && !path.isAbsolute(relativeToActiveState) ? defaultDir : path.join(params.stateDir, "data", "reef");
}
function resolveDefaultLegacyReefStateDir(homeDir = os.homedir()) {
	return path.join(homeDir, ".openclaw", "data", "reef");
}
async function legacyReefFileExists(filePath) {
	try {
		return (await fs.stat(filePath)).isFile();
	} catch {
		return false;
	}
}
//#endregion
export { REEF_MAX_PLAINTEXT_BYTES as $, reefReplayStoreKey as A, parseReefSetupSession as B, REEF_REVIEWS_MAX_ENTRIES as C, loadKeys as D, generateAndStoreKeys as E, clearReefSetupSession as F, REEF_AUDIT_HEAD_NAMESPACE as G, reserveReefIdentityBinding as H, finalizeReefIdentityBinding as I, REEF_AUDIT_MIGRATION_NAMESPACE as J, REEF_AUDIT_MAX_ENTRIES as K, loadReefIdentityBinding as L, REEF_REGISTRATION_NAMESPACE as M, REEF_REGISTRATION_SESSION_KEY as N, openStores$1 as O, assertReefIdentityBinding as P, reefAuditEntryKey as Q, loadReefSetupSession as R, REEF_REPLAY_TTL_MS as S, ReefInboxCursorStore as T, saveReefSetupSession as U, releaseReefIdentityReservation as V, REEF_AUDIT_HEAD_KEY as W, REEF_AUDIT_STORE_MAX_ENTRIES as X, REEF_AUDIT_NAMESPACE as Y, parseReefAuditHead as Z, REEF_KEYS_MIGRATION_KEY as _, REEF_OUTBOUND_DELIVERY_TTL_MS as a, validateMessageBody as at, REEF_REPLAY_MAX_ENTRIES as b, isReefPairingApprovalToken as c, parseHandleEpoch as ct, REEF_DELIVERED_MAX_ENTRIES as d, appendInboxRead as dt, ReplayedError as et, REEF_DELIVERED_NAMESPACE as f, verifyChain as ft, REEF_KEYS_KEY as g, REEF_DURABLE_MIGRATION_NAMESPACE as h, REEF_OUTBOUND_DELIVERY_MAX_ENTRIES as i, validateEnvelopeMetadata as it, REEF_REGISTRATION_IDENTITY_KEY as j, parseReefKeys as k, openReefTrustStore as l, signDeviceRequest as lt, REEF_DURABLE_MIGRATION_KEY as m, ed25519 as mt, legacyReefFileExists as n, openClaimed as nt, REEF_TRUST_STORE_MAX_ENTRIES as o, fingerprint as ot, REEF_DELIVERED_TTL_MS as p, verifyChainSegment as pt, REEF_AUDIT_MIGRATION_KEY as q, resolveLegacyReefStateDir as r, seal as rt, REEF_TRUST_STORE_NAMESPACE as s, formatHandleEpoch as st, REEF_DURABLE_LEGACY_FILENAMES as t, bodyHash as tt, resolveReefTrustStoreKey as u, appendAudit as ut, REEF_KEYS_MIGRATION_NAMESPACE as v, REEF_REVIEWS_NAMESPACE as w, REEF_REPLAY_NAMESPACE as x, REEF_KEYS_NAMESPACE as y, parseReefIdentityBinding as z };