askexperts
Version:
AskExperts SDK: build and use AI experts - ask them questions and pay with bitcoin on an open protocol
1,586 lines (1,572 loc) • 269 kB
JavaScript
var __defProp = Object.defineProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
// src/docstore/interfaces.ts
var MessageType = /* @__PURE__ */ ((MessageType2) => {
MessageType2["REQUEST"] = "request";
MessageType2["RESPONSE"] = "response";
MessageType2["SUBSCRIPTION"] = "subscription";
MessageType2["DOCUMENT"] = "document";
MessageType2["END"] = "end";
MessageType2["AUTH"] = "auth";
return MessageType2;
})(MessageType || {});
// src/docstore/DocStoreSQLite.ts
import { DatabaseSync } from "node:sqlite";
import crypto2 from "crypto";
// src/common/debug.ts
import debug from "debug";
var BASE_NAMESPACE = "askexperts";
var debugRelay = debug(`${BASE_NAMESPACE}:relay`);
var debugMCP = debug(`${BASE_NAMESPACE}:mcp`);
var debugExpert = debug(`${BASE_NAMESPACE}:expert`);
var debugClient = debug(`${BASE_NAMESPACE}:client`);
var debugServer = debug(`${BASE_NAMESPACE}:server`);
var debugDocstore = debug(`${BASE_NAMESPACE}:docstore`);
var debugDB = debug(`${BASE_NAMESPACE}:db`);
var debugCompression = debug(`${BASE_NAMESPACE}:compression`);
var debugStream = debug(`${BASE_NAMESPACE}:stream`);
var debugError = debug(`${BASE_NAMESPACE}:error`);
// src/docstore/DocStoreSQLite.ts
var DocStoreSQLite = class {
// 10 seconds
/**
* Creates a new DocStoreSQLite instance
* @param dbPath - Path to the SQLite database file
*/
constructor(dbPath) {
this.BATCH_SIZE = 1e3;
this.RETRY_INTERVAL_MS = 1e4;
debugDocstore(`Initializing DocStoreSQLite with database at: ${dbPath}`);
this.db = new DatabaseSync(dbPath);
this.initDatabase();
}
/**
* Initialize the database by creating required tables if they don't exist
*/
initDatabase() {
this.db.exec("PRAGMA journal_mode = WAL;");
this.db.exec("PRAGMA busy_timeout = 3000;");
this.db.exec(`
CREATE TABLE IF NOT EXISTS docstores (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
timestamp INTEGER NOT NULL,
model TEXT,
vector_size INTEGER,
options TEXT
)
`);
this.db.exec(`
CREATE TABLE IF NOT EXISTS docs (
aid INTEGER PRIMARY KEY AUTOINCREMENT,
id TEXT NOT NULL,
docstore_id TEXT NOT NULL,
timestamp INTEGER NOT NULL,
created_at INTEGER NOT NULL,
type TEXT NOT NULL,
data TEXT NOT NULL,
embeddings BLOB,
UNIQUE(docstore_id, id)
)
`);
this.db.exec(
"CREATE INDEX IF NOT EXISTS idx_docs_docstore_id ON docs (docstore_id)"
);
this.db.exec(
"CREATE INDEX IF NOT EXISTS idx_docs_timestamp ON docs (timestamp)"
);
this.db.exec("CREATE INDEX IF NOT EXISTS idx_docs_type ON docs (type)");
try {
const docstoreColumns = this.db.prepare("PRAGMA table_info(docstores)").all();
const hasUserIdColumn = docstoreColumns.some((col) => col.name === "user_id");
if (!hasUserIdColumn) {
debugDocstore("Adding user_id column to docstores table");
this.db.exec("ALTER TABLE docstores ADD COLUMN user_id TEXT NOT NULL DEFAULT ''");
this.db.exec("CREATE INDEX IF NOT EXISTS idx_docstores_user_id ON docstores (user_id)");
}
} catch (error) {
debugError("Error adding user_id column to docstores table:", error);
}
try {
const docsColumns = this.db.prepare("PRAGMA table_info(docs)").all();
const hasUserIdColumn = docsColumns.some((col) => col.name === "user_id");
if (!hasUserIdColumn) {
debugDocstore("Adding user_id column to docs table");
this.db.exec("ALTER TABLE docs ADD COLUMN user_id TEXT NOT NULL DEFAULT ''");
this.db.exec("CREATE INDEX IF NOT EXISTS idx_docs_user_id ON docs (user_id)");
}
} catch (error) {
debugError("Error adding user_id column to docs table:", error);
}
}
/**
* Subscribe to documents in a docstore with batched queries
* @param docstore_id - ID of the docstore to subscribe to
* @param type - Type of documents to filter by
* @param since - Start timestamp for filtering documents
* @param until - End timestamp for filtering documents
* @param onDoc - Callback function to handle each document
* @returns Subscription object to manage the subscription
*/
async subscribe(options, onDoc) {
let isActive = true;
let pauseTimeout;
let lastAid = 0;
const { docstore_id, type, since, until, user_id } = options;
debugDocstore(`Subscribing to docstore: ${docstore_id}, type: ${type || "all"}, since: ${since || "beginning"}, until: ${until || "now"}, user_id: ${user_id || "all"}`);
const rowToDoc = (row) => {
let embeddingsArray = [];
if (row.embeddings) {
embeddingsArray = this.blobToFloat32Arrays(row.embeddings, row.docstore_id.toString());
}
return {
id: row.id?.toString() || "",
docstore_id: row.docstore_id?.toString() || "",
timestamp: Number(row.timestamp || 0),
created_at: Number(row.created_at || 0),
type: row.type?.toString() || "",
data: row.data?.toString() || "",
embeddings: embeddingsArray,
user_id: row.user_id?.toString() || ""
// aid is not included in the returned Doc object as it's an internal implementation detail
};
};
const fetchBatch = async () => {
if (!isActive)
return;
let query = `
SELECT * FROM docs
WHERE docstore_id = ?
`;
const queryParams = [docstore_id];
if (user_id !== void 0) {
query += ` AND user_id = ?`;
queryParams.push(user_id);
}
if (type !== void 0) {
query += ` AND type = ?`;
queryParams.push(type);
}
if (since !== void 0) {
query += ` AND timestamp >= ?`;
queryParams.push(since);
}
if (until !== void 0) {
query += ` AND timestamp <= ?`;
queryParams.push(until);
}
query += `
AND aid > ?
ORDER BY aid ASC
LIMIT ?
`;
queryParams.push(lastAid, this.BATCH_SIZE);
const stmt = this.db.prepare(query);
const rows = stmt.all(...queryParams);
for (let i2 = 0; i2 < rows.length; i2++) {
if (!isActive)
return;
const row = rows[i2];
const doc = rowToDoc(row);
await onDoc(doc);
lastAid = row.aid ? Number(row.aid) : 0;
}
if (isActive && rows.length < this.BATCH_SIZE)
await onDoc(void 0);
if (isActive) {
if (rows.length < this.BATCH_SIZE) {
pauseTimeout = setTimeout(() => fetchBatch(), this.RETRY_INTERVAL_MS);
} else {
setImmediate(() => fetchBatch());
}
}
};
setImmediate(async () => {
try {
await fetchBatch();
} catch (err) {
debugError("Error in DocStoreSQLite subscription:", err);
}
});
const subscription = {
close: () => {
isActive = false;
if (pauseTimeout)
clearTimeout(pauseTimeout);
}
};
return Promise.resolve(subscription);
}
/**
* Upsert a document in the store using a single atomic operation
* @param doc - Document to upsert
*/
/**
* Convert Float32Array[] to a single Uint8Array for storage
* @param embeddings - Array of Float32Array embeddings
* @param vectorSize - Size of each embedding vector
* @returns Uint8Array containing all embeddings
*/
float32ArraysToBlob(embeddings, vector_size) {
if (embeddings.length >= 1 << 16) {
throw new Error(`Too many embeddings: ${embeddings.length}, maximum is ${(1 << 16) - 1}`);
}
for (let i2 = 0; i2 < embeddings.length; i2++) {
if (embeddings[i2].length !== vector_size) {
throw new Error(`Embedding at index ${i2} has incorrect size: ${embeddings[i2].length}, expected ${vector_size}`);
}
}
const totalSize = 2 + vector_size * 4 * embeddings.length;
const result = new Uint8Array(totalSize);
result[0] = embeddings.length & 255;
result[1] = embeddings.length >> 8 & 255;
let offset = 2;
for (const embedding of embeddings) {
const byteArray = new Uint8Array(embedding.buffer);
result.set(byteArray, offset);
offset += byteArray.length;
}
return result;
}
/**
* Convert a Uint8Array blob back to an array of Float32Array embeddings
* @param blob - Uint8Array blob containing embeddings
* @param docstore_id - ID of the docstore the blob belongs to
* @returns Array of Float32Array embeddings
*/
blobToFloat32Arrays(blob, docstore_id) {
const docstore = this.getDocstoreSync(docstore_id);
if (!docstore || !docstore.vector_size) {
return [];
}
const vector_size = docstore.vector_size;
if (!blob || blob.length < 2) {
debugError(`Invalid blob size: ${blob ? blob.length : "null"}, expected at least 2 bytes`);
return [];
}
const count = blob[0] | blob[1] << 8;
const bytesPerVector = vector_size * 4;
const expectedSize = 2 + count * bytesPerVector;
if (blob.length !== expectedSize) {
debugError(`Invalid blob size: ${blob.length}, expected ${expectedSize} bytes for ${count} vectors of size ${vector_size}`);
return [];
}
const embeddings = [];
let offset = 2;
for (let i2 = 0; i2 < count; i2++) {
const vectorBytes = blob.subarray(offset, offset + bytesPerVector);
const embedding = new Float32Array(vectorBytes.buffer.slice(vectorBytes.byteOffset, vectorBytes.byteOffset + vectorBytes.byteLength));
embeddings.push(embedding);
offset += bytesPerVector;
}
return embeddings;
}
// This method is no longer needed as we pass docstore_id directly to blobToFloat32Arrays
/**
* Get a docstore by ID
* @param id - ID of the docstore to get
* @returns The docstore if found, null otherwise
*/
getDocstoreSync(id, user_id) {
let query = "SELECT * FROM docstores WHERE id = ?";
const params = [id];
if (user_id !== void 0) {
query += " AND user_id = ?";
params.push(user_id);
}
const stmt = this.db.prepare(query);
const row = stmt.get(...params);
if (!row) {
return void 0;
}
return {
id: String(row.id || ""),
name: String(row.name || ""),
timestamp: Number(row.timestamp || 0),
model: String(row.model || ""),
vector_size: Number(row.vector_size || 0),
options: String(row.options || ""),
user_id: String(row.user_id || "")
};
}
async getDocstore(id, user_id) {
return Promise.resolve(this.getDocstoreSync(id, user_id));
}
async upsert(doc, user_id) {
debugDocstore(`Upserting document: ${doc.id} in docstore: ${doc.docstore_id}, type: ${doc.type}, user_id: ${user_id || doc.user_id || "none"}`);
if (user_id && doc.user_id !== user_id)
throw new Error("Wrong doc user");
const docstore = this.getDocstoreSync(doc.docstore_id);
if (!docstore) {
throw new Error(`Docstore not found: ${doc.docstore_id}`);
}
if (!docstore.vector_size) {
throw new Error(`Docstore ${doc.docstore_id} has no vector_size defined`);
}
let embeddingsBlob = null;
if (doc.embeddings && doc.embeddings.length > 0) {
embeddingsBlob = this.float32ArraysToBlob(doc.embeddings, docstore.vector_size);
}
const stmt = this.db.prepare(`
INSERT OR REPLACE INTO docs (
id, docstore_id, timestamp, created_at, type, data, embeddings, user_id
) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
`);
stmt.run(
doc.id,
doc.docstore_id,
doc.timestamp,
doc.created_at,
doc.type,
doc.data,
embeddingsBlob,
user_id || doc.user_id || ""
);
return Promise.resolve();
}
/**
* Get a document by ID
* @param docstore_id - ID of the docstore containing the document
* @param doc_id - ID of the document to get
* @returns The document if found, null otherwise
*/
async get(docstore_id, doc_id, user_id) {
let query = "SELECT * FROM docs WHERE docstore_id = ? AND id = ?";
const params = [docstore_id, doc_id];
if (user_id !== void 0) {
query += " AND user_id = ?";
params.push(user_id);
}
const stmt = this.db.prepare(query);
const row = stmt.get(...params);
if (!row) {
return Promise.resolve(null);
}
let embeddingsArray = [];
if (row.embeddings) {
embeddingsArray = this.blobToFloat32Arrays(row.embeddings, docstore_id);
}
const doc = {
id: row.id?.toString() || "",
docstore_id: row.docstore_id?.toString() || "",
timestamp: Number(row.timestamp || 0),
created_at: Number(row.created_at || 0),
type: row.type?.toString() || "",
data: row.data?.toString() || "",
embeddings: embeddingsArray,
user_id: row.user_id?.toString() || ""
};
return Promise.resolve(doc);
}
/**
* Delete a document from the store
* @param docstore_id - ID of the docstore containing the document
* @param doc_id - ID of the document to delete
* @returns true if document existed and was deleted, false otherwise
*/
async delete(docstore_id, doc_id, user_id) {
let query = "DELETE FROM docs WHERE docstore_id = ? AND id = ?";
const params = [docstore_id, doc_id];
if (user_id !== void 0) {
query += " AND user_id = ?";
params.push(user_id);
}
const stmt = this.db.prepare(query);
const result = stmt.run(...params);
return Promise.resolve(result.changes > 0);
}
/**
* Create a new docstore if one with the given name doesn't exist
* @param name - Name of the docstore to create
* @param model - Name of the embeddings model
* @param vector_size - Size of embedding vectors
* @param options - Options for the model, defaults to empty string
* @returns Promise that resolves with the ID of the created or existing docstore
*/
async createDocstore(name, model = "", vector_size = 0, options = "", user_id) {
debugDocstore(`Creating docstore with name: ${name}, model: ${model}, vector_size: ${vector_size}, user_id: ${user_id || "none"}`);
let query = "SELECT id FROM docstores WHERE name = ?";
const params = [name];
if (user_id !== void 0) {
query += " AND user_id = ?";
params.push(user_id);
}
const existingDocstore = this.db.prepare(query).get(...params);
if (existingDocstore && existingDocstore.id !== null) {
debugDocstore(`Docstore with name ${name} already exists with ID: ${existingDocstore.id}`);
return Promise.resolve(existingDocstore.id.toString());
}
const timestamp = Math.floor(Date.now() / 1e3);
const id = crypto2.randomUUID();
const stmt = this.db.prepare(
"INSERT INTO docstores (id, name, timestamp, model, vector_size, options, user_id) VALUES (?, ?, ?, ?, ?, ?, ?)"
);
stmt.run(id, name, timestamp, model, vector_size, options, user_id || "");
debugDocstore(`Created new docstore with name: ${name}, ID: ${id}, model: ${model}, vector_size: ${vector_size}`);
return Promise.resolve(id);
}
/**
* List all docstores
* @returns Promise that resolves with an array of docstore objects
*/
async listDocstores(user_id) {
let query = "SELECT * FROM docstores";
const params = [];
if (user_id !== void 0) {
query += " WHERE user_id = ?";
params.push(user_id);
}
query += " ORDER BY id ASC";
const stmt = this.db.prepare(query);
const rows = stmt.all(...params);
const docstores = rows.map(
(row) => ({
id: String(row.id || ""),
name: String(row.name || ""),
timestamp: Number(row.timestamp || 0),
model: String(row.model || ""),
vector_size: Number(row.vector_size || 0),
options: String(row.options || ""),
user_id: String(row.user_id || "")
})
);
return Promise.resolve(docstores);
}
/**
* List docstores by specific IDs
* @param ids - Array of docstore IDs to retrieve
* @returns Promise that resolves with an array of docstore objects
*/
async listDocStoresByIds(ids, user_id) {
if (ids.length === 0) {
return Promise.resolve([]);
}
const placeholders = ids.map(() => "?").join(",");
let query = `SELECT * FROM docstores WHERE id IN (${placeholders})`;
const params = [...ids];
if (user_id !== void 0) {
query += " AND user_id = ?";
params.push(user_id);
}
query += " ORDER BY id ASC";
const stmt = this.db.prepare(query);
const rows = stmt.all(...params);
const docstores = rows.map(
(row) => ({
id: String(row.id || ""),
name: String(row.name || ""),
timestamp: Number(row.timestamp || 0),
model: String(row.model || ""),
vector_size: Number(row.vector_size || 0),
options: String(row.options || ""),
user_id: String(row.user_id || "")
})
);
return Promise.resolve(docstores);
}
/**
* List documents by specific IDs
* @param docstore_id - ID of the docstore containing the documents
* @param ids - Array of document IDs to retrieve
* @returns Promise that resolves with an array of document objects
*/
async listDocsByIds(docstore_id, ids) {
if (ids.length === 0) {
return Promise.resolve([]);
}
const placeholders = ids.map(() => "?").join(",");
const query = `SELECT * FROM docs WHERE docstore_id = ? AND id IN (${placeholders}) ORDER BY id ASC`;
const params = [docstore_id, ...ids];
const stmt = this.db.prepare(query);
const rows = stmt.all(...params);
const docs = rows.map((row) => {
let embeddingsArray = [];
if (row.embeddings) {
embeddingsArray = this.blobToFloat32Arrays(row.embeddings, docstore_id);
}
return {
id: row.id?.toString() || "",
docstore_id: row.docstore_id?.toString() || "",
timestamp: Number(row.timestamp || 0),
created_at: Number(row.created_at || 0),
type: row.type?.toString() || "",
data: row.data?.toString() || "",
embeddings: embeddingsArray,
user_id: row.user_id?.toString() || ""
};
});
return Promise.resolve(docs);
}
/**
* Delete a docstore and all its documents
* @param id - ID of the docstore to delete
* @returns Promise that resolves with true if docstore existed and was deleted, false otherwise
*/
async deleteDocstore(id, user_id) {
this.db.exec("BEGIN TRANSACTION");
try {
let docsQuery = "DELETE FROM docs WHERE docstore_id = ?";
const docsParams = [id];
if (user_id !== void 0) {
docsQuery += " AND user_id = ?";
docsParams.push(user_id);
}
const docsStmt = this.db.prepare(docsQuery);
docsStmt.run(...docsParams);
let docstoreQuery = "DELETE FROM docstores WHERE id = ?";
const docstoreParams = [id];
if (user_id !== void 0) {
docstoreQuery += " AND user_id = ?";
docstoreParams.push(user_id);
}
const docstoreStmt = this.db.prepare(docstoreQuery);
const result = docstoreStmt.run(...docstoreParams);
this.db.exec("COMMIT");
return Promise.resolve(result.changes > 0);
} catch (error) {
this.db.exec("ROLLBACK");
debugError("Error deleting docstore:", error);
return Promise.resolve(false);
}
}
/**
* Count documents in a docstore
* @param docstore_id - ID of the docstore to count documents for
* @returns Promise that resolves with the number of documents in the docstore
*/
async countDocs(docstore_id, user_id) {
let query = "SELECT COUNT(*) as count FROM docs WHERE docstore_id = ?";
const params = [docstore_id];
if (user_id !== void 0) {
query += " AND user_id = ?";
params.push(user_id);
}
const stmt = this.db.prepare(query);
const result = stmt.get(...params);
return Promise.resolve(result && typeof result.count === "number" ? result.count : 0);
}
/**
* Symbol.dispose method for releasing resources
*/
[Symbol.dispose]() {
this.db.close();
}
};
// src/common/uuid.ts
function generateUUID() {
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
return crypto.randomUUID();
}
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) {
const r = Math.random() * 16 | 0;
const v = c === "x" ? r : r & 3 | 8;
return v.toString(16);
});
}
// node_modules/@noble/curves/node_modules/@noble/hashes/esm/_assert.js
function number(n) {
if (!Number.isSafeInteger(n) || n < 0)
throw new Error(`Wrong positive integer: ${n}`);
}
function bytes(b, ...lengths) {
if (!(b instanceof Uint8Array))
throw new Error("Expected Uint8Array");
if (lengths.length > 0 && !lengths.includes(b.length))
throw new Error(`Expected Uint8Array of length ${lengths}, not of length=${b.length}`);
}
function hash(hash3) {
if (typeof hash3 !== "function" || typeof hash3.create !== "function")
throw new Error("Hash should be wrapped by utils.wrapConstructor");
number(hash3.outputLen);
number(hash3.blockLen);
}
function exists(instance, checkFinished = true) {
if (instance.destroyed)
throw new Error("Hash instance has been destroyed");
if (checkFinished && instance.finished)
throw new Error("Hash#digest() has already been called");
}
function output(out, instance) {
bytes(out);
const min = instance.outputLen;
if (out.length < min) {
throw new Error(`digestInto() expects output buffer of length at least ${min}`);
}
}
// node_modules/@noble/curves/node_modules/@noble/hashes/esm/cryptoNode.js
import * as nc from "node:crypto";
var crypto3 = nc && typeof nc === "object" && "webcrypto" in nc ? nc.webcrypto : void 0;
// node_modules/@noble/curves/node_modules/@noble/hashes/esm/utils.js
var u8a = (a) => a instanceof Uint8Array;
var createView = (arr) => new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
var rotr = (word, shift) => word << 32 - shift | word >>> shift;
var isLE = new Uint8Array(new Uint32Array([287454020]).buffer)[0] === 68;
if (!isLE)
throw new Error("Non little-endian hardware is not supported");
function utf8ToBytes(str) {
if (typeof str !== "string")
throw new Error(`utf8ToBytes expected string, got ${typeof str}`);
return new Uint8Array(new TextEncoder().encode(str));
}
function toBytes(data) {
if (typeof data === "string")
data = utf8ToBytes(data);
if (!u8a(data))
throw new Error(`expected Uint8Array, got ${typeof data}`);
return data;
}
function concatBytes(...arrays) {
const r = new Uint8Array(arrays.reduce((sum, a) => sum + a.length, 0));
let pad2 = 0;
arrays.forEach((a) => {
if (!u8a(a))
throw new Error("Uint8Array expected");
r.set(a, pad2);
pad2 += a.length;
});
return r;
}
var Hash = class {
// Safe version that clones internal state
clone() {
return this._cloneInto();
}
};
var toStr = {}.toString;
function wrapConstructor(hashCons) {
const hashC = (msg) => hashCons().update(toBytes(msg)).digest();
const tmp = hashCons();
hashC.outputLen = tmp.outputLen;
hashC.blockLen = tmp.blockLen;
hashC.create = () => hashCons();
return hashC;
}
function randomBytes(bytesLength = 32) {
if (crypto3 && typeof crypto3.getRandomValues === "function") {
return crypto3.getRandomValues(new Uint8Array(bytesLength));
}
throw new Error("crypto.getRandomValues must be defined");
}
// node_modules/@noble/curves/node_modules/@noble/hashes/esm/_sha2.js
function setBigUint64(view, byteOffset, value, isLE4) {
if (typeof view.setBigUint64 === "function")
return view.setBigUint64(byteOffset, value, isLE4);
const _32n = BigInt(32);
const _u32_max = BigInt(4294967295);
const wh = Number(value >> _32n & _u32_max);
const wl = Number(value & _u32_max);
const h = isLE4 ? 4 : 0;
const l = isLE4 ? 0 : 4;
view.setUint32(byteOffset + h, wh, isLE4);
view.setUint32(byteOffset + l, wl, isLE4);
}
var SHA2 = class extends Hash {
constructor(blockLen, outputLen, padOffset, isLE4) {
super();
this.blockLen = blockLen;
this.outputLen = outputLen;
this.padOffset = padOffset;
this.isLE = isLE4;
this.finished = false;
this.length = 0;
this.pos = 0;
this.destroyed = false;
this.buffer = new Uint8Array(blockLen);
this.view = createView(this.buffer);
}
update(data) {
exists(this);
const { view, buffer, blockLen } = this;
data = toBytes(data);
const len = data.length;
for (let pos = 0; pos < len; ) {
const take = Math.min(blockLen - this.pos, len - pos);
if (take === blockLen) {
const dataView = createView(data);
for (; blockLen <= len - pos; pos += blockLen)
this.process(dataView, pos);
continue;
}
buffer.set(data.subarray(pos, pos + take), this.pos);
this.pos += take;
pos += take;
if (this.pos === blockLen) {
this.process(view, 0);
this.pos = 0;
}
}
this.length += data.length;
this.roundClean();
return this;
}
digestInto(out) {
exists(this);
output(out, this);
this.finished = true;
const { buffer, view, blockLen, isLE: isLE4 } = this;
let { pos } = this;
buffer[pos++] = 128;
this.buffer.subarray(pos).fill(0);
if (this.padOffset > blockLen - pos) {
this.process(view, 0);
pos = 0;
}
for (let i2 = pos; i2 < blockLen; i2++)
buffer[i2] = 0;
setBigUint64(view, blockLen - 8, BigInt(this.length * 8), isLE4);
this.process(view, 0);
const oview = createView(out);
const len = this.outputLen;
if (len % 4)
throw new Error("_sha2: outputLen should be aligned to 32bit");
const outLen = len / 4;
const state = this.get();
if (outLen > state.length)
throw new Error("_sha2: outputLen bigger than state");
for (let i2 = 0; i2 < outLen; i2++)
oview.setUint32(4 * i2, state[i2], isLE4);
}
digest() {
const { buffer, outputLen } = this;
this.digestInto(buffer);
const res = buffer.slice(0, outputLen);
this.destroy();
return res;
}
_cloneInto(to) {
to || (to = new this.constructor());
to.set(...this.get());
const { blockLen, buffer, length, finished, destroyed, pos } = this;
to.length = length;
to.pos = pos;
to.finished = finished;
to.destroyed = destroyed;
if (length % blockLen)
to.buffer.set(buffer);
return to;
}
};
// node_modules/@noble/curves/node_modules/@noble/hashes/esm/sha256.js
var Chi = (a, b, c) => a & b ^ ~a & c;
var Maj = (a, b, c) => a & b ^ a & c ^ b & c;
var SHA256_K = /* @__PURE__ */ new Uint32Array([
1116352408,
1899447441,
3049323471,
3921009573,
961987163,
1508970993,
2453635748,
2870763221,
3624381080,
310598401,
607225278,
1426881987,
1925078388,
2162078206,
2614888103,
3248222580,
3835390401,
4022224774,
264347078,
604807628,
770255983,
1249150122,
1555081692,
1996064986,
2554220882,
2821834349,
2952996808,
3210313671,
3336571891,
3584528711,
113926993,
338241895,
666307205,
773529912,
1294757372,
1396182291,
1695183700,
1986661051,
2177026350,
2456956037,
2730485921,
2820302411,
3259730800,
3345764771,
3516065817,
3600352804,
4094571909,
275423344,
430227734,
506948616,
659060556,
883997877,
958139571,
1322822218,
1537002063,
1747873779,
1955562222,
2024104815,
2227730452,
2361852424,
2428436474,
2756734187,
3204031479,
3329325298
]);
var IV = /* @__PURE__ */ new Uint32Array([
1779033703,
3144134277,
1013904242,
2773480762,
1359893119,
2600822924,
528734635,
1541459225
]);
var SHA256_W = /* @__PURE__ */ new Uint32Array(64);
var SHA256 = class extends SHA2 {
constructor() {
super(64, 32, 8, false);
this.A = IV[0] | 0;
this.B = IV[1] | 0;
this.C = IV[2] | 0;
this.D = IV[3] | 0;
this.E = IV[4] | 0;
this.F = IV[5] | 0;
this.G = IV[6] | 0;
this.H = IV[7] | 0;
}
get() {
const { A, B, C, D, E, F, G, H } = this;
return [A, B, C, D, E, F, G, H];
}
// prettier-ignore
set(A, B, C, D, E, F, G, H) {
this.A = A | 0;
this.B = B | 0;
this.C = C | 0;
this.D = D | 0;
this.E = E | 0;
this.F = F | 0;
this.G = G | 0;
this.H = H | 0;
}
process(view, offset) {
for (let i2 = 0; i2 < 16; i2++, offset += 4)
SHA256_W[i2] = view.getUint32(offset, false);
for (let i2 = 16; i2 < 64; i2++) {
const W15 = SHA256_W[i2 - 15];
const W2 = SHA256_W[i2 - 2];
const s0 = rotr(W15, 7) ^ rotr(W15, 18) ^ W15 >>> 3;
const s1 = rotr(W2, 17) ^ rotr(W2, 19) ^ W2 >>> 10;
SHA256_W[i2] = s1 + SHA256_W[i2 - 7] + s0 + SHA256_W[i2 - 16] | 0;
}
let { A, B, C, D, E, F, G, H } = this;
for (let i2 = 0; i2 < 64; i2++) {
const sigma1 = rotr(E, 6) ^ rotr(E, 11) ^ rotr(E, 25);
const T1 = H + sigma1 + Chi(E, F, G) + SHA256_K[i2] + SHA256_W[i2] | 0;
const sigma0 = rotr(A, 2) ^ rotr(A, 13) ^ rotr(A, 22);
const T2 = sigma0 + Maj(A, B, C) | 0;
H = G;
G = F;
F = E;
E = D + T1 | 0;
D = C;
C = B;
B = A;
A = T1 + T2 | 0;
}
A = A + this.A | 0;
B = B + this.B | 0;
C = C + this.C | 0;
D = D + this.D | 0;
E = E + this.E | 0;
F = F + this.F | 0;
G = G + this.G | 0;
H = H + this.H | 0;
this.set(A, B, C, D, E, F, G, H);
}
roundClean() {
SHA256_W.fill(0);
}
destroy() {
this.set(0, 0, 0, 0, 0, 0, 0, 0);
this.buffer.fill(0);
}
};
var sha256 = /* @__PURE__ */ wrapConstructor(() => new SHA256());
// node_modules/@noble/curves/esm/abstract/utils.js
var utils_exports = {};
__export(utils_exports, {
bitGet: () => bitGet,
bitLen: () => bitLen,
bitMask: () => bitMask,
bitSet: () => bitSet,
bytesToHex: () => bytesToHex,
bytesToNumberBE: () => bytesToNumberBE,
bytesToNumberLE: () => bytesToNumberLE,
concatBytes: () => concatBytes2,
createHmacDrbg: () => createHmacDrbg,
ensureBytes: () => ensureBytes,
equalBytes: () => equalBytes,
hexToBytes: () => hexToBytes,
hexToNumber: () => hexToNumber,
numberToBytesBE: () => numberToBytesBE,
numberToBytesLE: () => numberToBytesLE,
numberToHexUnpadded: () => numberToHexUnpadded,
numberToVarBytesBE: () => numberToVarBytesBE,
utf8ToBytes: () => utf8ToBytes2,
validateObject: () => validateObject
});
var _0n = BigInt(0);
var _1n = BigInt(1);
var _2n = BigInt(2);
var u8a2 = (a) => a instanceof Uint8Array;
var hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i2) => i2.toString(16).padStart(2, "0"));
function bytesToHex(bytes4) {
if (!u8a2(bytes4))
throw new Error("Uint8Array expected");
let hex2 = "";
for (let i2 = 0; i2 < bytes4.length; i2++) {
hex2 += hexes[bytes4[i2]];
}
return hex2;
}
function numberToHexUnpadded(num) {
const hex2 = num.toString(16);
return hex2.length & 1 ? `0${hex2}` : hex2;
}
function hexToNumber(hex2) {
if (typeof hex2 !== "string")
throw new Error("hex string expected, got " + typeof hex2);
return BigInt(hex2 === "" ? "0" : `0x${hex2}`);
}
function hexToBytes(hex2) {
if (typeof hex2 !== "string")
throw new Error("hex string expected, got " + typeof hex2);
const len = hex2.length;
if (len % 2)
throw new Error("padded hex string expected, got unpadded hex of length " + len);
const array = new Uint8Array(len / 2);
for (let i2 = 0; i2 < array.length; i2++) {
const j = i2 * 2;
const hexByte = hex2.slice(j, j + 2);
const byte = Number.parseInt(hexByte, 16);
if (Number.isNaN(byte) || byte < 0)
throw new Error("Invalid byte sequence");
array[i2] = byte;
}
return array;
}
function bytesToNumberBE(bytes4) {
return hexToNumber(bytesToHex(bytes4));
}
function bytesToNumberLE(bytes4) {
if (!u8a2(bytes4))
throw new Error("Uint8Array expected");
return hexToNumber(bytesToHex(Uint8Array.from(bytes4).reverse()));
}
function numberToBytesBE(n, len) {
return hexToBytes(n.toString(16).padStart(len * 2, "0"));
}
function numberToBytesLE(n, len) {
return numberToBytesBE(n, len).reverse();
}
function numberToVarBytesBE(n) {
return hexToBytes(numberToHexUnpadded(n));
}
function ensureBytes(title, hex2, expectedLength) {
let res;
if (typeof hex2 === "string") {
try {
res = hexToBytes(hex2);
} catch (e) {
throw new Error(`${title} must be valid hex string, got "${hex2}". Cause: ${e}`);
}
} else if (u8a2(hex2)) {
res = Uint8Array.from(hex2);
} else {
throw new Error(`${title} must be hex string or Uint8Array`);
}
const len = res.length;
if (typeof expectedLength === "number" && len !== expectedLength)
throw new Error(`${title} expected ${expectedLength} bytes, got ${len}`);
return res;
}
function concatBytes2(...arrays) {
const r = new Uint8Array(arrays.reduce((sum, a) => sum + a.length, 0));
let pad2 = 0;
arrays.forEach((a) => {
if (!u8a2(a))
throw new Error("Uint8Array expected");
r.set(a, pad2);
pad2 += a.length;
});
return r;
}
function equalBytes(b1, b2) {
if (b1.length !== b2.length)
return false;
for (let i2 = 0; i2 < b1.length; i2++)
if (b1[i2] !== b2[i2])
return false;
return true;
}
function utf8ToBytes2(str) {
if (typeof str !== "string")
throw new Error(`utf8ToBytes expected string, got ${typeof str}`);
return new Uint8Array(new TextEncoder().encode(str));
}
function bitLen(n) {
let len;
for (len = 0; n > _0n; n >>= _1n, len += 1)
;
return len;
}
function bitGet(n, pos) {
return n >> BigInt(pos) & _1n;
}
var bitSet = (n, pos, value) => {
return n | (value ? _1n : _0n) << BigInt(pos);
};
var bitMask = (n) => (_2n << BigInt(n - 1)) - _1n;
var u8n = (data) => new Uint8Array(data);
var u8fr = (arr) => Uint8Array.from(arr);
function createHmacDrbg(hashLen, qByteLen, hmacFn) {
if (typeof hashLen !== "number" || hashLen < 2)
throw new Error("hashLen must be a number");
if (typeof qByteLen !== "number" || qByteLen < 2)
throw new Error("qByteLen must be a number");
if (typeof hmacFn !== "function")
throw new Error("hmacFn must be a function");
let v = u8n(hashLen);
let k = u8n(hashLen);
let i2 = 0;
const reset = () => {
v.fill(1);
k.fill(0);
i2 = 0;
};
const h = (...b) => hmacFn(k, v, ...b);
const reseed = (seed = u8n()) => {
k = h(u8fr([0]), seed);
v = h();
if (seed.length === 0)
return;
k = h(u8fr([1]), seed);
v = h();
};
const gen = () => {
if (i2++ >= 1e3)
throw new Error("drbg: tried 1000 values");
let len = 0;
const out = [];
while (len < qByteLen) {
v = h();
const sl = v.slice();
out.push(sl);
len += v.length;
}
return concatBytes2(...out);
};
const genUntil = (seed, pred) => {
reset();
reseed(seed);
let res = void 0;
while (!(res = pred(gen())))
reseed();
reset();
return res;
};
return genUntil;
}
var validatorFns = {
bigint: (val) => typeof val === "bigint",
function: (val) => typeof val === "function",
boolean: (val) => typeof val === "boolean",
string: (val) => typeof val === "string",
stringOrUint8Array: (val) => typeof val === "string" || val instanceof Uint8Array,
isSafeInteger: (val) => Number.isSafeInteger(val),
array: (val) => Array.isArray(val),
field: (val, object) => object.Fp.isValid(val),
hash: (val) => typeof val === "function" && Number.isSafeInteger(val.outputLen)
};
function validateObject(object, validators, optValidators = {}) {
const checkField = (fieldName, type, isOptional) => {
const checkVal = validatorFns[type];
if (typeof checkVal !== "function")
throw new Error(`Invalid validator "${type}", expected function`);
const val = object[fieldName];
if (isOptional && val === void 0)
return;
if (!checkVal(val, object)) {
throw new Error(`Invalid param ${String(fieldName)}=${val} (${typeof val}), expected ${type}`);
}
};
for (const [fieldName, type] of Object.entries(validators))
checkField(fieldName, type, false);
for (const [fieldName, type] of Object.entries(optValidators))
checkField(fieldName, type, true);
return object;
}
// node_modules/@noble/curves/esm/abstract/modular.js
var _0n2 = BigInt(0);
var _1n2 = BigInt(1);
var _2n2 = BigInt(2);
var _3n = BigInt(3);
var _4n = BigInt(4);
var _5n = BigInt(5);
var _8n = BigInt(8);
var _9n = BigInt(9);
var _16n = BigInt(16);
function mod(a, b) {
const result = a % b;
return result >= _0n2 ? result : b + result;
}
function pow(num, power, modulo) {
if (modulo <= _0n2 || power < _0n2)
throw new Error("Expected power/modulo > 0");
if (modulo === _1n2)
return _0n2;
let res = _1n2;
while (power > _0n2) {
if (power & _1n2)
res = res * num % modulo;
num = num * num % modulo;
power >>= _1n2;
}
return res;
}
function pow2(x, power, modulo) {
let res = x;
while (power-- > _0n2) {
res *= res;
res %= modulo;
}
return res;
}
function invert(number4, modulo) {
if (number4 === _0n2 || modulo <= _0n2) {
throw new Error(`invert: expected positive integers, got n=${number4} mod=${modulo}`);
}
let a = mod(number4, modulo);
let b = modulo;
let x = _0n2, y = _1n2, u = _1n2, v = _0n2;
while (a !== _0n2) {
const q = b / a;
const r = b % a;
const m = x - u * q;
const n = y - v * q;
b = a, a = r, x = u, y = v, u = m, v = n;
}
const gcd2 = b;
if (gcd2 !== _1n2)
throw new Error("invert: does not exist");
return mod(x, modulo);
}
function tonelliShanks(P) {
const legendreC = (P - _1n2) / _2n2;
let Q, S, Z;
for (Q = P - _1n2, S = 0; Q % _2n2 === _0n2; Q /= _2n2, S++)
;
for (Z = _2n2; Z < P && pow(Z, legendreC, P) !== P - _1n2; Z++)
;
if (S === 1) {
const p1div4 = (P + _1n2) / _4n;
return function tonelliFast(Fp2, n) {
const root = Fp2.pow(n, p1div4);
if (!Fp2.eql(Fp2.sqr(root), n))
throw new Error("Cannot find square root");
return root;
};
}
const Q1div2 = (Q + _1n2) / _2n2;
return function tonelliSlow(Fp2, n) {
if (Fp2.pow(n, legendreC) === Fp2.neg(Fp2.ONE))
throw new Error("Cannot find square root");
let r = S;
let g = Fp2.pow(Fp2.mul(Fp2.ONE, Z), Q);
let x = Fp2.pow(n, Q1div2);
let b = Fp2.pow(n, Q);
while (!Fp2.eql(b, Fp2.ONE)) {
if (Fp2.eql(b, Fp2.ZERO))
return Fp2.ZERO;
let m = 1;
for (let t2 = Fp2.sqr(b); m < r; m++) {
if (Fp2.eql(t2, Fp2.ONE))
break;
t2 = Fp2.sqr(t2);
}
const ge2 = Fp2.pow(g, _1n2 << BigInt(r - m - 1));
g = Fp2.sqr(ge2);
x = Fp2.mul(x, ge2);
b = Fp2.mul(b, g);
r = m;
}
return x;
};
}
function FpSqrt(P) {
if (P % _4n === _3n) {
const p1div4 = (P + _1n2) / _4n;
return function sqrt3mod4(Fp2, n) {
const root = Fp2.pow(n, p1div4);
if (!Fp2.eql(Fp2.sqr(root), n))
throw new Error("Cannot find square root");
return root;
};
}
if (P % _8n === _5n) {
const c1 = (P - _5n) / _8n;
return function sqrt5mod8(Fp2, n) {
const n2 = Fp2.mul(n, _2n2);
const v = Fp2.pow(n2, c1);
const nv = Fp2.mul(n, v);
const i2 = Fp2.mul(Fp2.mul(nv, _2n2), v);
const root = Fp2.mul(nv, Fp2.sub(i2, Fp2.ONE));
if (!Fp2.eql(Fp2.sqr(root), n))
throw new Error("Cannot find square root");
return root;
};
}
if (P % _16n === _9n) {
}
return tonelliShanks(P);
}
var FIELD_FIELDS = [
"create",
"isValid",
"is0",
"neg",
"inv",
"sqrt",
"sqr",
"eql",
"add",
"sub",
"mul",
"pow",
"div",
"addN",
"subN",
"mulN",
"sqrN"
];
function validateField(field) {
const initial = {
ORDER: "bigint",
MASK: "bigint",
BYTES: "isSafeInteger",
BITS: "isSafeInteger"
};
const opts = FIELD_FIELDS.reduce((map, val) => {
map[val] = "function";
return map;
}, initial);
return validateObject(field, opts);
}
function FpPow(f, num, power) {
if (power < _0n2)
throw new Error("Expected power > 0");
if (power === _0n2)
return f.ONE;
if (power === _1n2)
return num;
let p = f.ONE;
let d = num;
while (power > _0n2) {
if (power & _1n2)
p = f.mul(p, d);
d = f.sqr(d);
power >>= _1n2;
}
return p;
}
function FpInvertBatch(f, nums) {
const tmp = new Array(nums.length);
const lastMultiplied = nums.reduce((acc, num, i2) => {
if (f.is0(num))
return acc;
tmp[i2] = acc;
return f.mul(acc, num);
}, f.ONE);
const inverted = f.inv(lastMultiplied);
nums.reduceRight((acc, num, i2) => {
if (f.is0(num))
return acc;
tmp[i2] = f.mul(acc, tmp[i2]);
return f.mul(acc, num);
}, inverted);
return tmp;
}
function nLength(n, nBitLength) {
const _nBitLength = nBitLength !== void 0 ? nBitLength : n.toString(2).length;
const nByteLength = Math.ceil(_nBitLength / 8);
return { nBitLength: _nBitLength, nByteLength };
}
function Field(ORDER, bitLen2, isLE4 = false, redef = {}) {
if (ORDER <= _0n2)
throw new Error(`Expected Field ORDER > 0, got ${ORDER}`);
const { nBitLength: BITS, nByteLength: BYTES } = nLength(ORDER, bitLen2);
if (BYTES > 2048)
throw new Error("Field lengths over 2048 bytes are not supported");
const sqrtP = FpSqrt(ORDER);
const f = Object.freeze({
ORDER,
BITS,
BYTES,
MASK: bitMask(BITS),
ZERO: _0n2,
ONE: _1n2,
create: (num) => mod(num, ORDER),
isValid: (num) => {
if (typeof num !== "bigint")
throw new Error(`Invalid field element: expected bigint, got ${typeof num}`);
return _0n2 <= num && num < ORDER;
},
is0: (num) => num === _0n2,
isOdd: (num) => (num & _1n2) === _1n2,
neg: (num) => mod(-num, ORDER),
eql: (lhs, rhs) => lhs === rhs,
sqr: (num) => mod(num * num, ORDER),
add: (lhs, rhs) => mod(lhs + rhs, ORDER),
sub: (lhs, rhs) => mod(lhs - rhs, ORDER),
mul: (lhs, rhs) => mod(lhs * rhs, ORDER),
pow: (num, power) => FpPow(f, num, power),
div: (lhs, rhs) => mod(lhs * invert(rhs, ORDER), ORDER),
// Same as above, but doesn't normalize
sqrN: (num) => num * num,
addN: (lhs, rhs) => lhs + rhs,
subN: (lhs, rhs) => lhs - rhs,
mulN: (lhs, rhs) => lhs * rhs,
inv: (num) => invert(num, ORDER),
sqrt: redef.sqrt || ((n) => sqrtP(f, n)),
invertBatch: (lst) => FpInvertBatch(f, lst),
// TODO: do we really need constant cmov?
// We don't have const-time bigints anyway, so probably will be not very useful
cmov: (a, b, c) => c ? b : a,
toBytes: (num) => isLE4 ? numberToBytesLE(num, BYTES) : numberToBytesBE(num, BYTES),
fromBytes: (bytes4) => {
if (bytes4.length !== BYTES)
throw new Error(`Fp.fromBytes: expected ${BYTES}, got ${bytes4.length}`);
return isLE4 ? bytesToNumberLE(bytes4) : bytesToNumberBE(bytes4);
}
});
return Object.freeze(f);
}
function getFieldBytesLength(fieldOrder) {
if (typeof fieldOrder !== "bigint")
throw new Error("field order must be bigint");
const bitLength = fieldOrder.toString(2).length;
return Math.ceil(bitLength / 8);
}
function getMinHashLength(fieldOrder) {
const length = getFieldBytesLength(fieldOrder);
return length + Math.ceil(length / 2);
}
function mapHashToField(key, fieldOrder, isLE4 = false) {
const len = key.length;
const fieldLen = getFieldBytesLength(fieldOrder);
const minLen = getMinHashLength(fieldOrder);
if (len < 16 || len < minLen || len > 1024)
throw new Error(`expected ${minLen}-1024 bytes of input, got ${len}`);
const num = isLE4 ? bytesToNumberBE(key) : bytesToNumberLE(key);
const reduced = mod(num, fieldOrder - _1n2) + _1n2;
return isLE4 ? numberToBytesLE(reduced, fieldLen) : numberToBytesBE(reduced, fieldLen);
}
// node_modules/@noble/curves/esm/abstract/curve.js
var _0n3 = BigInt(0);
var _1n3 = BigInt(1);
function wNAF(c, bits) {
const constTimeNegate = (condition, item) => {
const neg = item.negate();
return condition ? neg : item;
};
const opts = (W) => {
const windows = Math.ceil(bits / W) + 1;
const windowSize = 2 ** (W - 1);
return { windows, windowSize };
};
return {
constTimeNegate,
// non-const time multiplication ladder
unsafeLadder(elm, n) {
let p = c.ZERO;
let d = elm;
while (n > _0n3) {
if (n & _1n3)
p = p.add(d);
d = d.double();
n >>= _1n3;
}
return p;
},
/**
* Creates a wNAF precomputation window. Used for caching.
* Default window size is set by `utils.precompute()` and is equal to 8.
* Number of precomputed points depends on the curve size:
* 2^(𝑊−1) * (Math.ceil(𝑛 / 𝑊) + 1), where:
* - 𝑊 is the window size
* - 𝑛 is the bitlength of the curve order.
* For a 256-bit curve and window size 8, the number of precomputed points is 128 * 33 = 4224.
* @returns precomputed point tables flattened to a single array
*/
precomputeWindow(elm, W) {
const { windows, windowSize } = opts(W);
const points = [];
let p = elm;
let base = p;
for (let window = 0; window < windows; window++) {
base = p;
points.push(base);
for (let i2 = 1; i2 < windowSize; i2++) {
base = base.add(p);
points.push(base);
}
p = base.double();
}
return points;
},
/**
* Implements ec multiplication using precomputed tables and w-ary non-adjacent form.
* @param W window size
* @param precomputes precomputed tables
* @param n scalar (we don't check here, but should be less than curve order)
* @returns real and fake (for const-time) points
*/
wNAF(W, precomputes, n) {
const { windows, windowSize } = opts(W);
let p = c.ZERO;
let f = c.BASE;
const mask = BigInt(2 ** W - 1);
const maxNumber = 2 ** W;
const shiftBy = BigInt(W);
for (let window = 0; window < windows; window++) {
const offset = window * windowSize;
let wbits = Number(n & mask);
n >>= shiftBy;
if (wbits > windowSize) {
wbits -= maxNumber;
n += _1n3;
}
const offset1 = offset;
const offset2 = offset + Math.abs(wbits) - 1;
const cond1 = window % 2 !== 0;
const cond2 = wbits < 0;
if (wbits === 0) {
f = f.add(constTimeNegate(cond1, precomputes[offset1]));
} else {
p = p.add(constTimeNegate(cond2, precomputes[offset2]));
}
}
return { p, f };
},
wNAFCached(P, precomputesMap, n, transform) {
const W = P._WINDOW_SIZE || 1;
let comp = precomputesMap.get(P);
if (!comp) {
comp = this.precomputeWindow(P, W);
if (W !== 1) {
precomputesMap.set(P, transform(comp));
}
}
return this.wNAF(W, comp, n);
}
};
}
function validateBasic(curve) {
validateField(curve.Fp);
validateObject(curve, {
n: "bigint",
h: "bigint",
Gx: "field",
Gy: "field"
}, {
nBitLength: "isSafeInteger",
nByteLength: "isSafeInteger"
});
return Object.freeze({
...nLength(curve.n, curve.nBitLength),
...curve,
...{ p: curve.Fp.ORDER }
});
}
// node_modules/@noble/curves/esm/abstract/weierstrass.js
function validatePointOpts(curve) {
const opts = validateBasic(curve);
validateObject(opts, {
a: "field",
b: "field"
}, {
allowedPrivateKeyLengths: "array",
wrapPrivateKey: "boolean",
isTorsionFree: "function",
clearCofactor: "function",
allowInfinityPoint: "boolean",
fromBytes: "function",
toBytes: "function"
});
const { endo, Fp: Fp2, a } = opts;
if (endo) {
if (!Fp2.eql(a, Fp2.ZERO)) {
throw new Error("Endomorphism can only be defined for Koblitz curves that have a=0");
}
if (typeof endo !== "object" || typeof endo.beta !== "bigint" || typeof endo.splitScalar !== "function") {
throw new Error("Expected endomorphism with beta: bigint and splitScalar: function");
}
}
return Object.freeze({ ...opts });
}
var { bytesToNumberBE: b2n, hexToBytes: h2b } = utils_exports;
var DER = {
// asn.1 DER encoding utils
Err: class DERErr extends Error {
constructor(m = "") {
super(m);
}
},
_parseInt(data) {
const { Err: E } = DER;
if (data.length < 2 || data[0] !== 2)
throw new E("Invalid signature integer tag");
const len = data[1];
const res = data.subarray(2, len + 2);
if (!len || res.length !== len)
throw new E("Invalid signature integer: wrong length");
if (res[0] & 128)
throw new E("Invalid signature integer: negative");
if (res[0] === 0 && !(res[1] & 128))
throw new E("Invalid signature integer: unnecessary leading zero");
return { d: b2n(res), l: data.subarray(len + 2) };
},
toSig(hex2) {
const { Err: E } = DER;
const data = typeof hex2 === "string" ? h2b(hex2) : hex2;
if (!(data instanceof Uint8Array))
throw new Error("ui8a expected");
let l = data.length;
if (l < 2 || data[0] != 48)
throw new E("Invalid signature tag");
if (data[1] !== l - 2)
throw new E("Invalid signature: incorrect length");
const { d: r, l: sBytes } = DER._parseInt(data.subarray(2));
const { d: s, l: rBytesLeft } = DER._parseInt(sBytes);
if (rBytesLeft.length)
throw new E("Invalid signature: left bytes after parsing");
return { r, s };
},
hexFromSig(sig) {
const slice = (s2) => Number.parseInt(s2[0], 16) & 8 ? "00" + s2 : s2;
const h = (num) => {
const hex2 = num.toString(16);
return hex2.length & 1 ? `0${hex2}` : hex2;
};
const s = slice(h(sig.s));
const r = slice(h(sig.r));
const shl = s.length / 2;
const rhl = r