@fileverse/api 0.0.20 → 0.0.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +30 -34
- package/dist/cli/index.js.map +1 -1
- package/dist/commands/index.js +16 -131
- package/dist/commands/index.js.map +1 -1
- package/dist/index.js +133 -374
- package/dist/index.js.map +1 -1
- package/dist/worker.js +106 -297
- package/dist/worker.js.map +1 -1
- package/package.json +6 -5
- package/public/llm.txt +478 -204
- package/dist/cloudflare.js +0 -18276
- package/dist/cloudflare.js.map +0 -1
package/dist/worker.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../node_modules/tsup/assets/esm_shims.js","../src/cli/constants.generated.ts","../src/cli/constants.ts","../src/config/index.ts","../src/infra/logger.ts","../src/infra/asyncHandler.ts","../src/infra/database/adapters/sql-compat.ts","../src/infra/database/adapters/pg-column-map.ts","../src/infra/database/adapters/postgres-adapter.ts","../src/infra/database/adapters/sqlite-adapter.ts","../src/infra/database/connection.ts","../src/domain/file/constants.ts","../src/infra/database/query-builder.ts","../src/infra/database/index.ts","../src/infra/database/models/files.model.ts","../src/infra/database/models/portals.model.ts","../src/infra/database/models/apikeys.model.ts","../src/infra/database/models/folders.model.ts","../src/infra/worker/workerSignal.ts","../src/infra/database/models/events.model.ts","../src/infra/database/models/index.ts","../src/sdk/key-store.ts","../src/sdk/ucan.ts","../src/sdk/auth-token-provider.ts","../src/constants/chains.ts","../src/constants/events.ts","../src/constants/methods.ts","../src/constants/index.ts","../src/sdk/pimlico-utils.ts","../src/sdk/smart-agent.ts","../node_modules/@noble/ciphers/src/utils.ts","../node_modules/@noble/ciphers/src/_polyval.ts","../node_modules/@noble/ciphers/src/aes.ts","../src/sdk/file-encryption.ts","../src/sdk/file-utils.ts","../src/sdk/file-manager.ts","../src/domain/portal/publish.ts","../src/domain/portal/savePortal.ts","../src/domain/portal/saveApiKey.ts","../src/domain/portal/removeApiKey.ts","../src/domain/portal/index.ts","../src/errors/rate-limit.ts","../src/infra/worker/eventProcessor.ts","../src/infra/worker/worker.ts","../src/infra/worker/index.ts","../src/appWorker.ts","../src/infra/reporter.ts","../src/infra/index.ts","../src/worker.ts","../src/infra/database/migrations/index.ts"],"sourcesContent":["// Shim globals in esm bundle\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\n","export const STATIC_CONFIG = {\n API_URL: 'https://prod-apps-storage-5cdacc06ff79.herokuapp.com/',\n SERVER_DID: 'did:key:z6Mkroj9bxTin6Z5S9qwx2G2b87NPrCX7S85FhCpmBGPcDCz',\n PROXY_SERVER_DID: 'did:key:z6MkrZSmq8D6vQG87YbjUQatXeptaCCXWdTx8fYaWxWbRUHB',\n NETWORK_NAME: 'gnosis',\n DEFAULT_PORT: '8001',\n DEFAULT_RPC_URL: 'https://rpc.gnosischain.com',\n PIMLICO_PROXY_URL: 'https://pimlico-proxy-0a326da116f8.herokuapp.com/',\n SERVICE_NAME: 'fileverse-api',\n LOG_LEVEL: 'info',\n FRONTEND_URL: 'https://docs.fileverse.io'\n} as const;\n\nexport const BASE_CONFIG = STATIC_CONFIG;\n","export { STATIC_CONFIG, BASE_CONFIG } from \"./constants.generated.js\";\n","import dotenv from \"dotenv\";\nimport path from \"path\";\nimport fs from \"fs\";\nimport os from \"os\";\nimport { STATIC_CONFIG } from \"../cli/constants.js\";\n\nconst projectEnvPath = path.join(process.cwd(), \"config\", \".env\");\nconst userEnvPath = path.join(os.homedir(), \".fileverse\", \".env\");\n\nfunction getEnvPath(): string {\n if (fs.existsSync(projectEnvPath)) {\n return projectEnvPath;\n }\n return userEnvPath;\n}\n\nexport function loadConfig(override = true): void {\n const envPath = getEnvPath();\n dotenv.config({ path: envPath, override });\n}\n\nif (typeof globalThis.process !== 'undefined' && typeof globalThis.process.cwd === 'function') {\n try { loadConfig(false); } catch {}\n}\n\nexport function getRuntimeConfig() {\n return {\n get API_KEY() {\n return process.env.API_KEY;\n },\n get RPC_URL() {\n return process.env.RPC_URL || STATIC_CONFIG.DEFAULT_RPC_URL;\n },\n get DB_PATH() {\n return process.env.DB_PATH;\n },\n get DATABASE_URL() {\n return process.env.DATABASE_URL;\n },\n get PORT() {\n return process.env.PORT || STATIC_CONFIG.DEFAULT_PORT;\n },\n get NODE_ENV() {\n return process.env.NODE_ENV || \"production\";\n },\n get FRONTEND_URL() {\n return process.env.FRONTEND_URL || STATIC_CONFIG.FRONTEND_URL;\n },\n };\n}\n\nexport function validateDbConfig(): void {\n const databaseUrl = process.env.DATABASE_URL;\n const dbPath = process.env.DB_PATH;\n\n // If DATABASE_URL is set, skip file path validation (PostgreSQL mode)\n if (databaseUrl) {\n return;\n }\n\n if (!dbPath) {\n console.error(\"Error: DB_PATH or DATABASE_URL environment variable is required\");\n console.error(\"Please set DB_PATH or DATABASE_URL in your .env file (config/.env or ~/.fileverse/.env) or run the CLI first\");\n process.exit(1);\n }\n\n const dbDir = path.dirname(dbPath.trim());\n if (!fs.existsSync(dbDir)) {\n fs.mkdirSync(dbDir, { recursive: true });\n }\n}\n\n// Keep backwards-compatible alias\nexport const validateDbPath = validateDbConfig;\n\nconst config: Record<string, string | undefined> = {\n ...STATIC_CONFIG,\n get SERVICE_NAME() {\n return STATIC_CONFIG.SERVICE_NAME;\n },\n get LOG_LEVEL() {\n return STATIC_CONFIG.LOG_LEVEL;\n },\n get NETWORK_NAME() {\n return STATIC_CONFIG.NETWORK_NAME;\n },\n get UPLOAD_SERVER_URL() {\n return STATIC_CONFIG.API_URL;\n },\n get UPLOAD_SERVER_DID() {\n return STATIC_CONFIG.SERVER_DID;\n },\n get API_KEY() {\n return process.env.API_KEY;\n },\n get RPC_URL() {\n return process.env.RPC_URL || STATIC_CONFIG.DEFAULT_RPC_URL;\n },\n get DB_PATH() {\n return process.env.DB_PATH;\n },\n get DATABASE_URL() {\n return process.env.DATABASE_URL;\n },\n get PORT() {\n return process.env.PORT || STATIC_CONFIG.DEFAULT_PORT;\n },\n get NODE_ENV() {\n return process.env.NODE_ENV || \"production\";\n },\n get IP() {\n return process.env.IP || \"0.0.0.0\";\n },\n get FRONTEND_URL() {\n return process.env.FRONTEND_URL || STATIC_CONFIG.FRONTEND_URL;\n },\n};\n\nexport { config };\n","import pino, { Logger as PinoLogger, Level } from \"pino\";\nimport { STATIC_CONFIG } from \"../cli/constants\";\nimport { config } from \"../config\";\n\nconst isProduction = config.NODE_ENV === \"production\";\n\nconst pinoInstance = pino({\n name: STATIC_CONFIG.SERVICE_NAME,\n level: STATIC_CONFIG.LOG_LEVEL,\n formatters: {\n bindings: (bindings) => ({ name: bindings.name }),\n level: (label) => ({ level: label }),\n },\n serializers: {\n err(err: Error | undefined) {\n if (!err) return err;\n if (isProduction) {\n return { type: err.name, message: err.message };\n }\n return {\n type: err.name,\n message: err.message,\n stack: err.stack,\n };\n },\n },\n transport:\n config.NODE_ENV !== \"production\"\n ? {\n target: \"pino-pretty\",\n options: {\n colorize: true,\n translateTime: \"SYS:standard\",\n ignore: \"pid,hostname\",\n errorProps: \"*\",\n errorLikeObjectKeys: [\"err\", \"error\"],\n },\n }\n : undefined,\n});\n\ntype LogFn = {\n (msg: string, ...args: unknown[]): void;\n (obj: object, msg?: string, ...args: unknown[]): void;\n};\n\nconst createLogMethod = (level: Level): LogFn => {\n return (...args: unknown[]) => {\n const [first, ...rest] = args;\n const log = pinoInstance[level].bind(pinoInstance) as (...a: unknown[]) => void;\n\n if (typeof first === \"object\" && first !== null && !(first instanceof Error)) {\n log(first, ...rest);\n return;\n }\n\n if (rest.length > 0) {\n const last = rest[rest.length - 1];\n if (last instanceof Error) {\n log({ err: last }, first, ...rest.slice(0, -1));\n return;\n }\n }\n\n if (first instanceof Error) {\n log({ err: first }, first.message);\n return;\n }\n\n log(first, ...rest);\n };\n};\n\ninterface Logger {\n trace: LogFn;\n debug: LogFn;\n info: LogFn;\n warn: LogFn;\n error: LogFn;\n fatal: LogFn;\n level: Level;\n child: PinoLogger[\"child\"];\n}\n\nexport const logger: Logger = {\n trace: createLogMethod(\"trace\"),\n debug: createLogMethod(\"debug\"),\n info: createLogMethod(\"info\"),\n warn: createLogMethod(\"warn\"),\n error: createLogMethod(\"error\"),\n fatal: createLogMethod(\"fatal\"),\n get level() {\n return pinoInstance.level as Level;\n },\n set level(lvl: Level) {\n pinoInstance.level = lvl;\n },\n child: pinoInstance.child.bind(pinoInstance),\n};\n","import { Request, Response, NextFunction } from \"express\";\n\nconst asyncHandler =\n (fn: (req: Request, res: Response, next: NextFunction) => Promise<void>) =>\n (req: Request, res: Response, next: NextFunction) =>\n Promise.resolve(fn(req, res, next)).catch(next);\n\nconst asyncHandlerArray = (resolvers: any) => {\n return resolvers.map(asyncHandler);\n};\n\nexport { asyncHandler, asyncHandlerArray };\n","/**\n * Converts SQLite-style `?` placeholders to PostgreSQL-style `$1, $2, ...`\n * Skips placeholders inside single-quoted string literals.\n */\nexport function sqliteToPostgres(sql: string): string {\n let result = \"\";\n let paramIndex = 0;\n let inString = false;\n\n for (let i = 0; i < sql.length; i++) {\n const ch = sql[i];\n\n if (ch === \"'\") {\n // Handle escaped single quotes ('')\n if (inString && i + 1 < sql.length && sql[i + 1] === \"'\") {\n result += \"''\";\n i++;\n continue;\n }\n inString = !inString;\n result += ch;\n } else if (ch === \"?\" && !inString) {\n paramIndex++;\n result += `$${paramIndex}`;\n } else {\n result += ch;\n }\n }\n\n return result;\n}\n","/**\n * Static map of lowercase → camelCase column names.\n * PostgreSQL lowercases all unquoted identifiers, so query results come back\n * with lowercase keys. This map restores the original camelCase names.\n */\nconst COLUMN_MAP: Record<string, string> = {\n ddocid: \"ddocId\",\n localversion: \"localVersion\",\n onchainversion: \"onchainVersion\",\n syncstatus: \"syncStatus\",\n createdat: \"createdAt\",\n updatedat: \"updatedAt\",\n isdeleted: \"isDeleted\",\n portaladdress: \"portalAddress\",\n onchainfileid: \"onChainFileId\",\n commentkey: \"commentKey\",\n linkkey: \"linkKey\",\n linkkeynonce: \"linkKeyNonce\",\n portalseed: \"portalSeed\",\n owneraddress: \"ownerAddress\",\n apikeyseed: \"apiKeySeed\",\n collaboratoraddress: \"collaboratorAddress\",\n fileid: \"fileId\",\n retrycount: \"retryCount\",\n lasterror: \"lastError\",\n lockedat: \"lockedAt\",\n nextretryat: \"nextRetryAt\",\n userophash: \"userOpHash\",\n pendingpayload: \"pendingPayload\",\n folderid: \"folderId\",\n folderref: \"folderRef\",\n foldername: \"folderName\",\n metadataipfshash: \"metadataIPFSHash\",\n contentipfshash: \"contentIPFSHash\",\n lasttransactionhash: \"lastTransactionHash\",\n lasttransactionblocknumber: \"lastTransactionBlockNumber\",\n lasttransactionblocktimestamp: \"lastTransactionBlockTimestamp\",\n};\n\nexport function remapRow<T>(row: Record<string, unknown>): T {\n const out: Record<string, unknown> = {};\n for (const key in row) {\n out[COLUMN_MAP[key] ?? key] = row[key];\n }\n return out as T;\n}\n\nexport function remapRows<T>(rows: Record<string, unknown>[]): T[] {\n return rows.map((row) => remapRow<T>(row));\n}\n","import type { DatabaseAdapter, ExecuteResult } from \"./adapter.js\";\nimport { sqliteToPostgres } from \"./sql-compat.js\";\nimport { remapRows, remapRow } from \"./pg-column-map.js\";\nimport { logger } from \"../../index.js\";\n\n// pg is lazy-imported so SQLite-only users don't need it installed\nlet pgModule: typeof import(\"pg\") | null = null;\n\nasync function getPg() {\n if (!pgModule) {\n pgModule = await import(\"pg\");\n }\n return pgModule;\n}\n\nexport class PostgresAdapter implements DatabaseAdapter {\n private pool: InstanceType<typeof import(\"pg\").Pool> | null = null;\n private connectionUrl: string;\n private connected = false;\n readonly dialect = \"postgres\" as const;\n\n constructor(connectionUrl: string) {\n this.connectionUrl = connectionUrl;\n }\n\n private async getPool() {\n if (!this.pool) {\n const pg = await getPg();\n this.pool = new pg.default.Pool({\n connectionString: this.connectionUrl,\n max: 10,\n ssl: this.connectionUrl.includes(\"sslmode=require\") || this.connectionUrl.includes(\"amazonaws.com\") || this.connectionUrl.includes(\"heroku\")\n ? { rejectUnauthorized: false }\n : undefined,\n });\n // Verify connectivity\n const client = await this.pool.connect();\n client.release();\n this.connected = true;\n logger.info(\"PostgreSQL database connected\");\n }\n return this.pool;\n }\n\n async select<T>(sql: string, params: any[] = []): Promise<T[]> {\n const pool = await this.getPool();\n const pgSql = sqliteToPostgres(sql);\n const result = await pool.query(pgSql, params);\n return remapRows<T>(result.rows);\n }\n\n async selectOne<T>(sql: string, params: any[] = []): Promise<T | undefined> {\n const pool = await this.getPool();\n const pgSql = sqliteToPostgres(sql);\n const result = await pool.query(pgSql, params);\n return result.rows[0] ? remapRow<T>(result.rows[0]) : undefined;\n }\n\n async execute(sql: string, params: any[] = []): Promise<ExecuteResult> {\n const pool = await this.getPool();\n const pgSql = sqliteToPostgres(sql);\n const result = await pool.query(pgSql, params);\n return {\n changes: result.rowCount ?? 0,\n lastInsertRowid: 0,\n };\n }\n\n async transaction<T>(callback: () => Promise<T>): Promise<T> {\n const pool = await this.getPool();\n const client = await pool.connect();\n try {\n await client.query(\"BEGIN\");\n const result = await callback();\n await client.query(\"COMMIT\");\n return result;\n } catch (error) {\n await client.query(\"ROLLBACK\");\n throw error;\n } finally {\n client.release();\n }\n }\n\n async exec(sql: string): Promise<void> {\n const pool = await this.getPool();\n await pool.query(sql);\n }\n\n async close(): Promise<void> {\n if (this.pool) {\n await this.pool.end();\n this.pool = null;\n this.connected = false;\n logger.info(\"Database connection closed\");\n }\n }\n\n isConnected(): boolean {\n return this.connected;\n }\n}\n","import Database from \"better-sqlite3\";\nimport type { DatabaseAdapter, ExecuteResult } from \"./adapter.js\";\nimport { logger } from \"../../index.js\";\n\nexport class SqliteAdapter implements DatabaseAdapter {\n private db: Database.Database | null = null;\n readonly dialect = \"sqlite\" as const;\n\n constructor(private dbPath: string) {}\n\n private getDb(): Database.Database {\n if (!this.db) {\n this.db = new Database(this.dbPath);\n this.db.pragma(\"journal_mode = WAL\");\n this.db.pragma(\"foreign_keys = ON\");\n this.db.prepare(\"SELECT 1\").get();\n logger.info(`SQLite database connected: ${this.dbPath}`);\n }\n return this.db;\n }\n\n async select<T>(sql: string, params: any[] = []): Promise<T[]> {\n const stmt = this.getDb().prepare(sql);\n return stmt.all(params) as T[];\n }\n\n async selectOne<T>(sql: string, params: any[] = []): Promise<T | undefined> {\n const stmt = this.getDb().prepare(sql);\n return stmt.get(params) as T | undefined;\n }\n\n async execute(sql: string, params: any[] = []): Promise<ExecuteResult> {\n const stmt = this.getDb().prepare(sql);\n const result = stmt.run(params);\n return {\n changes: result.changes,\n lastInsertRowid: result.lastInsertRowid,\n };\n }\n\n async transaction<T>(callback: () => Promise<T>): Promise<T> {\n const db = this.getDb();\n const savepointName = `sp_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;\n db.exec(`SAVEPOINT ${savepointName}`);\n try {\n const result = await callback();\n db.exec(`RELEASE ${savepointName}`);\n return result;\n } catch (error) {\n db.exec(`ROLLBACK TO ${savepointName}`);\n db.exec(`RELEASE ${savepointName}`);\n throw error;\n }\n }\n\n async exec(sql: string): Promise<void> {\n this.getDb().exec(sql);\n }\n\n async close(): Promise<void> {\n if (this.db) {\n this.db.close();\n this.db = null;\n logger.info(\"Database connection closed\");\n }\n }\n\n isConnected(): boolean {\n return this.db !== null && this.db.open;\n }\n}\n","import type { DatabaseAdapter } from \"./adapters/index.js\";\nimport { logger } from \"../index.js\";\nimport path from \"path\";\nimport fs from \"fs\";\n\nlet adapter: DatabaseAdapter | null = null;\n\n/**\n * Auto-detect and initialize the database adapter:\n * - DATABASE_URL env → PostgreSQL\n * - DB_PATH env → SQLite\n */\nexport async function initializeAdapter(): Promise<DatabaseAdapter> {\n if (adapter) return adapter;\n\n const databaseUrl = process.env.DATABASE_URL;\n const dbPath = process.env.DB_PATH;\n\n if (databaseUrl) {\n const { PostgresAdapter } = await import(\"./adapters/postgres-adapter.js\");\n adapter = new PostgresAdapter(databaseUrl);\n logger.info(\"Using PostgreSQL adapter\");\n } else if (dbPath) {\n // Ensure DB directory exists\n const dbDir = path.dirname(dbPath.trim());\n if (!fs.existsSync(dbDir)) {\n fs.mkdirSync(dbDir, { recursive: true });\n }\n\n const { SqliteAdapter } = await import(\"./adapters/sqlite-adapter.js\");\n adapter = new SqliteAdapter(dbPath);\n logger.info(\"Using SQLite adapter\");\n } else {\n throw new Error(\n \"No database configured. Set DATABASE_URL (PostgreSQL) or DB_PATH (SQLite).\",\n );\n }\n\n return adapter;\n}\n\n/**\n * Returns the active adapter, lazy-initializing if needed.\n */\nexport async function getAdapter(): Promise<DatabaseAdapter> {\n if (!adapter) {\n return initializeAdapter();\n }\n return adapter;\n}\n\n/**\n * Inject an externally-created adapter (e.g. D1 for Cloudflare Workers).\n * Must be called before any domain logic runs.\n */\nexport function setAdapter(external: DatabaseAdapter): void {\n adapter = external;\n}\n\n/**\n * Graceful shutdown — close the active adapter.\n */\nexport async function closeAdapter(): Promise<void> {\n if (adapter) {\n await adapter.close();\n adapter = null;\n }\n}\n","/**\n * Default limit for listing files/ddocs\n * Used by both API and CLI to ensure consistent behavior\n */\nexport const DEFAULT_LIST_LIMIT = 10;\n","import { getAdapter } from \"./connection.js\";\nimport type { QueryOptions } from \"../../types\";\nimport type { ExecuteResult } from \"./adapters/index.js\";\nimport { DEFAULT_LIST_LIMIT } from \"../../domain/file/constants\";\n\nexport class QueryBuilder {\n static async select<T = any>(sql: string, params: any[] = []): Promise<T[]> {\n const adapter = await getAdapter();\n return adapter.select<T>(sql, params);\n }\n\n static async selectOne<T = any>(sql: string, params: any[] = []): Promise<T | undefined> {\n const adapter = await getAdapter();\n return adapter.selectOne<T>(sql, params);\n }\n\n static async execute(sql: string, params: any[] = []): Promise<ExecuteResult> {\n const adapter = await getAdapter();\n return adapter.execute(sql, params);\n }\n\n static async transaction<T>(callback: () => Promise<T>): Promise<T> {\n const adapter = await getAdapter();\n return adapter.transaction(callback);\n }\n\n static paginate(sql: string, options: QueryOptions = {}): string {\n let query = sql;\n\n if (options.orderBy) {\n query += ` ORDER BY ${options.orderBy} ${options.orderDirection || \"ASC\"}`;\n }\n\n const hasOffset = (options.offset ?? 0) > 0;\n const limit = options.limit ?? (hasOffset ? DEFAULT_LIST_LIMIT : undefined);\n\n if (limit) {\n query += ` LIMIT ${limit}`;\n }\n\n if (hasOffset) {\n query += ` OFFSET ${options.offset}`;\n }\n\n return query;\n }\n}\n","import { getAdapter, closeAdapter, initializeAdapter, setAdapter } from \"./connection.js\";\nimport { QueryBuilder } from \"./query-builder.js\";\n\nconst closeDatabase = async (): Promise<void> => {\n await closeAdapter();\n};\n\nexport { getAdapter, initializeAdapter, closeAdapter, setAdapter, closeDatabase, QueryBuilder };\n","import { QueryBuilder } from \"../index.js\";\nimport { uuidv7 } from \"uuidv7\";\nimport type { File, FileListResponse, UpdateFilePayload } from \"../../../types\";\n\nexport type { File, FileListResponse };\n\nexport class FilesModel {\n private static readonly TABLE = \"files\";\n\n private static parseFile(fileRaw: any): File {\n let metadata: Record<string, unknown> = {};\n try {\n if (fileRaw.metadata) {\n metadata = typeof fileRaw.metadata === \"string\" ? JSON.parse(fileRaw.metadata) : fileRaw.metadata;\n }\n } catch (e) {\n // If parsing fails, use empty object\n metadata = {};\n }\n\n return {\n _id: fileRaw._id,\n ddocId: fileRaw.ddocId,\n title: fileRaw.title,\n content: fileRaw.content,\n localVersion: fileRaw.localVersion,\n onchainVersion: fileRaw.onchainVersion,\n syncStatus: fileRaw.syncStatus,\n isDeleted: fileRaw.isDeleted,\n onChainFileId: fileRaw.onChainFileId ?? null,\n portalAddress: fileRaw.portalAddress,\n metadata: metadata || {},\n createdAt: fileRaw.createdAt,\n updatedAt: fileRaw.updatedAt,\n linkKey: fileRaw.linkKey,\n linkKeyNonce: fileRaw.linkKeyNonce,\n commentKey: fileRaw.commentKey,\n link: fileRaw.link,\n derivedKey: fileRaw.derivedKey,\n secretKey: fileRaw.secretKey,\n };\n }\n\n static async findAll(\n portalAddress: string,\n limit?: number,\n skip?: number,\n ): Promise<{ files: File[]; total: number; hasNext: boolean }> {\n const whereClause = \"isDeleted = 0 AND portalAddress = ?\";\n const params: any[] = [portalAddress];\n\n const countSql = `\n SELECT COUNT(*) as count\n FROM ${this.TABLE}\n WHERE ${whereClause}\n `;\n const totalResult = await QueryBuilder.selectOne<{ count: number }>(countSql, params);\n const total = totalResult?.count || 0;\n const sql = `\n SELECT *\n FROM ${this.TABLE}\n WHERE ${whereClause}\n `;\n const completeSql = QueryBuilder.paginate(sql, {\n limit,\n offset: skip,\n orderBy: \"createdAt\",\n orderDirection: \"DESC\",\n });\n\n const filesRaw = await QueryBuilder.select<any>(completeSql, params);\n const files = filesRaw.map(this.parseFile);\n const hasNext = skip !== undefined && limit !== undefined ? skip + limit < total : false;\n return { files, total, hasNext };\n }\n\n static async findById(_id: string, portalAddress: string): Promise<File | undefined> {\n const sql = `\n SELECT *\n FROM ${this.TABLE}\n WHERE _id = ? AND isDeleted = 0 AND portalAddress = ?\n `;\n const result = await QueryBuilder.selectOne<any>(sql, [_id, portalAddress]);\n return result ? this.parseFile(result) : undefined;\n }\n\n static async findByIdIncludingDeleted(_id: string): Promise<File | undefined> {\n const sql = `\n SELECT *\n FROM ${this.TABLE}\n WHERE _id = ?\n `;\n const result = await QueryBuilder.selectOne<any>(sql, [_id]);\n return result ? this.parseFile(result) : undefined;\n }\n\n static async findByIdExcludingDeleted(_id: string): Promise<File | undefined> {\n const sql = `\n SELECT *\n FROM ${this.TABLE}\n WHERE _id = ? AND isDeleted = 0\n `;\n const result = await QueryBuilder.selectOne<any>(sql, [_id]);\n return result ? this.parseFile(result) : undefined;\n }\n\n static async findByDDocId(ddocId: string, portalAddress: string): Promise<File | undefined> {\n const sql = `\n SELECT *\n FROM ${this.TABLE}\n WHERE ddocId = ? AND isDeleted = 0 AND portalAddress = ?\n `;\n const result = await QueryBuilder.selectOne<any>(sql, [ddocId, portalAddress]);\n return result ? this.parseFile(result) : undefined;\n }\n\n static async searchByTitle(searchTerm: string, portalAddress: string, limit?: number, skip?: number): Promise<File[]> {\n const sql = `\n SELECT *\n FROM ${this.TABLE}\n WHERE LOWER(title) LIKE LOWER(?) AND isDeleted = 0 AND portalAddress = ?\n `;\n const completeSql = QueryBuilder.paginate(sql, {\n limit,\n offset: skip,\n orderBy: \"createdAt\",\n orderDirection: \"DESC\",\n });\n const filesRaw = await QueryBuilder.select<any>(completeSql, [`%${searchTerm}%`, portalAddress]);\n return filesRaw.map(this.parseFile);\n }\n\n static async create(input: {\n title: string;\n content: string;\n ddocId: string;\n portalAddress: string;\n linkKey?: string;\n linkKeyNonce?: string;\n derivedKey?: string;\n secretKey?: string;\n }): Promise<File> {\n const _id = uuidv7();\n const sql = `\n INSERT INTO ${this.TABLE}\n (_id, title, content, ddocId, portalAddress, linkKey, linkKeyNonce, derivedKey, secretKey)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)\n `;\n\n await QueryBuilder.execute(sql, [\n _id,\n input.title,\n input.content,\n input.ddocId,\n input.portalAddress,\n input.linkKey ?? null,\n input.linkKeyNonce ?? null,\n input.derivedKey ?? null,\n input.secretKey ?? null,\n ]);\n // NOTE: default values while file creation: localVersion = 1, onchainVersion = 0, syncStatus = 'pending'\n\n const created = await this.findById(_id, input.portalAddress);\n if (!created) {\n throw new Error(\"Failed to create file\");\n }\n return created;\n }\n\n static async update(_id: string, payload: UpdateFilePayload, portalAddress: string): Promise<File> {\n const now = new Date().toISOString();\n\n const keys: string[] = [];\n const values: any[] = [];\n for (const [k, v] of Object.entries(payload)) {\n if (v !== undefined) {\n // Handle metadata specially - convert to JSON string\n if (k === \"metadata\" && typeof v === \"object\") {\n keys.push(`${k} = ?`);\n values.push(JSON.stringify(v));\n } else {\n keys.push(`${k} = ?`);\n values.push(v);\n }\n }\n }\n\n // Always add updatedAt\n keys.push(\"updatedAt = ?\");\n values.push(now, _id, portalAddress);\n\n const updateChain = keys.join(\", \");\n const sql = `UPDATE ${this.TABLE} SET ${updateChain} WHERE _id = ? AND portalAddress = ?`;\n\n await QueryBuilder.execute(sql, values);\n\n const updated = await this.findById(_id, portalAddress);\n if (!updated) {\n throw new Error(\"Failed to update file\");\n }\n return updated;\n }\n\n static async softDelete(_id: string): Promise<File> {\n const now = new Date().toISOString();\n const sql = `\n UPDATE ${this.TABLE}\n SET isDeleted = 1, syncStatus = 'pending', updatedAt = ?\n WHERE _id = ?\n `;\n\n await QueryBuilder.execute(sql, [now, _id]);\n\n // Use findByIdIncludingDeleted since the file is now marked as deleted\n const deleted = await this.findByIdIncludingDeleted(_id);\n if (!deleted) {\n throw new Error(\"Failed to delete file\");\n }\n return deleted;\n }\n}\n","import { QueryBuilder } from \"../index.js\";\nimport { uuidv7 } from \"uuidv7\";\nimport type { Portal } from \"../../../types\";\n\nexport type { Portal };\n\nexport class PortalsModel {\n private static readonly TABLE = \"portals\";\n\n static async findByPortalAddress(portalAddress: string): Promise<Portal | undefined> {\n const sql = `SELECT _id, portalAddress, portalSeed, ownerAddress, createdAt, updatedAt FROM ${this.TABLE} WHERE portalAddress = ?`;\n return QueryBuilder.selectOne<Portal>(sql, [portalAddress]);\n }\n\n static async create(input: { portalAddress: string; portalSeed: string; ownerAddress: string }): Promise<Portal> {\n const _id = uuidv7();\n const now = new Date().toISOString();\n const sql = `INSERT INTO ${this.TABLE} (_id, portalAddress, portalSeed, ownerAddress, createdAt, updatedAt) VALUES (?, ?, ?, ?, ?, ?)`;\n\n await QueryBuilder.execute(sql, [_id, input.portalAddress, input.portalSeed, input.ownerAddress, now, now]);\n\n const created = await this.findByPortalAddress(input.portalAddress);\n if (!created) {\n throw new Error(\"Failed to create portal\");\n }\n return created;\n }\n\n static async update(\n portalAddress: string,\n input: {\n portalSeed?: string;\n ownerAddress?: string;\n },\n ): Promise<Portal> {\n const now = new Date().toISOString();\n const keys: string[] = [];\n const values: any[] = [];\n\n for (const [k, v] of Object.entries(input)) {\n if (v !== undefined) {\n keys.push(`${k} = ?`);\n values.push(v);\n }\n }\n\n keys.push(\"updatedAt = ?\");\n values.push(now);\n\n const updateChain = keys.join(\", \");\n const sql = `UPDATE ${this.TABLE} SET ${updateChain} WHERE portalAddress = ?`;\n values.push(portalAddress);\n await QueryBuilder.execute(sql, values);\n\n const updated = await this.findByPortalAddress(portalAddress);\n if (!updated) {\n throw new Error(\"Failed to update portal\");\n }\n return updated;\n }\n\n static async upsert(input: { portalAddress: string; portalSeed: string; ownerAddress: string }): Promise<Portal> {\n const existing = await this.findByPortalAddress(input.portalAddress);\n if (existing) {\n return this.update(input.portalAddress, {\n portalSeed: input.portalSeed,\n ownerAddress: input.ownerAddress,\n });\n }\n return this.create(input);\n }\n}\n","import { QueryBuilder } from \"../index.js\";\nimport { uuidv7 } from \"uuidv7\";\nimport type { ApiKey } from \"../../../types\";\n\nexport type { ApiKey };\n\nexport class ApiKeysModel {\n private static readonly TABLE = \"api_keys\";\n\n static async create(input: {\n apiKeySeed: string;\n name: string;\n collaboratorAddress: string;\n portalAddress: string;\n }): Promise<ApiKey> {\n const _id = uuidv7();\n const now = new Date().toISOString();\n const sql = `INSERT INTO ${this.TABLE} (_id, apiKeySeed, name, collaboratorAddress, portalAddress, createdAt)\n VALUES (?, ?, ?, ?, ?, ?)`;\n\n const result = await QueryBuilder.execute(sql, [\n _id,\n input.apiKeySeed,\n input.name,\n input.collaboratorAddress,\n input.portalAddress,\n now,\n ]);\n\n if (result.changes === 0) {\n throw new Error(\"Failed to create API key\");\n }\n\n const created = await this.findById(_id);\n if (!created) {\n throw new Error(\"Failed to create API key\");\n }\n return created;\n }\n\n static async findById(_id: string): Promise<ApiKey | undefined> {\n const sql = `SELECT _id, apiKeySeed, name, collaboratorAddress, portalAddress, createdAt, isDeleted FROM ${this.TABLE} WHERE _id = ? AND isDeleted = 0`;\n return QueryBuilder.selectOne<ApiKey>(sql, [_id]);\n }\n\n static async findByCollaboratorAddress(collaboratorAddress: string): Promise<ApiKey | undefined> {\n const sql = `SELECT _id, apiKeySeed, name, collaboratorAddress, portalAddress, createdAt, isDeleted FROM ${this.TABLE} WHERE collaboratorAddress = ? AND isDeleted = 0 LIMIT 1`;\n return QueryBuilder.selectOne<ApiKey>(sql, [collaboratorAddress]);\n }\n\n static async delete(_id: string): Promise<void> {\n const sql = `UPDATE ${this.TABLE} SET isDeleted = 1 WHERE _id = ?`;\n await QueryBuilder.execute(sql, [_id]);\n }\n\n static async findByPortalAddress(portalAddress: string): Promise<ApiKey | undefined> {\n const sql = `SELECT _id, apiKeySeed, name, collaboratorAddress, portalAddress, createdAt, isDeleted FROM ${this.TABLE} WHERE portalAddress = ? AND isDeleted = 0`;\n return QueryBuilder.selectOne<ApiKey>(sql, [portalAddress]);\n }\n\n static async findByApiKey(apiKey: string): Promise<ApiKey | undefined> {\n const sql = `SELECT _id, apiKeySeed, name, collaboratorAddress, portalAddress, createdAt, isDeleted FROM ${this.TABLE} WHERE apiKeySeed = ? AND isDeleted = 0`;\n return QueryBuilder.selectOne<ApiKey>(sql, [apiKey]);\n }\n}\n","import { QueryBuilder } from \"../index.js\";\nimport type { File, Folder, FolderWithDDocs, FolderListResponse } from \"../../../types\";\n\nexport type { Folder, FolderWithDDocs, FolderListResponse };\n\nexport class FoldersModel {\n private static readonly TABLE = \"folders\";\n\n static async findAll(limit?: number, skip?: number): Promise<{ folders: Folder[]; total: number; hasNext: boolean }> {\n // Get total count\n const countSql = `SELECT COUNT(*) as count FROM ${this.TABLE} WHERE isDeleted = 0`;\n const totalResult = await QueryBuilder.selectOne<{ count: number }>(countSql);\n const total = totalResult?.count || 0;\n\n // Get paginated results\n const sql = QueryBuilder.paginate(`SELECT * FROM ${this.TABLE} WHERE isDeleted = 0`, {\n limit,\n offset: skip,\n orderBy: \"created_at\",\n orderDirection: \"DESC\",\n });\n\n const foldersRaw = await QueryBuilder.select<any>(sql);\n const folders = foldersRaw.map((folderRaw) => ({\n ...folderRaw,\n isDeleted: Boolean(folderRaw.isDeleted),\n }));\n\n const hasNext = skip !== undefined && limit !== undefined ? skip + limit < total : false;\n\n return { folders, total, hasNext };\n }\n\n static async findByFolderRefAndId(folderRef: string, folderId: string): Promise<FolderWithDDocs | undefined> {\n const sql = `SELECT * FROM ${this.TABLE} WHERE folderRef = ? AND folderId = ? AND isDeleted = 0`;\n const folderRaw = await QueryBuilder.selectOne<any>(sql, [folderRef, folderId]);\n\n if (!folderRaw) {\n return undefined;\n }\n\n const parsedFolder: Folder = {\n ...folderRaw,\n isDeleted: Boolean(folderRaw.isDeleted),\n };\n\n // Get ddocs in this folder\n // Note: FolderRef functionality removed in simplified schema, returning empty array\n const ddocs: File[] = [];\n\n return {\n ...parsedFolder,\n ddocs,\n };\n }\n\n static async findByFolderRef(folderRef: string): Promise<Folder | undefined> {\n const sql = `SELECT * FROM ${this.TABLE} WHERE folderRef = ? AND isDeleted = 0 LIMIT 1`;\n const folderRaw = await QueryBuilder.selectOne<any>(sql, [folderRef]);\n\n if (!folderRaw) {\n return undefined;\n }\n\n return {\n ...folderRaw,\n isDeleted: Boolean(folderRaw.isDeleted),\n };\n }\n\n static async searchByName(searchTerm: string, limit?: number, skip?: number): Promise<Folder[]> {\n const sql = QueryBuilder.paginate(\n `SELECT * FROM ${this.TABLE}\n WHERE isDeleted = 0 AND LOWER(folderName) LIKE LOWER(?)`,\n {\n limit,\n offset: skip,\n orderBy: \"created_at\",\n orderDirection: \"DESC\",\n },\n );\n\n const foldersRaw = await QueryBuilder.select<any>(sql, [`%${searchTerm}%`]);\n return foldersRaw.map((folderRaw) => ({\n ...folderRaw,\n isDeleted: Boolean(folderRaw.isDeleted),\n }));\n }\n\n static async create(input: {\n _id?: string;\n onchainFileId: number;\n folderId: string;\n folderRef: string;\n folderName: string;\n portalAddress: string;\n metadataIPFSHash: string;\n contentIPFSHash: string;\n lastTransactionHash?: string;\n lastTransactionBlockNumber: number;\n lastTransactionBlockTimestamp: number;\n }): Promise<Folder> {\n const _id = input._id || `folder_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n const now = new Date().toISOString();\n\n const sql = `INSERT INTO ${this.TABLE} (\n _id, onchainFileId, folderId, folderRef, folderName, portalAddress, metadataIPFSHash,\n contentIPFSHash, isDeleted, lastTransactionHash, lastTransactionBlockNumber,\n lastTransactionBlockTimestamp, created_at, updated_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`;\n\n await QueryBuilder.execute(sql, [\n _id,\n input.onchainFileId,\n input.folderId,\n input.folderRef,\n input.folderName,\n input.portalAddress,\n input.metadataIPFSHash,\n input.contentIPFSHash,\n 0, // isDeleted\n input.lastTransactionHash || null,\n input.lastTransactionBlockNumber,\n input.lastTransactionBlockTimestamp,\n now,\n now,\n ]);\n\n // Fetch the created folder (without ddocs)\n const selectSql = `SELECT * FROM ${this.TABLE} WHERE folderRef = ? AND folderId = ? AND isDeleted = 0`;\n const folderRaw = await QueryBuilder.selectOne<any>(selectSql, [input.folderRef, input.folderId]);\n\n if (!folderRaw) {\n throw new Error(\"Failed to create folder\");\n }\n\n return {\n ...folderRaw,\n isDeleted: Boolean(folderRaw.isDeleted),\n };\n }\n}\n","import { EventEmitter } from \"events\";\n\nclass WorkerSignal extends EventEmitter {}\n\nconst workerSignal = new WorkerSignal();\nworkerSignal.setMaxListeners(20);\n\nexport function notifyNewEvent(): void {\n workerSignal.emit(\"newEvent\");\n}\n\nexport function onNewEvent(callback: () => void): () => void {\n workerSignal.on(\"newEvent\", callback);\n return () => workerSignal.off(\"newEvent\", callback);\n}\n","import { QueryBuilder } from \"../index.js\";\nimport { uuidv7 } from \"uuidv7\";\nimport { notifyNewEvent } from \"../../worker/workerSignal\";\nimport type { Event, EventType, EventStatus } from \"../../../types\";\n\nexport type { Event, EventType, EventStatus };\n\nconst RETRY_DELAYS_MS = [5000, 30000, 120000];\n\ninterface EventRow {\n _id: string;\n type: string;\n timestamp: number;\n fileId: string;\n portalAddress: string;\n status: string;\n retryCount: number;\n lastError: string | null;\n lockedAt: number | null;\n nextRetryAt: number | null;\n userOpHash?: string | null;\n pendingPayload?: string | null;\n}\n\nexport class EventsModel {\n private static readonly TABLE = \"events\";\n\n static async create(input: { type: EventType; fileId: string; portalAddress: string }): Promise<Event> {\n const _id = uuidv7();\n const timestamp = Date.now();\n const status: EventStatus = \"pending\";\n\n const sql = `\n INSERT INTO ${this.TABLE}\n (_id, type, timestamp, fileId, portalAddress, status, retryCount, lastError, lockedAt, nextRetryAt)\n VALUES (?, ?, ?, ?, ?, ?, 0, NULL, NULL, NULL)\n `;\n\n await QueryBuilder.execute(sql, [_id, input.type, timestamp, input.fileId, input.portalAddress, status]);\n\n notifyNewEvent();\n\n return {\n _id,\n type: input.type,\n timestamp,\n fileId: input.fileId,\n portalAddress: input.portalAddress,\n status,\n retryCount: 0,\n lastError: null,\n lockedAt: null,\n nextRetryAt: null,\n };\n }\n\n static async findById(_id: string): Promise<Event | undefined> {\n const sql = `SELECT * FROM ${this.TABLE} WHERE _id = ?`;\n const row = await QueryBuilder.selectOne<EventRow>(sql, [_id]);\n return row ? this.parseEvent(row) : undefined;\n }\n\n static async findNextPending(): Promise<Event | undefined> {\n const sql = `\n SELECT * FROM ${this.TABLE}\n WHERE status = 'pending'\n ORDER BY timestamp ASC\n LIMIT 1\n `;\n const row = await QueryBuilder.selectOne<EventRow>(sql, []);\n return row ? this.parseEvent(row) : undefined;\n }\n\n static async findNextEligible(lockedFileIds: string[]): Promise<Event | undefined> {\n const now = Date.now();\n\n const exclusionClause =\n lockedFileIds.length > 0 ? `AND e1.fileId NOT IN (${lockedFileIds.map(() => \"?\").join(\", \")})` : \"\";\n\n const sql = `\n SELECT e1.* FROM ${this.TABLE} e1\n WHERE e1.status = 'pending'\n AND (e1.nextRetryAt IS NULL OR e1.nextRetryAt <= ?)\n ${exclusionClause}\n AND NOT EXISTS (\n SELECT 1 FROM ${this.TABLE} e2\n WHERE e2.fileId = e1.fileId\n AND e2.status = 'pending'\n AND e2.timestamp < e1.timestamp\n )\n ORDER BY e1.timestamp ASC\n LIMIT 1\n `;\n\n const params = [now, ...lockedFileIds];\n const row = await QueryBuilder.selectOne<EventRow>(sql, params);\n return row ? this.parseEvent(row) : undefined;\n }\n\n static async markProcessing(_id: string): Promise<void> {\n const sql = `\n UPDATE ${this.TABLE}\n SET status = 'processing',\n lockedAt = ?\n WHERE _id = ?\n `;\n await QueryBuilder.execute(sql, [Date.now(), _id]);\n }\n\n static async markSubmitted(_id: string): Promise<void> {\n const sql = `\n UPDATE ${this.TABLE}\n SET status = 'submitted',\n lockedAt = NULL\n WHERE _id = ?\n `;\n await QueryBuilder.execute(sql, [_id]);\n }\n\n static async findNextSubmitted(lockedFileIds: string[]): Promise<Event | undefined> {\n const exclusionClause =\n lockedFileIds.length > 0 ? `AND fileId NOT IN (${lockedFileIds.map(() => \"?\").join(\", \")})` : \"\";\n\n const sql = `\n SELECT * FROM ${this.TABLE}\n WHERE status = 'submitted'\n AND userOpHash IS NOT NULL\n ${exclusionClause}\n ORDER BY timestamp ASC\n LIMIT 1\n `;\n\n const params = [...lockedFileIds];\n const row = await QueryBuilder.selectOne<EventRow>(sql, params);\n return row ? this.parseEvent(row) : undefined;\n }\n\n static async markProcessed(_id: string): Promise<void> {\n const sql = `\n UPDATE ${this.TABLE}\n SET status = 'processed',\n lockedAt = NULL\n WHERE _id = ?\n `;\n await QueryBuilder.execute(sql, [_id]);\n }\n\n static async scheduleRetry(_id: string, errorMsg: string): Promise<void> {\n const event = await this.findById(_id);\n if (!event) return;\n\n const delay = RETRY_DELAYS_MS[Math.min(event.retryCount, RETRY_DELAYS_MS.length - 1)];\n const nextRetryAt = Date.now() + delay;\n\n const sql = `\n UPDATE ${this.TABLE}\n SET status = 'pending',\n retryCount = retryCount + 1,\n lastError = ?,\n nextRetryAt = ?,\n lockedAt = NULL\n WHERE _id = ?\n `;\n await QueryBuilder.execute(sql, [errorMsg, nextRetryAt, _id]);\n }\n\n static async scheduleRetryAfter(_id: string, errorMsg: string, retryAfterMs: number): Promise<void> {\n const nextRetryAt = Date.now() + retryAfterMs;\n const sql = `\n UPDATE ${this.TABLE}\n SET status = 'pending',\n lastError = ?,\n nextRetryAt = ?,\n lockedAt = NULL\n WHERE _id = ?\n `;\n await QueryBuilder.execute(sql, [errorMsg, nextRetryAt, _id]);\n }\n\n static async markFailed(_id: string, errorMsg: string): Promise<void> {\n const sql = `\n UPDATE ${this.TABLE}\n SET status = 'failed',\n lastError = ?,\n lockedAt = NULL\n WHERE _id = ?\n `;\n await QueryBuilder.execute(sql, [errorMsg, _id]);\n }\n\n static async listFailed(portalAddress?: string): Promise<Event[]> {\n const portalClause = portalAddress != null ? \"AND portalAddress = ?\" : \"\";\n const sql = `\n SELECT * FROM ${this.TABLE}\n WHERE status = 'failed'\n ${portalClause}\n ORDER BY timestamp ASC\n `;\n const params = portalAddress != null ? [portalAddress] : [];\n const rows = await QueryBuilder.select<EventRow>(sql, params);\n return rows.map((row) => this.parseEvent(row));\n }\n\n static async resetFailedToPending(_id: string, portalAddress?: string): Promise<boolean> {\n const portalClause = portalAddress != null ? \"AND portalAddress = ?\" : \"\";\n const sql = `\n UPDATE ${this.TABLE}\n SET status = 'pending',\n retryCount = 0,\n lastError = NULL,\n nextRetryAt = NULL,\n lockedAt = NULL\n WHERE _id = ?\n AND status = 'failed'\n ${portalClause}\n `;\n const params = portalAddress != null ? [_id, portalAddress] : [_id];\n const result = await QueryBuilder.execute(sql, params);\n if (result.changes > 0) {\n notifyNewEvent();\n }\n return result.changes > 0;\n }\n\n static async resetAllFailedToPending(portalAddress?: string): Promise<number> {\n const portalClause = portalAddress != null ? \"AND portalAddress = ?\" : \"\";\n const sql = `\n UPDATE ${this.TABLE}\n SET status = 'pending',\n retryCount = 0,\n lastError = NULL,\n nextRetryAt = NULL,\n lockedAt = NULL\n WHERE status = 'failed'\n ${portalClause}\n `;\n const params = portalAddress != null ? [portalAddress] : [];\n const result = await QueryBuilder.execute(sql, params);\n if (result.changes > 0) {\n notifyNewEvent();\n }\n return result.changes;\n }\n\n static async resetStaleEvents(staleThreshold: number): Promise<number> {\n const sql = `\n UPDATE ${this.TABLE}\n SET status = 'pending',\n lockedAt = NULL,\n userOpHash = NULL,\n pendingPayload = NULL\n WHERE status = 'processing'\n AND lockedAt IS NOT NULL\n AND lockedAt < ?\n `;\n const result = await QueryBuilder.execute(sql, [staleThreshold]);\n return result.changes;\n }\n\n static async setEventPendingOp(_id: string, userOpHash: string, payload: Record<string, unknown>): Promise<void> {\n const sql = `UPDATE ${this.TABLE} SET userOpHash = ?, pendingPayload = ? WHERE _id = ?`;\n await QueryBuilder.execute(sql, [userOpHash, JSON.stringify(payload), _id]);\n }\n\n static async clearEventPendingOp(_id: string): Promise<void> {\n const sql = `UPDATE ${this.TABLE} SET userOpHash = NULL, pendingPayload = NULL WHERE _id = ?`;\n await QueryBuilder.execute(sql, [_id]);\n }\n\n private static parseEvent(row: EventRow): Event {\n return {\n _id: row._id,\n type: row.type as EventType,\n timestamp: row.timestamp,\n fileId: row.fileId,\n portalAddress: row.portalAddress ?? \"\",\n status: row.status as EventStatus,\n retryCount: row.retryCount,\n lastError: row.lastError,\n lockedAt: row.lockedAt,\n nextRetryAt: row.nextRetryAt,\n userOpHash: row.userOpHash ?? null,\n pendingPayload: row.pendingPayload ?? null,\n };\n }\n}\n","import { type File, FilesModel, type FileListResponse } from \"./files.model\";\nimport { PortalsModel, type Portal } from \"./portals.model\";\nimport { ApiKeysModel, type ApiKey } from \"./apikeys.model\";\nimport { type Folder, type FolderWithDDocs, type FolderListResponse, FoldersModel } from \"./folders.model\";\nimport { EventsModel, type Event, type EventType, type EventStatus } from \"./events.model\";\n\nexport { FilesModel, PortalsModel, ApiKeysModel, FoldersModel, EventsModel };\nexport type {\n File,\n FileListResponse,\n Portal,\n ApiKey,\n Folder,\n FolderWithDDocs,\n FolderListResponse,\n Event,\n EventType,\n EventStatus,\n};\n","import { Hex } from \"viem\";\nimport { eciesDecrypt, eciesEncrypt, generateECKeyPair } from \"@fileverse/crypto/ecies\";\nimport { AuthTokenProvider } from \"./auth-token-provider\";\n\nexport class KeyStore {\n private portalKeySeed: Uint8Array | undefined;\n private portalAddress: Hex | undefined;\n\n constructor(\n seed: Uint8Array,\n address: Hex,\n private readonly authTokenProvider: AuthTokenProvider,\n ) {\n this.portalKeySeed = seed;\n this.portalAddress = address;\n this.authTokenProvider = authTokenProvider;\n }\n\n getPortalAddress() {\n if (!this.portalAddress) {\n throw new Error(\"Portal address is not set\");\n }\n return this.portalAddress;\n }\n\n private getAppEncryptionKey() {\n if (!this.portalKeySeed) {\n throw new Error(\"Portal key seed is not set\");\n }\n\n const keyPair = generateECKeyPair(this.portalKeySeed);\n return keyPair.publicKey;\n }\n\n private getAppDecryptionKey() {\n if (!this.portalKeySeed) {\n throw new Error(\"Portal key seed is not set\");\n }\n\n const keyPair = generateECKeyPair(this.portalKeySeed);\n return keyPair.privateKey;\n }\n\n encryptData(data: Uint8Array) {\n return eciesEncrypt(this.getAppEncryptionKey(), data);\n }\n\n decryptData(data: string) {\n return eciesDecrypt(this.getAppDecryptionKey(), data);\n }\n\n getAuthToken(audienceDid: string) {\n return this.authTokenProvider.getAuthToken(audienceDid);\n }\n}\n","import { sign, extractPublicKeyFromSecretKey } from \"@stablelib/ed25519\";\nimport { toUint8Array } from \"js-base64\";\n\nconst BASE58_ALPHABET = \"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz\";\nconst EDWARDS_DID_PREFIX = new Uint8Array([0xed, 0x01]);\n\nfunction base58btcEncode(bytes: Uint8Array): string {\n const digits = [0];\n for (const byte of bytes) {\n let carry = byte;\n for (let j = 0; j < digits.length; j++) {\n carry += digits[j] << 8;\n digits[j] = carry % 58;\n carry = (carry / 58) | 0;\n }\n while (carry > 0) {\n digits.push(carry % 58);\n carry = (carry / 58) | 0;\n }\n }\n let result = \"\";\n for (let i = 0; i < bytes.length && bytes[i] === 0; i++) {\n result += BASE58_ALPHABET[0];\n }\n for (let i = digits.length - 1; i >= 0; i--) {\n result += BASE58_ALPHABET[digits[i]];\n }\n return result;\n}\n\nfunction base64urlEncode(data: Uint8Array | string): string {\n const bytes = typeof data === \"string\" ? new TextEncoder().encode(data) : data;\n let binary = \"\";\n for (let i = 0; i < bytes.length; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary).replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=+$/, \"\");\n}\n\nexport class EdKeypair {\n readonly jwtAlg = \"EdDSA\";\n private secretKey: Uint8Array;\n private publicKey: Uint8Array;\n\n private constructor(secretKey: Uint8Array, publicKey: Uint8Array) {\n this.secretKey = secretKey;\n this.publicKey = publicKey;\n }\n\n static fromSecretKey(key: string): EdKeypair {\n const secretKey = toUint8Array(key);\n const publicKey = extractPublicKeyFromSecretKey(secretKey);\n return new EdKeypair(secretKey, publicKey);\n }\n\n did(): string {\n const bytes = new Uint8Array(EDWARDS_DID_PREFIX.length + this.publicKey.length);\n bytes.set(EDWARDS_DID_PREFIX);\n bytes.set(this.publicKey, EDWARDS_DID_PREFIX.length);\n return \"did:key:z\" + base58btcEncode(bytes);\n }\n\n async sign(msg: Uint8Array): Promise<Uint8Array> {\n return sign(this.secretKey, msg);\n }\n}\n\ninterface Capability {\n with: { scheme: string; hierPart: string };\n can: { namespace: string; segments: string[] };\n}\n\ninterface BuildParams {\n issuer: EdKeypair;\n audience: string;\n capabilities?: Capability[];\n lifetimeInSeconds?: number;\n expiration?: number;\n notBefore?: number;\n facts?: Record<string, unknown>[];\n proofs?: string[];\n}\n\nexport async function buildAndEncode(params: BuildParams): Promise<string> {\n const {\n issuer,\n audience,\n capabilities = [],\n lifetimeInSeconds = 30,\n expiration,\n notBefore,\n facts,\n proofs = [],\n } = params;\n\n const currentTime = Math.floor(Date.now() / 1000);\n const exp = expiration ?? currentTime + lifetimeInSeconds;\n\n const header = { alg: issuer.jwtAlg, typ: \"JWT\", ucv: \"0.8.1\" };\n\n const att = capabilities.map((cap) => ({\n with: `${cap.with.scheme}:${cap.with.hierPart}`,\n can: [cap.can.namespace, ...cap.can.segments].join(\"/\"),\n }));\n\n const payload: Record<string, unknown> = {\n iss: issuer.did(),\n aud: audience,\n exp,\n att,\n prf: proofs,\n };\n\n if (notBefore !== undefined) payload.nbf = notBefore;\n if (facts !== undefined) payload.fct = facts;\n\n const encodedHeader = base64urlEncode(JSON.stringify(header));\n const encodedPayload = base64urlEncode(JSON.stringify(payload));\n const signedData = `${encodedHeader}.${encodedPayload}`;\n\n const sig = await issuer.sign(new TextEncoder().encode(signedData));\n const signature = base64urlEncode(sig);\n\n return `${signedData}.${signature}`;\n}\n","import { EdKeypair, buildAndEncode } from \"./ucan\";\nimport type { Hex } from \"viem\";\n\nexport class AuthTokenProvider {\n private readonly DEFAULT_OPTIONS = {\n namespace: \"file\",\n segment: \"CREATE\",\n scheme: \"storage\",\n };\n private keyPair: EdKeypair;\n portalAddress: Hex;\n constructor(keyPair: EdKeypair, portalAddress: Hex) {\n this.keyPair = keyPair;\n this.portalAddress = portalAddress;\n }\n\n async getAuthToken(\n audienceDid: string,\n options: { namespace: string; segment: string; scheme: string } = this.DEFAULT_OPTIONS,\n ): Promise<string> {\n return buildAndEncode({\n audience: audienceDid,\n issuer: this.keyPair,\n lifetimeInSeconds: 7 * 86400,\n capabilities: [\n {\n with: {\n scheme: options.scheme,\n hierPart: this.portalAddress.toLocaleLowerCase(),\n },\n can: { namespace: options.namespace, segments: [options.segment] },\n },\n ],\n });\n }\n}\n","export { sepolia, gnosis } from \"viem/chains\";\n","export const ADDED_FILE_EVENT = [\n {\n anonymous: false,\n inputs: [\n {\n indexed: true,\n internalType: \"uint256\",\n name: \"fileId\",\n type: \"uint256\",\n },\n {\n indexed: false,\n internalType: \"string\",\n name: \"appFileId\",\n type: \"string\",\n },\n {\n indexed: false,\n internalType: \"enum FileverseApp.FileType\",\n name: \"fileType\",\n type: \"uint8\",\n },\n {\n indexed: false,\n internalType: \"string\",\n name: \"metadataIPFSHash\",\n type: \"string\",\n },\n {\n indexed: false,\n internalType: \"string\",\n name: \"contentIPFSHash\",\n type: \"string\",\n },\n {\n indexed: false,\n internalType: \"string\",\n name: \"gateIPFSHash\",\n type: \"string\",\n },\n {\n indexed: false,\n internalType: \"uint256\",\n name: \"version\",\n type: \"uint256\",\n },\n {\n indexed: true,\n internalType: \"address\",\n name: \"by\",\n type: \"address\",\n },\n ],\n name: \"AddedFile\",\n type: \"event\",\n },\n] as const;\n\nexport const EDITED_FILE_EVENT = [\n {\n anonymous: false,\n inputs: [\n {\n indexed: true,\n internalType: \"uint256\",\n name: \"fileId\",\n type: \"uint256\",\n },\n {\n indexed: false,\n internalType: \"string\",\n name: \"appFileId\",\n type: \"string\",\n },\n {\n indexed: false,\n internalType: \"enum FileverseApp.FileType\",\n name: \"fileType\",\n type: \"uint8\",\n },\n {\n indexed: false,\n internalType: \"string\",\n name: \"metadataIPFSHash\",\n type: \"string\",\n },\n {\n indexed: false,\n internalType: \"string\",\n name: \"contentIPFSHash\",\n type: \"string\",\n },\n {\n indexed: false,\n internalType: \"string\",\n name: \"gateIPFSHash\",\n type: \"string\",\n },\n {\n indexed: false,\n internalType: \"uint256\",\n name: \"version\",\n type: \"uint256\",\n },\n {\n indexed: true,\n internalType: \"address\",\n name: \"by\",\n type: \"address\",\n },\n ],\n name: \"EditedFile\",\n type: \"event\",\n },\n] as const;\n\nexport const DELETED_FILE_EVENT = [\n {\n anonymous: false,\n inputs: [\n {\n indexed: true,\n internalType: \"uint256\",\n name: \"fileId\",\n type: \"uint256\",\n },\n {\n indexed: false,\n internalType: \"string\",\n name: \"appFileId\",\n type: \"string\",\n },\n {\n indexed: true,\n internalType: \"address\",\n name: \"by\",\n type: \"address\",\n },\n ],\n name: \"DeletedFile\",\n type: \"event\",\n },\n] as const;\n","export const ADD_FILE_METHOD = [\n {\n inputs: [\n {\n internalType: \"string\",\n name: \"_appFileId\",\n type: \"string\",\n },\n {\n internalType: \"enum FileverseApp.FileType\",\n name: \"fileType\",\n type: \"uint8\",\n },\n {\n internalType: \"string\",\n name: \"_metadataIPFSHash\",\n type: \"string\",\n },\n {\n internalType: \"string\",\n name: \"_contentIPFSHash\",\n type: \"string\",\n },\n {\n internalType: \"string\",\n name: \"_gateIPFSHash\",\n type: \"string\",\n },\n {\n internalType: \"uint256\",\n name: \"version\",\n type: \"uint256\",\n },\n ],\n name: \"addFile\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n] as const;\n\nexport const EDIT_FILE_METHOD = [\n {\n inputs: [\n {\n internalType: \"uint256\",\n name: \"fileId\",\n type: \"uint256\",\n },\n {\n internalType: \"string\",\n name: \"_appFileId\",\n type: \"string\",\n },\n {\n internalType: \"string\",\n name: \"_metadataIPFSHash\",\n type: \"string\",\n },\n {\n internalType: \"string\",\n name: \"_contentIPFSHash\",\n type: \"string\",\n },\n {\n internalType: \"string\",\n name: \"_gateIPFSHash\",\n type: \"string\",\n },\n {\n internalType: \"enum FileverseApp.FileType\",\n name: \"fileType\",\n type: \"uint8\",\n },\n {\n internalType: \"uint256\",\n name: \"version\",\n type: \"uint256\",\n },\n ],\n name: \"editFile\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n] as const;\n\nexport const DELETED_FILE_ABI = [\n {\n inputs: [\n {\n internalType: \"uint256\",\n name: \"fileId\",\n type: \"uint256\",\n },\n ],\n name: \"deleteFile\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n] as const;\n","import { STATIC_CONFIG } from \"../cli/constants\";\nimport { getRuntimeConfig } from \"../config\";\nimport { gnosis, sepolia } from \"./chains\";\n\nexport const NETWORK_NAME = STATIC_CONFIG.NETWORK_NAME;\nexport const UPLOAD_SERVER_URL = STATIC_CONFIG.API_URL;\n\nexport const getRpcUrl = () => getRuntimeConfig().RPC_URL;\nexport const getPimlicoUrl = () => `${STATIC_CONFIG.PIMLICO_PROXY_URL}api/${NETWORK_NAME}/rpc`;\n\nconst CHAIN_MAP = {\n gnosis: gnosis,\n sepolia: sepolia,\n} as const;\n\nexport const CHAIN = CHAIN_MAP[NETWORK_NAME as keyof typeof CHAIN_MAP];\nexport { DELETED_FILE_EVENT, EDITED_FILE_EVENT, ADDED_FILE_EVENT } from \"./events\";\nexport { DELETED_FILE_ABI, EDIT_FILE_METHOD, ADD_FILE_METHOD } from \"./methods\";\n","import { createPublicClient, http, hexToBigInt, toHex, toBytes, type PrivateKeyAccount, type Hex } from \"viem\";\n\nimport { createPimlicoClient } from \"permissionless/clients/pimlico\";\nimport { createSmartAccountClient } from \"permissionless\";\nimport { toSafeSmartAccount } from \"permissionless/accounts\";\nimport { entryPoint07Address } from \"viem/account-abstraction\";\nimport { CHAIN, getRpcUrl, getPimlicoUrl } from \"../constants\";\nimport { generatePrivateKey } from \"viem/accounts\";\n\nexport const getPublicClient = () =>\n createPublicClient({\n transport: http(getRpcUrl(), {\n retryCount: 0,\n }),\n chain: CHAIN,\n });\n\nexport const getPimlicoClient = (authToken: string, portalAddress: Hex, invokerAddress: Hex) =>\n createPimlicoClient({\n transport: http(getPimlicoUrl(), {\n retryCount: 0,\n fetchOptions: {\n headers: {\n Authorization: `Bearer ${authToken}`,\n contract: portalAddress,\n invoker: invokerAddress,\n },\n },\n }),\n entryPoint: {\n address: entryPoint07Address,\n version: \"0.7\",\n },\n });\n\nexport const signerToSmartAccount = async (signer: PrivateKeyAccount) => {\n console.log(\"[pimlico] creating public client\");\n const client = getPublicClient();\n console.log(\"[pimlico] calling toSafeSmartAccount\");\n const account = await toSafeSmartAccount({\n client,\n owners: [signer],\n entryPoint: {\n address: entryPoint07Address,\n version: \"0.7\",\n },\n version: \"1.4.1\",\n });\n console.log(\"[pimlico] safe smart account created\");\n return account;\n};\n\nexport const getSmartAccountClient = async (signer: PrivateKeyAccount, authToken: string, portalAddress: Hex) => {\n console.log(\"[pimlico] signerToSmartAccount start\");\n const smartAccount = await signerToSmartAccount(signer);\n console.log(\"[pimlico] creating pimlico client\");\n const pimlicoClient = getPimlicoClient(authToken, portalAddress, smartAccount.address);\n console.log(\"[pimlico] creating smart account client\");\n const result = createSmartAccountClient({\n account: smartAccount,\n chain: CHAIN,\n paymaster: pimlicoClient,\n bundlerTransport: http(getPimlicoUrl(), {\n fetchOptions: {\n headers: {\n Authorization: `Bearer ${authToken}`,\n contract: portalAddress,\n invoker: smartAccount.address,\n },\n },\n retryCount: 0,\n }),\n userOperation: {\n estimateFeesPerGas: async () => (await pimlicoClient.getUserOperationGasPrice()).fast,\n },\n });\n console.log(\"[pimlico] smart account client created\");\n return result;\n};\n\nexport const getNonce = () =>\n hexToBigInt(\n toHex(toBytes(generatePrivateKey()).slice(0, 24), {\n size: 32,\n }),\n );\n\nexport const getUserOpReceipt = async (\n hash: Hex,\n authToken: string,\n portalAddress: Hex,\n invokerAddress: Hex,\n) => {\n const pimlicoClient = getPimlicoClient(authToken, portalAddress, invokerAddress);\n try {\n return await pimlicoClient.getUserOperationReceipt({ hash });\n } catch {\n return null;\n }\n};\n\nexport const waitForUserOpReceipt = async (\n hash: Hex,\n authToken: string,\n portalAddress: Hex,\n invokerAddress: Hex,\n timeout = 120000,\n) => {\n const pimlicoClient = getPimlicoClient(authToken, portalAddress, invokerAddress);\n return pimlicoClient.waitForUserOperationReceipt({\n hash,\n timeout,\n });\n};\n","import { Hex, toHex } from \"viem\";\nimport { privateKeyToAccount } from \"viem/accounts\";\nimport { getSmartAccountClient, getNonce, waitForUserOpReceipt } from \"./pimlico-utils\";\nimport { AuthTokenProvider } from \"./auth-token-provider\";\nimport { STATIC_CONFIG } from \"../cli/constants\";\nimport { createSmartAccountClient } from \"permissionless\";\nimport type { IExecuteUserOperationRequest } from \"../types\";\n\nexport type { IExecuteUserOperationRequest };\n\nexport class AgentClient {\n private smartAccountAgent: ReturnType<typeof createSmartAccountClient> | null = null;\n private readonly MAX_CALL_GAS_LIMIT = 500000;\n private readonly authOptions: {\n namespace: string;\n segment: string;\n scheme: string;\n } = { namespace: \"proxy\", segment: \"ACCESS\", scheme: \"pimlico\" };\n\n constructor(private readonly authTokenProvider: AuthTokenProvider) {\n this.authTokenProvider = authTokenProvider;\n }\n\n async initializeAgentClient(keyMaterial: Uint8Array) {\n console.log(\"[agent] creating account from key\");\n const agentAccount = privateKeyToAccount(toHex(keyMaterial));\n console.log(\"[agent] getting auth token\");\n const authToken = await this.authTokenProvider.getAuthToken(STATIC_CONFIG.PROXY_SERVER_DID, this.authOptions);\n console.log(\"[agent] getting smart account client\");\n const smartAccountClient = await getSmartAccountClient(\n agentAccount,\n authToken,\n this.authTokenProvider.portalAddress,\n );\n console.log(\"[agent] smart account client ready\");\n this.smartAccountAgent = smartAccountClient;\n }\n\n getSmartAccountAgent() {\n if (!this.smartAccountAgent) throw new Error(\"Agent client not initialized\");\n\n return this.smartAccountAgent;\n }\n\n getAgentAddress() {\n const smartAccountAgent = this.getSmartAccountAgent();\n if (!smartAccountAgent.account) throw new Error(\"Agent account not found\");\n return smartAccountAgent.account.address;\n }\n\n getAgentAccount() {\n const smartAccountAgent = this.getSmartAccountAgent();\n if (!smartAccountAgent.account) throw new Error(\"Agent account not found\");\n return smartAccountAgent.account;\n }\n\n destroyAgentClient() {\n this.smartAccountAgent = null;\n }\n\n async getCallData(request: IExecuteUserOperationRequest | IExecuteUserOperationRequest[]) {\n const agentAccount = this.getAgentAccount();\n if (Array.isArray(request)) {\n if (request.length === 0 || request.length > 10) throw new Error(\"Request length must be between 1 and 10\");\n\n const encodedCallData = request.map((req) => ({\n to: req.contractAddress,\n data: req.data,\n value: BigInt(0),\n }));\n\n return await agentAccount.encodeCalls(encodedCallData);\n }\n\n return await agentAccount.encodeCalls([\n {\n to: request.contractAddress,\n data: request.data,\n value: BigInt(0),\n },\n ]);\n }\n\n async sendUserOperation(\n request: IExecuteUserOperationRequest | IExecuteUserOperationRequest[],\n customGasLimit?: number,\n ) {\n const smartAccountAgent = this.getSmartAccountAgent();\n console.log(\"[agent] encoding call data\");\n const callData = await this.getCallData(request);\n console.log(\"[agent] generating nonce\");\n const nonce = getNonce();\n console.log(\"[agent] sending user operation\");\n const hash = await smartAccountAgent.sendUserOperation({\n callData,\n callGasLimit: BigInt(customGasLimit || this.MAX_CALL_GAS_LIMIT),\n nonce,\n });\n console.log(\"[agent] user operation sent\");\n return hash;\n }\n\n async executeUserOperationRequest(\n request: IExecuteUserOperationRequest | IExecuteUserOperationRequest[],\n timeout: number,\n customGasLimit?: number,\n ) {\n const userOpHash = await this.sendUserOperation(request, customGasLimit);\n const { authToken, portalAddress, invokerAddress } = await this.getAuthParams();\n const receipt = await waitForUserOpReceipt(userOpHash, authToken, portalAddress, invokerAddress, timeout);\n if (!receipt.success) throw new Error(`Failed to execute user operation: ${receipt.reason}`);\n return receipt;\n }\n\n async getAuthParams(): Promise<{ authToken: string; portalAddress: Hex; invokerAddress: Hex }> {\n const authToken = await this.authTokenProvider.getAuthToken(STATIC_CONFIG.PROXY_SERVER_DID, this.authOptions);\n return {\n authToken,\n portalAddress: this.authTokenProvider.portalAddress,\n invokerAddress: this.getAgentAddress(),\n };\n }\n}\n","/**\n * Utilities for hex, bytes, CSPRNG.\n * @module\n */\n/*! noble-ciphers - MIT License (c) 2023 Paul Miller (paulmillr.com) */\n\n/** Checks if something is Uint8Array. Be careful: nodejs Buffer will return true. */\nexport function isBytes(a: unknown): a is Uint8Array {\n return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');\n}\n\n/** Asserts something is boolean. */\nexport function abool(b: boolean): void {\n if (typeof b !== 'boolean') throw new Error(`boolean expected, not ${b}`);\n}\n\n/** Asserts something is positive integer. */\nexport function anumber(n: number): void {\n if (!Number.isSafeInteger(n) || n < 0) throw new Error('positive integer expected, got ' + n);\n}\n\n/** Asserts something is Uint8Array. */\nexport function abytes(value: Uint8Array, length?: number, title: string = ''): Uint8Array {\n const bytes = isBytes(value);\n const len = value?.length;\n const needsLen = length !== undefined;\n if (!bytes || (needsLen && len !== length)) {\n const prefix = title && `\"${title}\" `;\n const ofLen = needsLen ? ` of length ${length}` : '';\n const got = bytes ? `length=${len}` : `type=${typeof value}`;\n throw new Error(prefix + 'expected Uint8Array' + ofLen + ', got ' + got);\n }\n return value;\n}\n\n/** Asserts a hash instance has not been destroyed / finished */\nexport function aexists(instance: any, checkFinished = true): void {\n if (instance.destroyed) throw new Error('Hash instance has been destroyed');\n if (checkFinished && instance.finished) throw new Error('Hash#digest() has already been called');\n}\n\n/** Asserts output is properly-sized byte array */\nexport function aoutput(out: any, instance: any): void {\n abytes(out, undefined, 'output');\n const min = instance.outputLen;\n if (out.length < min) {\n throw new Error('digestInto() expects output buffer of length at least ' + min);\n }\n}\n\nexport type IHash = {\n (data: string | Uint8Array): Uint8Array;\n blockLen: number;\n outputLen: number;\n create: any;\n};\n\n/** Generic type encompassing 8/16/32-byte arrays - but not 64-byte. */\n// prettier-ignore\nexport type TypedArray = Int8Array | Uint8ClampedArray | Uint8Array |\n Uint16Array | Int16Array | Uint32Array | Int32Array;\n\n/** Cast u8 / u16 / u32 to u8. */\nexport function u8(arr: TypedArray): Uint8Array {\n return new Uint8Array(arr.buffer, arr.byteOffset, arr.byteLength);\n}\n\n/** Cast u8 / u16 / u32 to u32. */\nexport function u32(arr: TypedArray): Uint32Array {\n return new Uint32Array(arr.buffer, arr.byteOffset, Math.floor(arr.byteLength / 4));\n}\n\n/** Zeroize a byte array. Warning: JS provides no guarantees. */\nexport function clean(...arrays: TypedArray[]): void {\n for (let i = 0; i < arrays.length; i++) {\n arrays[i].fill(0);\n }\n}\n\n/** Create DataView of an array for easy byte-level manipulation. */\nexport function createView(arr: TypedArray): DataView {\n return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);\n}\n\n/** Is current platform little-endian? Most are. Big-Endian platform: IBM */\nexport const isLE: boolean = /* @__PURE__ */ (() =>\n new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44)();\n\n// Built-in hex conversion https://caniuse.com/mdn-javascript_builtins_uint8array_fromhex\nconst hasHexBuiltin: boolean = /* @__PURE__ */ (() =>\n // @ts-ignore\n typeof Uint8Array.from([]).toHex === 'function' && typeof Uint8Array.fromHex === 'function')();\n\n// Array where index 0xf0 (240) is mapped to string 'f0'\nconst hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) =>\n i.toString(16).padStart(2, '0')\n);\n\n/**\n * Convert byte array to hex string. Uses built-in function, when available.\n * @example bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])) // 'cafe0123'\n */\nexport function bytesToHex(bytes: Uint8Array): string {\n abytes(bytes);\n // @ts-ignore\n if (hasHexBuiltin) return bytes.toHex();\n // pre-caching improves the speed 6x\n let hex = '';\n for (let i = 0; i < bytes.length; i++) {\n hex += hexes[bytes[i]];\n }\n return hex;\n}\n\n// We use optimized technique to convert hex string to byte array\nconst asciis = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 } as const;\nfunction asciiToBase16(ch: number): number | undefined {\n if (ch >= asciis._0 && ch <= asciis._9) return ch - asciis._0; // '2' => 50-48\n if (ch >= asciis.A && ch <= asciis.F) return ch - (asciis.A - 10); // 'B' => 66-(65-10)\n if (ch >= asciis.a && ch <= asciis.f) return ch - (asciis.a - 10); // 'b' => 98-(97-10)\n return;\n}\n\n/**\n * Convert hex string to byte array. Uses built-in function, when available.\n * @example hexToBytes('cafe0123') // Uint8Array.from([0xca, 0xfe, 0x01, 0x23])\n */\nexport function hexToBytes(hex: string): Uint8Array {\n if (typeof hex !== 'string') throw new Error('hex string expected, got ' + typeof hex);\n // @ts-ignore\n if (hasHexBuiltin) return Uint8Array.fromHex(hex);\n const hl = hex.length;\n const al = hl / 2;\n if (hl % 2) throw new Error('hex string expected, got unpadded hex of length ' + hl);\n const array = new Uint8Array(al);\n for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) {\n const n1 = asciiToBase16(hex.charCodeAt(hi));\n const n2 = asciiToBase16(hex.charCodeAt(hi + 1));\n if (n1 === undefined || n2 === undefined) {\n const char = hex[hi] + hex[hi + 1];\n throw new Error('hex string expected, got non-hex character \"' + char + '\" at index ' + hi);\n }\n array[ai] = n1 * 16 + n2; // multiply first octet, e.g. 'a3' => 10*16+3 => 160 + 3 => 163\n }\n return array;\n}\n\n// Used in micro\nexport function hexToNumber(hex: string): bigint {\n if (typeof hex !== 'string') throw new Error('hex string expected, got ' + typeof hex);\n return BigInt(hex === '' ? '0' : '0x' + hex); // Big Endian\n}\n\n// Used in ff1\n// BE: Big Endian, LE: Little Endian\nexport function bytesToNumberBE(bytes: Uint8Array): bigint {\n return hexToNumber(bytesToHex(bytes));\n}\n\n// Used in micro, ff1\nexport function numberToBytesBE(n: number | bigint, len: number): Uint8Array {\n return hexToBytes(n.toString(16).padStart(len * 2, '0'));\n}\n\n// Global symbols, but ts doesn't see them: https://github.com/microsoft/TypeScript/issues/31535\ndeclare const TextEncoder: any;\ndeclare const TextDecoder: any;\n\n/**\n * Converts string to bytes using UTF8 encoding.\n * @example utf8ToBytes('abc') // new Uint8Array([97, 98, 99])\n */\nexport function utf8ToBytes(str: string): Uint8Array {\n if (typeof str !== 'string') throw new Error('string expected');\n return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809\n}\n\n/**\n * Converts bytes to string using UTF8 encoding.\n * @example bytesToUtf8(new Uint8Array([97, 98, 99])) // 'abc'\n */\nexport function bytesToUtf8(bytes: Uint8Array): string {\n return new TextDecoder().decode(bytes);\n}\n\n/**\n * Checks if two U8A use same underlying buffer and overlaps.\n * This is invalid and can corrupt data.\n */\nexport function overlapBytes(a: Uint8Array, b: Uint8Array): boolean {\n return (\n a.buffer === b.buffer && // best we can do, may fail with an obscure Proxy\n a.byteOffset < b.byteOffset + b.byteLength && // a starts before b end\n b.byteOffset < a.byteOffset + a.byteLength // b starts before a end\n );\n}\n\n/**\n * If input and output overlap and input starts before output, we will overwrite end of input before\n * we start processing it, so this is not supported for most ciphers (except chacha/salse, which designed with this)\n */\nexport function complexOverlapBytes(input: Uint8Array, output: Uint8Array): void {\n // This is very cursed. It works somehow, but I'm completely unsure,\n // reasoning about overlapping aligned windows is very hard.\n if (overlapBytes(input, output) && input.byteOffset < output.byteOffset)\n throw new Error('complex overlap of input and output is not supported');\n}\n\n/**\n * Copies several Uint8Arrays into one.\n */\nexport function concatBytes(...arrays: Uint8Array[]): Uint8Array {\n let sum = 0;\n for (let i = 0; i < arrays.length; i++) {\n const a = arrays[i];\n abytes(a);\n sum += a.length;\n }\n const res = new Uint8Array(sum);\n for (let i = 0, pad = 0; i < arrays.length; i++) {\n const a = arrays[i];\n res.set(a, pad);\n pad += a.length;\n }\n return res;\n}\n\n// Used in ARX only\ntype EmptyObj = {};\nexport function checkOpts<T1 extends EmptyObj, T2 extends EmptyObj>(\n defaults: T1,\n opts: T2\n): T1 & T2 {\n if (opts == null || typeof opts !== 'object') throw new Error('options must be defined');\n const merged = Object.assign(defaults, opts);\n return merged as T1 & T2;\n}\n\n/** Compares 2 uint8array-s in kinda constant time. */\nexport function equalBytes(a: Uint8Array, b: Uint8Array): boolean {\n if (a.length !== b.length) return false;\n let diff = 0;\n for (let i = 0; i < a.length; i++) diff |= a[i] ^ b[i];\n return diff === 0;\n}\n\n// TODO: remove\nexport interface IHash2 {\n blockLen: number; // Bytes per block\n outputLen: number; // Bytes in output\n update(buf: string | Uint8Array): this;\n // Writes digest into buf\n digestInto(buf: Uint8Array): void;\n digest(): Uint8Array;\n /**\n * Resets internal state. Makes Hash instance unusable.\n * Reset is impossible for keyed hashes if key is consumed into state. If digest is not consumed\n * by user, they will need to manually call `destroy()` when zeroing is necessary.\n */\n destroy(): void;\n}\n\n// This will allow to re-use with composable things like packed & base encoders\n// Also, we probably can make tags composable\n\n/** Sync cipher: takes byte array and returns byte array. */\nexport type Cipher = {\n encrypt(plaintext: Uint8Array): Uint8Array;\n decrypt(ciphertext: Uint8Array): Uint8Array;\n};\n\n/** Async cipher e.g. from built-in WebCrypto. */\nexport type AsyncCipher = {\n encrypt(plaintext: Uint8Array): Promise<Uint8Array>;\n decrypt(ciphertext: Uint8Array): Promise<Uint8Array>;\n};\n\n/** Cipher with `output` argument which can optimize by doing 1 less allocation. */\nexport type CipherWithOutput = Cipher & {\n encrypt(plaintext: Uint8Array, output?: Uint8Array): Uint8Array;\n decrypt(ciphertext: Uint8Array, output?: Uint8Array): Uint8Array;\n};\n\n/**\n * Params are outside of return type, so it is accessible before calling constructor.\n * If function support multiple nonceLength's, we return the best one.\n */\nexport type CipherParams = {\n blockSize: number;\n nonceLength?: number;\n tagLength?: number;\n varSizeNonce?: boolean;\n};\n/** ARX cipher, like salsa or chacha. */\nexport type ARXCipher = ((\n key: Uint8Array,\n nonce: Uint8Array,\n AAD?: Uint8Array\n) => CipherWithOutput) & {\n blockSize: number;\n nonceLength: number;\n tagLength: number;\n};\nexport type CipherCons<T extends any[]> = (key: Uint8Array, ...args: T) => Cipher;\n/**\n * Wraps a cipher: validates args, ensures encrypt() can only be called once.\n * @__NO_SIDE_EFFECTS__\n */\nexport const wrapCipher = <C extends CipherCons<any>, P extends CipherParams>(\n params: P,\n constructor: C\n): C & P => {\n function wrappedCipher(key: Uint8Array, ...args: any[]): CipherWithOutput {\n // Validate key\n abytes(key, undefined, 'key');\n\n // Big-Endian hardware is rare. Just in case someone still decides to run ciphers:\n if (!isLE) throw new Error('Non little-endian hardware is not yet supported');\n\n // Validate nonce if nonceLength is present\n if (params.nonceLength !== undefined) {\n const nonce = args[0];\n abytes(nonce, params.varSizeNonce ? undefined : params.nonceLength, 'nonce');\n }\n\n // Validate AAD if tagLength present\n const tagl = params.tagLength;\n if (tagl && args[1] !== undefined) abytes(args[1], undefined, 'AAD');\n\n const cipher = constructor(key, ...args);\n const checkOutput = (fnLength: number, output?: Uint8Array) => {\n if (output !== undefined) {\n if (fnLength !== 2) throw new Error('cipher output not supported');\n abytes(output, undefined, 'output');\n }\n };\n // Create wrapped cipher with validation and single-use encryption\n let called = false;\n const wrCipher = {\n encrypt(data: Uint8Array, output?: Uint8Array) {\n if (called) throw new Error('cannot encrypt() twice with same key + nonce');\n called = true;\n abytes(data);\n checkOutput(cipher.encrypt.length, output);\n return (cipher as CipherWithOutput).encrypt(data, output);\n },\n decrypt(data: Uint8Array, output?: Uint8Array) {\n abytes(data);\n if (tagl && data.length < tagl)\n throw new Error('\"ciphertext\" expected length bigger than tagLength=' + tagl);\n checkOutput(cipher.decrypt.length, output);\n return (cipher as CipherWithOutput).decrypt(data, output);\n },\n };\n\n return wrCipher;\n }\n\n Object.assign(wrappedCipher, params);\n return wrappedCipher as C & P;\n};\n\n/** Represents salsa / chacha stream. */\nexport type XorStream = (\n key: Uint8Array,\n nonce: Uint8Array,\n data: Uint8Array,\n output?: Uint8Array,\n counter?: number\n) => Uint8Array;\n\n/**\n * By default, returns u8a of length.\n * When out is available, it checks it for validity and uses it.\n */\nexport function getOutput(\n expectedLength: number,\n out?: Uint8Array,\n onlyAligned = true\n): Uint8Array {\n if (out === undefined) return new Uint8Array(expectedLength);\n if (out.length !== expectedLength)\n throw new Error(\n '\"output\" expected Uint8Array of length ' + expectedLength + ', got: ' + out.length\n );\n if (onlyAligned && !isAligned32(out)) throw new Error('invalid output, must be aligned');\n return out;\n}\n\nexport function u64Lengths(dataLength: number, aadLength: number, isLE: boolean): Uint8Array {\n abool(isLE);\n const num = new Uint8Array(16);\n const view = createView(num);\n view.setBigUint64(0, BigInt(aadLength), isLE);\n view.setBigUint64(8, BigInt(dataLength), isLE);\n return num;\n}\n\n// Is byte array aligned to 4 byte offset (u32)?\nexport function isAligned32(bytes: Uint8Array): boolean {\n return bytes.byteOffset % 4 === 0;\n}\n\n// copy bytes to new u8a (aligned). Because Buffer.slice is broken.\nexport function copyBytes(bytes: Uint8Array): Uint8Array {\n return Uint8Array.from(bytes);\n}\n\n/** Cryptographically secure PRNG. Uses internal OS-level `crypto.getRandomValues`. */\nexport function randomBytes(bytesLength = 32): Uint8Array {\n const cr = typeof globalThis === 'object' ? (globalThis as any).crypto : null;\n if (typeof cr?.getRandomValues !== 'function')\n throw new Error('crypto.getRandomValues must be defined');\n return cr.getRandomValues(new Uint8Array(bytesLength));\n}\n\n/**\n * The pseudorandom number generator doesn't wipe current state:\n * instead, it generates new one based on previous state + entropy.\n * Not reseed/rekey, since AES CTR DRBG does rekey on each randomBytes,\n * which is in fact `reseed`, since it changes counter too.\n */\nexport interface PRG {\n addEntropy(seed: Uint8Array): void;\n randomBytes(length: number): Uint8Array;\n clean(): void;\n}\n\ntype RemoveNonceInner<T extends any[], Ret> = ((...args: T) => Ret) extends (\n arg0: any,\n arg1: any,\n ...rest: infer R\n) => any\n ? (key: Uint8Array, ...args: R) => Ret\n : never;\n\nexport type RemoveNonce<T extends (...args: any) => any> = RemoveNonceInner<\n Parameters<T>,\n ReturnType<T>\n>;\nexport type CipherWithNonce = ((\n key: Uint8Array,\n nonce: Uint8Array,\n ...args: any[]\n) => Cipher | AsyncCipher) & {\n nonceLength: number;\n};\n\n/**\n * Uses CSPRG for nonce, nonce injected in ciphertext.\n * For `encrypt`, a `nonceBytes`-length buffer is fetched from CSPRNG and\n * prepended to encrypted ciphertext. For `decrypt`, first `nonceBytes` of ciphertext\n * are treated as nonce.\n *\n * NOTE: Under the same key, using random nonces (e.g. `managedNonce`) with AES-GCM and ChaCha\n * should be limited to `2**23` (8M) messages to get a collision chance of `2**-50`. Stretching to * `2**32` (4B) messages, chance would become `2**-33` - still negligible, but creeping up.\n * @example\n * const gcm = managedNonce(aes.gcm);\n * const ciphr = gcm(key).encrypt(data);\n * const plain = gcm(key).decrypt(ciph);\n */\nexport function managedNonce<T extends CipherWithNonce>(\n fn: T,\n randomBytes_: typeof randomBytes = randomBytes\n): RemoveNonce<T> {\n const { nonceLength } = fn;\n anumber(nonceLength);\n const addNonce = (nonce: Uint8Array, ciphertext: Uint8Array) => {\n const out = concatBytes(nonce, ciphertext);\n ciphertext.fill(0);\n return out;\n };\n // NOTE: we cannot support DST here, it would be mistake:\n // - we don't know how much dst length cipher requires\n // - nonce may unalign dst and break everything\n // - we create new u8a anyway (concatBytes)\n // - previously we passed all args to cipher, but that was mistake!\n return ((key: Uint8Array, ...args: any[]): any => ({\n encrypt(plaintext: Uint8Array) {\n abytes(plaintext);\n const nonce = randomBytes_(nonceLength);\n const encrypted = fn(key, nonce, ...args).encrypt(plaintext);\n // @ts-ignore\n if (encrypted instanceof Promise) return encrypted.then((ct) => addNonce(nonce, ct));\n return addNonce(nonce, encrypted);\n },\n decrypt(ciphertext: Uint8Array) {\n abytes(ciphertext);\n const nonce = ciphertext.subarray(0, nonceLength);\n const decrypted = ciphertext.subarray(nonceLength);\n return fn(key, nonce, ...args).decrypt(decrypted);\n },\n })) as RemoveNonce<T>;\n}\n\n// workaround for TS 5.9 language mess:\nexport type Uint8ArrayBuffer = ReturnType<typeof Uint8Array.of>;\n","/**\n * GHash from AES-GCM and its little-endian \"mirror image\" Polyval from AES-SIV.\n *\n * Implemented in terms of GHash with conversion function for keys\n * GCM GHASH from\n * [NIST SP800-38d](https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf),\n * SIV from\n * [RFC 8452](https://www.rfc-editor.org/rfc/rfc8452).\n *\n * GHASH modulo: x^128 + x^7 + x^2 + x + 1\n * POLYVAL modulo: x^128 + x^127 + x^126 + x^121 + 1\n *\n * @module\n */\nimport {\n abytes,\n aexists,\n aoutput,\n clean,\n copyBytes,\n createView,\n u32,\n type IHash2,\n} from './utils.ts';\n\nconst BLOCK_SIZE = 16;\n// TODO: rewrite\n// temporary padding buffer\nconst ZEROS16 = /* @__PURE__ */ new Uint8Array(16);\nconst ZEROS32 = u32(ZEROS16);\nconst POLY = 0xe1; // v = 2*v % POLY\n\n// v = 2*v % POLY\n// NOTE: because x + x = 0 (add/sub is same), mul2(x) != x+x\n// We can multiply any number using montgomery ladder and this function (works as double, add is simple xor)\nconst mul2 = (s0: number, s1: number, s2: number, s3: number) => {\n const hiBit = s3 & 1;\n return {\n s3: (s2 << 31) | (s3 >>> 1),\n s2: (s1 << 31) | (s2 >>> 1),\n s1: (s0 << 31) | (s1 >>> 1),\n s0: (s0 >>> 1) ^ ((POLY << 24) & -(hiBit & 1)), // reduce % poly\n };\n};\n\nconst swapLE = (n: number) =>\n (((n >>> 0) & 0xff) << 24) |\n (((n >>> 8) & 0xff) << 16) |\n (((n >>> 16) & 0xff) << 8) |\n ((n >>> 24) & 0xff) |\n 0;\n\n/**\n * `mulX_POLYVAL(ByteReverse(H))` from spec\n * @param k mutated in place\n */\nexport function _toGHASHKey(k: Uint8Array): Uint8Array {\n k.reverse();\n const hiBit = k[15] & 1;\n // k >>= 1\n let carry = 0;\n for (let i = 0; i < k.length; i++) {\n const t = k[i];\n k[i] = (t >>> 1) | carry;\n carry = (t & 1) << 7;\n }\n k[0] ^= -hiBit & 0xe1; // if (hiBit) n ^= 0xe1000000000000000000000000000000;\n return k;\n}\n\ntype Value = { s0: number; s1: number; s2: number; s3: number };\n\nconst estimateWindow = (bytes: number) => {\n if (bytes > 64 * 1024) return 8;\n if (bytes > 1024) return 4;\n return 2;\n};\n\nexport class GHASH implements IHash2 {\n readonly blockLen: number = BLOCK_SIZE;\n readonly outputLen: number = BLOCK_SIZE;\n protected s0 = 0;\n protected s1 = 0;\n protected s2 = 0;\n protected s3 = 0;\n protected finished = false;\n protected t: Value[];\n private W: number;\n private windowSize: number;\n // We select bits per window adaptively based on expectedLength\n constructor(key: Uint8Array, expectedLength?: number) {\n abytes(key, 16, 'key');\n key = copyBytes(key);\n const kView = createView(key);\n let k0 = kView.getUint32(0, false);\n let k1 = kView.getUint32(4, false);\n let k2 = kView.getUint32(8, false);\n let k3 = kView.getUint32(12, false);\n // generate table of doubled keys (half of montgomery ladder)\n const doubles: Value[] = [];\n for (let i = 0; i < 128; i++) {\n doubles.push({ s0: swapLE(k0), s1: swapLE(k1), s2: swapLE(k2), s3: swapLE(k3) });\n ({ s0: k0, s1: k1, s2: k2, s3: k3 } = mul2(k0, k1, k2, k3));\n }\n const W = estimateWindow(expectedLength || 1024);\n if (![1, 2, 4, 8].includes(W))\n throw new Error('ghash: invalid window size, expected 2, 4 or 8');\n this.W = W;\n const bits = 128; // always 128 bits;\n const windows = bits / W;\n const windowSize = (this.windowSize = 2 ** W);\n const items: Value[] = [];\n // Create precompute table for window of W bits\n for (let w = 0; w < windows; w++) {\n // truth table: 00, 01, 10, 11\n for (let byte = 0; byte < windowSize; byte++) {\n // prettier-ignore\n let s0 = 0, s1 = 0, s2 = 0, s3 = 0;\n for (let j = 0; j < W; j++) {\n const bit = (byte >>> (W - j - 1)) & 1;\n if (!bit) continue;\n const { s0: d0, s1: d1, s2: d2, s3: d3 } = doubles[W * w + j];\n ((s0 ^= d0), (s1 ^= d1), (s2 ^= d2), (s3 ^= d3));\n }\n items.push({ s0, s1, s2, s3 });\n }\n }\n this.t = items;\n }\n protected _updateBlock(s0: number, s1: number, s2: number, s3: number): void {\n ((s0 ^= this.s0), (s1 ^= this.s1), (s2 ^= this.s2), (s3 ^= this.s3));\n const { W, t, windowSize } = this;\n // prettier-ignore\n let o0 = 0, o1 = 0, o2 = 0, o3 = 0;\n const mask = (1 << W) - 1; // 2**W will kill performance.\n let w = 0;\n for (const num of [s0, s1, s2, s3]) {\n for (let bytePos = 0; bytePos < 4; bytePos++) {\n const byte = (num >>> (8 * bytePos)) & 0xff;\n for (let bitPos = 8 / W - 1; bitPos >= 0; bitPos--) {\n const bit = (byte >>> (W * bitPos)) & mask;\n const { s0: e0, s1: e1, s2: e2, s3: e3 } = t[w * windowSize + bit];\n ((o0 ^= e0), (o1 ^= e1), (o2 ^= e2), (o3 ^= e3));\n w += 1;\n }\n }\n }\n this.s0 = o0;\n this.s1 = o1;\n this.s2 = o2;\n this.s3 = o3;\n }\n update(data: Uint8Array): this {\n aexists(this);\n abytes(data);\n data = copyBytes(data);\n const b32 = u32(data);\n const blocks = Math.floor(data.length / BLOCK_SIZE);\n const left = data.length % BLOCK_SIZE;\n for (let i = 0; i < blocks; i++) {\n this._updateBlock(b32[i * 4 + 0], b32[i * 4 + 1], b32[i * 4 + 2], b32[i * 4 + 3]);\n }\n if (left) {\n ZEROS16.set(data.subarray(blocks * BLOCK_SIZE));\n this._updateBlock(ZEROS32[0], ZEROS32[1], ZEROS32[2], ZEROS32[3]);\n clean(ZEROS32); // clean tmp buffer\n }\n return this;\n }\n destroy(): void {\n const { t } = this;\n // clean precompute table\n for (const elm of t) {\n ((elm.s0 = 0), (elm.s1 = 0), (elm.s2 = 0), (elm.s3 = 0));\n }\n }\n digestInto(out: Uint8Array): Uint8Array {\n aexists(this);\n aoutput(out, this);\n this.finished = true;\n const { s0, s1, s2, s3 } = this;\n const o32 = u32(out);\n o32[0] = s0;\n o32[1] = s1;\n o32[2] = s2;\n o32[3] = s3;\n return out;\n }\n digest(): Uint8Array {\n const res = new Uint8Array(BLOCK_SIZE);\n this.digestInto(res);\n this.destroy();\n return res;\n }\n}\n\nexport class Polyval extends GHASH {\n constructor(key: Uint8Array, expectedLength?: number) {\n abytes(key);\n const ghKey = _toGHASHKey(copyBytes(key));\n super(ghKey, expectedLength);\n clean(ghKey);\n }\n update(data: Uint8Array): this {\n aexists(this);\n abytes(data);\n data = copyBytes(data);\n const b32 = u32(data);\n const left = data.length % BLOCK_SIZE;\n const blocks = Math.floor(data.length / BLOCK_SIZE);\n for (let i = 0; i < blocks; i++) {\n this._updateBlock(\n swapLE(b32[i * 4 + 3]),\n swapLE(b32[i * 4 + 2]),\n swapLE(b32[i * 4 + 1]),\n swapLE(b32[i * 4 + 0])\n );\n }\n if (left) {\n ZEROS16.set(data.subarray(blocks * BLOCK_SIZE));\n this._updateBlock(\n swapLE(ZEROS32[3]),\n swapLE(ZEROS32[2]),\n swapLE(ZEROS32[1]),\n swapLE(ZEROS32[0])\n );\n clean(ZEROS32);\n }\n return this;\n }\n digestInto(out: Uint8Array): Uint8Array {\n aexists(this);\n aoutput(out, this);\n this.finished = true;\n // tmp ugly hack\n const { s0, s1, s2, s3 } = this;\n const o32 = u32(out);\n o32[0] = s0;\n o32[1] = s1;\n o32[2] = s2;\n o32[3] = s3;\n return out.reverse();\n }\n}\n\nexport type CHashPV = ReturnType<typeof wrapConstructorWithKey>;\nfunction wrapConstructorWithKey<H extends IHash2>(\n hashCons: (key: Uint8Array, expectedLength?: number) => H\n): {\n (msg: Uint8Array, key: Uint8Array): Uint8Array;\n outputLen: number;\n blockLen: number;\n create(key: Uint8Array, expectedLength?: number): H;\n} {\n const hashC = (msg: Uint8Array, key: Uint8Array): Uint8Array =>\n hashCons(key, msg.length).update(msg).digest();\n const tmp = hashCons(new Uint8Array(16), 0);\n hashC.outputLen = tmp.outputLen;\n hashC.blockLen = tmp.blockLen;\n hashC.create = (key: Uint8Array, expectedLength?: number) => hashCons(key, expectedLength);\n return hashC;\n}\n\n/** GHash MAC for AES-GCM. */\nexport const ghash: CHashPV = wrapConstructorWithKey(\n (key, expectedLength) => new GHASH(key, expectedLength)\n);\n\n/** Polyval MAC for AES-SIV. */\nexport const polyval: CHashPV = wrapConstructorWithKey(\n (key, expectedLength) => new Polyval(key, expectedLength)\n);\n","/**\n * [AES](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard)\n * a.k.a. Advanced Encryption Standard\n * is a variant of Rijndael block cipher, standardized by NIST in 2001.\n * We provide the fastest available pure JS implementation.\n *\n * `cipher = encrypt(block, key)`\n *\n * Data is split into 128-bit blocks. Encrypted in 10/12/14 rounds (128/192/256 bits). In every round:\n * 1. **S-box**, table substitution\n * 2. **Shift rows**, cyclic shift left of all rows of data array\n * 3. **Mix columns**, multiplying every column by fixed polynomial\n * 4. **Add round key**, round_key xor i-th column of array\n *\n * Check out [FIPS-197](https://csrc.nist.gov/files/pubs/fips/197/final/docs/fips-197.pdf),\n * [NIST 800-38G](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38G.pdf)\n * and [original proposal](https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/aes-development/rijndael-ammended.pdf)\n * @module\n */\nimport { ghash, polyval } from './_polyval.ts';\n// prettier-ignore\nimport {\n abytes, anumber, clean, complexOverlapBytes, concatBytes,\n copyBytes, createView, equalBytes, getOutput, isAligned32, overlapBytes,\n u32, u64Lengths, u8, wrapCipher,\n type Cipher, type CipherWithOutput, type PRG, type Uint8ArrayBuffer\n} from './utils.ts';\n\nconst BLOCK_SIZE = 16;\nconst BLOCK_SIZE32 = 4;\nconst EMPTY_BLOCK = /* @__PURE__ */ new Uint8Array(BLOCK_SIZE);\nconst ONE_BLOCK = /* @__PURE__ */ Uint8Array.from([\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,\n]);\nconst POLY = 0x11b; // 1 + x + x**3 + x**4 + x**8\n\nfunction validateKeyLength(key: Uint8Array) {\n if (![16, 24, 32].includes(key.length))\n throw new Error('\"aes key\" expected Uint8Array of length 16/24/32, got length=' + key.length);\n}\n\n// TODO: remove multiplication, binary ops only\nfunction mul2(n: number) {\n return (n << 1) ^ (POLY & -(n >> 7));\n}\n\nfunction mul(a: number, b: number) {\n let res = 0;\n for (; b > 0; b >>= 1) {\n // Montgomery ladder\n res ^= a & -(b & 1); // if (b&1) res ^=a (but const-time).\n a = mul2(a); // a = 2*a\n }\n return res;\n}\n\n// Increments bigint with wrap around\n// NOTE: we cannot use u32 here since it may overflow on carry!\nconst incBytes = (data: Uint8Array, isLE: boolean, carry: number = 1) => {\n if (!Number.isSafeInteger(carry)) throw new Error('incBytes: wrong carry ' + carry);\n abytes(data);\n for (let i = 0; i < data.length; i++) {\n const pos = !isLE ? data.length - 1 - i : i;\n carry = (carry + (data[pos] & 0xff)) | 0;\n data[pos] = carry & 0xff;\n carry >>>= 8;\n }\n};\n\n// AES S-box is generated using finite field inversion,\n// an affine transform, and xor of a constant 0x63.\nconst sbox = /* @__PURE__ */ (() => {\n const t = new Uint8Array(256);\n for (let i = 0, x = 1; i < 256; i++, x ^= mul2(x)) t[i] = x;\n const box = new Uint8Array(256);\n box[0] = 0x63; // first elm\n for (let i = 0; i < 255; i++) {\n let x = t[255 - i];\n x |= x << 8;\n box[t[i]] = (x ^ (x >> 4) ^ (x >> 5) ^ (x >> 6) ^ (x >> 7) ^ 0x63) & 0xff;\n }\n clean(t);\n return box;\n})();\n\n// Inverted S-box\nconst invSbox = /* @__PURE__ */ sbox.map((_, j) => sbox.indexOf(j));\n\n// Rotate u32 by 8\nconst rotr32_8 = (n: number) => (n << 24) | (n >>> 8);\nconst rotl32_8 = (n: number) => (n << 8) | (n >>> 24);\n// The byte swap operation for uint32 (LE<->BE)\nconst byteSwap = (word: number) =>\n ((word << 24) & 0xff000000) |\n ((word << 8) & 0xff0000) |\n ((word >>> 8) & 0xff00) |\n ((word >>> 24) & 0xff);\n\n// T-table is optimization suggested in 5.2 of original proposal (missed from FIPS-197). Changes:\n// - LE instead of BE\n// - bigger tables: T0 and T1 are merged into T01 table and T2 & T3 into T23;\n// so index is u16, instead of u8. This speeds up things, unexpectedly\nfunction genTtable(sbox: Uint8Array, fn: (n: number) => number) {\n if (sbox.length !== 256) throw new Error('Wrong sbox length');\n const T0 = new Uint32Array(256).map((_, j) => fn(sbox[j]));\n const T1 = T0.map(rotl32_8);\n const T2 = T1.map(rotl32_8);\n const T3 = T2.map(rotl32_8);\n const T01 = new Uint32Array(256 * 256);\n const T23 = new Uint32Array(256 * 256);\n const sbox2 = new Uint16Array(256 * 256);\n for (let i = 0; i < 256; i++) {\n for (let j = 0; j < 256; j++) {\n const idx = i * 256 + j;\n T01[idx] = T0[i] ^ T1[j];\n T23[idx] = T2[i] ^ T3[j];\n sbox2[idx] = (sbox[i] << 8) | sbox[j];\n }\n }\n return { sbox, sbox2, T0, T1, T2, T3, T01, T23 };\n}\n\nconst tableEncoding = /* @__PURE__ */ genTtable(\n sbox,\n (s: number) => (mul(s, 3) << 24) | (s << 16) | (s << 8) | mul(s, 2)\n);\nconst tableDecoding = /* @__PURE__ */ genTtable(\n invSbox,\n (s) => (mul(s, 11) << 24) | (mul(s, 13) << 16) | (mul(s, 9) << 8) | mul(s, 14)\n);\n\nconst xPowers = /* @__PURE__ */ (() => {\n const p = new Uint8Array(16);\n for (let i = 0, x = 1; i < 16; i++, x = mul2(x)) p[i] = x;\n return p;\n})();\n\n/** Key expansion used in CTR. */\nfunction expandKeyLE(key: Uint8Array): Uint32Array {\n abytes(key);\n const len = key.length;\n validateKeyLength(key);\n const { sbox2 } = tableEncoding;\n const toClean = [];\n if (!isAligned32(key)) toClean.push((key = copyBytes(key)));\n const k32 = u32(key);\n const Nk = k32.length;\n const subByte = (n: number) => applySbox(sbox2, n, n, n, n);\n const xk = new Uint32Array(len + 28); // expanded key\n xk.set(k32);\n // 4.3.1 Key expansion\n for (let i = Nk; i < xk.length; i++) {\n let t = xk[i - 1];\n if (i % Nk === 0) t = subByte(rotr32_8(t)) ^ xPowers[i / Nk - 1];\n else if (Nk > 6 && i % Nk === 4) t = subByte(t);\n xk[i] = xk[i - Nk] ^ t;\n }\n clean(...toClean);\n return xk;\n}\n\nfunction expandKeyDecLE(key: Uint8Array): Uint32Array {\n const encKey = expandKeyLE(key);\n const xk = encKey.slice();\n const Nk = encKey.length;\n const { sbox2 } = tableEncoding;\n const { T0, T1, T2, T3 } = tableDecoding;\n // Inverse key by chunks of 4 (rounds)\n for (let i = 0; i < Nk; i += 4) {\n for (let j = 0; j < 4; j++) xk[i + j] = encKey[Nk - i - 4 + j];\n }\n clean(encKey);\n // apply InvMixColumn except first & last round\n for (let i = 4; i < Nk - 4; i++) {\n const x = xk[i];\n const w = applySbox(sbox2, x, x, x, x);\n xk[i] = T0[w & 0xff] ^ T1[(w >>> 8) & 0xff] ^ T2[(w >>> 16) & 0xff] ^ T3[w >>> 24];\n }\n return xk;\n}\n\n// Apply tables\nfunction apply0123(\n T01: Uint32Array,\n T23: Uint32Array,\n s0: number,\n s1: number,\n s2: number,\n s3: number\n) {\n return (\n T01[((s0 << 8) & 0xff00) | ((s1 >>> 8) & 0xff)] ^\n T23[((s2 >>> 8) & 0xff00) | ((s3 >>> 24) & 0xff)]\n );\n}\n\nfunction applySbox(sbox2: Uint16Array, s0: number, s1: number, s2: number, s3: number) {\n return (\n sbox2[(s0 & 0xff) | (s1 & 0xff00)] |\n (sbox2[((s2 >>> 16) & 0xff) | ((s3 >>> 16) & 0xff00)] << 16)\n );\n}\n\nfunction encrypt(\n xk: Uint32Array,\n s0: number,\n s1: number,\n s2: number,\n s3: number\n): { s0: number; s1: number; s2: number; s3: number } {\n const { sbox2, T01, T23 } = tableEncoding;\n let k = 0;\n ((s0 ^= xk[k++]), (s1 ^= xk[k++]), (s2 ^= xk[k++]), (s3 ^= xk[k++]));\n const rounds = xk.length / 4 - 2;\n for (let i = 0; i < rounds; i++) {\n const t0 = xk[k++] ^ apply0123(T01, T23, s0, s1, s2, s3);\n const t1 = xk[k++] ^ apply0123(T01, T23, s1, s2, s3, s0);\n const t2 = xk[k++] ^ apply0123(T01, T23, s2, s3, s0, s1);\n const t3 = xk[k++] ^ apply0123(T01, T23, s3, s0, s1, s2);\n ((s0 = t0), (s1 = t1), (s2 = t2), (s3 = t3));\n }\n // last round (without mixcolumns, so using SBOX2 table)\n const t0 = xk[k++] ^ applySbox(sbox2, s0, s1, s2, s3);\n const t1 = xk[k++] ^ applySbox(sbox2, s1, s2, s3, s0);\n const t2 = xk[k++] ^ applySbox(sbox2, s2, s3, s0, s1);\n const t3 = xk[k++] ^ applySbox(sbox2, s3, s0, s1, s2);\n return { s0: t0, s1: t1, s2: t2, s3: t3 };\n}\n\n// Can't be merged with encrypt: arg positions for apply0123 / applySbox are different\nfunction decrypt(\n xk: Uint32Array,\n s0: number,\n s1: number,\n s2: number,\n s3: number\n): {\n s0: number;\n s1: number;\n s2: number;\n s3: number;\n} {\n const { sbox2, T01, T23 } = tableDecoding;\n let k = 0;\n ((s0 ^= xk[k++]), (s1 ^= xk[k++]), (s2 ^= xk[k++]), (s3 ^= xk[k++]));\n const rounds = xk.length / 4 - 2;\n for (let i = 0; i < rounds; i++) {\n const t0 = xk[k++] ^ apply0123(T01, T23, s0, s3, s2, s1);\n const t1 = xk[k++] ^ apply0123(T01, T23, s1, s0, s3, s2);\n const t2 = xk[k++] ^ apply0123(T01, T23, s2, s1, s0, s3);\n const t3 = xk[k++] ^ apply0123(T01, T23, s3, s2, s1, s0);\n ((s0 = t0), (s1 = t1), (s2 = t2), (s3 = t3));\n }\n // Last round\n const t0: number = xk[k++] ^ applySbox(sbox2, s0, s3, s2, s1);\n const t1: number = xk[k++] ^ applySbox(sbox2, s1, s0, s3, s2);\n const t2: number = xk[k++] ^ applySbox(sbox2, s2, s1, s0, s3);\n const t3: number = xk[k++] ^ applySbox(sbox2, s3, s2, s1, s0);\n return { s0: t0, s1: t1, s2: t2, s3: t3 };\n}\n\n// TODO: investigate merging with ctr32\nfunction ctrCounter(\n xk: Uint32Array,\n nonce: Uint8Array,\n src: Uint8Array,\n dst?: Uint8Array\n): Uint8Array {\n abytes(nonce, BLOCK_SIZE, 'nonce');\n abytes(src);\n const srcLen = src.length;\n dst = getOutput(srcLen, dst);\n complexOverlapBytes(src, dst);\n const ctr = nonce;\n const c32 = u32(ctr);\n // Fill block (empty, ctr=0)\n let { s0, s1, s2, s3 } = encrypt(xk, c32[0], c32[1], c32[2], c32[3]);\n const src32 = u32(src);\n const dst32 = u32(dst);\n // process blocks\n for (let i = 0; i + 4 <= src32.length; i += 4) {\n dst32[i + 0] = src32[i + 0] ^ s0;\n dst32[i + 1] = src32[i + 1] ^ s1;\n dst32[i + 2] = src32[i + 2] ^ s2;\n dst32[i + 3] = src32[i + 3] ^ s3;\n incBytes(ctr, false, 1); // Full 128 bit counter with wrap around\n ({ s0, s1, s2, s3 } = encrypt(xk, c32[0], c32[1], c32[2], c32[3]));\n }\n // leftovers (less than block)\n // It's possible to handle > u32 fast, but is it worth it?\n const start = BLOCK_SIZE * Math.floor(src32.length / BLOCK_SIZE32);\n if (start < srcLen) {\n const b32 = new Uint32Array([s0, s1, s2, s3]);\n const buf = u8(b32);\n for (let i = start, pos = 0; i < srcLen; i++, pos++) dst[i] = src[i] ^ buf[pos];\n clean(b32);\n }\n return dst;\n}\n\n// AES CTR with overflowing 32 bit counter\n// It's possible to do 32le significantly simpler (and probably faster) by using u32.\n// But, we need both, and perf bottleneck is in ghash anyway.\nfunction ctr32(\n xk: Uint32Array,\n isLE: boolean,\n nonce: Uint8Array,\n src: Uint8Array,\n dst?: Uint8Array\n): Uint8Array {\n abytes(nonce, BLOCK_SIZE, 'nonce');\n abytes(src);\n dst = getOutput(src.length, dst);\n const ctr = nonce; // write new value to nonce, so it can be re-used\n const c32 = u32(ctr);\n const view = createView(ctr);\n const src32 = u32(src);\n const dst32 = u32(dst);\n const ctrPos = isLE ? 0 : 12;\n const srcLen = src.length;\n // Fill block (empty, ctr=0)\n let ctrNum = view.getUint32(ctrPos, isLE); // read current counter value\n let { s0, s1, s2, s3 } = encrypt(xk, c32[0], c32[1], c32[2], c32[3]);\n // process blocks\n for (let i = 0; i + 4 <= src32.length; i += 4) {\n dst32[i + 0] = src32[i + 0] ^ s0;\n dst32[i + 1] = src32[i + 1] ^ s1;\n dst32[i + 2] = src32[i + 2] ^ s2;\n dst32[i + 3] = src32[i + 3] ^ s3;\n ctrNum = (ctrNum + 1) >>> 0; // u32 wrap\n view.setUint32(ctrPos, ctrNum, isLE);\n ({ s0, s1, s2, s3 } = encrypt(xk, c32[0], c32[1], c32[2], c32[3]));\n }\n // leftovers (less than a block)\n const start = BLOCK_SIZE * Math.floor(src32.length / BLOCK_SIZE32);\n if (start < srcLen) {\n const b32 = new Uint32Array([s0, s1, s2, s3]);\n const buf = u8(b32);\n for (let i = start, pos = 0; i < srcLen; i++, pos++) dst[i] = src[i] ^ buf[pos];\n clean(b32);\n }\n return dst;\n}\n\n/**\n * **CTR** (Counter Mode): Turns a block cipher into a stream cipher using a counter and IV (nonce).\n * Efficient and parallelizable. Requires a unique nonce per encryption. Unauthenticated: needs MAC.\n */\nexport const ctr: ((key: Uint8Array, nonce: Uint8Array) => CipherWithOutput) & {\n blockSize: number;\n nonceLength: number;\n} = /* @__PURE__ */ wrapCipher(\n { blockSize: 16, nonceLength: 16 },\n function aesctr(key: Uint8Array, nonce: Uint8Array): CipherWithOutput {\n function processCtr(buf: Uint8Array, dst?: Uint8Array) {\n abytes(buf);\n if (dst !== undefined) {\n abytes(dst);\n if (!isAligned32(dst)) throw new Error('unaligned destination');\n }\n const xk = expandKeyLE(key);\n const n = copyBytes(nonce); // align + avoid changing\n const toClean = [xk, n];\n if (!isAligned32(buf)) toClean.push((buf = copyBytes(buf)));\n const out = ctrCounter(xk, n, buf, dst);\n clean(...toClean);\n return out;\n }\n return {\n encrypt: (plaintext: Uint8Array, dst?: Uint8Array) => processCtr(plaintext, dst),\n decrypt: (ciphertext: Uint8Array, dst?: Uint8Array) => processCtr(ciphertext, dst),\n };\n }\n);\n\nfunction validateBlockDecrypt(data: Uint8Array) {\n abytes(data);\n if (data.length % BLOCK_SIZE !== 0) {\n throw new Error(\n 'aes-(cbc/ecb).decrypt ciphertext should consist of blocks with size ' + BLOCK_SIZE\n );\n }\n}\n\nfunction validateBlockEncrypt(plaintext: Uint8Array, pcks5: boolean, dst?: Uint8Array) {\n abytes(plaintext);\n let outLen = plaintext.length;\n const remaining = outLen % BLOCK_SIZE;\n if (!pcks5 && remaining !== 0)\n throw new Error('aec/(cbc-ecb): unpadded plaintext with disabled padding');\n if (!isAligned32(plaintext)) plaintext = copyBytes(plaintext);\n const b = u32(plaintext);\n if (pcks5) {\n let left = BLOCK_SIZE - remaining;\n if (!left) left = BLOCK_SIZE; // if no bytes left, create empty padding block\n outLen = outLen + left;\n }\n dst = getOutput(outLen, dst);\n complexOverlapBytes(plaintext, dst);\n const o = u32(dst);\n return { b, o, out: dst };\n}\n\nfunction validatePCKS(data: Uint8Array, pcks5: boolean) {\n if (!pcks5) return data;\n const len = data.length;\n if (!len) throw new Error('aes/pcks5: empty ciphertext not allowed');\n const lastByte = data[len - 1];\n if (lastByte <= 0 || lastByte > 16) throw new Error('aes/pcks5: wrong padding');\n const out = data.subarray(0, -lastByte);\n for (let i = 0; i < lastByte; i++)\n if (data[len - i - 1] !== lastByte) throw new Error('aes/pcks5: wrong padding');\n return out;\n}\n\nfunction padPCKS(left: Uint8Array) {\n const tmp = new Uint8Array(16);\n const tmp32 = u32(tmp);\n tmp.set(left);\n const paddingByte = BLOCK_SIZE - left.length;\n for (let i = BLOCK_SIZE - paddingByte; i < BLOCK_SIZE; i++) tmp[i] = paddingByte;\n return tmp32;\n}\n\n/** Options for ECB and CBC. */\nexport type BlockOpts = { disablePadding?: boolean };\n\n/**\n * **ECB** (Electronic Codebook): Deterministic encryption; identical plaintext blocks yield\n * identical ciphertexts. Not secure due to pattern leakage.\n * See [AES Penguin](https://words.filippo.io/the-ecb-penguin/).\n */\nexport const ecb: ((key: Uint8Array, opts?: BlockOpts) => CipherWithOutput) & {\n blockSize: number;\n} = /* @__PURE__ */ wrapCipher(\n { blockSize: 16 },\n function aesecb(key: Uint8Array, opts: BlockOpts = {}): CipherWithOutput {\n const pcks5 = !opts.disablePadding;\n return {\n encrypt(plaintext: Uint8Array, dst?: Uint8Array) {\n const { b, o, out: _out } = validateBlockEncrypt(plaintext, pcks5, dst);\n const xk = expandKeyLE(key);\n let i = 0;\n for (; i + 4 <= b.length; ) {\n const { s0, s1, s2, s3 } = encrypt(xk, b[i + 0], b[i + 1], b[i + 2], b[i + 3]);\n ((o[i++] = s0), (o[i++] = s1), (o[i++] = s2), (o[i++] = s3));\n }\n if (pcks5) {\n const tmp32 = padPCKS(plaintext.subarray(i * 4));\n const { s0, s1, s2, s3 } = encrypt(xk, tmp32[0], tmp32[1], tmp32[2], tmp32[3]);\n ((o[i++] = s0), (o[i++] = s1), (o[i++] = s2), (o[i++] = s3));\n }\n clean(xk);\n return _out;\n },\n decrypt(ciphertext: Uint8Array, dst?: Uint8Array) {\n validateBlockDecrypt(ciphertext);\n const xk = expandKeyDecLE(key);\n dst = getOutput(ciphertext.length, dst);\n const toClean: (Uint8Array | Uint32Array)[] = [xk];\n if (!isAligned32(ciphertext)) toClean.push((ciphertext = copyBytes(ciphertext)));\n complexOverlapBytes(ciphertext, dst);\n const b = u32(ciphertext);\n const o = u32(dst);\n for (let i = 0; i + 4 <= b.length; ) {\n const { s0, s1, s2, s3 } = decrypt(xk, b[i + 0], b[i + 1], b[i + 2], b[i + 3]);\n ((o[i++] = s0), (o[i++] = s1), (o[i++] = s2), (o[i++] = s3));\n }\n clean(...toClean);\n return validatePCKS(dst, pcks5);\n },\n };\n }\n);\n\n/**\n * **CBC** (Cipher Block Chaining): Each plaintext block is XORed with the\n * previous block of ciphertext before encryption.\n * Hard to use: requires proper padding and an IV. Unauthenticated: needs MAC.\n */\nexport const cbc: ((key: Uint8Array, iv: Uint8Array, opts?: BlockOpts) => CipherWithOutput) & {\n blockSize: number;\n nonceLength: number;\n} = /* @__PURE__ */ wrapCipher(\n { blockSize: 16, nonceLength: 16 },\n function aescbc(key: Uint8Array, iv: Uint8Array, opts: BlockOpts = {}): CipherWithOutput {\n const pcks5 = !opts.disablePadding;\n return {\n encrypt(plaintext: Uint8Array, dst?: Uint8Array) {\n const xk = expandKeyLE(key);\n const { b, o, out: _out } = validateBlockEncrypt(plaintext, pcks5, dst);\n let _iv = iv;\n const toClean: (Uint8Array | Uint32Array)[] = [xk];\n if (!isAligned32(_iv)) toClean.push((_iv = copyBytes(_iv)));\n const n32 = u32(_iv);\n // prettier-ignore\n let s0 = n32[0], s1 = n32[1], s2 = n32[2], s3 = n32[3];\n let i = 0;\n for (; i + 4 <= b.length; ) {\n ((s0 ^= b[i + 0]), (s1 ^= b[i + 1]), (s2 ^= b[i + 2]), (s3 ^= b[i + 3]));\n ({ s0, s1, s2, s3 } = encrypt(xk, s0, s1, s2, s3));\n ((o[i++] = s0), (o[i++] = s1), (o[i++] = s2), (o[i++] = s3));\n }\n if (pcks5) {\n const tmp32 = padPCKS(plaintext.subarray(i * 4));\n ((s0 ^= tmp32[0]), (s1 ^= tmp32[1]), (s2 ^= tmp32[2]), (s3 ^= tmp32[3]));\n ({ s0, s1, s2, s3 } = encrypt(xk, s0, s1, s2, s3));\n ((o[i++] = s0), (o[i++] = s1), (o[i++] = s2), (o[i++] = s3));\n }\n clean(...toClean);\n return _out;\n },\n decrypt(ciphertext: Uint8Array, dst?: Uint8Array) {\n validateBlockDecrypt(ciphertext);\n const xk = expandKeyDecLE(key);\n let _iv = iv;\n const toClean: (Uint8Array | Uint32Array)[] = [xk];\n if (!isAligned32(_iv)) toClean.push((_iv = copyBytes(_iv)));\n const n32 = u32(_iv);\n dst = getOutput(ciphertext.length, dst);\n if (!isAligned32(ciphertext)) toClean.push((ciphertext = copyBytes(ciphertext)));\n complexOverlapBytes(ciphertext, dst);\n const b = u32(ciphertext);\n const o = u32(dst);\n // prettier-ignore\n let s0 = n32[0], s1 = n32[1], s2 = n32[2], s3 = n32[3];\n for (let i = 0; i + 4 <= b.length; ) {\n // prettier-ignore\n const ps0 = s0, ps1 = s1, ps2 = s2, ps3 = s3;\n ((s0 = b[i + 0]), (s1 = b[i + 1]), (s2 = b[i + 2]), (s3 = b[i + 3]));\n const { s0: o0, s1: o1, s2: o2, s3: o3 } = decrypt(xk, s0, s1, s2, s3);\n ((o[i++] = o0 ^ ps0), (o[i++] = o1 ^ ps1), (o[i++] = o2 ^ ps2), (o[i++] = o3 ^ ps3));\n }\n clean(...toClean);\n return validatePCKS(dst, pcks5);\n },\n };\n }\n);\n\n/**\n * CFB: Cipher Feedback Mode. The input for the block cipher is the previous cipher output.\n * Unauthenticated: needs MAC.\n */\nexport const cfb: ((key: Uint8Array, iv: Uint8Array) => CipherWithOutput) & {\n blockSize: number;\n nonceLength: number;\n} = /* @__PURE__ */ wrapCipher(\n { blockSize: 16, nonceLength: 16 },\n function aescfb(key: Uint8Array, iv: Uint8Array): CipherWithOutput {\n function processCfb(src: Uint8Array, isEncrypt: boolean, dst?: Uint8Array) {\n abytes(src);\n const srcLen = src.length;\n dst = getOutput(srcLen, dst);\n if (overlapBytes(src, dst)) throw new Error('overlapping src and dst not supported.');\n const xk = expandKeyLE(key);\n let _iv = iv;\n const toClean: (Uint8Array | Uint32Array)[] = [xk];\n if (!isAligned32(_iv)) toClean.push((_iv = copyBytes(_iv)));\n if (!isAligned32(src)) toClean.push((src = copyBytes(src)));\n const src32 = u32(src);\n const dst32 = u32(dst);\n const next32 = isEncrypt ? dst32 : src32;\n const n32 = u32(_iv);\n // prettier-ignore\n let s0 = n32[0], s1 = n32[1], s2 = n32[2], s3 = n32[3];\n for (let i = 0; i + 4 <= src32.length; ) {\n const { s0: e0, s1: e1, s2: e2, s3: e3 } = encrypt(xk, s0, s1, s2, s3);\n dst32[i + 0] = src32[i + 0] ^ e0;\n dst32[i + 1] = src32[i + 1] ^ e1;\n dst32[i + 2] = src32[i + 2] ^ e2;\n dst32[i + 3] = src32[i + 3] ^ e3;\n ((s0 = next32[i++]), (s1 = next32[i++]), (s2 = next32[i++]), (s3 = next32[i++]));\n }\n // leftovers (less than block)\n const start = BLOCK_SIZE * Math.floor(src32.length / BLOCK_SIZE32);\n if (start < srcLen) {\n ({ s0, s1, s2, s3 } = encrypt(xk, s0, s1, s2, s3));\n const buf = u8(new Uint32Array([s0, s1, s2, s3]));\n for (let i = start, pos = 0; i < srcLen; i++, pos++) dst[i] = src[i] ^ buf[pos];\n clean(buf);\n }\n clean(...toClean);\n return dst;\n }\n return {\n encrypt: (plaintext: Uint8Array, dst?: Uint8Array) => processCfb(plaintext, true, dst),\n decrypt: (ciphertext: Uint8Array, dst?: Uint8Array) => processCfb(ciphertext, false, dst),\n };\n }\n);\n\n// TODO: merge with chacha, however gcm has bitLen while chacha has byteLen\nfunction computeTag(\n fn: typeof ghash,\n isLE: boolean,\n key: Uint8Array,\n data: Uint8Array,\n AAD?: Uint8Array\n) {\n const aadLength = AAD ? AAD.length : 0;\n const h = fn.create(key, data.length + aadLength);\n if (AAD) h.update(AAD);\n const num = u64Lengths(8 * data.length, 8 * aadLength, isLE);\n h.update(data);\n h.update(num);\n const res = h.digest();\n clean(num);\n return res;\n}\n\n/**\n * **GCM** (Galois/Counter Mode): Combines CTR mode with polynomial MAC. Efficient and widely used.\n * Not perfect:\n * a) conservative key wear-out is `2**32` (4B) msgs.\n * b) key wear-out under random nonces is even smaller: `2**23` (8M) messages for `2**-50` chance.\n * c) MAC can be forged: see Poly1305 documentation.\n */\nexport const gcm: ((key: Uint8Array, nonce: Uint8Array, AAD?: Uint8Array) => Cipher) & {\n blockSize: number;\n nonceLength: number;\n tagLength: number;\n varSizeNonce: true;\n} = /* @__PURE__ */ wrapCipher(\n { blockSize: 16, nonceLength: 12, tagLength: 16, varSizeNonce: true },\n function aesgcm(key: Uint8Array, nonce: Uint8Array, AAD?: Uint8Array): Cipher {\n // NIST 800-38d doesn't enforce minimum nonce length.\n // We enforce 8 bytes for compat with openssl.\n // 12 bytes are recommended. More than 12 bytes would be converted into 12.\n if (nonce.length < 8) throw new Error('aes/gcm: invalid nonce length');\n const tagLength = 16;\n function _computeTag(authKey: Uint8Array, tagMask: Uint8Array, data: Uint8Array) {\n const tag = computeTag(ghash, false, authKey, data, AAD);\n for (let i = 0; i < tagMask.length; i++) tag[i] ^= tagMask[i];\n return tag;\n }\n function deriveKeys() {\n const xk = expandKeyLE(key);\n const authKey = EMPTY_BLOCK.slice();\n const counter = EMPTY_BLOCK.slice();\n ctr32(xk, false, counter, counter, authKey);\n // NIST 800-38d, page 15: different behavior for 96-bit and non-96-bit nonces\n if (nonce.length === 12) {\n counter.set(nonce);\n } else {\n const nonceLen = EMPTY_BLOCK.slice();\n const view = createView(nonceLen);\n view.setBigUint64(8, BigInt(nonce.length * 8), false);\n // ghash(nonce || u64be(0) || u64be(nonceLen*8))\n const g = ghash.create(authKey).update(nonce).update(nonceLen);\n g.digestInto(counter); // digestInto doesn't trigger '.destroy'\n g.destroy();\n }\n const tagMask = ctr32(xk, false, counter, EMPTY_BLOCK);\n return { xk, authKey, counter, tagMask };\n }\n return {\n encrypt(plaintext: Uint8Array) {\n const { xk, authKey, counter, tagMask } = deriveKeys();\n const out = new Uint8Array(plaintext.length + tagLength);\n const toClean: (Uint8Array | Uint32Array)[] = [xk, authKey, counter, tagMask];\n if (!isAligned32(plaintext)) toClean.push((plaintext = copyBytes(plaintext)));\n ctr32(xk, false, counter, plaintext, out.subarray(0, plaintext.length));\n const tag = _computeTag(authKey, tagMask, out.subarray(0, out.length - tagLength));\n toClean.push(tag);\n out.set(tag, plaintext.length);\n clean(...toClean);\n return out;\n },\n decrypt(ciphertext: Uint8Array) {\n const { xk, authKey, counter, tagMask } = deriveKeys();\n const toClean: (Uint8Array | Uint32Array)[] = [xk, authKey, tagMask, counter];\n if (!isAligned32(ciphertext)) toClean.push((ciphertext = copyBytes(ciphertext)));\n const data = ciphertext.subarray(0, -tagLength);\n const passedTag = ciphertext.subarray(-tagLength);\n const tag = _computeTag(authKey, tagMask, data);\n toClean.push(tag);\n if (!equalBytes(tag, passedTag)) throw new Error('aes/gcm: invalid ghash tag');\n const out = ctr32(xk, false, counter, data);\n clean(...toClean);\n return out;\n },\n };\n }\n);\n\nconst limit = (name: string, min: number, max: number) => (value: number) => {\n if (!Number.isSafeInteger(value) || min > value || value > max) {\n const minmax = '[' + min + '..' + max + ']';\n throw new Error('' + name + ': expected value in range ' + minmax + ', got ' + value);\n }\n};\n\n/**\n * **SIV** (Synthetic IV): GCM with nonce-misuse resistance.\n * Repeating nonces reveal only the fact plaintexts are identical.\n * Also suffers from GCM issues: key wear-out limits & MAC forging.\n * See [RFC 8452](https://www.rfc-editor.org/rfc/rfc8452).\n */\nexport const gcmsiv: ((key: Uint8Array, nonce: Uint8Array, AAD?: Uint8Array) => Cipher) & {\n blockSize: number;\n nonceLength: number;\n tagLength: number;\n varSizeNonce: true;\n} = /* @__PURE__ */ wrapCipher(\n { blockSize: 16, nonceLength: 12, tagLength: 16, varSizeNonce: true },\n function aessiv(key: Uint8Array, nonce: Uint8Array, AAD?: Uint8Array): Cipher {\n const tagLength = 16;\n // From RFC 8452: Section 6\n const AAD_LIMIT = limit('AAD', 0, 2 ** 36);\n const PLAIN_LIMIT = limit('plaintext', 0, 2 ** 36);\n const NONCE_LIMIT = limit('nonce', 12, 12);\n const CIPHER_LIMIT = limit('ciphertext', 16, 2 ** 36 + 16);\n abytes(key);\n validateKeyLength(key);\n NONCE_LIMIT(nonce.length);\n if (AAD !== undefined) AAD_LIMIT(AAD.length);\n function deriveKeys() {\n const xk = expandKeyLE(key);\n const encKey = new Uint8Array(key.length);\n const authKey = new Uint8Array(16);\n const toClean: (Uint8Array | Uint32Array)[] = [xk, encKey];\n let _nonce = nonce;\n if (!isAligned32(_nonce)) toClean.push((_nonce = copyBytes(_nonce)));\n const n32 = u32(_nonce);\n // prettier-ignore\n let s0 = 0, s1 = n32[0], s2 = n32[1], s3 = n32[2];\n let counter = 0;\n for (const derivedKey of [authKey, encKey].map(u32)) {\n const d32 = u32(derivedKey);\n for (let i = 0; i < d32.length; i += 2) {\n // aes(u32le(0) || nonce)[:8] || aes(u32le(1) || nonce)[:8] ...\n const { s0: o0, s1: o1 } = encrypt(xk, s0, s1, s2, s3);\n d32[i + 0] = o0;\n d32[i + 1] = o1;\n s0 = ++counter; // increment counter inside state\n }\n }\n const res = { authKey, encKey: expandKeyLE(encKey) };\n // Cleanup\n clean(...toClean);\n return res;\n }\n function _computeTag(encKey: Uint32Array, authKey: Uint8Array, data: Uint8Array) {\n const tag = computeTag(polyval, true, authKey, data, AAD);\n // Compute the expected tag by XORing S_s and the nonce, clearing the\n // most significant bit of the last byte and encrypting with the\n // message-encryption key.\n for (let i = 0; i < 12; i++) tag[i] ^= nonce[i];\n tag[15] &= 0x7f; // Clear the highest bit\n // encrypt tag as block\n const t32 = u32(tag);\n // prettier-ignore\n let s0 = t32[0], s1 = t32[1], s2 = t32[2], s3 = t32[3];\n ({ s0, s1, s2, s3 } = encrypt(encKey, s0, s1, s2, s3));\n ((t32[0] = s0), (t32[1] = s1), (t32[2] = s2), (t32[3] = s3));\n return tag;\n }\n // actual decrypt/encrypt of message.\n function processSiv(encKey: Uint32Array, tag: Uint8Array, input: Uint8Array) {\n let block = copyBytes(tag);\n block[15] |= 0x80; // Force highest bit\n const res = ctr32(encKey, true, block, input);\n // Cleanup\n clean(block);\n return res;\n }\n return {\n encrypt(plaintext: Uint8Array) {\n PLAIN_LIMIT(plaintext.length);\n const { encKey, authKey } = deriveKeys();\n const tag = _computeTag(encKey, authKey, plaintext);\n const toClean: (Uint8Array | Uint32Array)[] = [encKey, authKey, tag];\n if (!isAligned32(plaintext)) toClean.push((plaintext = copyBytes(plaintext)));\n const out = new Uint8Array(plaintext.length + tagLength);\n out.set(tag, plaintext.length);\n out.set(processSiv(encKey, tag, plaintext));\n // Cleanup\n clean(...toClean);\n return out;\n },\n decrypt(ciphertext: Uint8Array) {\n CIPHER_LIMIT(ciphertext.length);\n const tag = ciphertext.subarray(-tagLength);\n const { encKey, authKey } = deriveKeys();\n const toClean: (Uint8Array | Uint32Array)[] = [encKey, authKey];\n if (!isAligned32(ciphertext)) toClean.push((ciphertext = copyBytes(ciphertext)));\n const plaintext = processSiv(encKey, tag, ciphertext.subarray(0, -tagLength));\n const expectedTag = _computeTag(encKey, authKey, plaintext);\n toClean.push(expectedTag);\n if (!equalBytes(tag, expectedTag)) {\n clean(...toClean);\n throw new Error('invalid polyval tag');\n }\n // Cleanup\n clean(...toClean);\n return plaintext;\n },\n };\n }\n);\n\nfunction isBytes32(a: unknown): a is Uint32Array {\n return (\n a instanceof Uint32Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint32Array')\n );\n}\n\nfunction encryptBlock(xk: Uint32Array, block: Uint8Array): Uint8Array {\n abytes(block, 16, 'block');\n if (!isBytes32(xk)) throw new Error('_encryptBlock accepts result of expandKeyLE');\n const b32 = u32(block);\n let { s0, s1, s2, s3 } = encrypt(xk, b32[0], b32[1], b32[2], b32[3]);\n ((b32[0] = s0), (b32[1] = s1), (b32[2] = s2), (b32[3] = s3));\n return block;\n}\n\nfunction decryptBlock(xk: Uint32Array, block: Uint8Array): Uint8Array {\n abytes(block, 16, 'block');\n if (!isBytes32(xk)) throw new Error('_decryptBlock accepts result of expandKeyLE');\n const b32 = u32(block);\n let { s0, s1, s2, s3 } = decrypt(xk, b32[0], b32[1], b32[2], b32[3]);\n ((b32[0] = s0), (b32[1] = s1), (b32[2] = s2), (b32[3] = s3));\n return block;\n}\n\n/**\n * AES-W (base for AESKW/AESKWP).\n * Specs: [SP800-38F](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38F.pdf),\n * [RFC 3394](https://www.rfc-editor.org/rfc/rfc3394),\n * [RFC 5649](https://www.rfc-editor.org/rfc/rfc5649).\n */\nconst AESW = {\n /*\n High-level pseudocode:\n ```\n A: u64 = IV\n out = []\n for (let i=0, ctr = 0; i<6; i++) {\n for (const chunk of chunks(plaintext, 8)) {\n A ^= swapEndianess(ctr++)\n [A, res] = chunks(encrypt(A || chunk), 8);\n out ||= res\n }\n }\n out = A || out\n ```\n Decrypt is the same, but reversed.\n */\n encrypt(kek: Uint8Array, out: Uint8Array) {\n // Size is limited to 4GB, otherwise ctr will overflow and we'll need to switch to bigints.\n // If you need it larger, open an issue.\n if (out.length >= 2 ** 32) throw new Error('plaintext should be less than 4gb');\n const xk = expandKeyLE(kek);\n if (out.length === 16) encryptBlock(xk, out);\n else {\n const o32 = u32(out);\n // prettier-ignore\n let a0 = o32[0], a1 = o32[1]; // A\n for (let j = 0, ctr = 1; j < 6; j++) {\n for (let pos = 2; pos < o32.length; pos += 2, ctr++) {\n const { s0, s1, s2, s3 } = encrypt(xk, a0, a1, o32[pos], o32[pos + 1]);\n // A = MSB(64, B) ^ t where t = (n*j)+i\n ((a0 = s0), (a1 = s1 ^ byteSwap(ctr)), (o32[pos] = s2), (o32[pos + 1] = s3));\n }\n }\n ((o32[0] = a0), (o32[1] = a1)); // out = A || out\n }\n xk.fill(0);\n },\n decrypt(kek: Uint8Array, out: Uint8Array) {\n if (out.length - 8 >= 2 ** 32) throw new Error('ciphertext should be less than 4gb');\n const xk = expandKeyDecLE(kek);\n const chunks = out.length / 8 - 1; // first chunk is IV\n if (chunks === 1) decryptBlock(xk, out);\n else {\n const o32 = u32(out);\n // prettier-ignore\n let a0 = o32[0], a1 = o32[1]; // A\n for (let j = 0, ctr = chunks * 6; j < 6; j++) {\n for (let pos = chunks * 2; pos >= 1; pos -= 2, ctr--) {\n a1 ^= byteSwap(ctr);\n const { s0, s1, s2, s3 } = decrypt(xk, a0, a1, o32[pos], o32[pos + 1]);\n ((a0 = s0), (a1 = s1), (o32[pos] = s2), (o32[pos + 1] = s3));\n }\n }\n ((o32[0] = a0), (o32[1] = a1));\n }\n xk.fill(0);\n },\n};\n\nconst AESKW_IV = /* @__PURE__ */ new Uint8Array(8).fill(0xa6); // A6A6A6A6A6A6A6A6\n\n/**\n * AES-KW (key-wrap). Injects static IV into plaintext, adds counter, encrypts 6 times.\n * Reduces block size from 16 to 8 bytes.\n * For padded version, use aeskwp.\n * [RFC 3394](https://www.rfc-editor.org/rfc/rfc3394/),\n * [NIST.SP.800-38F](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38F.pdf).\n */\nexport const aeskw: ((kek: Uint8Array) => Cipher) & {\n blockSize: number;\n} = /* @__PURE__ */ wrapCipher(\n { blockSize: 8 },\n (kek: Uint8Array): Cipher => ({\n encrypt(plaintext: Uint8Array) {\n if (!plaintext.length || plaintext.length % 8 !== 0)\n throw new Error('invalid plaintext length');\n if (plaintext.length === 8)\n throw new Error('8-byte keys not allowed in AESKW, use AESKWP instead');\n const out = concatBytes(AESKW_IV, plaintext);\n AESW.encrypt(kek, out);\n return out;\n },\n decrypt(ciphertext: Uint8Array) {\n // ciphertext must be at least 24 bytes and a multiple of 8 bytes\n // 24 because should have at least two block (1 iv + 2).\n // Replace with 16 to enable '8-byte keys'\n if (ciphertext.length % 8 !== 0 || ciphertext.length < 3 * 8)\n throw new Error('invalid ciphertext length');\n const out = copyBytes(ciphertext);\n AESW.decrypt(kek, out);\n if (!equalBytes(out.subarray(0, 8), AESKW_IV)) throw new Error('integrity check failed');\n out.subarray(0, 8).fill(0); // ciphertext.subarray(0, 8) === IV, but we clean it anyway\n return out.subarray(8);\n },\n })\n);\n\n/*\nWe don't support 8-byte keys. The rabbit hole:\n\n- Wycheproof says: \"NIST SP 800-38F does not define the wrapping of 8 byte keys.\n RFC 3394 Section 2 on the other hand specifies that 8 byte keys are wrapped\n by directly encrypting one block with AES.\"\n - https://github.com/C2SP/wycheproof/blob/master/doc/key_wrap.md\n - \"RFC 3394 specifies in Section 2, that the input for the key wrap\n algorithm must be at least two blocks and otherwise the constant\n field and key are simply encrypted with ECB as a single block\"\n- What RFC 3394 actually says (in Section 2):\n - \"Before being wrapped, the key data is parsed into n blocks of 64 bits.\n The only restriction the key wrap algorithm places on n is that n be\n at least two\"\n - \"For key data with length less than or equal to 64 bits, the constant\n field used in this specification and the key data form a single\n 128-bit codebook input making this key wrap unnecessary.\"\n- Which means \"assert(n >= 2)\" and \"use something else for 8 byte keys\"\n- NIST SP800-38F actually prohibits 8-byte in \"5.3.1 Mandatory Limits\".\n It states that plaintext for KW should be \"2 to 2^54 -1 semiblocks\".\n- So, where does \"directly encrypt single block with AES\" come from?\n - Not RFC 3394. Pseudocode of key wrap in 2.2 explicitly uses\n loop of 6 for any code path\n - There is a weird W3C spec:\n https://www.w3.org/TR/2002/REC-xmlenc-core-20021210/Overview.html#kw-aes128\n - This spec is outdated, as admitted by Wycheproof authors\n - There is RFC 5649 for padded key wrap, which is padding construction on\n top of AESKW. In '4.1.2' it says: \"If the padded plaintext contains exactly\n eight octets, then prepend the AIV as defined in Section 3 above to P[1] and\n encrypt the resulting 128-bit block using AES in ECB mode [Modes] with key\n K (the KEK). In this case, the output is two 64-bit blocks C[0] and C[1]:\"\n - Browser subtle crypto is actually crashes on wrapping keys less than 16 bytes:\n `Error: error:1C8000E6:Provider routines::invalid input length] { opensslErrorStack: [ 'error:030000BD:digital envelope routines::update error' ]`\n\nIn the end, seems like a bug in Wycheproof.\nThe 8-byte check can be easily disabled inside of AES_W.\n*/\n\nconst AESKWP_IV = 0xa65959a6; // single u32le value\n\n/**\n * AES-KW, but with padding and allows random keys.\n * Second u32 of IV is used as counter for length.\n * [RFC 5649](https://www.rfc-editor.org/rfc/rfc5649)\n */\nexport const aeskwp: ((kek: Uint8Array) => Cipher) & {\n blockSize: number;\n} = /* @__PURE__ */ wrapCipher(\n { blockSize: 8 },\n (kek: Uint8Array): Cipher => ({\n encrypt(plaintext: Uint8Array) {\n if (!plaintext.length) throw new Error('invalid plaintext length');\n const padded = Math.ceil(plaintext.length / 8) * 8;\n const out = new Uint8Array(8 + padded);\n out.set(plaintext, 8);\n const out32 = u32(out);\n out32[0] = AESKWP_IV;\n out32[1] = byteSwap(plaintext.length);\n AESW.encrypt(kek, out);\n return out;\n },\n decrypt(ciphertext: Uint8Array) {\n // 16 because should have at least one block\n if (ciphertext.length < 16) throw new Error('invalid ciphertext length');\n const out = copyBytes(ciphertext);\n const o32 = u32(out);\n AESW.decrypt(kek, out);\n const len = byteSwap(o32[1]) >>> 0;\n const padded = Math.ceil(len / 8) * 8;\n if (o32[0] !== AESKWP_IV || out.length - 8 !== padded)\n throw new Error('integrity check failed');\n for (let i = len; i < padded; i++)\n if (out[8 + i] !== 0) throw new Error('integrity check failed');\n out.subarray(0, 8).fill(0); // ciphertext.subarray(0, 8) === IV, but we clean it anyway\n return out.subarray(8, 8 + len);\n },\n })\n);\n\nclass _AesCtrDRBG implements PRG {\n readonly blockLen: number;\n private key: Uint8Array;\n private nonce: Uint8Array;\n private state: Uint8Array;\n private reseedCnt: number;\n constructor(keyLen: number, seed: Uint8Array, personalization?: Uint8Array) {\n this.blockLen = ctr.blockSize;\n const keyLenBytes = keyLen / 8;\n const nonceLen = 16;\n this.state = new Uint8Array(keyLenBytes + nonceLen);\n this.key = this.state.subarray(0, keyLenBytes);\n this.nonce = this.state.subarray(keyLenBytes, keyLenBytes + nonceLen);\n this.reseedCnt = 1;\n incBytes(this.nonce, false, 1);\n this.addEntropy(seed, personalization);\n }\n private update(data?: Uint8Array) {\n // cannot re-use state here, because we will wipe current key\n ctr(this.key, this.nonce).encrypt(new Uint8Array(this.state.length), this.state);\n if (data) {\n abytes(data);\n for (let i = 0; i < data.length; i++) this.state[i] ^= data[i];\n }\n incBytes(this.nonce, false, 1);\n }\n addEntropy(seed: Uint8Array, info?: Uint8Array): void {\n abytes(seed, this.state.length, 'seed');\n const _seed = seed.slice();\n if (info) {\n abytes(info);\n if (info.length > _seed.length) throw new Error('info length is too big');\n for (let i = 0; i < info.length; i++) _seed[i] ^= info[i];\n }\n this.update(_seed);\n _seed.fill(0);\n this.reseedCnt = 1;\n }\n randomBytes(len: number, info?: Uint8Array): Uint8Array {\n anumber(len);\n if (this.reseedCnt++ >= 2 ** 48) throw new Error('entropy exhausted');\n if (info) this.update(info);\n const res = new Uint8Array(len);\n ctr(this.key, this.nonce).encrypt(res, res);\n incBytes(this.nonce, false, Math.ceil(len / this.blockLen));\n this.update(info);\n return res;\n }\n clean(): void {\n this.state.fill(0);\n this.reseedCnt = 0;\n }\n}\n\nexport type AesCtrDrbg = (seed: Uint8Array, personalization?: Uint8Array) => _AesCtrDRBG;\n\nconst createAesDrbg: (keyLen: number) => AesCtrDrbg = (keyLen) => {\n return (seed, personalization = undefined) => new _AesCtrDRBG(keyLen, seed, personalization);\n};\n\n/**\n * AES-CTR DRBG 128-bit - CSPRNG (cryptographically secure pseudorandom number generator).\n * It's best to limit usage to non-production, non-critical cases: for example, test-only.\n */\nexport const rngAesCtrDrbg128: AesCtrDrbg = /* @__PURE__ */ createAesDrbg(128);\n/**\n * AES-CTR DRBG 256-bit - CSPRNG (cryptographically secure pseudorandom number generator).\n * It's best to limit usage to non-production, non-critical cases: for example, test-only.\n */\nexport const rngAesCtrDrbg256: AesCtrDrbg = /* @__PURE__ */ createAesDrbg(256);\n\n//#region CMAC\n\n/**\n * Left-shift by one bit and conditionally XOR with 0x87:\n * ```\n * if MSB(L) is equal to 0\n * then K1 := L << 1;\n * else K1 := (L << 1) XOR const_Rb;\n * ```\n *\n * Specs: [RFC 4493, Section 2.3](https://www.rfc-editor.org/rfc/rfc4493.html#section-2.3),\n * [RFC 5297 Section 2.3](https://datatracker.ietf.org/doc/html/rfc5297.html#section-2.3)\n *\n * @returns modified `block` (for chaining)\n */\nfunction dbl<T extends Uint8Array>(block: T): T {\n let carry = 0;\n\n // Left shift by 1 bit\n for (let i = BLOCK_SIZE - 1; i >= 0; i--) {\n const newCarry = (block[i] & 0x80) >>> 7;\n block[i] = (block[i] << 1) | carry;\n carry = newCarry;\n }\n\n // XOR with 0x87 if there was a carry from the most significant bit\n if (carry) {\n block[BLOCK_SIZE - 1] ^= 0x87;\n }\n\n return block;\n}\n\n/**\n * `a XOR b`, running in-site on `a`.\n * @param a left operand and output\n * @param b right operand\n * @returns `a` (for chaining)\n */\nfunction xorBlock<T extends Uint8Array>(a: T, b: Uint8Array): T {\n if (a.length !== b.length) throw new Error('xorBlock: blocks must have same length');\n for (let i = 0; i < a.length; i++) {\n a[i] = a[i] ^ b[i];\n }\n return a;\n}\n\n/**\n * xorend as defined in [RFC 5297 Section 2.1](https://datatracker.ietf.org/doc/html/rfc5297.html#section-2.1).\n *\n * ```\n * leftmost(A, len(A)-len(B)) || (rightmost(A, len(B)) xor B)\n * ```\n */\nfunction xorend<T extends Uint8Array>(a: T, b: Uint8Array): T {\n if (b.length > a.length) {\n throw new Error('xorend: len(B) must be less than or equal to len(A)');\n }\n // keep leftmost part of `a` unchanged\n // and xor only the rightmost part:\n const offset = a.length - b.length;\n for (let i = 0; i < b.length; i++) {\n a[offset + i] = a[offset + i] ^ b[i];\n }\n return a;\n}\n\n/**\n * Internal CMAC class.\n */\nclass _CMAC {\n private buffer: Uint8Array;\n private destroyed: boolean;\n private k1: Uint8Array;\n private k2: Uint8Array;\n private xk: Uint32Array;\n\n constructor(key: Uint8Array) {\n abytes(key);\n validateKeyLength(key);\n this.xk = expandKeyLE(key);\n this.buffer = new Uint8Array(0);\n this.destroyed = false;\n // L = AES_encrypt(K, const_Zero)\n const L = new Uint8Array(BLOCK_SIZE);\n encryptBlock(this.xk, L);\n // Generate subkeys K1 and K2 from the main key according to\n // [RFC 4493, Section 2.3](https://www.rfc-editor.org/rfc/rfc4493.html#section-2.3)\n // K1\n this.k1 = dbl(L);\n this.k2 = dbl(new Uint8Array(this.k1));\n }\n\n update(data: Uint8Array): _CMAC {\n const { destroyed, buffer } = this;\n if (destroyed) throw new Error('CMAC instance was destroyed');\n abytes(data);\n const newBuffer = new Uint8Array(buffer.length + data.length);\n newBuffer.set(buffer);\n newBuffer.set(data, buffer.length);\n this.buffer = newBuffer;\n return this;\n }\n\n // see https://www.rfc-editor.org/rfc/rfc4493.html#section-2.4\n digest(): Uint8ArrayBuffer {\n if (this.destroyed) throw new Error('CMAC instance was destroyed');\n const { buffer } = this;\n const msgLen = buffer.length;\n\n // Step 2:\n let n = Math.ceil(msgLen / BLOCK_SIZE); // n := ceil(len/const_Bsize);\n\n // Step 3:\n let flag: boolean; // denoting if last block is complete or not\n if (n === 0) {\n n = 1;\n flag = false;\n } else {\n flag = msgLen % BLOCK_SIZE === 0; // if len mod const_Bsize is 0\n }\n\n // Step 4:\n const lastBlockStart = (n - 1) * BLOCK_SIZE;\n const lastBlockData = buffer.subarray(lastBlockStart);\n let m_last: Uint8ArrayBuffer;\n if (flag) {\n // M_last := M_n XOR K1;\n m_last = xorBlock(new Uint8Array(lastBlockData), this.k1);\n } else {\n // M_last := padding(M_n) XOR K2;\n //\n // [...] padding(x) is the concatenation of x and a single '1',\n // followed by the minimum number of '0's, so that the total length is\n // equal to 128 bits.\n const padded = new Uint8Array(BLOCK_SIZE);\n padded.set(lastBlockData);\n padded[lastBlockData.length] = 0x80; // single '1' bit\n m_last = xorBlock(padded, this.k2);\n }\n\n // Step 5:\n let x = new Uint8Array(BLOCK_SIZE); // X := const_Zero;\n\n // Step 6:\n for (let i = 0; i < n - 1; i++) {\n const m_i = buffer.subarray(i * BLOCK_SIZE, (i + 1) * BLOCK_SIZE); // M_i\n xorBlock(x, m_i); // Y := X XOR M_i;\n encryptBlock(this.xk, x); // X := AES-128(K,Y);\n }\n\n // Step 7:\n xorBlock(x, m_last); // Y := M_last XOR X;\n encryptBlock(this.xk, x); // T := AES-128(K,Y);\n\n // cleanup:\n clean(m_last);\n\n return x; // T\n }\n\n destroy(): void {\n const { buffer, destroyed, xk, k1, k2 } = this;\n if (destroyed) return;\n this.destroyed = true;\n clean(buffer, xk, k1, k2);\n }\n}\n\n/**\n * AES-CMAC (Cipher-based Message Authentication Code).\n * Specs: [RFC 4493](https://www.rfc-editor.org/rfc/rfc4493.html).\n */\nexport const cmac: {\n (key: Uint8Array, message: Uint8Array): Uint8Array;\n create(key: Uint8Array): _CMAC;\n} = (key: Uint8Array, message: Uint8Array): Uint8Array => new _CMAC(key).update(message).digest();\ncmac.create = (key: Uint8Array): _CMAC => new _CMAC(key);\n\n/**\n * S2V (Synthetic Initialization Vector) function as described in [RFC 5297 Section 2.4](https://datatracker.ietf.org/doc/html/rfc5297.html#section-2.4).\n *\n * ```\n * S2V(K, S1, ..., Sn) {\n * if n = 0 then\n * return V = AES-CMAC(K, <one>)\n * fi\n * D = AES-CMAC(K, <zero>)\n * for i = 1 to n-1 do\n * D = dbl(D) xor AES-CMAC(K, Si)\n * done\n * if len(Sn) >= 128 then\n * T = Sn xorend D\n * else\n * T = dbl(D) xor pad(Sn)\n * fi\n * return V = AES-CMAC(K, T)\n * }\n * ```\n *\n * S2V takes a key and a vector of strings S1, S2, ..., Sn and returns a 128-bit string.\n * The S2V function is used to generate a synthetic IV for AES-SIV.\n *\n * @param key - AES key (128, 192, or 256 bits)\n * @param strings - Array of byte arrays to process\n * @returns 128-bit synthetic IV\n */\nfunction s2v(key: Uint8Array, strings: Uint8Array[]): Uint8Array {\n validateKeyLength(key);\n const len = strings.length;\n if (len > 127) {\n // see https://datatracker.ietf.org/doc/html/rfc5297.html#section-7\n throw new Error('s2v: number of input strings must be less than or equal to 127');\n }\n\n if (len === 0) return cmac(key, ONE_BLOCK);\n\n // D = AES-CMAC(K, <zero>)\n let d = cmac(key, EMPTY_BLOCK);\n\n // for i = 1 to n-1 do\n // D = dbl(D) xor AES-CMAC(K, Si)\n for (let i = 0; i < len - 1; i++) {\n dbl(d);\n const cmacResult = cmac(key, strings[i]);\n xorBlock(d, cmacResult);\n clean(cmacResult);\n }\n\n const s_n = strings[len - 1];\n let t: Uint8Array;\n\n // if len(Sn) >= 128 then\n if (s_n.byteLength >= BLOCK_SIZE) {\n // T = Sn xorend D\n t = xorend(Uint8Array.from(s_n), d);\n } else {\n // pad(Sn):\n const paddedSn = new Uint8Array(BLOCK_SIZE);\n paddedSn.set(s_n);\n paddedSn[s_n.length] = 0x80; // padding: 0x80 followed by zeros\n\n // T = dbl(D) xor pad(Sn)\n t = xorBlock(dbl(d), paddedSn);\n clean(paddedSn);\n }\n\n // V = AES-CMAC(K, T)\n const result = cmac(key, t);\n clean(d, t);\n return result;\n}\n\n/** Use `gcmsiv` or `aessiv`. */\nexport const siv: () => never = () => {\n throw new Error('\"siv\" from v1 is now \"gcmsiv\"');\n};\n\n/**\n * **SIV**: Synthetic Initialization Vector (SIV) Authenticated Encryption\n * Nonce is derived from the plaintext and AAD using the S2V function.\n * See [RFC 5297](https://datatracker.ietf.org/doc/html/rfc5297.html).\n */\nexport const aessiv: ((key: Uint8Array, ...AAD: Uint8Array[]) => Cipher) & {\n blockSize: number;\n tagLength: number;\n} = /* @__PURE__ */ wrapCipher(\n { blockSize: 16, tagLength: 16 },\n function aessiv(key: Uint8Array, ...AAD: Uint8Array[]): Cipher {\n // From RFC 5297: Section 6.1, 6.2, 6.3:\n const PLAIN_LIMIT = limit('plaintext', 0, 2 ** 132);\n const CIPHER_LIMIT = limit('ciphertext', 16, 2 ** 132 + 16);\n if (AAD.length > 126) {\n // see https://datatracker.ietf.org/doc/html/rfc5297.html#section-7\n throw new Error('\"AAD\" number of elements must be less than or equal to 126');\n }\n AAD.forEach((aad) => abytes(aad));\n abytes(key);\n if (![32, 48, 64].includes(key.length))\n throw new Error('\"aes key\" expected Uint8Array of length 32/48/64, got length=' + key.length);\n\n // The key is split into equal halves, K1 = leftmost(K, len(K)/2) and\n // K2 = rightmost(K, len(K)/2). K1 is used for S2V and K2 is used for CTR.\n const k1 = key.subarray(0, key.length / 2);\n const k2 = key.subarray(key.length / 2);\n\n return {\n // https://datatracker.ietf.org/doc/html/rfc5297.html#section-2.6\n encrypt(plaintext: Uint8Array) {\n PLAIN_LIMIT(plaintext.length);\n\n const v = s2v(k1, [...AAD, plaintext]);\n\n // clear out the 31st and 63rd (rightmost) bit:\n const q = Uint8Array.from(v);\n q[8] &= 0x7f;\n q[12] &= 0x7f;\n\n // encrypt:\n const c = ctr(k2, q).encrypt(plaintext);\n\n return concatBytes(v, c);\n },\n // https://datatracker.ietf.org/doc/html/rfc5297.html#section-2.7\n decrypt(ciphertext: Uint8Array) {\n CIPHER_LIMIT(ciphertext.length);\n const v = ciphertext.subarray(0, BLOCK_SIZE);\n const c = ciphertext.subarray(BLOCK_SIZE);\n\n // clear out the 31st and 63rd (rightmost) bit:\n const q = Uint8Array.from(v);\n q[8] &= 0x7f;\n q[12] &= 0x7f;\n\n // decrypt:\n const p = ctr(k2, q).decrypt(c);\n\n // verify tag:\n const t = s2v(k1, [...AAD, p]);\n\n if (equalBytes(t, v)) {\n return p;\n } else {\n throw new Error('invalid siv tag');\n }\n },\n };\n }\n);\n//#endregion\n\n/** Unsafe low-level internal methods. May change at any time. */\nexport const unsafe: {\n expandKeyLE: typeof expandKeyLE;\n expandKeyDecLE: typeof expandKeyDecLE;\n encrypt: typeof encrypt;\n decrypt: typeof decrypt;\n encryptBlock: typeof encryptBlock;\n decryptBlock: typeof decryptBlock;\n ctrCounter: typeof ctrCounter;\n ctr32: typeof ctr32;\n dbl: typeof dbl;\n xorBlock: typeof xorBlock;\n xorend: typeof xorend;\n s2v: typeof s2v;\n} = {\n expandKeyLE,\n expandKeyDecLE,\n encrypt,\n decrypt,\n encryptBlock,\n decryptBlock,\n ctrCounter,\n ctr32,\n dbl,\n xorBlock,\n xorend,\n s2v,\n};\n","import { gcm } from \"@noble/ciphers/aes.js\";\nimport { generateRandomBytes } from \"@fileverse/crypto/utils\";\n\nconst KEY_LEN = 32;\nconst IV_LEN = 12;\nconst TAG_LEN = 16;\n\nconst b64ToBytes = (b64: string) => Uint8Array.from(Buffer.from(b64, \"base64\"));\nconst bytesToB64 = (b: Uint8Array) => Buffer.from(b).toString(\"base64\");\n\nimport type { DecryptionOptions } from \"../types\";\nexport type { DecryptionOptions };\n\nexport function gcmEncrypt(plaintext: Uint8Array) {\n const key = generateRandomBytes(KEY_LEN);\n const iv = generateRandomBytes(IV_LEN);\n if (key.length !== KEY_LEN) throw new Error(\"key must be 32 bytes\");\n if (iv.length !== IV_LEN) throw new Error(\"iv must be 12 bytes\");\n\n const out = gcm(key, iv).encrypt(plaintext);\n const ciphertext = out.subarray(0, out.length - TAG_LEN);\n const authTag = out.subarray(out.length - TAG_LEN);\n\n return {\n ciphertext,\n authTag: bytesToB64(authTag),\n key: bytesToB64(key),\n iv: bytesToB64(iv),\n };\n}\n\nexport function gcmDecrypt(ciphertext: Uint8Array, opts: DecryptionOptions) {\n const key = b64ToBytes(opts.key);\n const iv = b64ToBytes(opts.iv);\n const tag = b64ToBytes(opts.authTag);\n if (key.length !== KEY_LEN) throw new Error(\"key must be 32 bytes\");\n if (iv.length !== IV_LEN) throw new Error(\"iv must be 12 bytes\");\n if (tag.length !== TAG_LEN) throw new Error(\"authTag must be 16 bytes\");\n\n const combined = new Uint8Array(ciphertext.length + TAG_LEN);\n combined.set(ciphertext, 0);\n combined.set(tag, ciphertext.length);\n\n return gcm(key, iv).decrypt(combined);\n}\n","import { bytesToBase64, generateRandomBytes } from \"@fileverse/crypto/utils\";\nimport { derivePBKDF2Key, encryptAesCBC } from \"@fileverse/crypto/kdf\";\nimport { secretBoxEncrypt } from \"@fileverse/crypto/nacl\";\n\nimport tweetnacl from \"tweetnacl\";\nimport { fromUint8Array, toUint8Array } from \"js-base64\";\nimport { gcmEncrypt } from \"./file-encryption\";\nimport { toAESKey, aesEncrypt } from \"@fileverse/crypto/webcrypto\";\nimport { ADD_FILE_METHOD, DELETED_FILE_ABI, EDIT_FILE_METHOD, UPLOAD_SERVER_URL, NETWORK_NAME } from \"../constants\";\nimport type { UploadFileAuthParams, FileMetadataParams, UploadFilesParams } from \"../types\";\nimport { encodeFunctionData, type Hex, parseEventLogs, type Abi } from \"viem\";\n\nexport const jsonToFile = (json: any, fileName: string) => {\n const blob = new Blob([JSON.stringify(json)], {\n type: \"application/json\",\n });\n\n const file = new File([blob], fileName, {\n type: \"application/json\",\n });\n\n return file;\n};\n\nconst appendAuthTagIvToBlob = async (blob: Blob, authTag: Uint8Array, iv: Uint8Array) => {\n const encryptedFileBytes = await blob.arrayBuffer();\n const encryptedBytes = new Uint8Array(encryptedFileBytes);\n const combinedLength = encryptedBytes.length + authTag.length + iv.length;\n const combinedArray = new Uint8Array(combinedLength);\n\n let offset = 0;\n combinedArray.set(encryptedBytes, offset);\n offset += encryptedBytes.length;\n\n combinedArray.set(authTag, offset);\n offset += authTag.length;\n\n combinedArray.set(iv, offset);\n\n return new Blob([combinedArray], { type: blob.type });\n};\n\nexport const encryptFile = async (file: File) => {\n const arrayBuffer = await file.arrayBuffer();\n\n const plaintext = new Uint8Array(arrayBuffer);\n\n const { ciphertext, authTag, key, iv } = gcmEncrypt(plaintext);\n\n const encryptedBlob = new Blob([ciphertext], { type: file.type });\n\n const encryptedBlobWithAuthTagIv = await appendAuthTagIvToBlob(\n encryptedBlob,\n toUint8Array(authTag),\n toUint8Array(iv),\n );\n\n return {\n encryptedFile: new File([encryptedBlobWithAuthTagIv], file.name),\n key,\n };\n};\n\nexport const getNonceAppendedCipherText = (nonce: Uint8Array, cipherText: Uint8Array) => {\n return fromUint8Array(nonce, true) + \"__n__\" + fromUint8Array(cipherText, true);\n};\n\nexport const jsonToBytes = (json: Record<string, any>) => new TextEncoder().encode(JSON.stringify(json));\n\nexport const buildLinklock = (key: Uint8Array, fileKey: Uint8Array, commentKey: Uint8Array) => {\n const ikm = generateRandomBytes();\n const kdfSalt = generateRandomBytes();\n const derivedEphermalKey = derivePBKDF2Key(ikm, kdfSalt);\n\n const { iv, cipherText } = encryptAesCBC(\n {\n key: derivedEphermalKey,\n message: fileKey,\n },\n \"base64\",\n );\n\n const { iv: commentIv, cipherText: commentCipherText } = encryptAesCBC(\n {\n key: derivedEphermalKey,\n message: commentKey,\n },\n \"base64\",\n );\n\n const encryptedIkm = secretBoxEncrypt(ikm, key);\n\n const lockedFileKey = iv + \"__n__\" + cipherText;\n\n const lockedChatKey = commentIv + \"__n__\" + commentCipherText;\n\n const keyMaterial = bytesToBase64(kdfSalt) + \"__n__\" + encryptedIkm;\n\n const fileKeyNonce = generateRandomBytes(24);\n const encryptedFileKey = tweetnacl.secretbox(jsonToBytes({ key: fromUint8Array(fileKey) }), fileKeyNonce, key);\n\n const chatKeyNonce = generateRandomBytes(24);\n const encryptedChatKey = tweetnacl.secretbox(commentKey, chatKeyNonce, key);\n\n return {\n lockedFileKey: getNonceAppendedCipherText(fileKeyNonce, encryptedFileKey),\n lockedChatKey: getNonceAppendedCipherText(chatKeyNonce, encryptedChatKey),\n lockedFileKey_v2: lockedFileKey,\n lockedChatKey_v2: lockedChatKey,\n keyMaterial,\n };\n};\n\nexport const encryptTitleWithFileKey = async (args: { title: string; key: string }) => {\n const key = await toAESKey(toUint8Array(args.key));\n if (!key) throw new Error(\"Key is undefined\");\n\n const titleBytes = new TextEncoder().encode(args.title);\n\n const encryptedTitle = await aesEncrypt(key, titleBytes, \"base64\");\n\n return encryptedTitle;\n};\n\ninterface UploadFileParams {\n file: File;\n ipfsType: string;\n appFileId: string;\n}\n\nexport type { UploadFileAuthParams };\n\nexport const uploadFileToIPFS = async (fileParams: UploadFileParams, authParams: UploadFileAuthParams) => {\n const { file, ipfsType, appFileId } = fileParams;\n const { token, invoker, contractAddress } = authParams;\n\n const body = new FormData();\n body.append(\"file\", file);\n body.append(\"ipfsType\", ipfsType);\n body.append(\"appFileId\", appFileId);\n body.append(\"sourceApp\", \"ddoc\");\n\n const response = await fetch(UPLOAD_SERVER_URL + \"upload\", {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${token}`,\n contract: contractAddress,\n invoker: invoker,\n chain: NETWORK_NAME,\n },\n body,\n });\n\n if (!response.ok) {\n throw new Error(`Upload failed: ${response.status} ${response.statusText}`);\n }\n\n const data: any = await response.json();\n return data.ipfsHash;\n};\n\nconst getEditFileTrxCalldata = (args: {\n fileId: number;\n appFileId: string;\n metadataHash: string;\n contentHash: string;\n gateHash: string;\n}) => {\n return encodeFunctionData({\n abi: EDIT_FILE_METHOD,\n functionName: \"editFile\",\n args: [BigInt(args.fileId), args.appFileId, args.metadataHash, args.contentHash, args.gateHash, 2, BigInt(0)],\n });\n};\n\nconst getAddFileTrxCalldata = (args: {\n appFileId: string;\n metadataHash: string;\n contentHash: string;\n gateHash: string;\n}) => {\n return encodeFunctionData({\n abi: ADD_FILE_METHOD,\n functionName: \"addFile\",\n args: [args.appFileId, 2, args.metadataHash, args.contentHash, args.gateHash, BigInt(0)],\n });\n};\n\nexport const prepareCallData = (args: {\n metadataHash: string;\n contentHash: string;\n gateHash: string;\n appFileId: string;\n fileId?: number;\n}) => {\n if (args.fileId) {\n return getEditFileTrxCalldata({\n fileId: args.fileId,\n appFileId: args.appFileId,\n metadataHash: args.metadataHash,\n contentHash: args.contentHash,\n gateHash: args.gateHash,\n });\n }\n return getAddFileTrxCalldata(args);\n};\n\nexport const prepareDeleteFileCallData = (args: { onChainFileId: number }) => {\n return encodeFunctionData({\n abi: DELETED_FILE_ABI,\n functionName: \"deleteFile\",\n args: [BigInt(args.onChainFileId)],\n });\n};\n\nexport const createEncryptedContentFile = async (content: any) => {\n const contentFile = jsonToFile(\n { file: content, source: \"ddoc\" },\n `${fromUint8Array(generateRandomBytes(16))}-CONTENT`,\n );\n return encryptFile(contentFile);\n};\n\nexport type { FileMetadataParams };\n\nexport const buildFileMetadata = (params: FileMetadataParams) => ({\n title: params.encryptedTitle,\n size: params.encryptedFileSize,\n mimeType: \"application/json\",\n appLock: params.appLock,\n ownerLock: params.ownerLock,\n ddocId: params.ddocId,\n nonce: params.nonce,\n owner: params.owner,\n version: \"4\",\n sourceApp: \"fileverse-api\",\n});\n\nexport const parseFileEventLog = (logs: any[], eventName: string, abi: Abi): number => {\n const [parsedLog] = parseEventLogs({ abi, logs, eventName });\n\n if (!parsedLog) throw new Error(`${eventName} event not found`);\n\n const fileId = (parsedLog as any).args.fileId;\n\n if (fileId === undefined || fileId === null) throw new Error(\"FileId not found in event logs\");\n\n return Number(fileId);\n};\n\nexport type { UploadFilesParams };\n\nexport const uploadAllFilesToIPFS = async (params: UploadFilesParams, authParams: UploadFileAuthParams) => {\n const { metadata, encryptedFile, linkLock, ddocId } = params;\n\n const [metadataHash, contentHash, gateHash] = await Promise.all([\n uploadFileToIPFS(\n {\n file: jsonToFile(metadata, `${fromUint8Array(generateRandomBytes(16))}-METADATA`),\n ipfsType: \"METADATA\",\n appFileId: ddocId,\n },\n authParams,\n ),\n uploadFileToIPFS(\n {\n file: encryptedFile,\n ipfsType: \"CONTENT\",\n appFileId: ddocId,\n },\n authParams,\n ),\n uploadFileToIPFS(\n {\n file: jsonToFile(linkLock, `${fromUint8Array(generateRandomBytes(16))}-GATE`),\n ipfsType: \"GATE\",\n appFileId: ddocId,\n },\n authParams,\n ),\n ]);\n\n return { metadataHash, contentHash, gateHash };\n};\n","import { fromUint8Array, toUint8Array } from \"js-base64\";\nimport { KeyStore } from \"./key-store\";\nimport {\n buildLinklock,\n encryptTitleWithFileKey,\n prepareCallData,\n createEncryptedContentFile,\n buildFileMetadata,\n parseFileEventLog,\n uploadAllFilesToIPFS,\n UploadFileAuthParams,\n prepareDeleteFileCallData,\n} from \"./file-utils\";\nimport { AgentClient } from \"./smart-agent\";\nimport { generateAESKey, exportAESKey } from \"@fileverse/crypto/webcrypto\";\nimport { STATIC_CONFIG } from \"../cli/constants\";\nimport { DELETED_FILE_EVENT, EDITED_FILE_EVENT } from \"../constants\";\nimport { markdownToYjs } from \"@fileverse/content-processor\";\nimport { logger } from \"../infra\";\n\nexport class FileManager {\n private keyStore: KeyStore;\n private agentClient: AgentClient;\n\n constructor(keyStore: KeyStore, agentClient: AgentClient) {\n this.keyStore = keyStore;\n this.agentClient = agentClient;\n }\n\n private createLocks(key: string, encryptedSecretKey: string, commentKey: Uint8Array) {\n const appLock = {\n lockedFileKey: this.keyStore.encryptData(toUint8Array(key)),\n lockedLinkKey: this.keyStore.encryptData(toUint8Array(encryptedSecretKey)),\n lockedChatKey: this.keyStore.encryptData(commentKey),\n };\n return { appLock, ownerLock: { ...appLock } };\n }\n\n private async getAuthParams(): Promise<UploadFileAuthParams> {\n return {\n token: await this.keyStore.getAuthToken(STATIC_CONFIG.SERVER_DID),\n contractAddress: this.keyStore.getPortalAddress(),\n invoker: this.agentClient.getAgentAddress(),\n };\n }\n\n private async executeFileOperation(callData: `0x${string}`) {\n return this.agentClient.executeUserOperationRequest(\n {\n contractAddress: this.keyStore.getPortalAddress(),\n data: callData,\n },\n 1000000,\n );\n }\n\n private async sendFileOperation(callData: `0x${string}`) {\n return this.agentClient.sendUserOperation(\n {\n contractAddress: this.keyStore.getPortalAddress(),\n data: callData,\n },\n 1000000,\n );\n }\n\n async getProxyAuthParams() {\n return this.agentClient.getAuthParams();\n }\n\n async submitAddFileTrx(file: any) {\n console.log(\"Submitting add file trx\");\n logger.debug(`Preparing to add file ${file.ddocId}`);\n const encryptedSecretKey = file.linkKey;\n const nonce = toUint8Array(file.linkKeyNonce);\n const secretKey = toUint8Array(file.secretKey);\n console.log(\"Got encrypted secret key, nonce, and secret key\");\n const yJSContent = markdownToYjs(file.content);\n console.log(\"Generated yjs content\");\n const { encryptedFile, key } = await createEncryptedContentFile(yJSContent);\n console.log(\"Generated encrypted content file\");\n logger.debug(`Generated encrypted content file for file ${file.ddocId}`);\n const commentKey = await exportAESKey(await generateAESKey(128));\n console.log(\"Generated comment key\");\n const { appLock, ownerLock } = this.createLocks(key, encryptedSecretKey, commentKey);\n console.log(\"Built app lock and owner lock\");\n const linkLock = buildLinklock(secretKey, toUint8Array(key), commentKey);\n console.log(\"Built link lock\");\n const encryptedTitle = await encryptTitleWithFileKey({\n title: file.title || \"Untitled\",\n key,\n });\n console.log(\"Built encrypted title\");\n const metadata = buildFileMetadata({\n encryptedTitle,\n encryptedFileSize: encryptedFile.size,\n appLock,\n ownerLock,\n ddocId: file.ddocId,\n nonce: fromUint8Array(nonce),\n owner: this.agentClient.getAgentAddress(),\n });\n console.log(\"Built metadata\");\n\n const authParams = await this.getAuthParams();\n console.log(\"Got auth params\");\n console.log(\"Uploading files to IPFS\");\n const { metadataHash, contentHash, gateHash } = await uploadAllFilesToIPFS(\n { metadata, encryptedFile, linkLock, ddocId: file.ddocId },\n authParams,\n );\n console.log(\"Uploaded files to IPFS\");\n logger.debug(`Uploaded files to IPFS for file ${file.ddocId}`);\n\n\n const callData = prepareCallData({\n metadataHash,\n contentHash,\n gateHash,\n appFileId: file.ddocId,\n fileId: file.fileId,\n });\n console.log(\"Prepared call data\");\n logger.debug(`Prepared call data for file ${file.ddocId}`);\n\n const userOpHash = await this.sendFileOperation(callData);\n console.log(\"Submitted user op\");\n logger.debug(`Submitted user op for file ${file.ddocId}`);\n return {\n userOpHash,\n linkKey: encryptedSecretKey,\n linkKeyNonce: fromUint8Array(nonce),\n commentKey: fromUint8Array(commentKey),\n metadata,\n };\n }\n\n async submitUpdateFile(file: any) {\n logger.debug(`Submitting update for file ${file.ddocId} with onChainFileId ${file.onChainFileId}`);\n const encryptedSecretKey = file.linkKey;\n const nonce = toUint8Array(file.linkKeyNonce);\n const secretKey = toUint8Array(file.secretKey);\n\n const yjsContent = markdownToYjs(file.content);\n const { encryptedFile, key } = await createEncryptedContentFile(yjsContent);\n const commentKey = toUint8Array(file.commentKey);\n\n const { appLock, ownerLock } = this.createLocks(key, encryptedSecretKey, commentKey);\n const linkLock = buildLinklock(secretKey, toUint8Array(key), commentKey);\n\n const encryptedTitle = await encryptTitleWithFileKey({\n title: file.title || \"Untitled\",\n key,\n });\n const metadata = buildFileMetadata({\n encryptedTitle,\n encryptedFileSize: encryptedFile.size,\n appLock,\n ownerLock,\n ddocId: file.ddocId,\n nonce: fromUint8Array(nonce),\n owner: this.agentClient.getAgentAddress(),\n });\n\n const authParams = await this.getAuthParams();\n const { metadataHash, contentHash, gateHash } = await uploadAllFilesToIPFS(\n { metadata, encryptedFile, linkLock, ddocId: file.ddocId },\n authParams,\n );\n\n const callData = prepareCallData({\n metadataHash,\n contentHash,\n gateHash,\n appFileId: file.ddocId,\n fileId: file.onChainFileId,\n });\n\n const userOpHash = await this.sendFileOperation(callData);\n logger.debug(`Submitted update user op for file ${file.ddocId}`);\n return { userOpHash, metadata };\n }\n\n async submitDeleteFile(file: any) {\n logger.debug(`Submitting delete for file ${file.ddocId} with onChainFileId ${file.onChainFileId}`);\n const callData = prepareDeleteFileCallData({\n onChainFileId: file.onChainFileId,\n });\n const userOpHash = await this.sendFileOperation(callData);\n logger.debug(`Submitted delete user op for file ${file.ddocId}`);\n return { userOpHash };\n }\n\n async updateFile(file: any) {\n logger.debug(`Updating file ${file.ddocId} with onChainFileId ${file.onChainFileId}`);\n const encryptedSecretKey = file.linkKey;\n const nonce = toUint8Array(file.linkKeyNonce);\n const secretKey = toUint8Array(file.secretKey);\n\n logger.debug(`Generating encrypted content file for file ${file.ddocId} with onChainFileId ${file.onChainFileId}`);\n\n const yjsContent = markdownToYjs(file.content);\n const { encryptedFile, key } = await createEncryptedContentFile(yjsContent);\n const commentKey = toUint8Array(file.commentKey);\n\n const { appLock, ownerLock } = this.createLocks(key, encryptedSecretKey, commentKey);\n const linkLock = buildLinklock(secretKey, toUint8Array(key), commentKey);\n\n const encryptedTitle = await encryptTitleWithFileKey({\n title: file.title || \"Untitled\",\n key,\n });\n const metadata = buildFileMetadata({\n encryptedTitle,\n encryptedFileSize: encryptedFile.size,\n appLock,\n ownerLock,\n ddocId: file.ddocId,\n nonce: fromUint8Array(nonce),\n owner: this.agentClient.getAgentAddress(),\n });\n\n const authParams = await this.getAuthParams();\n logger.debug(`Uploading files to IPFS for file ${file.ddocId} with onChainFileId ${file.onChainFileId}`);\n const { metadataHash, contentHash, gateHash } = await uploadAllFilesToIPFS(\n { metadata, encryptedFile, linkLock, ddocId: file.ddocId },\n authParams,\n );\n\n const callData = prepareCallData({\n metadataHash,\n contentHash,\n gateHash,\n appFileId: file.ddocId,\n fileId: file.onChainFileId,\n });\n logger.debug(`Executing file operation for file ${file.ddocId} with onChainFileId ${file.onChainFileId}`);\n\n const { logs } = await this.executeFileOperation(callData);\n const onChainFileId = parseFileEventLog(logs, \"EditedFile\", EDITED_FILE_EVENT);\n\n return { onChainFileId, metadata };\n }\n\n async deleteFile(file: any) {\n logger.debug(`Deleting file ${file.ddocId} with onChainFileId ${file.onChainFileId}`);\n const callData = prepareDeleteFileCallData({\n onChainFileId: file.onChainFileId,\n });\n logger.debug(`Prepared call data for deleting file ${file.ddocId} with onChainFileId ${file.onChainFileId}`);\n\n const { logs } = await this.executeFileOperation(callData);\n parseFileEventLog(logs, \"DeletedFile\", DELETED_FILE_EVENT);\n logger.debug(`Executed file operation for deleting file ${file.ddocId} with onChainFileId ${file.onChainFileId}`);\n return {\n fileId: file.id,\n onChainFileId: file.onChainFileId,\n metadata: file.metadata,\n };\n }\n}\n","import { FilesModel, PortalsModel } from \"../../infra/database/models\";\nimport { logger } from \"../../infra\";\nimport { KeyStore } from \"../../sdk/key-store\";\nimport { AuthTokenProvider } from \"../../sdk/auth-token-provider\";\nimport { fromUint8Array, toUint8Array } from \"js-base64\";\nimport { Hex, stringToBytes } from \"viem\";\nimport { deriveHKDFKey } from \"@fileverse/crypto/kdf\";\nimport { generateKeyPairFromSeed } from \"@stablelib/ed25519\";\nimport { EdKeypair } from \"../../sdk/ucan\";\nimport { AgentClient } from \"../../sdk/smart-agent\";\nimport { FileManager } from \"../../sdk/file-manager\";\nimport { getRuntimeConfig } from \"../../config\";\n\nimport { getUserOpReceipt } from \"../../sdk/pimlico-utils\";\nimport { parseFileEventLog } from \"../../sdk/file-utils\";\nimport { ADDED_FILE_EVENT, EDITED_FILE_EVENT, DELETED_FILE_EVENT } from \"../../constants\";\n\nimport type { PublishResult } from \"../../types\";\nimport type { File, Portal, EventType } from \"../../types\";\n\ninterface PublishContext {\n file: File | undefined;\n portalDetails: Portal;\n apiKey: string;\n}\n\nasync function getPortalData(fileId: string): Promise<PublishContext> {\n const file = await FilesModel.findByIdIncludingDeleted(fileId);\n if (!file) {\n throw new Error(`File with _id ${fileId} not found`);\n }\n\n const portalDetails = await PortalsModel.findByPortalAddress(file.portalAddress);\n if (!portalDetails) {\n throw new Error(`Portal with address ${file.portalAddress} not found`);\n }\n\n const apiKey = getRuntimeConfig().API_KEY;\n if (!apiKey) {\n throw new Error(\"API key is not set\");\n }\n\n return { file, portalDetails, apiKey };\n}\n\nfunction deriveCollaboratorKeys(apiKeySeed: Uint8Array) {\n const salt = new Uint8Array([0]);\n\n const privateAccountKey = deriveHKDFKey(apiKeySeed, salt, stringToBytes(\"COLLABORATOR_PRIVATE_KEY\"));\n\n const ucanDerivedSecret = deriveHKDFKey(apiKeySeed, salt, stringToBytes(\"COLLABORATOR_UCAN_SECRET\"));\n\n const { secretKey: ucanSecret } = generateKeyPairFromSeed(ucanDerivedSecret);\n\n return { privateAccountKey, ucanSecret };\n}\n\nconst createFileManager = async (\n portalSeed: string,\n portalAddress: Hex,\n ucanSecret: Uint8Array,\n privateAccountKey: Uint8Array,\n): Promise<FileManager> => {\n console.log(\"Creating file manager\");\n const keyPair = EdKeypair.fromSecretKey(fromUint8Array(ucanSecret));\n console.log(\"Created key pair\");\n const authTokenProvider = new AuthTokenProvider(keyPair, portalAddress);\n console.log(\"Created auth token provider\");\n const keyStore = new KeyStore(toUint8Array(portalSeed), portalAddress, authTokenProvider);\n console.log(\"Created key store\");\n const agentClient = new AgentClient(authTokenProvider);\n console.log(\"Created agent client\");\n await agentClient.initializeAgentClient(privateAccountKey);\n console.log(\"Initialized agent client\");\n\n return new FileManager(keyStore, agentClient);\n};\n\nconst executeOperation = async (\n fileManager: FileManager,\n file: any,\n operation: \"update\" | \"delete\",\n): Promise<PublishResult> => {\n\n if (operation === \"update\") {\n const result = await fileManager.updateFile(file);\n return { success: true, ...result };\n }\n\n if (operation === \"delete\") {\n const result = await fileManager.deleteFile(file);\n return { success: true, ...result };\n }\n\n throw new Error(`Invalid operation: ${operation}`);\n};\n\nexport const handleExistingFileOp = async (fileId: string, operation: \"update\" | \"delete\"): Promise<PublishResult> => {\n try {\n const { file, portalDetails, apiKey } = await getPortalData(fileId);\n\n const apiKeySeed = toUint8Array(apiKey);\n const { privateAccountKey, ucanSecret } = deriveCollaboratorKeys(apiKeySeed);\n\n const fileManager = await createFileManager(\n portalDetails.portalSeed,\n portalDetails.portalAddress as Hex,\n ucanSecret,\n privateAccountKey,\n );\n\n return executeOperation(fileManager, file, operation);\n } catch (error: any) {\n logger.error(`Failed to publish file ${fileId}:`, error);\n throw error;\n }\n};\n\nexport const handleNewFileOp = async (\n fileId: string,\n): Promise<{\n userOpHash: string;\n linkKey: string;\n linkKeyNonce: string;\n commentKey: string;\n metadata: Record<string, unknown>;\n}> => {\n const { file, portalDetails, apiKey } = await getPortalData(fileId);\n console.log(\"Got portal data\")\n const apiKeySeed = toUint8Array(apiKey);\n const { privateAccountKey, ucanSecret } = deriveCollaboratorKeys(apiKeySeed);\n console.log(\"Derived collaborator keys\");\n const fileManager = await createFileManager(\n portalDetails.portalSeed,\n portalDetails.portalAddress as Hex,\n ucanSecret,\n privateAccountKey,\n );\n console.log(\"Created file manager\");\n return fileManager.submitAddFileTrx(file);\n};\n\nexport const getProxyAuthParams = async (\n fileId: string,\n): Promise<{\n authToken: string;\n portalAddress: Hex;\n invokerAddress: Hex;\n}> => {\n const { portalDetails, apiKey } = await getPortalData(fileId);\n const apiKeySeed = toUint8Array(apiKey);\n const { privateAccountKey, ucanSecret } = deriveCollaboratorKeys(apiKeySeed);\n const fileManager = await createFileManager(\n portalDetails.portalSeed,\n portalDetails.portalAddress as Hex,\n ucanSecret,\n privateAccountKey,\n );\n return fileManager.getProxyAuthParams();\n};\n\nexport const submitUpdateFileOp = async (\n fileId: string,\n): Promise<{ userOpHash: string; metadata: Record<string, unknown> }> => {\n const { file, portalDetails, apiKey } = await getPortalData(fileId);\n const apiKeySeed = toUint8Array(apiKey);\n const { privateAccountKey, ucanSecret } = deriveCollaboratorKeys(apiKeySeed);\n const fileManager = await createFileManager(\n portalDetails.portalSeed,\n portalDetails.portalAddress as Hex,\n ucanSecret,\n privateAccountKey,\n );\n return fileManager.submitUpdateFile(file);\n};\n\nexport const submitDeleteFileOp = async (\n fileId: string,\n): Promise<{ userOpHash: string }> => {\n const { file, portalDetails, apiKey } = await getPortalData(fileId);\n const apiKeySeed = toUint8Array(apiKey);\n const { privateAccountKey, ucanSecret } = deriveCollaboratorKeys(apiKeySeed);\n const fileManager = await createFileManager(\n portalDetails.portalSeed,\n portalDetails.portalAddress as Hex,\n ucanSecret,\n privateAccountKey,\n );\n return fileManager.submitDeleteFile(file);\n};\n\nexport const resolveFileOp = async (\n fileId: string,\n userOpHash: string,\n eventType: EventType,\n): Promise<{ receipt: any } | null> => {\n const { portalDetails, apiKey } = await getPortalData(fileId);\n const apiKeySeed = toUint8Array(apiKey);\n const { privateAccountKey, ucanSecret } = deriveCollaboratorKeys(apiKeySeed);\n const fileManager = await createFileManager(\n portalDetails.portalSeed,\n portalDetails.portalAddress as Hex,\n ucanSecret,\n privateAccountKey,\n );\n const { authToken, portalAddress, invokerAddress } = await fileManager.getProxyAuthParams();\n const receipt = await getUserOpReceipt(\n userOpHash as `0x${string}`,\n authToken,\n portalAddress,\n invokerAddress,\n );\n if (!receipt) return null;\n return { receipt };\n};\n","import { PortalsModel } from \"../../infra/database/models\";\nimport type { Portal, SavePortalInput } from \"../../types\";\n\nexport async function savePortal(input: SavePortalInput): Promise<Portal> {\n if (!input.portalAddress || !input.portalSeed || !input.ownerAddress) {\n throw new Error(\"portalAddress, portalSeed, and ownerAddress are required\");\n }\n\n return PortalsModel.upsert(input);\n}\n","import { ApiKeysModel, PortalsModel } from \"../../infra/database/models\";\nimport type { AddApiKeyInput, ApiKey } from \"../../types\";\n\nexport async function addApiKey(input: AddApiKeyInput): Promise<ApiKey> {\n if (!input.apiKeySeed || !input.name || !input.collaboratorAddress || !input.portalAddress) {\n throw new Error(\"apiKeySeed, name, collaboratorAddress, and portalAddress are required\");\n }\n\n const portal = await PortalsModel.findByPortalAddress(input.portalAddress);\n if (!portal) {\n throw new Error(`Portal with address ${input.portalAddress} does not exist`);\n }\n\n return ApiKeysModel.create(input);\n}\n","import { ApiKeysModel, type ApiKey } from \"../../infra/database/models\";\n\nexport async function removeApiKey(collaboratorAddress: string): Promise<ApiKey> {\n if (!collaboratorAddress) {\n throw new Error(\"collaboratorAddress is required\");\n }\n\n const apiKey = await ApiKeysModel.findByCollaboratorAddress(collaboratorAddress);\n if (!apiKey) {\n throw new Error(\"API key not found\");\n }\n\n await ApiKeysModel.delete(apiKey._id);\n return { ...apiKey, isDeleted: 1 };\n}\n","import {\n handleExistingFileOp,\n handleNewFileOp,\n getProxyAuthParams,\n submitUpdateFileOp,\n submitDeleteFileOp,\n resolveFileOp,\n} from \"./publish\";\nimport { savePortal } from \"./savePortal\";\nimport { addApiKey } from \"./saveApiKey\";\nimport { removeApiKey } from \"./removeApiKey\";\n\nexport {\n handleExistingFileOp,\n handleNewFileOp,\n getProxyAuthParams,\n submitUpdateFileOp,\n submitDeleteFileOp,\n resolveFileOp,\n savePortal,\n addApiKey,\n removeApiKey,\n};\n","import { HttpRequestError } from \"viem\";\n\nexport class RateLimitError extends Error {\n readonly retryAfterSeconds: number;\n\n constructor(retryAfterSeconds: number, message = \"Rate limit exceeded\") {\n super(message);\n this.name = \"RateLimitError\";\n this.retryAfterSeconds = retryAfterSeconds;\n }\n}\n\nconst MAX_RETRY_AFTER_SECONDS = 300;\nconst DEFAULT_RETRY_AFTER_SECONDS = 3600;\n\nfunction parseRetryAfterRaw(raw: string | null): number {\n if (!raw) return DEFAULT_RETRY_AFTER_SECONDS;\n const parsed = parseInt(raw, 10);\n if (!Number.isNaN(parsed) && parsed >= 0) return Math.min(parsed, MAX_RETRY_AFTER_SECONDS);\n const date = Date.parse(raw);\n if (!Number.isNaN(date)) {\n const seconds = Math.max(0, Math.ceil((date - Date.now()) / 1000));\n return Math.min(seconds, MAX_RETRY_AFTER_SECONDS);\n }\n return DEFAULT_RETRY_AFTER_SECONDS;\n}\n\nexport const parseRetryAfterSeconds = (response: Response): number =>\n parseRetryAfterRaw(response.headers.get(\"Retry-After\"));\n\nexport const parseRetryAfterFromHeaders = (headers?: Headers): number =>\n parseRetryAfterRaw(headers?.get(\"Retry-After\") ?? null);\n\nexport function normalizeRateLimitError(error: unknown): unknown {\n if (!(error instanceof HttpRequestError) || error.status !== 429) return error;\n const retryAfter = parseRetryAfterFromHeaders(error.headers);\n const message = \"Beta API rate limit reached. Try again in an hour please!\"\n return new RateLimitError(retryAfter, message);\n}\n","import { getRuntimeConfig } from \"../../config\";\nimport {\n handleNewFileOp,\n handleExistingFileOp,\n getProxyAuthParams,\n submitUpdateFileOp,\n submitDeleteFileOp,\n resolveFileOp,\n} from \"../../domain/portal\";\nimport { FilesModel, EventsModel } from \"../database/models\";\nimport type { Event, ProcessResult, UpdateFilePayload } from \"../../types\";\nimport { logger } from \"../index\";\nimport { waitForUserOpReceipt } from \"../../sdk/pimlico-utils\";\nimport { parseFileEventLog } from \"../../sdk/file-utils\";\nimport { ADDED_FILE_EVENT, EDITED_FILE_EVENT, DELETED_FILE_EVENT } from \"../../constants\";\nimport { RateLimitError, normalizeRateLimitError } from \"../../errors/rate-limit\";\n\nexport type { ProcessResult };\n\n// ── Legacy single-shot processor (kept for local worker compatibility) ──\n\nexport const processEvent = async (event: Event): Promise<ProcessResult> => {\n const { fileId, type } = event;\n\n try {\n switch (type) {\n case \"create\":\n await processCreateEvent(event);\n break;\n case \"update\":\n await processUpdateEvent(event);\n break;\n case \"delete\":\n await processDeleteEvent(event);\n break;\n default:\n throw new Error(`Unknown event type: ${type}`);\n }\n return { success: true };\n } catch (error) {\n const normalized = normalizeRateLimitError(error);\n if (normalized instanceof RateLimitError) throw normalized;\n const errorMsg = error instanceof Error ? error.message : String(error);\n logger.error(`Error processing ${type} event for file ${fileId}:`, errorMsg);\n return { success: false, error: errorMsg };\n }\n};\n\n// ── Two-phase processors for Cloudflare Worker ──\n\nexport type SubmitEventResult =\n | { userOpHash: string; pendingPayload: Record<string, unknown> }\n | { noOp: true; fileId: string; portalAddress: string }\n | null;\n\nexport const submitEvent = async (event: Event): Promise<SubmitEventResult> => {\n const { fileId, type } = event;\n\n switch (type) {\n case \"create\": {\n console.log(\"Starting create event submission\");\n const file = await FilesModel.findByIdIncludingDeleted(fileId);\n console.log(\"File found\");\n if (!file) throw new Error(`File ${fileId} not found`);\n if (file.isDeleted === 1) {\n logger.info(`File ${fileId} is deleted, skipping create submit`);\n return null;\n }\n\n console.log(\"Submitting new file op\");\n const result = await handleNewFileOp(fileId);\n console.log(\"New file op submitted\");\n logger.info(`File ${file.ddocId} create op submitted (hash: ${result.userOpHash})`);\n return { userOpHash: result.userOpHash, pendingPayload: { metadata: result.metadata } };\n }\n case \"update\": {\n const file = await FilesModel.findByIdExcludingDeleted(fileId);\n if (!file) return null;\n if (file.localVersion <= file.onchainVersion) return null;\n\n const result = await submitUpdateFileOp(fileId);\n logger.info(`File ${file.ddocId} update op submitted (hash: ${result.userOpHash})`);\n return {\n userOpHash: result.userOpHash,\n pendingPayload: { metadata: result.metadata, localVersion: file.localVersion },\n };\n }\n case \"delete\": {\n const file = await FilesModel.findByIdIncludingDeleted(fileId);\n if (!file) return null;\n if (file.isDeleted === 1 && file.syncStatus === \"synced\") {\n logger.info(`File ${fileId} deletion already synced, skipping`);\n return null;\n }\n if (file.onChainFileId === null || file.onChainFileId === undefined) {\n return { noOp: true, fileId, portalAddress: file.portalAddress };\n }\n\n const result = await submitDeleteFileOp(fileId);\n logger.info(`File ${file.ddocId} delete op submitted (hash: ${result.userOpHash})`);\n return { userOpHash: result.userOpHash, pendingPayload: {} };\n }\n default:\n throw new Error(`Unknown event type: ${type}`);\n }\n};\n\nexport const resolveEvent = async (event: Event): Promise<{ resolved: boolean }> => {\n const { fileId, type, userOpHash } = event;\n if (!userOpHash) {\n logger.warn(`Event ${event._id} has no userOpHash, cannot resolve`);\n return { resolved: false };\n }\n\n const result = await resolveFileOp(fileId, userOpHash, type);\n if (!result) {\n return { resolved: false };\n }\n\n const { receipt } = result;\n if (!receipt.success) {\n await EventsModel.clearEventPendingOp(event._id);\n throw new Error(`User operation failed: ${receipt.reason}`);\n }\n\n switch (type) {\n case \"create\": {\n const file = await FilesModel.findByIdIncludingDeleted(fileId);\n if (!file) throw new Error(`File ${fileId} not found during resolve`);\n\n const onChainFileId = parseFileEventLog(receipt.logs, \"AddedFile\", ADDED_FILE_EVENT);\n const pending = JSON.parse(event.pendingPayload!) as {\n linkKey: string;\n linkKeyNonce: string;\n commentKey: string;\n metadata: Record<string, unknown>;\n };\n\n const frontendUrl = getRuntimeConfig().FRONTEND_URL;\n const payload: UpdateFilePayload = {\n onchainVersion: file.localVersion,\n onChainFileId,\n linkKey: pending.linkKey,\n linkKeyNonce: pending.linkKeyNonce,\n commentKey: pending.commentKey,\n metadata: pending.metadata,\n link: `${frontendUrl}/${file.portalAddress}/${onChainFileId}#key=${pending.linkKey}`,\n };\n const updatedFile = await FilesModel.update(fileId, payload, file.portalAddress);\n if (updatedFile.localVersion === updatedFile.onchainVersion) {\n await FilesModel.update(fileId, { syncStatus: \"synced\" }, file.portalAddress);\n }\n await EventsModel.clearEventPendingOp(event._id);\n logger.info(`File ${file.ddocId} create resolved successfully`);\n break;\n }\n case \"update\": {\n const file = await FilesModel.findByIdExcludingDeleted(fileId);\n if (!file) throw new Error(`File ${fileId} not found during resolve`);\n\n parseFileEventLog(receipt.logs, \"EditedFile\", EDITED_FILE_EVENT);\n const pending = JSON.parse(event.pendingPayload!) as {\n metadata: Record<string, unknown>;\n localVersion: number;\n };\n\n const payload: UpdateFilePayload = {\n onchainVersion: pending.localVersion,\n metadata: pending.metadata,\n };\n const updatedFile = await FilesModel.update(fileId, payload, file.portalAddress);\n if (updatedFile.localVersion === updatedFile.onchainVersion) {\n await FilesModel.update(fileId, { syncStatus: \"synced\" }, file.portalAddress);\n }\n await EventsModel.clearEventPendingOp(event._id);\n logger.info(`File ${file.ddocId} update resolved successfully`);\n break;\n }\n case \"delete\": {\n const file = await FilesModel.findByIdIncludingDeleted(fileId);\n if (!file) throw new Error(`File ${fileId} not found during resolve`);\n\n parseFileEventLog(receipt.logs, \"DeletedFile\", DELETED_FILE_EVENT);\n await FilesModel.update(\n fileId,\n { syncStatus: \"synced\", isDeleted: 1, onchainVersion: file.localVersion },\n file.portalAddress,\n );\n await EventsModel.clearEventPendingOp(event._id);\n logger.info(`File ${fileId} delete resolved successfully`);\n break;\n }\n default:\n throw new Error(`Unknown event type: ${type}`);\n }\n\n return { resolved: true };\n};\n\n// ── Legacy helpers (used by processEvent) ──\n\nconst onTransactionSuccess = async (\n fileId: string,\n file: Awaited<ReturnType<typeof FilesModel.findByIdIncludingDeleted>>,\n onChainFileId: number,\n pending: { linkKey: string; linkKeyNonce: string; commentKey: string; metadata: Record<string, unknown> },\n): Promise<void> => {\n const frontendUrl = getRuntimeConfig().FRONTEND_URL;\n const payload: UpdateFilePayload = {\n onchainVersion: file!.localVersion,\n onChainFileId,\n linkKey: pending.linkKey,\n linkKeyNonce: pending.linkKeyNonce,\n commentKey: pending.commentKey,\n metadata: pending.metadata,\n link: `${frontendUrl}/${file!.portalAddress}/${onChainFileId}#key=${pending.linkKey}`,\n };\n const updatedFile = await FilesModel.update(fileId, payload, file!.portalAddress);\n if (updatedFile.localVersion === updatedFile.onchainVersion) {\n await FilesModel.update(fileId, { syncStatus: \"synced\" }, file!.portalAddress);\n }\n};\n\nconst processCreateEvent = async (event: Event): Promise<void> => {\n const { fileId } = event;\n\n const file = await FilesModel.findByIdIncludingDeleted(fileId);\n if (!file) {\n throw new Error(`File ${fileId} not found`);\n }\n\n if (file.isDeleted === 1) {\n logger.info(`File ${fileId} is deleted, skipping create event`);\n return;\n }\n\n const waitContext = await getProxyAuthParams(fileId);\n const timeout = 120000;\n\n if (event.userOpHash) {\n const receipt = await waitForUserOpReceipt(\n event.userOpHash as `0x${string}`,\n waitContext.authToken,\n waitContext.portalAddress,\n waitContext.invokerAddress,\n timeout,\n );\n if (!receipt.success) {\n await EventsModel.clearEventPendingOp(event._id);\n throw new Error(`User operation failed: ${receipt.reason}`);\n }\n const onChainFileId = parseFileEventLog(receipt.logs, \"AddedFile\", ADDED_FILE_EVENT);\n const pending = JSON.parse(event.pendingPayload!) as {\n linkKey: string;\n linkKeyNonce: string;\n commentKey: string;\n metadata: Record<string, unknown>;\n };\n await onTransactionSuccess(fileId, file, onChainFileId, pending);\n await EventsModel.clearEventPendingOp(event._id);\n logger.info(`File ${file.ddocId} created and published successfully (resumed from pending op)`);\n return;\n }\n\n const result = await handleNewFileOp(fileId);\n await EventsModel.setEventPendingOp(event._id, result.userOpHash, {\n linkKey: result.linkKey,\n linkKeyNonce: result.linkKeyNonce,\n commentKey: result.commentKey,\n metadata: result.metadata,\n });\n\n const receipt = await waitForUserOpReceipt(\n result.userOpHash as `0x${string}`,\n waitContext.authToken,\n waitContext.portalAddress,\n waitContext.invokerAddress,\n timeout,\n );\n if (!receipt.success) {\n await EventsModel.clearEventPendingOp(event._id);\n throw new Error(`User operation failed: ${receipt.reason}`);\n }\n const onChainFileId = parseFileEventLog(receipt.logs, \"AddedFile\", ADDED_FILE_EVENT);\n await onTransactionSuccess(fileId, file, onChainFileId, {\n linkKey: result.linkKey,\n linkKeyNonce: result.linkKeyNonce,\n commentKey: result.commentKey,\n metadata: result.metadata,\n });\n await EventsModel.clearEventPendingOp(event._id);\n logger.info(`File ${file.ddocId} created and published successfully`);\n};\n\nconst processUpdateEvent = async (event: Event): Promise<void> => {\n const { fileId } = event;\n\n const file = await FilesModel.findByIdExcludingDeleted(fileId);\n if (!file) {\n return;\n }\n\n if (file.localVersion <= file.onchainVersion) {\n return;\n }\n\n const result = await handleExistingFileOp(fileId, \"update\");\n if (!result.success) {\n throw new Error(`Publish failed for file ${fileId}`);\n }\n\n const payload: UpdateFilePayload = {\n onchainVersion: file.localVersion,\n metadata: result.metadata,\n };\n const updatedFile = await FilesModel.update(fileId, payload, file.portalAddress);\n\n if (updatedFile.localVersion === updatedFile.onchainVersion) {\n await FilesModel.update(fileId, { syncStatus: \"synced\" }, file.portalAddress);\n }\n logger.info(`File ${file.ddocId} updated and published successfully`);\n};\n\nconst processDeleteEvent = async (event: Event): Promise<void> => {\n const { fileId } = event;\n\n const file = await FilesModel.findByIdIncludingDeleted(fileId);\n if (!file) {\n return;\n }\n\n if (file.isDeleted === 1 && file.syncStatus === \"synced\") {\n logger.info(`File ${fileId} deletion already synced, skipping`);\n return;\n }\n\n const payload: UpdateFilePayload = {\n syncStatus: \"synced\",\n isDeleted: 1,\n };\n\n if (file.onChainFileId !== null || file.onChainFileId !== undefined) {\n const result = await handleExistingFileOp(fileId, \"delete\");\n if (!result.success) {\n throw new Error(`Publish failed for file ${fileId}`);\n }\n\n payload.onchainVersion = file.localVersion;\n payload.metadata = result.metadata;\n payload.isDeleted = 1;\n }\n\n await FilesModel.update(fileId, payload, file.portalAddress);\n\n logger.info(`File ${fileId} delete event processed (syncStatus set to synced)`);\n};\n","import { logger } from \"../index\";\nimport { processEvent } from \"./eventProcessor\";\nimport { onNewEvent } from \"./workerSignal\";\nimport { EventsModel } from \"../database/models\";\nimport type { Event } from \"../database/models\";\nimport { RateLimitError } from \"../../errors/rate-limit\";\n\nconst DEFAULT_CONCURRENCY = 5;\nconst STALE_THRESHOLD_MS = 5 * 60 * 1000;\nconst SIGNAL_RETRY_DELAY_MS = 50;\nconst FALLBACK_POLL_MS = 30000;\nconst MAX_RETRIES = 10;\n\nexport class FileEventsWorker {\n private isRunning = false;\n private concurrency: number;\n private activeProcessors = new Map<string, Promise<void>>();\n private signalCleanup: (() => void) | null = null;\n private pendingSignal = false;\n private wakeResolver: (() => void) | null = null;\n\n constructor(concurrency: number = DEFAULT_CONCURRENCY) {\n this.concurrency = concurrency;\n }\n\n async start(): Promise<void> {\n if (this.isRunning) {\n logger.warn(\"Worker is already running\");\n return;\n }\n this.isRunning = true;\n\n const staleCount = await this.recoverStaleEvents();\n if (staleCount > 0) {\n logger.info(`Recovered ${staleCount} stale event(s)`);\n }\n\n this.signalCleanup = onNewEvent(() => {\n this.pendingSignal = true;\n this.wakeUp();\n });\n\n logger.debug(`File events worker started (concurrency: ${this.concurrency})`);\n this.run();\n }\n\n private async run(): Promise<void> {\n while (this.isRunning) {\n const foundEvents = await this.fillSlots();\n logger.debug(`Found ${foundEvents ? \"events\" : \"no events\"} to process`);\n if (this.activeProcessors.size === 0) {\n if (this.pendingSignal && !foundEvents) {\n this.pendingSignal = false;\n await this.sleep(SIGNAL_RETRY_DELAY_MS);\n continue;\n }\n\n this.pendingSignal = false;\n await this.waitForSignalOrTimeout(FALLBACK_POLL_MS);\n } else {\n await Promise.race(this.activeProcessors.values());\n }\n }\n }\n\n private async fillSlots(): Promise<boolean> {\n let foundAny = false;\n\n while (this.activeProcessors.size < this.concurrency && this.isRunning) {\n const lockedFileIds = Array.from(this.activeProcessors.keys());\n const event = await EventsModel.findNextEligible(lockedFileIds);\n\n if (!event) break;\n\n foundAny = true;\n await EventsModel.markProcessing(event._id);\n const processor = this.processEventWrapper(event);\n this.activeProcessors.set(event.fileId, processor);\n }\n\n logger.debug(`Slots filled: ${this.activeProcessors.size}`);\n return foundAny;\n }\n\n private async processEventWrapper(event: Event): Promise<void> {\n try {\n const result = await processEvent(event);\n if (result.success) {\n await EventsModel.markProcessed(event._id);\n } else {\n await this.handleFailure(event, result.error);\n }\n } catch (err) {\n await this.handleFailure(event, err);\n } finally {\n this.activeProcessors.delete(event.fileId);\n }\n }\n\n private async handleFailure(event: Event, error: unknown): Promise<void> {\n const errorMsg = error instanceof Error ? error.message : String(error);\n if (error instanceof RateLimitError) {\n const retryAfterMs = error.retryAfterSeconds * 1000;\n await EventsModel.scheduleRetryAfter(event._id, errorMsg, retryAfterMs);\n logger.warn(`Event ${event._id} rate limited; retry after ${error.retryAfterSeconds}s`);\n return;\n }\n if (event.retryCount < MAX_RETRIES) {\n await EventsModel.scheduleRetry(event._id, errorMsg);\n logger.warn(`Event ${event._id} failed (retry ${event.retryCount + 1}/${MAX_RETRIES}): ${errorMsg}`);\n } else {\n await EventsModel.markFailed(event._id, errorMsg);\n logger.error(`Event ${event._id} permanently failed after ${MAX_RETRIES} retries: ${errorMsg}`);\n }\n }\n\n private async recoverStaleEvents(): Promise<number> {\n const staleThreshold = Date.now() - STALE_THRESHOLD_MS;\n return EventsModel.resetStaleEvents(staleThreshold);\n }\n\n private wakeUp(): void {\n if (this.wakeResolver) {\n this.wakeResolver();\n this.wakeResolver = null;\n }\n }\n\n private waitForSignalOrTimeout(ms: number): Promise<void> {\n return new Promise((resolve) => {\n const timeout = setTimeout(() => {\n this.wakeResolver = null;\n resolve();\n }, ms);\n\n this.wakeResolver = () => {\n clearTimeout(timeout);\n resolve();\n };\n });\n }\n\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n\n async close(): Promise<void> {\n if (!this.isRunning) {\n return;\n }\n logger.info(\"Closing worker gracefully...\");\n this.isRunning = false;\n\n if (this.signalCleanup) {\n this.signalCleanup();\n this.signalCleanup = null;\n }\n\n this.wakeUp();\n this.wakeResolver = null;\n\n if (this.activeProcessors.size > 0) {\n logger.info(`Waiting for ${this.activeProcessors.size} active processor(s) to complete...`);\n await Promise.all(this.activeProcessors.values());\n }\n\n logger.info(\"Worker closed\");\n }\n\n isActive(): boolean {\n return this.isRunning;\n }\n\n getActiveCount(): number {\n return this.activeProcessors.size;\n }\n}\n\nexport function createWorker(concurrency: number = DEFAULT_CONCURRENCY): FileEventsWorker {\n return new FileEventsWorker(concurrency);\n}\n","export { createWorker, FileEventsWorker } from \"./worker\";\nexport { notifyNewEvent } from \"./workerSignal\";\n","import { createWorker, type FileEventsWorker } from \"./infra/worker\";\n\nconst DEFAULT_CONCURRENCY = 5;\n\nlet worker: FileEventsWorker | null = null;\n\nexport async function startWorker(concurrency: number = DEFAULT_CONCURRENCY): Promise<void> {\n if (worker?.isActive()) {\n return;\n }\n worker = createWorker(concurrency);\n await worker.start();\n}\n\nexport async function closeWorker(): Promise<void> {\n if (worker) {\n await worker.close();\n worker = null;\n }\n}\n\nexport function isWorkerActive(): boolean {\n return worker?.isActive() ?? false;\n}\n\nexport function getWorkerActiveCount(): number {\n return worker?.getActiveCount() ?? 0;\n}\n","// Error reporting service\n// Example: Slack, Sentry, etc.\n\nclass Reporter {\n async reportError(message: string): Promise<void> {\n // Implement your error reporting logic\n console.error(\"Error reported:\", message);\n }\n}\n\nexport default new Reporter();\n","import { logger } from \"./logger\";\nimport { asyncHandler, asyncHandlerArray } from \"./asyncHandler\";\nimport { closeWorker } from \"../appWorker\";\nimport { closeDatabase } from \"./database\";\n\nimport reporter from \"./reporter\";\n\nexport { logger, asyncHandler, asyncHandlerArray, reporter, closeWorker, closeDatabase };\n","import { validateDbConfig } from \"./config\";\nimport { logger } from \"./infra\";\nimport { runMigrations } from \"./infra/database/migrations\";\nimport { closeWorker, isWorkerActive, startWorker } from \"./appWorker\";\n\nconst main = async () => {\n validateDbConfig();\n await runMigrations();\n\n const concurrency = parseInt(process.env.WORKER_CONCURRENCY || \"5\", 10);\n await startWorker(concurrency);\n\n setTimeout(() => {\n if (isWorkerActive()) {\n logger.info(\"File events worker started and active\");\n return;\n }\n\n logger.error(\"Worker failed to start\");\n process.exit(1);\n }, 100);\n};\n\nmain().catch((error) => {\n logger.error(\"Failed to start worker:\", error);\n process.exit(1);\n});\n\nconst shutdown = async () => {\n logger.info(\"Shutting down worker gracefully...\");\n await closeWorker();\n process.exit(0);\n};\n\nprocess.on(\"SIGTERM\", shutdown);\nprocess.on(\"SIGINT\", shutdown);\n","import { getAdapter } from \"../connection.js\";\nimport { logger } from \"../../index.js\";\n\nconst STABLE_SCHEMA = `\nCREATE TABLE IF NOT EXISTS files (\n _id TEXT PRIMARY KEY,\n ddocId TEXT NOT NULL,\n title TEXT NOT NULL,\n content TEXT NOT NULL,\n localVersion INTEGER NOT NULL DEFAULT 1,\n onchainVersion INTEGER NOT NULL DEFAULT 0,\n syncStatus TEXT NOT NULL DEFAULT 'pending',\n createdAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n updatedAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n isDeleted INTEGER NOT NULL DEFAULT 0,\n portalAddress TEXT NOT NULL,\n metadata TEXT DEFAULT '{}',\n onChainFileId INTEGER,\n commentKey TEXT,\n linkKey TEXT,\n linkKeyNonce TEXT,\n link TEXT,\n derivedKey TEXT,\n secretKey TEXT\n);\nCREATE INDEX IF NOT EXISTS idx_files_createdAt ON files(createdAt);\nCREATE INDEX IF NOT EXISTS idx_files_syncStatus ON files(syncStatus);\nCREATE INDEX IF NOT EXISTS idx_files_title ON files(title);\nCREATE INDEX IF NOT EXISTS idx_files_portalAddress ON files(portalAddress);\n\nCREATE TABLE IF NOT EXISTS portals (\n _id TEXT PRIMARY KEY,\n portalAddress TEXT NOT NULL UNIQUE,\n portalSeed TEXT NOT NULL UNIQUE,\n ownerAddress TEXT NOT NULL,\n createdAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n updatedAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n);\n\nCREATE TABLE IF NOT EXISTS api_keys (\n _id TEXT PRIMARY KEY,\n apiKeySeed TEXT NOT NULL UNIQUE,\n name TEXT NOT NULL,\n collaboratorAddress TEXT NOT NULL UNIQUE,\n portalAddress TEXT NOT NULL,\n createdAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n isDeleted INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE IF NOT EXISTS events (\n _id TEXT PRIMARY KEY,\n type TEXT NOT NULL CHECK (type IN ('create', 'update', 'delete')),\n timestamp BIGINT NOT NULL,\n fileId TEXT NOT NULL,\n status TEXT NOT NULL DEFAULT 'pending' CHECK (status IN ('pending', 'processing', 'submitted', 'processed', 'failed')),\n retryCount INTEGER NOT NULL DEFAULT 0,\n lastError TEXT,\n lockedAt BIGINT,\n nextRetryAt BIGINT,\n userOpHash TEXT,\n pendingPayload TEXT,\n portalAddress TEXT\n);\nCREATE INDEX IF NOT EXISTS idx_events_pending_eligible ON events (status, nextRetryAt, timestamp) WHERE status = 'pending';\nCREATE INDEX IF NOT EXISTS idx_events_file_pending_ts ON events (fileId, status, timestamp) WHERE status = 'pending';\nCREATE INDEX IF NOT EXISTS idx_events_processing_locked ON events (status, lockedAt) WHERE status = 'processing';\nCREATE INDEX IF NOT EXISTS idx_events_failed_portal ON events (portalAddress, status) WHERE status = 'failed';\n\nCREATE TABLE IF NOT EXISTS folders (\n _id TEXT PRIMARY KEY,\n onchainFileId INTEGER NOT NULL,\n folderId TEXT NOT NULL,\n folderRef TEXT NOT NULL,\n folderName TEXT NOT NULL,\n portalAddress TEXT NOT NULL,\n metadataIPFSHash TEXT NOT NULL,\n contentIPFSHash TEXT NOT NULL,\n isDeleted INTEGER NOT NULL DEFAULT 0,\n lastTransactionHash TEXT,\n lastTransactionBlockNumber BIGINT NOT NULL,\n lastTransactionBlockTimestamp BIGINT NOT NULL,\n created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n);\nCREATE INDEX IF NOT EXISTS idx_folders_folderRef_folderId ON folders(folderRef, folderId);\nCREATE INDEX IF NOT EXISTS idx_folders_folderRef ON folders(folderRef);\nCREATE INDEX IF NOT EXISTS idx_folders_created_at ON folders(created_at);\n`;\n\nexport async function runMigrations(): Promise<void> {\n const adapter = await getAdapter();\n await adapter.exec(STABLE_SCHEMA);\n logger.debug(\"Database schema ready\");\n}\n"],"mappings":"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","names":["path","path","fs","PostgresAdapter","SqliteAdapter","init_constants","init_constants","adapter","uuidv7","uuidv7","uuidv7","init_constants","init_constants","toHex","isLE","mul2","POLY","sbox","sbox2","t0","t1","t2","t3","isLE","BLOCK_SIZE","generateRandomBytes","toUint8Array","init_constants","fromUint8Array","toUint8Array","init_constants","fromUint8Array","toUint8Array","init_constants","receipt","onChainFileId","init_worker","DEFAULT_CONCURRENCY","init_worker","adapter"]}
|
|
1
|
+
{"version":3,"sources":["../node_modules/tsup/assets/esm_shims.js","../src/cli/constants.generated.ts","../src/cli/constants.ts","../src/config/index.ts","../src/infra/logger.ts","../src/infra/asyncHandler.ts","../src/infra/database/adapters/sql-compat.ts","../src/infra/database/adapters/pg-column-map.ts","../src/infra/database/adapters/postgres-adapter.ts","../src/infra/database/adapters/sqlite-adapter.ts","../src/infra/database/connection.ts","../src/domain/file/constants.ts","../src/infra/database/query-builder.ts","../src/infra/database/index.ts","../src/infra/database/models/files.model.ts","../src/infra/database/models/portals.model.ts","../src/infra/database/models/apikeys.model.ts","../src/infra/database/models/folders.model.ts","../src/infra/worker/workerSignal.ts","../src/infra/database/models/events.model.ts","../src/infra/database/models/index.ts","../src/sdk/key-store.ts","../src/sdk/auth-token-provider.ts","../src/constants/chains.ts","../src/constants/events.ts","../src/constants/methods.ts","../src/constants/index.ts","../src/sdk/pimlico-utils.ts","../src/sdk/smart-agent.ts","../node_modules/@noble/ciphers/src/utils.ts","../node_modules/@noble/ciphers/src/_polyval.ts","../node_modules/@noble/ciphers/src/aes.ts","../src/sdk/file-encryption.ts","../src/sdk/file-utils.ts","../src/sdk/file-manager.ts","../src/domain/portal/publish.ts","../src/domain/portal/savePortal.ts","../src/domain/portal/saveApiKey.ts","../src/domain/portal/removeApiKey.ts","../src/domain/portal/index.ts","../src/errors/rate-limit.ts","../src/infra/worker/eventProcessor.ts","../src/infra/worker/worker.ts","../src/infra/worker/index.ts","../src/appWorker.ts","../src/infra/reporter.ts","../src/infra/index.ts","../src/worker.ts","../src/infra/database/migrations/index.ts"],"sourcesContent":["// Shim globals in esm bundle\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\n","export const STATIC_CONFIG = {\n API_URL: 'https://prod-apps-storage-5cdacc06ff79.herokuapp.com/',\n SERVER_DID: 'did:key:z6Mkroj9bxTin6Z5S9qwx2G2b87NPrCX7S85FhCpmBGPcDCz',\n PROXY_SERVER_DID: 'did:key:z6MkrZSmq8D6vQG87YbjUQatXeptaCCXWdTx8fYaWxWbRUHB',\n NETWORK_NAME: 'gnosis',\n DEFAULT_PORT: '8001',\n DEFAULT_RPC_URL: 'https://rpc.gnosischain.com',\n PIMLICO_PROXY_URL: 'https://pimlico-proxy-0a326da116f8.herokuapp.com/',\n SERVICE_NAME: 'fileverse-api',\n LOG_LEVEL: 'info',\n FRONTEND_URL: 'https://docs.fileverse.io'\n} as const;\n\nexport const BASE_CONFIG = STATIC_CONFIG;\n","export { STATIC_CONFIG, BASE_CONFIG } from \"./constants.generated.js\";\n","import dotenv from \"dotenv\";\nimport path from \"path\";\nimport fs from \"fs\";\nimport os from \"os\";\nimport { STATIC_CONFIG } from \"../cli/constants.js\";\n\nconst projectEnvPath = path.join(process.cwd(), \"config\", \".env\");\nconst userEnvPath = path.join(os.homedir(), \".fileverse\", \".env\");\n\nfunction getEnvPath(): string {\n if (fs.existsSync(projectEnvPath)) {\n return projectEnvPath;\n }\n return userEnvPath;\n}\n\nexport function loadConfig(override = true): void {\n const envPath = getEnvPath();\n dotenv.config({ path: envPath, override });\n}\n\nloadConfig(false);\n\nexport function getRuntimeConfig() {\n return {\n get API_KEY() {\n return process.env.API_KEY;\n },\n get RPC_URL() {\n return process.env.RPC_URL || STATIC_CONFIG.DEFAULT_RPC_URL;\n },\n get DB_PATH() {\n return process.env.DB_PATH;\n },\n get DATABASE_URL() {\n return process.env.DATABASE_URL;\n },\n get PORT() {\n return process.env.PORT || STATIC_CONFIG.DEFAULT_PORT;\n },\n get NODE_ENV() {\n return process.env.NODE_ENV || \"production\";\n },\n get FRONTEND_URL() {\n return process.env.FRONTEND_URL || STATIC_CONFIG.FRONTEND_URL;\n },\n };\n}\n\nexport function validateDbConfig(): void {\n const databaseUrl = process.env.DATABASE_URL;\n const dbPath = process.env.DB_PATH;\n\n // If DATABASE_URL is set, skip file path validation (PostgreSQL mode)\n if (databaseUrl) {\n return;\n }\n\n if (!dbPath) {\n console.error(\"Error: DB_PATH or DATABASE_URL environment variable is required\");\n console.error(\"Please set DB_PATH or DATABASE_URL in your .env file (config/.env or ~/.fileverse/.env) or run the CLI first\");\n process.exit(1);\n }\n\n const dbDir = path.dirname(dbPath.trim());\n if (!fs.existsSync(dbDir)) {\n fs.mkdirSync(dbDir, { recursive: true });\n }\n}\n\n// Keep backwards-compatible alias\nexport const validateDbPath = validateDbConfig;\n\nconst config: Record<string, string | undefined> = {\n ...STATIC_CONFIG,\n get SERVICE_NAME() {\n return STATIC_CONFIG.SERVICE_NAME;\n },\n get LOG_LEVEL() {\n return STATIC_CONFIG.LOG_LEVEL;\n },\n get NETWORK_NAME() {\n return STATIC_CONFIG.NETWORK_NAME;\n },\n get UPLOAD_SERVER_URL() {\n return STATIC_CONFIG.API_URL;\n },\n get UPLOAD_SERVER_DID() {\n return STATIC_CONFIG.SERVER_DID;\n },\n get API_KEY() {\n return process.env.API_KEY;\n },\n get RPC_URL() {\n return process.env.RPC_URL || STATIC_CONFIG.DEFAULT_RPC_URL;\n },\n get DB_PATH() {\n return process.env.DB_PATH;\n },\n get DATABASE_URL() {\n return process.env.DATABASE_URL;\n },\n get PORT() {\n return process.env.PORT || STATIC_CONFIG.DEFAULT_PORT;\n },\n get NODE_ENV() {\n return process.env.NODE_ENV || \"production\";\n },\n get IP() {\n return process.env.IP || \"0.0.0.0\";\n },\n get FRONTEND_URL() {\n return process.env.FRONTEND_URL || STATIC_CONFIG.FRONTEND_URL;\n },\n};\n\nexport { config };\n","import pino, { Logger as PinoLogger, Level } from \"pino\";\nimport { STATIC_CONFIG } from \"../cli/constants\";\nimport { config } from \"../config\";\n\nconst isProduction = config.NODE_ENV === \"production\";\n\nconst pinoInstance = pino({\n name: STATIC_CONFIG.SERVICE_NAME,\n level: STATIC_CONFIG.LOG_LEVEL,\n formatters: {\n bindings: (bindings) => ({ name: bindings.name }),\n level: (label) => ({ level: label }),\n },\n serializers: {\n err(err: Error | undefined) {\n if (!err) return err;\n if (isProduction) {\n return { type: err.name, message: err.message };\n }\n return {\n type: err.name,\n message: err.message,\n stack: err.stack,\n };\n },\n },\n transport:\n config.NODE_ENV !== \"production\"\n ? {\n target: \"pino-pretty\",\n options: {\n colorize: true,\n translateTime: \"SYS:standard\",\n ignore: \"pid,hostname\",\n errorProps: \"*\",\n errorLikeObjectKeys: [\"err\", \"error\"],\n },\n }\n : undefined,\n});\n\ntype LogFn = {\n (msg: string, ...args: unknown[]): void;\n (obj: object, msg?: string, ...args: unknown[]): void;\n};\n\nconst createLogMethod = (level: Level): LogFn => {\n return (...args: unknown[]) => {\n const [first, ...rest] = args;\n const log = pinoInstance[level].bind(pinoInstance) as (...a: unknown[]) => void;\n\n if (typeof first === \"object\" && first !== null && !(first instanceof Error)) {\n log(first, ...rest);\n return;\n }\n\n if (rest.length > 0) {\n const last = rest[rest.length - 1];\n if (last instanceof Error) {\n log({ err: last }, first, ...rest.slice(0, -1));\n return;\n }\n }\n\n if (first instanceof Error) {\n log({ err: first }, first.message);\n return;\n }\n\n log(first, ...rest);\n };\n};\n\ninterface Logger {\n trace: LogFn;\n debug: LogFn;\n info: LogFn;\n warn: LogFn;\n error: LogFn;\n fatal: LogFn;\n level: Level;\n child: PinoLogger[\"child\"];\n}\n\nexport const logger: Logger = {\n trace: createLogMethod(\"trace\"),\n debug: createLogMethod(\"debug\"),\n info: createLogMethod(\"info\"),\n warn: createLogMethod(\"warn\"),\n error: createLogMethod(\"error\"),\n fatal: createLogMethod(\"fatal\"),\n get level() {\n return pinoInstance.level as Level;\n },\n set level(lvl: Level) {\n pinoInstance.level = lvl;\n },\n child: pinoInstance.child.bind(pinoInstance),\n};\n","import { Request, Response, NextFunction } from \"express\";\n\nconst asyncHandler =\n (fn: (req: Request, res: Response, next: NextFunction) => Promise<void>) =>\n (req: Request, res: Response, next: NextFunction) =>\n Promise.resolve(fn(req, res, next)).catch(next);\n\nconst asyncHandlerArray = (resolvers: any) => {\n return resolvers.map(asyncHandler);\n};\n\nexport { asyncHandler, asyncHandlerArray };\n","/**\n * Converts SQLite-style `?` placeholders to PostgreSQL-style `$1, $2, ...`\n * Skips placeholders inside single-quoted string literals.\n */\nexport function sqliteToPostgres(sql: string): string {\n let result = \"\";\n let paramIndex = 0;\n let inString = false;\n\n for (let i = 0; i < sql.length; i++) {\n const ch = sql[i];\n\n if (ch === \"'\") {\n // Handle escaped single quotes ('')\n if (inString && i + 1 < sql.length && sql[i + 1] === \"'\") {\n result += \"''\";\n i++;\n continue;\n }\n inString = !inString;\n result += ch;\n } else if (ch === \"?\" && !inString) {\n paramIndex++;\n result += `$${paramIndex}`;\n } else {\n result += ch;\n }\n }\n\n return result;\n}\n","/**\n * Static map of lowercase → camelCase column names.\n * PostgreSQL lowercases all unquoted identifiers, so query results come back\n * with lowercase keys. This map restores the original camelCase names.\n */\nconst COLUMN_MAP: Record<string, string> = {\n ddocid: \"ddocId\",\n localversion: \"localVersion\",\n onchainversion: \"onchainVersion\",\n syncstatus: \"syncStatus\",\n createdat: \"createdAt\",\n updatedat: \"updatedAt\",\n isdeleted: \"isDeleted\",\n portaladdress: \"portalAddress\",\n onchainfileid: \"onChainFileId\",\n commentkey: \"commentKey\",\n linkkey: \"linkKey\",\n linkkeynonce: \"linkKeyNonce\",\n portalseed: \"portalSeed\",\n owneraddress: \"ownerAddress\",\n apikeyseed: \"apiKeySeed\",\n collaboratoraddress: \"collaboratorAddress\",\n fileid: \"fileId\",\n retrycount: \"retryCount\",\n lasterror: \"lastError\",\n lockedat: \"lockedAt\",\n nextretryat: \"nextRetryAt\",\n userophash: \"userOpHash\",\n pendingpayload: \"pendingPayload\",\n folderid: \"folderId\",\n folderref: \"folderRef\",\n foldername: \"folderName\",\n metadataipfshash: \"metadataIPFSHash\",\n contentipfshash: \"contentIPFSHash\",\n lasttransactionhash: \"lastTransactionHash\",\n lasttransactionblocknumber: \"lastTransactionBlockNumber\",\n lasttransactionblocktimestamp: \"lastTransactionBlockTimestamp\",\n};\n\nexport function remapRow<T>(row: Record<string, unknown>): T {\n const out: Record<string, unknown> = {};\n for (const key in row) {\n out[COLUMN_MAP[key] ?? key] = row[key];\n }\n return out as T;\n}\n\nexport function remapRows<T>(rows: Record<string, unknown>[]): T[] {\n return rows.map((row) => remapRow<T>(row));\n}\n","import type { DatabaseAdapter, ExecuteResult } from \"./adapter.js\";\nimport { sqliteToPostgres } from \"./sql-compat.js\";\nimport { remapRows, remapRow } from \"./pg-column-map.js\";\nimport { logger } from \"../../index.js\";\n\n// pg is lazy-imported so SQLite-only users don't need it installed\nlet pgModule: typeof import(\"pg\") | null = null;\n\nasync function getPg() {\n if (!pgModule) {\n pgModule = await import(\"pg\");\n }\n return pgModule;\n}\n\nexport class PostgresAdapter implements DatabaseAdapter {\n private pool: InstanceType<typeof import(\"pg\").Pool> | null = null;\n private connectionUrl: string;\n private connected = false;\n readonly dialect = \"postgres\" as const;\n\n constructor(connectionUrl: string) {\n this.connectionUrl = connectionUrl;\n }\n\n private async getPool() {\n if (!this.pool) {\n const pg = await getPg();\n this.pool = new pg.default.Pool({\n connectionString: this.connectionUrl,\n max: 10,\n ssl: this.connectionUrl.includes(\"sslmode=require\") || this.connectionUrl.includes(\"amazonaws.com\") || this.connectionUrl.includes(\"heroku\")\n ? { rejectUnauthorized: false }\n : undefined,\n });\n // Verify connectivity\n const client = await this.pool.connect();\n client.release();\n this.connected = true;\n logger.info(\"PostgreSQL database connected\");\n }\n return this.pool;\n }\n\n async select<T>(sql: string, params: any[] = []): Promise<T[]> {\n const pool = await this.getPool();\n const pgSql = sqliteToPostgres(sql);\n const result = await pool.query(pgSql, params);\n return remapRows<T>(result.rows);\n }\n\n async selectOne<T>(sql: string, params: any[] = []): Promise<T | undefined> {\n const pool = await this.getPool();\n const pgSql = sqliteToPostgres(sql);\n const result = await pool.query(pgSql, params);\n return result.rows[0] ? remapRow<T>(result.rows[0]) : undefined;\n }\n\n async execute(sql: string, params: any[] = []): Promise<ExecuteResult> {\n const pool = await this.getPool();\n const pgSql = sqliteToPostgres(sql);\n const result = await pool.query(pgSql, params);\n return {\n changes: result.rowCount ?? 0,\n lastInsertRowid: 0,\n };\n }\n\n async transaction<T>(callback: () => Promise<T>): Promise<T> {\n const pool = await this.getPool();\n const client = await pool.connect();\n try {\n await client.query(\"BEGIN\");\n const result = await callback();\n await client.query(\"COMMIT\");\n return result;\n } catch (error) {\n await client.query(\"ROLLBACK\");\n throw error;\n } finally {\n client.release();\n }\n }\n\n async exec(sql: string): Promise<void> {\n const pool = await this.getPool();\n await pool.query(sql);\n }\n\n async close(): Promise<void> {\n if (this.pool) {\n await this.pool.end();\n this.pool = null;\n this.connected = false;\n logger.info(\"Database connection closed\");\n }\n }\n\n isConnected(): boolean {\n return this.connected;\n }\n}\n","import Database from \"better-sqlite3\";\nimport type { DatabaseAdapter, ExecuteResult } from \"./adapter.js\";\nimport { logger } from \"../../index.js\";\n\nexport class SqliteAdapter implements DatabaseAdapter {\n private db: Database.Database | null = null;\n readonly dialect = \"sqlite\" as const;\n\n constructor(private dbPath: string) {}\n\n private getDb(): Database.Database {\n if (!this.db) {\n this.db = new Database(this.dbPath);\n this.db.pragma(\"journal_mode = WAL\");\n this.db.pragma(\"foreign_keys = ON\");\n this.db.prepare(\"SELECT 1\").get();\n logger.info(`SQLite database connected: ${this.dbPath}`);\n }\n return this.db;\n }\n\n async select<T>(sql: string, params: any[] = []): Promise<T[]> {\n const stmt = this.getDb().prepare(sql);\n return stmt.all(params) as T[];\n }\n\n async selectOne<T>(sql: string, params: any[] = []): Promise<T | undefined> {\n const stmt = this.getDb().prepare(sql);\n return stmt.get(params) as T | undefined;\n }\n\n async execute(sql: string, params: any[] = []): Promise<ExecuteResult> {\n const stmt = this.getDb().prepare(sql);\n const result = stmt.run(params);\n return {\n changes: result.changes,\n lastInsertRowid: result.lastInsertRowid,\n };\n }\n\n async transaction<T>(callback: () => Promise<T>): Promise<T> {\n const db = this.getDb();\n const savepointName = `sp_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;\n db.exec(`SAVEPOINT ${savepointName}`);\n try {\n const result = await callback();\n db.exec(`RELEASE ${savepointName}`);\n return result;\n } catch (error) {\n db.exec(`ROLLBACK TO ${savepointName}`);\n db.exec(`RELEASE ${savepointName}`);\n throw error;\n }\n }\n\n async exec(sql: string): Promise<void> {\n this.getDb().exec(sql);\n }\n\n async close(): Promise<void> {\n if (this.db) {\n this.db.close();\n this.db = null;\n logger.info(\"Database connection closed\");\n }\n }\n\n isConnected(): boolean {\n return this.db !== null && this.db.open;\n }\n}\n","import type { DatabaseAdapter } from \"./adapters/index.js\";\nimport { logger } from \"../index.js\";\nimport path from \"path\";\nimport fs from \"fs\";\n\nlet adapter: DatabaseAdapter | null = null;\n\n/**\n * Auto-detect and initialize the database adapter:\n * - DATABASE_URL env → PostgreSQL\n * - DB_PATH env → SQLite\n */\nexport async function initializeAdapter(): Promise<DatabaseAdapter> {\n if (adapter) return adapter;\n\n const databaseUrl = process.env.DATABASE_URL;\n const dbPath = process.env.DB_PATH;\n\n if (databaseUrl) {\n const { PostgresAdapter } = await import(\"./adapters/postgres-adapter.js\");\n adapter = new PostgresAdapter(databaseUrl);\n logger.info(\"Using PostgreSQL adapter\");\n } else if (dbPath) {\n // Ensure DB directory exists\n const dbDir = path.dirname(dbPath.trim());\n if (!fs.existsSync(dbDir)) {\n fs.mkdirSync(dbDir, { recursive: true });\n }\n\n const { SqliteAdapter } = await import(\"./adapters/sqlite-adapter.js\");\n adapter = new SqliteAdapter(dbPath);\n logger.info(\"Using SQLite adapter\");\n } else {\n throw new Error(\n \"No database configured. Set DATABASE_URL (PostgreSQL) or DB_PATH (SQLite).\",\n );\n }\n\n return adapter;\n}\n\n/**\n * Returns the active adapter, lazy-initializing if needed.\n */\nexport async function getAdapter(): Promise<DatabaseAdapter> {\n if (!adapter) {\n return initializeAdapter();\n }\n return adapter;\n}\n\n/**\n * Graceful shutdown — close the active adapter.\n */\nexport async function closeAdapter(): Promise<void> {\n if (adapter) {\n await adapter.close();\n adapter = null;\n }\n}\n","/**\n * Default limit for listing files/ddocs\n * Used by both API and CLI to ensure consistent behavior\n */\nexport const DEFAULT_LIST_LIMIT = 10;\n","import { getAdapter } from \"./connection.js\";\nimport type { QueryOptions } from \"../../types\";\nimport type { ExecuteResult } from \"./adapters/index.js\";\nimport { DEFAULT_LIST_LIMIT } from \"../../domain/file/constants\";\n\nexport class QueryBuilder {\n static async select<T = any>(sql: string, params: any[] = []): Promise<T[]> {\n const adapter = await getAdapter();\n return adapter.select<T>(sql, params);\n }\n\n static async selectOne<T = any>(sql: string, params: any[] = []): Promise<T | undefined> {\n const adapter = await getAdapter();\n return adapter.selectOne<T>(sql, params);\n }\n\n static async execute(sql: string, params: any[] = []): Promise<ExecuteResult> {\n const adapter = await getAdapter();\n return adapter.execute(sql, params);\n }\n\n static async transaction<T>(callback: () => Promise<T>): Promise<T> {\n const adapter = await getAdapter();\n return adapter.transaction(callback);\n }\n\n static paginate(sql: string, options: QueryOptions = {}): string {\n let query = sql;\n\n if (options.orderBy) {\n query += ` ORDER BY ${options.orderBy} ${options.orderDirection || \"ASC\"}`;\n }\n\n const hasOffset = (options.offset ?? 0) > 0;\n const limit = options.limit ?? (hasOffset ? DEFAULT_LIST_LIMIT : undefined);\n\n if (limit) {\n query += ` LIMIT ${limit}`;\n }\n\n if (hasOffset) {\n query += ` OFFSET ${options.offset}`;\n }\n\n return query;\n }\n}\n","import { getAdapter, closeAdapter, initializeAdapter } from \"./connection.js\";\nimport { QueryBuilder } from \"./query-builder.js\";\n\nconst closeDatabase = async (): Promise<void> => {\n await closeAdapter();\n};\n\nexport { getAdapter, initializeAdapter, closeAdapter, closeDatabase, QueryBuilder };\n","import { QueryBuilder } from \"../index.js\";\nimport { uuidv7 } from \"uuidv7\";\nimport type { File, FileListResponse, UpdateFilePayload } from \"../../../types\";\n\nexport type { File, FileListResponse };\n\nexport class FilesModel {\n private static readonly TABLE = \"files\";\n\n private static parseFile(fileRaw: any): File {\n let metadata: Record<string, unknown> = {};\n try {\n if (fileRaw.metadata) {\n metadata = typeof fileRaw.metadata === \"string\" ? JSON.parse(fileRaw.metadata) : fileRaw.metadata;\n }\n } catch (e) {\n // If parsing fails, use empty object\n metadata = {};\n }\n\n return {\n _id: fileRaw._id,\n ddocId: fileRaw.ddocId,\n title: fileRaw.title,\n content: fileRaw.content,\n localVersion: fileRaw.localVersion,\n onchainVersion: fileRaw.onchainVersion,\n syncStatus: fileRaw.syncStatus,\n isDeleted: fileRaw.isDeleted,\n onChainFileId: fileRaw.onChainFileId ?? null,\n portalAddress: fileRaw.portalAddress,\n metadata: metadata || {},\n createdAt: fileRaw.createdAt,\n updatedAt: fileRaw.updatedAt,\n linkKey: fileRaw.linkKey,\n linkKeyNonce: fileRaw.linkKeyNonce,\n commentKey: fileRaw.commentKey,\n link: fileRaw.link,\n };\n }\n\n static async findAll(\n portalAddress: string,\n limit?: number,\n skip?: number,\n ): Promise<{ files: File[]; total: number; hasNext: boolean }> {\n const whereClause = \"isDeleted = 0 AND portalAddress = ?\";\n const params: any[] = [portalAddress];\n\n const countSql = `\n SELECT COUNT(*) as count\n FROM ${this.TABLE}\n WHERE ${whereClause}\n `;\n const totalResult = await QueryBuilder.selectOne<{ count: number }>(countSql, params);\n const total = totalResult?.count || 0;\n const sql = `\n SELECT *\n FROM ${this.TABLE}\n WHERE ${whereClause}\n `;\n const completeSql = QueryBuilder.paginate(sql, {\n limit,\n offset: skip,\n orderBy: \"createdAt\",\n orderDirection: \"DESC\",\n });\n\n const filesRaw = await QueryBuilder.select<any>(completeSql, params);\n const files = filesRaw.map(this.parseFile);\n const hasNext = skip !== undefined && limit !== undefined ? skip + limit < total : false;\n return { files, total, hasNext };\n }\n\n static async findById(_id: string, portalAddress: string): Promise<File | undefined> {\n const sql = `\n SELECT *\n FROM ${this.TABLE}\n WHERE _id = ? AND isDeleted = 0 AND portalAddress = ?\n `;\n const result = await QueryBuilder.selectOne<any>(sql, [_id, portalAddress]);\n return result ? this.parseFile(result) : undefined;\n }\n\n static async findByIdIncludingDeleted(_id: string): Promise<File | undefined> {\n const sql = `\n SELECT *\n FROM ${this.TABLE}\n WHERE _id = ?\n `;\n const result = await QueryBuilder.selectOne<any>(sql, [_id]);\n return result ? this.parseFile(result) : undefined;\n }\n\n static async findByIdExcludingDeleted(_id: string): Promise<File | undefined> {\n const sql = `\n SELECT *\n FROM ${this.TABLE}\n WHERE _id = ? AND isDeleted = 0\n `;\n const result = await QueryBuilder.selectOne<any>(sql, [_id]);\n return result ? this.parseFile(result) : undefined;\n }\n\n static async findByDDocId(ddocId: string, portalAddress: string): Promise<File | undefined> {\n const sql = `\n SELECT *\n FROM ${this.TABLE}\n WHERE ddocId = ? AND isDeleted = 0 AND portalAddress = ?\n `;\n const result = await QueryBuilder.selectOne<any>(sql, [ddocId, portalAddress]);\n return result ? this.parseFile(result) : undefined;\n }\n\n static async searchByTitle(searchTerm: string, portalAddress: string, limit?: number, skip?: number): Promise<File[]> {\n const sql = `\n SELECT *\n FROM ${this.TABLE}\n WHERE LOWER(title) LIKE LOWER(?) AND isDeleted = 0 AND portalAddress = ?\n `;\n const completeSql = QueryBuilder.paginate(sql, {\n limit,\n offset: skip,\n orderBy: \"createdAt\",\n orderDirection: \"DESC\",\n });\n const filesRaw = await QueryBuilder.select<any>(completeSql, [`%${searchTerm}%`, portalAddress]);\n return filesRaw.map(this.parseFile);\n }\n\n static async create(input: { title: string; content: string; ddocId: string; portalAddress: string }): Promise<File> {\n const _id = uuidv7();\n const sql = `\n INSERT INTO ${this.TABLE}\n (_id, title, content, ddocId, portalAddress)\n VALUES (?, ?, ?, ?, ?)\n `;\n\n await QueryBuilder.execute(sql, [_id, input.title, input.content, input.ddocId, input.portalAddress]);\n // NOTE: default values while file creation: localVersion = 1, onchainVersion = 0, syncStatus = 'pending'\n\n const created = await this.findById(_id, input.portalAddress);\n if (!created) {\n throw new Error(\"Failed to create file\");\n }\n return created;\n }\n\n static async update(_id: string, payload: UpdateFilePayload, portalAddress: string): Promise<File> {\n const now = new Date().toISOString();\n\n const keys: string[] = [];\n const values: any[] = [];\n for (const [k, v] of Object.entries(payload)) {\n if (v !== undefined) {\n // Handle metadata specially - convert to JSON string\n if (k === \"metadata\" && typeof v === \"object\") {\n keys.push(`${k} = ?`);\n values.push(JSON.stringify(v));\n } else {\n keys.push(`${k} = ?`);\n values.push(v);\n }\n }\n }\n\n // Always add updatedAt\n keys.push(\"updatedAt = ?\");\n values.push(now, _id, portalAddress);\n\n const updateChain = keys.join(\", \");\n const sql = `UPDATE ${this.TABLE} SET ${updateChain} WHERE _id = ? AND portalAddress = ?`;\n\n await QueryBuilder.execute(sql, values);\n\n const updated = await this.findById(_id, portalAddress);\n if (!updated) {\n throw new Error(\"Failed to update file\");\n }\n return updated;\n }\n\n static async softDelete(_id: string): Promise<File> {\n const now = new Date().toISOString();\n const sql = `\n UPDATE ${this.TABLE}\n SET isDeleted = 1, syncStatus = 'pending', updatedAt = ?\n WHERE _id = ?\n `;\n\n await QueryBuilder.execute(sql, [now, _id]);\n\n // Use findByIdIncludingDeleted since the file is now marked as deleted\n const deleted = await this.findByIdIncludingDeleted(_id);\n if (!deleted) {\n throw new Error(\"Failed to delete file\");\n }\n return deleted;\n }\n}\n","import { QueryBuilder } from \"../index.js\";\nimport { uuidv7 } from \"uuidv7\";\nimport type { Portal } from \"../../../types\";\n\nexport type { Portal };\n\nexport class PortalsModel {\n private static readonly TABLE = \"portals\";\n\n static async findByPortalAddress(portalAddress: string): Promise<Portal | undefined> {\n const sql = `SELECT _id, portalAddress, portalSeed, ownerAddress, createdAt, updatedAt FROM ${this.TABLE} WHERE portalAddress = ?`;\n return QueryBuilder.selectOne<Portal>(sql, [portalAddress]);\n }\n\n static async create(input: { portalAddress: string; portalSeed: string; ownerAddress: string }): Promise<Portal> {\n const _id = uuidv7();\n const now = new Date().toISOString();\n const sql = `INSERT INTO ${this.TABLE} (_id, portalAddress, portalSeed, ownerAddress, createdAt, updatedAt) VALUES (?, ?, ?, ?, ?, ?)`;\n\n await QueryBuilder.execute(sql, [_id, input.portalAddress, input.portalSeed, input.ownerAddress, now, now]);\n\n const created = await this.findByPortalAddress(input.portalAddress);\n if (!created) {\n throw new Error(\"Failed to create portal\");\n }\n return created;\n }\n\n static async update(\n portalAddress: string,\n input: {\n portalSeed?: string;\n ownerAddress?: string;\n },\n ): Promise<Portal> {\n const now = new Date().toISOString();\n const keys: string[] = [];\n const values: any[] = [];\n\n for (const [k, v] of Object.entries(input)) {\n if (v !== undefined) {\n keys.push(`${k} = ?`);\n values.push(v);\n }\n }\n\n keys.push(\"updatedAt = ?\");\n values.push(now);\n\n const updateChain = keys.join(\", \");\n const sql = `UPDATE ${this.TABLE} SET ${updateChain} WHERE portalAddress = ?`;\n values.push(portalAddress);\n await QueryBuilder.execute(sql, values);\n\n const updated = await this.findByPortalAddress(portalAddress);\n if (!updated) {\n throw new Error(\"Failed to update portal\");\n }\n return updated;\n }\n\n static async upsert(input: { portalAddress: string; portalSeed: string; ownerAddress: string }): Promise<Portal> {\n const existing = await this.findByPortalAddress(input.portalAddress);\n if (existing) {\n return this.update(input.portalAddress, {\n portalSeed: input.portalSeed,\n ownerAddress: input.ownerAddress,\n });\n }\n return this.create(input);\n }\n}\n","import { QueryBuilder } from \"../index.js\";\nimport { uuidv7 } from \"uuidv7\";\nimport type { ApiKey } from \"../../../types\";\n\nexport type { ApiKey };\n\nexport class ApiKeysModel {\n private static readonly TABLE = \"api_keys\";\n\n static async create(input: {\n apiKeySeed: string;\n name: string;\n collaboratorAddress: string;\n portalAddress: string;\n }): Promise<ApiKey> {\n const _id = uuidv7();\n const now = new Date().toISOString();\n const sql = `INSERT INTO ${this.TABLE} (_id, apiKeySeed, name, collaboratorAddress, portalAddress, createdAt)\n VALUES (?, ?, ?, ?, ?, ?)`;\n\n const result = await QueryBuilder.execute(sql, [\n _id,\n input.apiKeySeed,\n input.name,\n input.collaboratorAddress,\n input.portalAddress,\n now,\n ]);\n\n if (result.changes === 0) {\n throw new Error(\"Failed to create API key\");\n }\n\n const created = await this.findById(_id);\n if (!created) {\n throw new Error(\"Failed to create API key\");\n }\n return created;\n }\n\n static async findById(_id: string): Promise<ApiKey | undefined> {\n const sql = `SELECT _id, apiKeySeed, name, collaboratorAddress, portalAddress, createdAt, isDeleted FROM ${this.TABLE} WHERE _id = ? AND isDeleted = 0`;\n return QueryBuilder.selectOne<ApiKey>(sql, [_id]);\n }\n\n static async findByCollaboratorAddress(collaboratorAddress: string): Promise<ApiKey | undefined> {\n const sql = `SELECT _id, apiKeySeed, name, collaboratorAddress, portalAddress, createdAt, isDeleted FROM ${this.TABLE} WHERE collaboratorAddress = ? AND isDeleted = 0 LIMIT 1`;\n return QueryBuilder.selectOne<ApiKey>(sql, [collaboratorAddress]);\n }\n\n static async delete(_id: string): Promise<void> {\n const sql = `UPDATE ${this.TABLE} SET isDeleted = 1 WHERE _id = ?`;\n await QueryBuilder.execute(sql, [_id]);\n }\n\n static async findByPortalAddress(portalAddress: string): Promise<ApiKey | undefined> {\n const sql = `SELECT _id, apiKeySeed, name, collaboratorAddress, portalAddress, createdAt, isDeleted FROM ${this.TABLE} WHERE portalAddress = ? AND isDeleted = 0`;\n return QueryBuilder.selectOne<ApiKey>(sql, [portalAddress]);\n }\n\n static async findByApiKey(apiKey: string): Promise<ApiKey | undefined> {\n const sql = `SELECT _id, apiKeySeed, name, collaboratorAddress, portalAddress, createdAt, isDeleted FROM ${this.TABLE} WHERE apiKeySeed = ? AND isDeleted = 0`;\n return QueryBuilder.selectOne<ApiKey>(sql, [apiKey]);\n }\n}\n","import { QueryBuilder } from \"../index.js\";\nimport type { File, Folder, FolderWithDDocs, FolderListResponse } from \"../../../types\";\n\nexport type { Folder, FolderWithDDocs, FolderListResponse };\n\nexport class FoldersModel {\n private static readonly TABLE = \"folders\";\n\n static async findAll(limit?: number, skip?: number): Promise<{ folders: Folder[]; total: number; hasNext: boolean }> {\n // Get total count\n const countSql = `SELECT COUNT(*) as count FROM ${this.TABLE} WHERE isDeleted = 0`;\n const totalResult = await QueryBuilder.selectOne<{ count: number }>(countSql);\n const total = totalResult?.count || 0;\n\n // Get paginated results\n const sql = QueryBuilder.paginate(`SELECT * FROM ${this.TABLE} WHERE isDeleted = 0`, {\n limit,\n offset: skip,\n orderBy: \"created_at\",\n orderDirection: \"DESC\",\n });\n\n const foldersRaw = await QueryBuilder.select<any>(sql);\n const folders = foldersRaw.map((folderRaw) => ({\n ...folderRaw,\n isDeleted: Boolean(folderRaw.isDeleted),\n }));\n\n const hasNext = skip !== undefined && limit !== undefined ? skip + limit < total : false;\n\n return { folders, total, hasNext };\n }\n\n static async findByFolderRefAndId(folderRef: string, folderId: string): Promise<FolderWithDDocs | undefined> {\n const sql = `SELECT * FROM ${this.TABLE} WHERE folderRef = ? AND folderId = ? AND isDeleted = 0`;\n const folderRaw = await QueryBuilder.selectOne<any>(sql, [folderRef, folderId]);\n\n if (!folderRaw) {\n return undefined;\n }\n\n const parsedFolder: Folder = {\n ...folderRaw,\n isDeleted: Boolean(folderRaw.isDeleted),\n };\n\n // Get ddocs in this folder\n // Note: FolderRef functionality removed in simplified schema, returning empty array\n const ddocs: File[] = [];\n\n return {\n ...parsedFolder,\n ddocs,\n };\n }\n\n static async findByFolderRef(folderRef: string): Promise<Folder | undefined> {\n const sql = `SELECT * FROM ${this.TABLE} WHERE folderRef = ? AND isDeleted = 0 LIMIT 1`;\n const folderRaw = await QueryBuilder.selectOne<any>(sql, [folderRef]);\n\n if (!folderRaw) {\n return undefined;\n }\n\n return {\n ...folderRaw,\n isDeleted: Boolean(folderRaw.isDeleted),\n };\n }\n\n static async searchByName(searchTerm: string, limit?: number, skip?: number): Promise<Folder[]> {\n const sql = QueryBuilder.paginate(\n `SELECT * FROM ${this.TABLE}\n WHERE isDeleted = 0 AND LOWER(folderName) LIKE LOWER(?)`,\n {\n limit,\n offset: skip,\n orderBy: \"created_at\",\n orderDirection: \"DESC\",\n },\n );\n\n const foldersRaw = await QueryBuilder.select<any>(sql, [`%${searchTerm}%`]);\n return foldersRaw.map((folderRaw) => ({\n ...folderRaw,\n isDeleted: Boolean(folderRaw.isDeleted),\n }));\n }\n\n static async create(input: {\n _id?: string;\n onchainFileId: number;\n folderId: string;\n folderRef: string;\n folderName: string;\n portalAddress: string;\n metadataIPFSHash: string;\n contentIPFSHash: string;\n lastTransactionHash?: string;\n lastTransactionBlockNumber: number;\n lastTransactionBlockTimestamp: number;\n }): Promise<Folder> {\n const _id = input._id || `folder_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n const now = new Date().toISOString();\n\n const sql = `INSERT INTO ${this.TABLE} (\n _id, onchainFileId, folderId, folderRef, folderName, portalAddress, metadataIPFSHash,\n contentIPFSHash, isDeleted, lastTransactionHash, lastTransactionBlockNumber,\n lastTransactionBlockTimestamp, created_at, updated_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`;\n\n await QueryBuilder.execute(sql, [\n _id,\n input.onchainFileId,\n input.folderId,\n input.folderRef,\n input.folderName,\n input.portalAddress,\n input.metadataIPFSHash,\n input.contentIPFSHash,\n 0, // isDeleted\n input.lastTransactionHash || null,\n input.lastTransactionBlockNumber,\n input.lastTransactionBlockTimestamp,\n now,\n now,\n ]);\n\n // Fetch the created folder (without ddocs)\n const selectSql = `SELECT * FROM ${this.TABLE} WHERE folderRef = ? AND folderId = ? AND isDeleted = 0`;\n const folderRaw = await QueryBuilder.selectOne<any>(selectSql, [input.folderRef, input.folderId]);\n\n if (!folderRaw) {\n throw new Error(\"Failed to create folder\");\n }\n\n return {\n ...folderRaw,\n isDeleted: Boolean(folderRaw.isDeleted),\n };\n }\n}\n","import { EventEmitter } from \"events\";\n\nclass WorkerSignal extends EventEmitter {}\n\nconst workerSignal = new WorkerSignal();\nworkerSignal.setMaxListeners(20);\n\nexport function notifyNewEvent(): void {\n workerSignal.emit(\"newEvent\");\n}\n\nexport function onNewEvent(callback: () => void): () => void {\n workerSignal.on(\"newEvent\", callback);\n return () => workerSignal.off(\"newEvent\", callback);\n}\n","import { QueryBuilder } from \"../index.js\";\nimport { uuidv7 } from \"uuidv7\";\nimport { notifyNewEvent } from \"../../worker/workerSignal\";\nimport type { Event, EventType, EventStatus } from \"../../../types\";\n\nexport type { Event, EventType, EventStatus };\n\nconst RETRY_DELAYS_MS = [5000, 30000, 120000];\n\ninterface EventRow {\n _id: string;\n type: string;\n timestamp: number;\n fileId: string;\n portalAddress: string;\n status: string;\n retryCount: number;\n lastError: string | null;\n lockedAt: number | null;\n nextRetryAt: number | null;\n userOpHash?: string | null;\n pendingPayload?: string | null;\n}\n\nexport class EventsModel {\n private static readonly TABLE = \"events\";\n\n static async create(input: { type: EventType; fileId: string; portalAddress: string }): Promise<Event> {\n const _id = uuidv7();\n const timestamp = Date.now();\n const status: EventStatus = \"pending\";\n\n const sql = `\n INSERT INTO ${this.TABLE}\n (_id, type, timestamp, fileId, portalAddress, status, retryCount, lastError, lockedAt, nextRetryAt)\n VALUES (?, ?, ?, ?, ?, ?, 0, NULL, NULL, NULL)\n `;\n\n await QueryBuilder.execute(sql, [_id, input.type, timestamp, input.fileId, input.portalAddress, status]);\n\n notifyNewEvent();\n\n return {\n _id,\n type: input.type,\n timestamp,\n fileId: input.fileId,\n portalAddress: input.portalAddress,\n status,\n retryCount: 0,\n lastError: null,\n lockedAt: null,\n nextRetryAt: null,\n };\n }\n\n static async findById(_id: string): Promise<Event | undefined> {\n const sql = `SELECT * FROM ${this.TABLE} WHERE _id = ?`;\n const row = await QueryBuilder.selectOne<EventRow>(sql, [_id]);\n return row ? this.parseEvent(row) : undefined;\n }\n\n static async findNextPending(): Promise<Event | undefined> {\n const sql = `\n SELECT * FROM ${this.TABLE}\n WHERE status = 'pending'\n ORDER BY timestamp ASC\n LIMIT 1\n `;\n const row = await QueryBuilder.selectOne<EventRow>(sql, []);\n return row ? this.parseEvent(row) : undefined;\n }\n\n static async findNextEligible(lockedFileIds: string[]): Promise<Event | undefined> {\n const now = Date.now();\n\n const exclusionClause =\n lockedFileIds.length > 0 ? `AND e1.fileId NOT IN (${lockedFileIds.map(() => \"?\").join(\", \")})` : \"\";\n\n const sql = `\n SELECT e1.* FROM ${this.TABLE} e1\n WHERE e1.status = 'pending'\n AND (e1.nextRetryAt IS NULL OR e1.nextRetryAt <= ?)\n ${exclusionClause}\n AND NOT EXISTS (\n SELECT 1 FROM ${this.TABLE} e2\n WHERE e2.fileId = e1.fileId\n AND e2.status = 'pending'\n AND e2.timestamp < e1.timestamp\n )\n ORDER BY e1.timestamp ASC\n LIMIT 1\n `;\n\n const params = [now, ...lockedFileIds];\n const row = await QueryBuilder.selectOne<EventRow>(sql, params);\n return row ? this.parseEvent(row) : undefined;\n }\n\n static async markProcessing(_id: string): Promise<void> {\n const sql = `\n UPDATE ${this.TABLE}\n SET status = 'processing',\n lockedAt = ?\n WHERE _id = ?\n `;\n await QueryBuilder.execute(sql, [Date.now(), _id]);\n }\n\n static async markProcessed(_id: string): Promise<void> {\n const sql = `\n UPDATE ${this.TABLE}\n SET status = 'processed',\n lockedAt = NULL\n WHERE _id = ?\n `;\n await QueryBuilder.execute(sql, [_id]);\n }\n\n static async scheduleRetry(_id: string, errorMsg: string): Promise<void> {\n const event = await this.findById(_id);\n if (!event) return;\n\n const delay = RETRY_DELAYS_MS[Math.min(event.retryCount, RETRY_DELAYS_MS.length - 1)];\n const nextRetryAt = Date.now() + delay;\n\n const sql = `\n UPDATE ${this.TABLE}\n SET status = 'pending',\n retryCount = retryCount + 1,\n lastError = ?,\n nextRetryAt = ?,\n lockedAt = NULL\n WHERE _id = ?\n `;\n await QueryBuilder.execute(sql, [errorMsg, nextRetryAt, _id]);\n }\n\n static async scheduleRetryAfter(_id: string, errorMsg: string, retryAfterMs: number): Promise<void> {\n const nextRetryAt = Date.now() + retryAfterMs;\n const sql = `\n UPDATE ${this.TABLE}\n SET status = 'pending',\n lastError = ?,\n nextRetryAt = ?,\n lockedAt = NULL\n WHERE _id = ?\n `;\n await QueryBuilder.execute(sql, [errorMsg, nextRetryAt, _id]);\n }\n\n static async markFailed(_id: string, errorMsg: string): Promise<void> {\n const sql = `\n UPDATE ${this.TABLE}\n SET status = 'failed',\n lastError = ?,\n lockedAt = NULL\n WHERE _id = ?\n `;\n await QueryBuilder.execute(sql, [errorMsg, _id]);\n }\n\n static async listFailed(portalAddress?: string): Promise<Event[]> {\n const portalClause = portalAddress != null ? \"AND portalAddress = ?\" : \"\";\n const sql = `\n SELECT * FROM ${this.TABLE}\n WHERE status = 'failed'\n ${portalClause}\n ORDER BY timestamp ASC\n `;\n const params = portalAddress != null ? [portalAddress] : [];\n const rows = await QueryBuilder.select<EventRow>(sql, params);\n return rows.map((row) => this.parseEvent(row));\n }\n\n static async resetFailedToPending(_id: string, portalAddress?: string): Promise<boolean> {\n const portalClause = portalAddress != null ? \"AND portalAddress = ?\" : \"\";\n const sql = `\n UPDATE ${this.TABLE}\n SET status = 'pending',\n retryCount = 0,\n lastError = NULL,\n nextRetryAt = NULL,\n lockedAt = NULL\n WHERE _id = ?\n AND status = 'failed'\n ${portalClause}\n `;\n const params = portalAddress != null ? [_id, portalAddress] : [_id];\n const result = await QueryBuilder.execute(sql, params);\n if (result.changes > 0) {\n notifyNewEvent();\n }\n return result.changes > 0;\n }\n\n static async resetAllFailedToPending(portalAddress?: string): Promise<number> {\n const portalClause = portalAddress != null ? \"AND portalAddress = ?\" : \"\";\n const sql = `\n UPDATE ${this.TABLE}\n SET status = 'pending',\n retryCount = 0,\n lastError = NULL,\n nextRetryAt = NULL,\n lockedAt = NULL\n WHERE status = 'failed'\n ${portalClause}\n `;\n const params = portalAddress != null ? [portalAddress] : [];\n const result = await QueryBuilder.execute(sql, params);\n if (result.changes > 0) {\n notifyNewEvent();\n }\n return result.changes;\n }\n\n static async resetStaleEvents(staleThreshold: number): Promise<number> {\n const sql = `\n UPDATE ${this.TABLE}\n SET status = 'pending',\n lockedAt = NULL,\n userOpHash = NULL,\n pendingPayload = NULL\n WHERE status = 'processing'\n AND lockedAt IS NOT NULL\n AND lockedAt < ?\n `;\n const result = await QueryBuilder.execute(sql, [staleThreshold]);\n return result.changes;\n }\n\n static async setEventPendingOp(_id: string, userOpHash: string, payload: Record<string, unknown>): Promise<void> {\n const sql = `UPDATE ${this.TABLE} SET userOpHash = ?, pendingPayload = ? WHERE _id = ?`;\n await QueryBuilder.execute(sql, [userOpHash, JSON.stringify(payload), _id]);\n }\n\n static async clearEventPendingOp(_id: string): Promise<void> {\n const sql = `UPDATE ${this.TABLE} SET userOpHash = NULL, pendingPayload = NULL WHERE _id = ?`;\n await QueryBuilder.execute(sql, [_id]);\n }\n\n private static parseEvent(row: EventRow): Event {\n return {\n _id: row._id,\n type: row.type as EventType,\n timestamp: row.timestamp,\n fileId: row.fileId,\n portalAddress: row.portalAddress ?? \"\",\n status: row.status as EventStatus,\n retryCount: row.retryCount,\n lastError: row.lastError,\n lockedAt: row.lockedAt,\n nextRetryAt: row.nextRetryAt,\n userOpHash: row.userOpHash ?? null,\n pendingPayload: row.pendingPayload ?? null,\n };\n }\n}\n","import { type File, FilesModel, type FileListResponse } from \"./files.model\";\nimport { PortalsModel, type Portal } from \"./portals.model\";\nimport { ApiKeysModel, type ApiKey } from \"./apikeys.model\";\nimport { type Folder, type FolderWithDDocs, type FolderListResponse, FoldersModel } from \"./folders.model\";\nimport { EventsModel, type Event, type EventType, type EventStatus } from \"./events.model\";\n\nexport { FilesModel, PortalsModel, ApiKeysModel, FoldersModel, EventsModel };\nexport type {\n File,\n FileListResponse,\n Portal,\n ApiKey,\n Folder,\n FolderWithDDocs,\n FolderListResponse,\n Event,\n EventType,\n EventStatus,\n};\n","import { Hex } from \"viem\";\nimport { eciesDecrypt, eciesEncrypt, generateECKeyPair } from \"@fileverse/crypto/ecies\";\nimport { AuthTokenProvider } from \"./auth-token-provider\";\n\nexport class KeyStore {\n private portalKeySeed: Uint8Array | undefined;\n private portalAddress: Hex | undefined;\n\n constructor(\n seed: Uint8Array,\n address: Hex,\n private readonly authTokenProvider: AuthTokenProvider,\n ) {\n this.portalKeySeed = seed;\n this.portalAddress = address;\n this.authTokenProvider = authTokenProvider;\n }\n\n getPortalAddress() {\n if (!this.portalAddress) {\n throw new Error(\"Portal address is not set\");\n }\n return this.portalAddress;\n }\n\n private getAppEncryptionKey() {\n if (!this.portalKeySeed) {\n throw new Error(\"Portal key seed is not set\");\n }\n\n const keyPair = generateECKeyPair(this.portalKeySeed);\n return keyPair.publicKey;\n }\n\n private getAppDecryptionKey() {\n if (!this.portalKeySeed) {\n throw new Error(\"Portal key seed is not set\");\n }\n\n const keyPair = generateECKeyPair(this.portalKeySeed);\n return keyPair.privateKey;\n }\n\n encryptData(data: Uint8Array) {\n return eciesEncrypt(this.getAppEncryptionKey(), data);\n }\n\n decryptData(data: string) {\n return eciesDecrypt(this.getAppDecryptionKey(), data);\n }\n\n getAuthToken(audienceDid: string) {\n return this.authTokenProvider.getAuthToken(audienceDid);\n }\n}\n","import * as ucans from \"@ucans/ucans\";\nimport type { Hex } from \"viem\";\n\nexport class AuthTokenProvider {\n private readonly DEFAULT_OPTIONS = {\n namespace: \"file\",\n segment: \"CREATE\",\n scheme: \"storage\",\n };\n private keyPair: ucans.EdKeypair;\n portalAddress: Hex;\n constructor(keyPair: ucans.EdKeypair, portalAddress: Hex) {\n this.keyPair = keyPair;\n this.portalAddress = portalAddress;\n }\n\n async getAuthToken(\n audienceDid: string,\n options: { namespace: string; segment: string; scheme: string } = this.DEFAULT_OPTIONS,\n ): Promise<string> {\n const ucan = await ucans.build({\n audience: audienceDid,\n issuer: this.keyPair,\n lifetimeInSeconds: 7 * 86400,\n capabilities: [\n {\n with: {\n scheme: options.scheme,\n hierPart: this.portalAddress.toLocaleLowerCase(),\n },\n can: { namespace: options.namespace, segments: [options.segment] },\n },\n ],\n });\n\n return ucans.encode(ucan);\n }\n}\n","export { sepolia, gnosis } from \"viem/chains\";\n","export const ADDED_FILE_EVENT = [\n {\n anonymous: false,\n inputs: [\n {\n indexed: true,\n internalType: \"uint256\",\n name: \"fileId\",\n type: \"uint256\",\n },\n {\n indexed: false,\n internalType: \"string\",\n name: \"appFileId\",\n type: \"string\",\n },\n {\n indexed: false,\n internalType: \"enum FileverseApp.FileType\",\n name: \"fileType\",\n type: \"uint8\",\n },\n {\n indexed: false,\n internalType: \"string\",\n name: \"metadataIPFSHash\",\n type: \"string\",\n },\n {\n indexed: false,\n internalType: \"string\",\n name: \"contentIPFSHash\",\n type: \"string\",\n },\n {\n indexed: false,\n internalType: \"string\",\n name: \"gateIPFSHash\",\n type: \"string\",\n },\n {\n indexed: false,\n internalType: \"uint256\",\n name: \"version\",\n type: \"uint256\",\n },\n {\n indexed: true,\n internalType: \"address\",\n name: \"by\",\n type: \"address\",\n },\n ],\n name: \"AddedFile\",\n type: \"event\",\n },\n] as const;\n\nexport const EDITED_FILE_EVENT = [\n {\n anonymous: false,\n inputs: [\n {\n indexed: true,\n internalType: \"uint256\",\n name: \"fileId\",\n type: \"uint256\",\n },\n {\n indexed: false,\n internalType: \"string\",\n name: \"appFileId\",\n type: \"string\",\n },\n {\n indexed: false,\n internalType: \"enum FileverseApp.FileType\",\n name: \"fileType\",\n type: \"uint8\",\n },\n {\n indexed: false,\n internalType: \"string\",\n name: \"metadataIPFSHash\",\n type: \"string\",\n },\n {\n indexed: false,\n internalType: \"string\",\n name: \"contentIPFSHash\",\n type: \"string\",\n },\n {\n indexed: false,\n internalType: \"string\",\n name: \"gateIPFSHash\",\n type: \"string\",\n },\n {\n indexed: false,\n internalType: \"uint256\",\n name: \"version\",\n type: \"uint256\",\n },\n {\n indexed: true,\n internalType: \"address\",\n name: \"by\",\n type: \"address\",\n },\n ],\n name: \"EditedFile\",\n type: \"event\",\n },\n] as const;\n\nexport const DELETED_FILE_EVENT = [\n {\n anonymous: false,\n inputs: [\n {\n indexed: true,\n internalType: \"uint256\",\n name: \"fileId\",\n type: \"uint256\",\n },\n {\n indexed: false,\n internalType: \"string\",\n name: \"appFileId\",\n type: \"string\",\n },\n {\n indexed: true,\n internalType: \"address\",\n name: \"by\",\n type: \"address\",\n },\n ],\n name: \"DeletedFile\",\n type: \"event\",\n },\n] as const;\n","export const ADD_FILE_METHOD = [\n {\n inputs: [\n {\n internalType: \"string\",\n name: \"_appFileId\",\n type: \"string\",\n },\n {\n internalType: \"enum FileverseApp.FileType\",\n name: \"fileType\",\n type: \"uint8\",\n },\n {\n internalType: \"string\",\n name: \"_metadataIPFSHash\",\n type: \"string\",\n },\n {\n internalType: \"string\",\n name: \"_contentIPFSHash\",\n type: \"string\",\n },\n {\n internalType: \"string\",\n name: \"_gateIPFSHash\",\n type: \"string\",\n },\n {\n internalType: \"uint256\",\n name: \"version\",\n type: \"uint256\",\n },\n ],\n name: \"addFile\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n] as const;\n\nexport const EDIT_FILE_METHOD = [\n {\n inputs: [\n {\n internalType: \"uint256\",\n name: \"fileId\",\n type: \"uint256\",\n },\n {\n internalType: \"string\",\n name: \"_appFileId\",\n type: \"string\",\n },\n {\n internalType: \"string\",\n name: \"_metadataIPFSHash\",\n type: \"string\",\n },\n {\n internalType: \"string\",\n name: \"_contentIPFSHash\",\n type: \"string\",\n },\n {\n internalType: \"string\",\n name: \"_gateIPFSHash\",\n type: \"string\",\n },\n {\n internalType: \"enum FileverseApp.FileType\",\n name: \"fileType\",\n type: \"uint8\",\n },\n {\n internalType: \"uint256\",\n name: \"version\",\n type: \"uint256\",\n },\n ],\n name: \"editFile\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n] as const;\n\nexport const DELETED_FILE_ABI = [\n {\n inputs: [\n {\n internalType: \"uint256\",\n name: \"fileId\",\n type: \"uint256\",\n },\n ],\n name: \"deleteFile\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n] as const;\n","import { STATIC_CONFIG } from \"../cli/constants\";\nimport { getRuntimeConfig } from \"../config\";\nimport { gnosis, sepolia } from \"./chains\";\n\nexport const NETWORK_NAME = STATIC_CONFIG.NETWORK_NAME;\nexport const UPLOAD_SERVER_URL = STATIC_CONFIG.API_URL;\n\nexport const getRpcUrl = () => getRuntimeConfig().RPC_URL;\nexport const getPimlicoUrl = () => `${STATIC_CONFIG.PIMLICO_PROXY_URL}api/${NETWORK_NAME}/rpc`;\n\nconst CHAIN_MAP = {\n gnosis: gnosis,\n sepolia: sepolia,\n} as const;\n\nexport const CHAIN = CHAIN_MAP[NETWORK_NAME as keyof typeof CHAIN_MAP];\nexport { DELETED_FILE_EVENT, EDITED_FILE_EVENT, ADDED_FILE_EVENT } from \"./events\";\nexport { DELETED_FILE_ABI, EDIT_FILE_METHOD, ADD_FILE_METHOD } from \"./methods\";\n","import { createPublicClient, http, hexToBigInt, toHex, toBytes, type PrivateKeyAccount, type Hex } from \"viem\";\n\nimport { createPimlicoClient } from \"permissionless/clients/pimlico\";\nimport { createSmartAccountClient } from \"permissionless\";\nimport { toSafeSmartAccount } from \"permissionless/accounts\";\nimport { entryPoint07Address } from \"viem/account-abstraction\";\nimport { CHAIN, getRpcUrl, getPimlicoUrl } from \"../constants\";\nimport { generatePrivateKey } from \"viem/accounts\";\n\nexport const getPublicClient = () =>\n createPublicClient({\n transport: http(getRpcUrl(), {\n retryCount: 0,\n }),\n chain: CHAIN,\n });\n\nexport const getPimlicoClient = (authToken: string, portalAddress: Hex, invokerAddress: Hex) =>\n createPimlicoClient({\n transport: http(getPimlicoUrl(), {\n retryCount: 0,\n fetchOptions: {\n headers: {\n Authorization: `Bearer ${authToken}`,\n contract: portalAddress,\n invoker: invokerAddress,\n },\n },\n }),\n entryPoint: {\n address: entryPoint07Address,\n version: \"0.7\",\n },\n });\n\nexport const signerToSmartAccount = async (signer: PrivateKeyAccount) =>\n await toSafeSmartAccount({\n client: getPublicClient(),\n owners: [signer],\n entryPoint: {\n address: entryPoint07Address,\n version: \"0.7\",\n },\n version: \"1.4.1\",\n });\n\nexport const getSmartAccountClient = async (signer: PrivateKeyAccount, authToken: string, portalAddress: Hex) => {\n const smartAccount = await signerToSmartAccount(signer);\n const pimlicoClient = getPimlicoClient(authToken, portalAddress, smartAccount.address);\n\n return createSmartAccountClient({\n account: smartAccount,\n chain: CHAIN,\n paymaster: pimlicoClient,\n bundlerTransport: http(getPimlicoUrl(), {\n fetchOptions: {\n headers: {\n Authorization: `Bearer ${authToken}`,\n contract: portalAddress,\n invoker: smartAccount.address,\n },\n },\n retryCount: 0,\n }),\n userOperation: {\n estimateFeesPerGas: async () => (await pimlicoClient.getUserOperationGasPrice()).fast,\n },\n });\n};\n\nexport const getNonce = () =>\n hexToBigInt(\n toHex(toBytes(generatePrivateKey()).slice(0, 24), {\n size: 32,\n }),\n );\n\nexport const waitForUserOpReceipt = async (\n hash: Hex,\n authToken: string,\n portalAddress: Hex,\n invokerAddress: Hex,\n timeout = 120000,\n) => {\n const pimlicoClient = getPimlicoClient(authToken, portalAddress, invokerAddress);\n return pimlicoClient.waitForUserOperationReceipt({\n hash,\n timeout,\n });\n};\n","import { Hex, toHex } from \"viem\";\nimport { privateKeyToAccount } from \"viem/accounts\";\nimport { getSmartAccountClient, getNonce, waitForUserOpReceipt } from \"./pimlico-utils\";\nimport { AuthTokenProvider } from \"./auth-token-provider\";\nimport { STATIC_CONFIG } from \"../cli/constants\";\nimport { createSmartAccountClient } from \"permissionless\";\nimport type { IExecuteUserOperationRequest } from \"../types\";\n\nexport type { IExecuteUserOperationRequest };\n\nexport class AgentClient {\n private smartAccountAgent: ReturnType<typeof createSmartAccountClient> | null = null;\n private readonly MAX_CALL_GAS_LIMIT = 500000;\n private readonly authOptions: {\n namespace: string;\n segment: string;\n scheme: string;\n } = { namespace: \"proxy\", segment: \"ACCESS\", scheme: \"pimlico\" };\n\n constructor(private readonly authTokenProvider: AuthTokenProvider) {\n this.authTokenProvider = authTokenProvider;\n }\n\n async initializeAgentClient(keyMaterial: Uint8Array) {\n const agentAccount = privateKeyToAccount(toHex(keyMaterial));\n const authToken = await this.authTokenProvider.getAuthToken(STATIC_CONFIG.PROXY_SERVER_DID, this.authOptions);\n const smartAccountClient = await getSmartAccountClient(\n agentAccount,\n authToken,\n this.authTokenProvider.portalAddress,\n );\n this.smartAccountAgent = smartAccountClient;\n }\n\n getSmartAccountAgent() {\n if (!this.smartAccountAgent) throw new Error(\"Agent client not initialized\");\n\n return this.smartAccountAgent;\n }\n\n getAgentAddress() {\n const smartAccountAgent = this.getSmartAccountAgent();\n if (!smartAccountAgent.account) throw new Error(\"Agent account not found\");\n return smartAccountAgent.account.address;\n }\n\n getAgentAccount() {\n const smartAccountAgent = this.getSmartAccountAgent();\n if (!smartAccountAgent.account) throw new Error(\"Agent account not found\");\n return smartAccountAgent.account;\n }\n\n destroyAgentClient() {\n this.smartAccountAgent = null;\n }\n\n async getCallData(request: IExecuteUserOperationRequest | IExecuteUserOperationRequest[]) {\n const agentAccount = this.getAgentAccount();\n if (Array.isArray(request)) {\n if (request.length === 0 || request.length > 10) throw new Error(\"Request length must be between 1 and 10\");\n\n const encodedCallData = request.map((req) => ({\n to: req.contractAddress,\n data: req.data,\n value: BigInt(0),\n }));\n\n return await agentAccount.encodeCalls(encodedCallData);\n }\n\n return await agentAccount.encodeCalls([\n {\n to: request.contractAddress,\n data: request.data,\n value: BigInt(0),\n },\n ]);\n }\n\n async sendUserOperation(\n request: IExecuteUserOperationRequest | IExecuteUserOperationRequest[],\n customGasLimit?: number,\n ) {\n try {\n const smartAccountAgent = this.getSmartAccountAgent();\n\n const callData = await this.getCallData(request);\n\n return await smartAccountAgent.sendUserOperation({\n callData,\n callGasLimit: BigInt(customGasLimit || this.MAX_CALL_GAS_LIMIT),\n nonce: getNonce(),\n });\n } catch (error) {\n throw error;\n }\n }\n\n async executeUserOperationRequest(\n request: IExecuteUserOperationRequest | IExecuteUserOperationRequest[],\n timeout: number,\n customGasLimit?: number,\n ) {\n const userOpHash = await this.sendUserOperation(request, customGasLimit);\n const { authToken, portalAddress, invokerAddress } = await this.getAuthParams();\n const receipt = await waitForUserOpReceipt(userOpHash, authToken, portalAddress, invokerAddress, timeout);\n if (!receipt.success) throw new Error(`Failed to execute user operation: ${receipt.reason}`);\n return receipt;\n }\n\n async getAuthParams(): Promise<{ authToken: string; portalAddress: Hex; invokerAddress: Hex }> {\n const authToken = await this.authTokenProvider.getAuthToken(STATIC_CONFIG.PROXY_SERVER_DID, this.authOptions);\n return {\n authToken,\n portalAddress: this.authTokenProvider.portalAddress,\n invokerAddress: this.getAgentAddress(),\n };\n }\n}\n","/**\n * Utilities for hex, bytes, CSPRNG.\n * @module\n */\n/*! noble-ciphers - MIT License (c) 2023 Paul Miller (paulmillr.com) */\n\n/** Checks if something is Uint8Array. Be careful: nodejs Buffer will return true. */\nexport function isBytes(a: unknown): a is Uint8Array {\n return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');\n}\n\n/** Asserts something is boolean. */\nexport function abool(b: boolean): void {\n if (typeof b !== 'boolean') throw new Error(`boolean expected, not ${b}`);\n}\n\n/** Asserts something is positive integer. */\nexport function anumber(n: number): void {\n if (!Number.isSafeInteger(n) || n < 0) throw new Error('positive integer expected, got ' + n);\n}\n\n/** Asserts something is Uint8Array. */\nexport function abytes(value: Uint8Array, length?: number, title: string = ''): Uint8Array {\n const bytes = isBytes(value);\n const len = value?.length;\n const needsLen = length !== undefined;\n if (!bytes || (needsLen && len !== length)) {\n const prefix = title && `\"${title}\" `;\n const ofLen = needsLen ? ` of length ${length}` : '';\n const got = bytes ? `length=${len}` : `type=${typeof value}`;\n throw new Error(prefix + 'expected Uint8Array' + ofLen + ', got ' + got);\n }\n return value;\n}\n\n/** Asserts a hash instance has not been destroyed / finished */\nexport function aexists(instance: any, checkFinished = true): void {\n if (instance.destroyed) throw new Error('Hash instance has been destroyed');\n if (checkFinished && instance.finished) throw new Error('Hash#digest() has already been called');\n}\n\n/** Asserts output is properly-sized byte array */\nexport function aoutput(out: any, instance: any): void {\n abytes(out, undefined, 'output');\n const min = instance.outputLen;\n if (out.length < min) {\n throw new Error('digestInto() expects output buffer of length at least ' + min);\n }\n}\n\nexport type IHash = {\n (data: string | Uint8Array): Uint8Array;\n blockLen: number;\n outputLen: number;\n create: any;\n};\n\n/** Generic type encompassing 8/16/32-byte arrays - but not 64-byte. */\n// prettier-ignore\nexport type TypedArray = Int8Array | Uint8ClampedArray | Uint8Array |\n Uint16Array | Int16Array | Uint32Array | Int32Array;\n\n/** Cast u8 / u16 / u32 to u8. */\nexport function u8(arr: TypedArray): Uint8Array {\n return new Uint8Array(arr.buffer, arr.byteOffset, arr.byteLength);\n}\n\n/** Cast u8 / u16 / u32 to u32. */\nexport function u32(arr: TypedArray): Uint32Array {\n return new Uint32Array(arr.buffer, arr.byteOffset, Math.floor(arr.byteLength / 4));\n}\n\n/** Zeroize a byte array. Warning: JS provides no guarantees. */\nexport function clean(...arrays: TypedArray[]): void {\n for (let i = 0; i < arrays.length; i++) {\n arrays[i].fill(0);\n }\n}\n\n/** Create DataView of an array for easy byte-level manipulation. */\nexport function createView(arr: TypedArray): DataView {\n return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);\n}\n\n/** Is current platform little-endian? Most are. Big-Endian platform: IBM */\nexport const isLE: boolean = /* @__PURE__ */ (() =>\n new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44)();\n\n// Built-in hex conversion https://caniuse.com/mdn-javascript_builtins_uint8array_fromhex\nconst hasHexBuiltin: boolean = /* @__PURE__ */ (() =>\n // @ts-ignore\n typeof Uint8Array.from([]).toHex === 'function' && typeof Uint8Array.fromHex === 'function')();\n\n// Array where index 0xf0 (240) is mapped to string 'f0'\nconst hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) =>\n i.toString(16).padStart(2, '0')\n);\n\n/**\n * Convert byte array to hex string. Uses built-in function, when available.\n * @example bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])) // 'cafe0123'\n */\nexport function bytesToHex(bytes: Uint8Array): string {\n abytes(bytes);\n // @ts-ignore\n if (hasHexBuiltin) return bytes.toHex();\n // pre-caching improves the speed 6x\n let hex = '';\n for (let i = 0; i < bytes.length; i++) {\n hex += hexes[bytes[i]];\n }\n return hex;\n}\n\n// We use optimized technique to convert hex string to byte array\nconst asciis = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 } as const;\nfunction asciiToBase16(ch: number): number | undefined {\n if (ch >= asciis._0 && ch <= asciis._9) return ch - asciis._0; // '2' => 50-48\n if (ch >= asciis.A && ch <= asciis.F) return ch - (asciis.A - 10); // 'B' => 66-(65-10)\n if (ch >= asciis.a && ch <= asciis.f) return ch - (asciis.a - 10); // 'b' => 98-(97-10)\n return;\n}\n\n/**\n * Convert hex string to byte array. Uses built-in function, when available.\n * @example hexToBytes('cafe0123') // Uint8Array.from([0xca, 0xfe, 0x01, 0x23])\n */\nexport function hexToBytes(hex: string): Uint8Array {\n if (typeof hex !== 'string') throw new Error('hex string expected, got ' + typeof hex);\n // @ts-ignore\n if (hasHexBuiltin) return Uint8Array.fromHex(hex);\n const hl = hex.length;\n const al = hl / 2;\n if (hl % 2) throw new Error('hex string expected, got unpadded hex of length ' + hl);\n const array = new Uint8Array(al);\n for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) {\n const n1 = asciiToBase16(hex.charCodeAt(hi));\n const n2 = asciiToBase16(hex.charCodeAt(hi + 1));\n if (n1 === undefined || n2 === undefined) {\n const char = hex[hi] + hex[hi + 1];\n throw new Error('hex string expected, got non-hex character \"' + char + '\" at index ' + hi);\n }\n array[ai] = n1 * 16 + n2; // multiply first octet, e.g. 'a3' => 10*16+3 => 160 + 3 => 163\n }\n return array;\n}\n\n// Used in micro\nexport function hexToNumber(hex: string): bigint {\n if (typeof hex !== 'string') throw new Error('hex string expected, got ' + typeof hex);\n return BigInt(hex === '' ? '0' : '0x' + hex); // Big Endian\n}\n\n// Used in ff1\n// BE: Big Endian, LE: Little Endian\nexport function bytesToNumberBE(bytes: Uint8Array): bigint {\n return hexToNumber(bytesToHex(bytes));\n}\n\n// Used in micro, ff1\nexport function numberToBytesBE(n: number | bigint, len: number): Uint8Array {\n return hexToBytes(n.toString(16).padStart(len * 2, '0'));\n}\n\n// Global symbols, but ts doesn't see them: https://github.com/microsoft/TypeScript/issues/31535\ndeclare const TextEncoder: any;\ndeclare const TextDecoder: any;\n\n/**\n * Converts string to bytes using UTF8 encoding.\n * @example utf8ToBytes('abc') // new Uint8Array([97, 98, 99])\n */\nexport function utf8ToBytes(str: string): Uint8Array {\n if (typeof str !== 'string') throw new Error('string expected');\n return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809\n}\n\n/**\n * Converts bytes to string using UTF8 encoding.\n * @example bytesToUtf8(new Uint8Array([97, 98, 99])) // 'abc'\n */\nexport function bytesToUtf8(bytes: Uint8Array): string {\n return new TextDecoder().decode(bytes);\n}\n\n/**\n * Checks if two U8A use same underlying buffer and overlaps.\n * This is invalid and can corrupt data.\n */\nexport function overlapBytes(a: Uint8Array, b: Uint8Array): boolean {\n return (\n a.buffer === b.buffer && // best we can do, may fail with an obscure Proxy\n a.byteOffset < b.byteOffset + b.byteLength && // a starts before b end\n b.byteOffset < a.byteOffset + a.byteLength // b starts before a end\n );\n}\n\n/**\n * If input and output overlap and input starts before output, we will overwrite end of input before\n * we start processing it, so this is not supported for most ciphers (except chacha/salse, which designed with this)\n */\nexport function complexOverlapBytes(input: Uint8Array, output: Uint8Array): void {\n // This is very cursed. It works somehow, but I'm completely unsure,\n // reasoning about overlapping aligned windows is very hard.\n if (overlapBytes(input, output) && input.byteOffset < output.byteOffset)\n throw new Error('complex overlap of input and output is not supported');\n}\n\n/**\n * Copies several Uint8Arrays into one.\n */\nexport function concatBytes(...arrays: Uint8Array[]): Uint8Array {\n let sum = 0;\n for (let i = 0; i < arrays.length; i++) {\n const a = arrays[i];\n abytes(a);\n sum += a.length;\n }\n const res = new Uint8Array(sum);\n for (let i = 0, pad = 0; i < arrays.length; i++) {\n const a = arrays[i];\n res.set(a, pad);\n pad += a.length;\n }\n return res;\n}\n\n// Used in ARX only\ntype EmptyObj = {};\nexport function checkOpts<T1 extends EmptyObj, T2 extends EmptyObj>(\n defaults: T1,\n opts: T2\n): T1 & T2 {\n if (opts == null || typeof opts !== 'object') throw new Error('options must be defined');\n const merged = Object.assign(defaults, opts);\n return merged as T1 & T2;\n}\n\n/** Compares 2 uint8array-s in kinda constant time. */\nexport function equalBytes(a: Uint8Array, b: Uint8Array): boolean {\n if (a.length !== b.length) return false;\n let diff = 0;\n for (let i = 0; i < a.length; i++) diff |= a[i] ^ b[i];\n return diff === 0;\n}\n\n// TODO: remove\nexport interface IHash2 {\n blockLen: number; // Bytes per block\n outputLen: number; // Bytes in output\n update(buf: string | Uint8Array): this;\n // Writes digest into buf\n digestInto(buf: Uint8Array): void;\n digest(): Uint8Array;\n /**\n * Resets internal state. Makes Hash instance unusable.\n * Reset is impossible for keyed hashes if key is consumed into state. If digest is not consumed\n * by user, they will need to manually call `destroy()` when zeroing is necessary.\n */\n destroy(): void;\n}\n\n// This will allow to re-use with composable things like packed & base encoders\n// Also, we probably can make tags composable\n\n/** Sync cipher: takes byte array and returns byte array. */\nexport type Cipher = {\n encrypt(plaintext: Uint8Array): Uint8Array;\n decrypt(ciphertext: Uint8Array): Uint8Array;\n};\n\n/** Async cipher e.g. from built-in WebCrypto. */\nexport type AsyncCipher = {\n encrypt(plaintext: Uint8Array): Promise<Uint8Array>;\n decrypt(ciphertext: Uint8Array): Promise<Uint8Array>;\n};\n\n/** Cipher with `output` argument which can optimize by doing 1 less allocation. */\nexport type CipherWithOutput = Cipher & {\n encrypt(plaintext: Uint8Array, output?: Uint8Array): Uint8Array;\n decrypt(ciphertext: Uint8Array, output?: Uint8Array): Uint8Array;\n};\n\n/**\n * Params are outside of return type, so it is accessible before calling constructor.\n * If function support multiple nonceLength's, we return the best one.\n */\nexport type CipherParams = {\n blockSize: number;\n nonceLength?: number;\n tagLength?: number;\n varSizeNonce?: boolean;\n};\n/** ARX cipher, like salsa or chacha. */\nexport type ARXCipher = ((\n key: Uint8Array,\n nonce: Uint8Array,\n AAD?: Uint8Array\n) => CipherWithOutput) & {\n blockSize: number;\n nonceLength: number;\n tagLength: number;\n};\nexport type CipherCons<T extends any[]> = (key: Uint8Array, ...args: T) => Cipher;\n/**\n * Wraps a cipher: validates args, ensures encrypt() can only be called once.\n * @__NO_SIDE_EFFECTS__\n */\nexport const wrapCipher = <C extends CipherCons<any>, P extends CipherParams>(\n params: P,\n constructor: C\n): C & P => {\n function wrappedCipher(key: Uint8Array, ...args: any[]): CipherWithOutput {\n // Validate key\n abytes(key, undefined, 'key');\n\n // Big-Endian hardware is rare. Just in case someone still decides to run ciphers:\n if (!isLE) throw new Error('Non little-endian hardware is not yet supported');\n\n // Validate nonce if nonceLength is present\n if (params.nonceLength !== undefined) {\n const nonce = args[0];\n abytes(nonce, params.varSizeNonce ? undefined : params.nonceLength, 'nonce');\n }\n\n // Validate AAD if tagLength present\n const tagl = params.tagLength;\n if (tagl && args[1] !== undefined) abytes(args[1], undefined, 'AAD');\n\n const cipher = constructor(key, ...args);\n const checkOutput = (fnLength: number, output?: Uint8Array) => {\n if (output !== undefined) {\n if (fnLength !== 2) throw new Error('cipher output not supported');\n abytes(output, undefined, 'output');\n }\n };\n // Create wrapped cipher with validation and single-use encryption\n let called = false;\n const wrCipher = {\n encrypt(data: Uint8Array, output?: Uint8Array) {\n if (called) throw new Error('cannot encrypt() twice with same key + nonce');\n called = true;\n abytes(data);\n checkOutput(cipher.encrypt.length, output);\n return (cipher as CipherWithOutput).encrypt(data, output);\n },\n decrypt(data: Uint8Array, output?: Uint8Array) {\n abytes(data);\n if (tagl && data.length < tagl)\n throw new Error('\"ciphertext\" expected length bigger than tagLength=' + tagl);\n checkOutput(cipher.decrypt.length, output);\n return (cipher as CipherWithOutput).decrypt(data, output);\n },\n };\n\n return wrCipher;\n }\n\n Object.assign(wrappedCipher, params);\n return wrappedCipher as C & P;\n};\n\n/** Represents salsa / chacha stream. */\nexport type XorStream = (\n key: Uint8Array,\n nonce: Uint8Array,\n data: Uint8Array,\n output?: Uint8Array,\n counter?: number\n) => Uint8Array;\n\n/**\n * By default, returns u8a of length.\n * When out is available, it checks it for validity and uses it.\n */\nexport function getOutput(\n expectedLength: number,\n out?: Uint8Array,\n onlyAligned = true\n): Uint8Array {\n if (out === undefined) return new Uint8Array(expectedLength);\n if (out.length !== expectedLength)\n throw new Error(\n '\"output\" expected Uint8Array of length ' + expectedLength + ', got: ' + out.length\n );\n if (onlyAligned && !isAligned32(out)) throw new Error('invalid output, must be aligned');\n return out;\n}\n\nexport function u64Lengths(dataLength: number, aadLength: number, isLE: boolean): Uint8Array {\n abool(isLE);\n const num = new Uint8Array(16);\n const view = createView(num);\n view.setBigUint64(0, BigInt(aadLength), isLE);\n view.setBigUint64(8, BigInt(dataLength), isLE);\n return num;\n}\n\n// Is byte array aligned to 4 byte offset (u32)?\nexport function isAligned32(bytes: Uint8Array): boolean {\n return bytes.byteOffset % 4 === 0;\n}\n\n// copy bytes to new u8a (aligned). Because Buffer.slice is broken.\nexport function copyBytes(bytes: Uint8Array): Uint8Array {\n return Uint8Array.from(bytes);\n}\n\n/** Cryptographically secure PRNG. Uses internal OS-level `crypto.getRandomValues`. */\nexport function randomBytes(bytesLength = 32): Uint8Array {\n const cr = typeof globalThis === 'object' ? (globalThis as any).crypto : null;\n if (typeof cr?.getRandomValues !== 'function')\n throw new Error('crypto.getRandomValues must be defined');\n return cr.getRandomValues(new Uint8Array(bytesLength));\n}\n\n/**\n * The pseudorandom number generator doesn't wipe current state:\n * instead, it generates new one based on previous state + entropy.\n * Not reseed/rekey, since AES CTR DRBG does rekey on each randomBytes,\n * which is in fact `reseed`, since it changes counter too.\n */\nexport interface PRG {\n addEntropy(seed: Uint8Array): void;\n randomBytes(length: number): Uint8Array;\n clean(): void;\n}\n\ntype RemoveNonceInner<T extends any[], Ret> = ((...args: T) => Ret) extends (\n arg0: any,\n arg1: any,\n ...rest: infer R\n) => any\n ? (key: Uint8Array, ...args: R) => Ret\n : never;\n\nexport type RemoveNonce<T extends (...args: any) => any> = RemoveNonceInner<\n Parameters<T>,\n ReturnType<T>\n>;\nexport type CipherWithNonce = ((\n key: Uint8Array,\n nonce: Uint8Array,\n ...args: any[]\n) => Cipher | AsyncCipher) & {\n nonceLength: number;\n};\n\n/**\n * Uses CSPRG for nonce, nonce injected in ciphertext.\n * For `encrypt`, a `nonceBytes`-length buffer is fetched from CSPRNG and\n * prepended to encrypted ciphertext. For `decrypt`, first `nonceBytes` of ciphertext\n * are treated as nonce.\n *\n * NOTE: Under the same key, using random nonces (e.g. `managedNonce`) with AES-GCM and ChaCha\n * should be limited to `2**23` (8M) messages to get a collision chance of `2**-50`. Stretching to * `2**32` (4B) messages, chance would become `2**-33` - still negligible, but creeping up.\n * @example\n * const gcm = managedNonce(aes.gcm);\n * const ciphr = gcm(key).encrypt(data);\n * const plain = gcm(key).decrypt(ciph);\n */\nexport function managedNonce<T extends CipherWithNonce>(\n fn: T,\n randomBytes_: typeof randomBytes = randomBytes\n): RemoveNonce<T> {\n const { nonceLength } = fn;\n anumber(nonceLength);\n const addNonce = (nonce: Uint8Array, ciphertext: Uint8Array) => {\n const out = concatBytes(nonce, ciphertext);\n ciphertext.fill(0);\n return out;\n };\n // NOTE: we cannot support DST here, it would be mistake:\n // - we don't know how much dst length cipher requires\n // - nonce may unalign dst and break everything\n // - we create new u8a anyway (concatBytes)\n // - previously we passed all args to cipher, but that was mistake!\n return ((key: Uint8Array, ...args: any[]): any => ({\n encrypt(plaintext: Uint8Array) {\n abytes(plaintext);\n const nonce = randomBytes_(nonceLength);\n const encrypted = fn(key, nonce, ...args).encrypt(plaintext);\n // @ts-ignore\n if (encrypted instanceof Promise) return encrypted.then((ct) => addNonce(nonce, ct));\n return addNonce(nonce, encrypted);\n },\n decrypt(ciphertext: Uint8Array) {\n abytes(ciphertext);\n const nonce = ciphertext.subarray(0, nonceLength);\n const decrypted = ciphertext.subarray(nonceLength);\n return fn(key, nonce, ...args).decrypt(decrypted);\n },\n })) as RemoveNonce<T>;\n}\n\n// workaround for TS 5.9 language mess:\nexport type Uint8ArrayBuffer = ReturnType<typeof Uint8Array.of>;\n","/**\n * GHash from AES-GCM and its little-endian \"mirror image\" Polyval from AES-SIV.\n *\n * Implemented in terms of GHash with conversion function for keys\n * GCM GHASH from\n * [NIST SP800-38d](https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf),\n * SIV from\n * [RFC 8452](https://www.rfc-editor.org/rfc/rfc8452).\n *\n * GHASH modulo: x^128 + x^7 + x^2 + x + 1\n * POLYVAL modulo: x^128 + x^127 + x^126 + x^121 + 1\n *\n * @module\n */\nimport {\n abytes,\n aexists,\n aoutput,\n clean,\n copyBytes,\n createView,\n u32,\n type IHash2,\n} from './utils.ts';\n\nconst BLOCK_SIZE = 16;\n// TODO: rewrite\n// temporary padding buffer\nconst ZEROS16 = /* @__PURE__ */ new Uint8Array(16);\nconst ZEROS32 = u32(ZEROS16);\nconst POLY = 0xe1; // v = 2*v % POLY\n\n// v = 2*v % POLY\n// NOTE: because x + x = 0 (add/sub is same), mul2(x) != x+x\n// We can multiply any number using montgomery ladder and this function (works as double, add is simple xor)\nconst mul2 = (s0: number, s1: number, s2: number, s3: number) => {\n const hiBit = s3 & 1;\n return {\n s3: (s2 << 31) | (s3 >>> 1),\n s2: (s1 << 31) | (s2 >>> 1),\n s1: (s0 << 31) | (s1 >>> 1),\n s0: (s0 >>> 1) ^ ((POLY << 24) & -(hiBit & 1)), // reduce % poly\n };\n};\n\nconst swapLE = (n: number) =>\n (((n >>> 0) & 0xff) << 24) |\n (((n >>> 8) & 0xff) << 16) |\n (((n >>> 16) & 0xff) << 8) |\n ((n >>> 24) & 0xff) |\n 0;\n\n/**\n * `mulX_POLYVAL(ByteReverse(H))` from spec\n * @param k mutated in place\n */\nexport function _toGHASHKey(k: Uint8Array): Uint8Array {\n k.reverse();\n const hiBit = k[15] & 1;\n // k >>= 1\n let carry = 0;\n for (let i = 0; i < k.length; i++) {\n const t = k[i];\n k[i] = (t >>> 1) | carry;\n carry = (t & 1) << 7;\n }\n k[0] ^= -hiBit & 0xe1; // if (hiBit) n ^= 0xe1000000000000000000000000000000;\n return k;\n}\n\ntype Value = { s0: number; s1: number; s2: number; s3: number };\n\nconst estimateWindow = (bytes: number) => {\n if (bytes > 64 * 1024) return 8;\n if (bytes > 1024) return 4;\n return 2;\n};\n\nexport class GHASH implements IHash2 {\n readonly blockLen: number = BLOCK_SIZE;\n readonly outputLen: number = BLOCK_SIZE;\n protected s0 = 0;\n protected s1 = 0;\n protected s2 = 0;\n protected s3 = 0;\n protected finished = false;\n protected t: Value[];\n private W: number;\n private windowSize: number;\n // We select bits per window adaptively based on expectedLength\n constructor(key: Uint8Array, expectedLength?: number) {\n abytes(key, 16, 'key');\n key = copyBytes(key);\n const kView = createView(key);\n let k0 = kView.getUint32(0, false);\n let k1 = kView.getUint32(4, false);\n let k2 = kView.getUint32(8, false);\n let k3 = kView.getUint32(12, false);\n // generate table of doubled keys (half of montgomery ladder)\n const doubles: Value[] = [];\n for (let i = 0; i < 128; i++) {\n doubles.push({ s0: swapLE(k0), s1: swapLE(k1), s2: swapLE(k2), s3: swapLE(k3) });\n ({ s0: k0, s1: k1, s2: k2, s3: k3 } = mul2(k0, k1, k2, k3));\n }\n const W = estimateWindow(expectedLength || 1024);\n if (![1, 2, 4, 8].includes(W))\n throw new Error('ghash: invalid window size, expected 2, 4 or 8');\n this.W = W;\n const bits = 128; // always 128 bits;\n const windows = bits / W;\n const windowSize = (this.windowSize = 2 ** W);\n const items: Value[] = [];\n // Create precompute table for window of W bits\n for (let w = 0; w < windows; w++) {\n // truth table: 00, 01, 10, 11\n for (let byte = 0; byte < windowSize; byte++) {\n // prettier-ignore\n let s0 = 0, s1 = 0, s2 = 0, s3 = 0;\n for (let j = 0; j < W; j++) {\n const bit = (byte >>> (W - j - 1)) & 1;\n if (!bit) continue;\n const { s0: d0, s1: d1, s2: d2, s3: d3 } = doubles[W * w + j];\n ((s0 ^= d0), (s1 ^= d1), (s2 ^= d2), (s3 ^= d3));\n }\n items.push({ s0, s1, s2, s3 });\n }\n }\n this.t = items;\n }\n protected _updateBlock(s0: number, s1: number, s2: number, s3: number): void {\n ((s0 ^= this.s0), (s1 ^= this.s1), (s2 ^= this.s2), (s3 ^= this.s3));\n const { W, t, windowSize } = this;\n // prettier-ignore\n let o0 = 0, o1 = 0, o2 = 0, o3 = 0;\n const mask = (1 << W) - 1; // 2**W will kill performance.\n let w = 0;\n for (const num of [s0, s1, s2, s3]) {\n for (let bytePos = 0; bytePos < 4; bytePos++) {\n const byte = (num >>> (8 * bytePos)) & 0xff;\n for (let bitPos = 8 / W - 1; bitPos >= 0; bitPos--) {\n const bit = (byte >>> (W * bitPos)) & mask;\n const { s0: e0, s1: e1, s2: e2, s3: e3 } = t[w * windowSize + bit];\n ((o0 ^= e0), (o1 ^= e1), (o2 ^= e2), (o3 ^= e3));\n w += 1;\n }\n }\n }\n this.s0 = o0;\n this.s1 = o1;\n this.s2 = o2;\n this.s3 = o3;\n }\n update(data: Uint8Array): this {\n aexists(this);\n abytes(data);\n data = copyBytes(data);\n const b32 = u32(data);\n const blocks = Math.floor(data.length / BLOCK_SIZE);\n const left = data.length % BLOCK_SIZE;\n for (let i = 0; i < blocks; i++) {\n this._updateBlock(b32[i * 4 + 0], b32[i * 4 + 1], b32[i * 4 + 2], b32[i * 4 + 3]);\n }\n if (left) {\n ZEROS16.set(data.subarray(blocks * BLOCK_SIZE));\n this._updateBlock(ZEROS32[0], ZEROS32[1], ZEROS32[2], ZEROS32[3]);\n clean(ZEROS32); // clean tmp buffer\n }\n return this;\n }\n destroy(): void {\n const { t } = this;\n // clean precompute table\n for (const elm of t) {\n ((elm.s0 = 0), (elm.s1 = 0), (elm.s2 = 0), (elm.s3 = 0));\n }\n }\n digestInto(out: Uint8Array): Uint8Array {\n aexists(this);\n aoutput(out, this);\n this.finished = true;\n const { s0, s1, s2, s3 } = this;\n const o32 = u32(out);\n o32[0] = s0;\n o32[1] = s1;\n o32[2] = s2;\n o32[3] = s3;\n return out;\n }\n digest(): Uint8Array {\n const res = new Uint8Array(BLOCK_SIZE);\n this.digestInto(res);\n this.destroy();\n return res;\n }\n}\n\nexport class Polyval extends GHASH {\n constructor(key: Uint8Array, expectedLength?: number) {\n abytes(key);\n const ghKey = _toGHASHKey(copyBytes(key));\n super(ghKey, expectedLength);\n clean(ghKey);\n }\n update(data: Uint8Array): this {\n aexists(this);\n abytes(data);\n data = copyBytes(data);\n const b32 = u32(data);\n const left = data.length % BLOCK_SIZE;\n const blocks = Math.floor(data.length / BLOCK_SIZE);\n for (let i = 0; i < blocks; i++) {\n this._updateBlock(\n swapLE(b32[i * 4 + 3]),\n swapLE(b32[i * 4 + 2]),\n swapLE(b32[i * 4 + 1]),\n swapLE(b32[i * 4 + 0])\n );\n }\n if (left) {\n ZEROS16.set(data.subarray(blocks * BLOCK_SIZE));\n this._updateBlock(\n swapLE(ZEROS32[3]),\n swapLE(ZEROS32[2]),\n swapLE(ZEROS32[1]),\n swapLE(ZEROS32[0])\n );\n clean(ZEROS32);\n }\n return this;\n }\n digestInto(out: Uint8Array): Uint8Array {\n aexists(this);\n aoutput(out, this);\n this.finished = true;\n // tmp ugly hack\n const { s0, s1, s2, s3 } = this;\n const o32 = u32(out);\n o32[0] = s0;\n o32[1] = s1;\n o32[2] = s2;\n o32[3] = s3;\n return out.reverse();\n }\n}\n\nexport type CHashPV = ReturnType<typeof wrapConstructorWithKey>;\nfunction wrapConstructorWithKey<H extends IHash2>(\n hashCons: (key: Uint8Array, expectedLength?: number) => H\n): {\n (msg: Uint8Array, key: Uint8Array): Uint8Array;\n outputLen: number;\n blockLen: number;\n create(key: Uint8Array, expectedLength?: number): H;\n} {\n const hashC = (msg: Uint8Array, key: Uint8Array): Uint8Array =>\n hashCons(key, msg.length).update(msg).digest();\n const tmp = hashCons(new Uint8Array(16), 0);\n hashC.outputLen = tmp.outputLen;\n hashC.blockLen = tmp.blockLen;\n hashC.create = (key: Uint8Array, expectedLength?: number) => hashCons(key, expectedLength);\n return hashC;\n}\n\n/** GHash MAC for AES-GCM. */\nexport const ghash: CHashPV = wrapConstructorWithKey(\n (key, expectedLength) => new GHASH(key, expectedLength)\n);\n\n/** Polyval MAC for AES-SIV. */\nexport const polyval: CHashPV = wrapConstructorWithKey(\n (key, expectedLength) => new Polyval(key, expectedLength)\n);\n","/**\n * [AES](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard)\n * a.k.a. Advanced Encryption Standard\n * is a variant of Rijndael block cipher, standardized by NIST in 2001.\n * We provide the fastest available pure JS implementation.\n *\n * `cipher = encrypt(block, key)`\n *\n * Data is split into 128-bit blocks. Encrypted in 10/12/14 rounds (128/192/256 bits). In every round:\n * 1. **S-box**, table substitution\n * 2. **Shift rows**, cyclic shift left of all rows of data array\n * 3. **Mix columns**, multiplying every column by fixed polynomial\n * 4. **Add round key**, round_key xor i-th column of array\n *\n * Check out [FIPS-197](https://csrc.nist.gov/files/pubs/fips/197/final/docs/fips-197.pdf),\n * [NIST 800-38G](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38G.pdf)\n * and [original proposal](https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/aes-development/rijndael-ammended.pdf)\n * @module\n */\nimport { ghash, polyval } from './_polyval.ts';\n// prettier-ignore\nimport {\n abytes, anumber, clean, complexOverlapBytes, concatBytes,\n copyBytes, createView, equalBytes, getOutput, isAligned32, overlapBytes,\n u32, u64Lengths, u8, wrapCipher,\n type Cipher, type CipherWithOutput, type PRG, type Uint8ArrayBuffer\n} from './utils.ts';\n\nconst BLOCK_SIZE = 16;\nconst BLOCK_SIZE32 = 4;\nconst EMPTY_BLOCK = /* @__PURE__ */ new Uint8Array(BLOCK_SIZE);\nconst ONE_BLOCK = /* @__PURE__ */ Uint8Array.from([\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,\n]);\nconst POLY = 0x11b; // 1 + x + x**3 + x**4 + x**8\n\nfunction validateKeyLength(key: Uint8Array) {\n if (![16, 24, 32].includes(key.length))\n throw new Error('\"aes key\" expected Uint8Array of length 16/24/32, got length=' + key.length);\n}\n\n// TODO: remove multiplication, binary ops only\nfunction mul2(n: number) {\n return (n << 1) ^ (POLY & -(n >> 7));\n}\n\nfunction mul(a: number, b: number) {\n let res = 0;\n for (; b > 0; b >>= 1) {\n // Montgomery ladder\n res ^= a & -(b & 1); // if (b&1) res ^=a (but const-time).\n a = mul2(a); // a = 2*a\n }\n return res;\n}\n\n// Increments bigint with wrap around\n// NOTE: we cannot use u32 here since it may overflow on carry!\nconst incBytes = (data: Uint8Array, isLE: boolean, carry: number = 1) => {\n if (!Number.isSafeInteger(carry)) throw new Error('incBytes: wrong carry ' + carry);\n abytes(data);\n for (let i = 0; i < data.length; i++) {\n const pos = !isLE ? data.length - 1 - i : i;\n carry = (carry + (data[pos] & 0xff)) | 0;\n data[pos] = carry & 0xff;\n carry >>>= 8;\n }\n};\n\n// AES S-box is generated using finite field inversion,\n// an affine transform, and xor of a constant 0x63.\nconst sbox = /* @__PURE__ */ (() => {\n const t = new Uint8Array(256);\n for (let i = 0, x = 1; i < 256; i++, x ^= mul2(x)) t[i] = x;\n const box = new Uint8Array(256);\n box[0] = 0x63; // first elm\n for (let i = 0; i < 255; i++) {\n let x = t[255 - i];\n x |= x << 8;\n box[t[i]] = (x ^ (x >> 4) ^ (x >> 5) ^ (x >> 6) ^ (x >> 7) ^ 0x63) & 0xff;\n }\n clean(t);\n return box;\n})();\n\n// Inverted S-box\nconst invSbox = /* @__PURE__ */ sbox.map((_, j) => sbox.indexOf(j));\n\n// Rotate u32 by 8\nconst rotr32_8 = (n: number) => (n << 24) | (n >>> 8);\nconst rotl32_8 = (n: number) => (n << 8) | (n >>> 24);\n// The byte swap operation for uint32 (LE<->BE)\nconst byteSwap = (word: number) =>\n ((word << 24) & 0xff000000) |\n ((word << 8) & 0xff0000) |\n ((word >>> 8) & 0xff00) |\n ((word >>> 24) & 0xff);\n\n// T-table is optimization suggested in 5.2 of original proposal (missed from FIPS-197). Changes:\n// - LE instead of BE\n// - bigger tables: T0 and T1 are merged into T01 table and T2 & T3 into T23;\n// so index is u16, instead of u8. This speeds up things, unexpectedly\nfunction genTtable(sbox: Uint8Array, fn: (n: number) => number) {\n if (sbox.length !== 256) throw new Error('Wrong sbox length');\n const T0 = new Uint32Array(256).map((_, j) => fn(sbox[j]));\n const T1 = T0.map(rotl32_8);\n const T2 = T1.map(rotl32_8);\n const T3 = T2.map(rotl32_8);\n const T01 = new Uint32Array(256 * 256);\n const T23 = new Uint32Array(256 * 256);\n const sbox2 = new Uint16Array(256 * 256);\n for (let i = 0; i < 256; i++) {\n for (let j = 0; j < 256; j++) {\n const idx = i * 256 + j;\n T01[idx] = T0[i] ^ T1[j];\n T23[idx] = T2[i] ^ T3[j];\n sbox2[idx] = (sbox[i] << 8) | sbox[j];\n }\n }\n return { sbox, sbox2, T0, T1, T2, T3, T01, T23 };\n}\n\nconst tableEncoding = /* @__PURE__ */ genTtable(\n sbox,\n (s: number) => (mul(s, 3) << 24) | (s << 16) | (s << 8) | mul(s, 2)\n);\nconst tableDecoding = /* @__PURE__ */ genTtable(\n invSbox,\n (s) => (mul(s, 11) << 24) | (mul(s, 13) << 16) | (mul(s, 9) << 8) | mul(s, 14)\n);\n\nconst xPowers = /* @__PURE__ */ (() => {\n const p = new Uint8Array(16);\n for (let i = 0, x = 1; i < 16; i++, x = mul2(x)) p[i] = x;\n return p;\n})();\n\n/** Key expansion used in CTR. */\nfunction expandKeyLE(key: Uint8Array): Uint32Array {\n abytes(key);\n const len = key.length;\n validateKeyLength(key);\n const { sbox2 } = tableEncoding;\n const toClean = [];\n if (!isAligned32(key)) toClean.push((key = copyBytes(key)));\n const k32 = u32(key);\n const Nk = k32.length;\n const subByte = (n: number) => applySbox(sbox2, n, n, n, n);\n const xk = new Uint32Array(len + 28); // expanded key\n xk.set(k32);\n // 4.3.1 Key expansion\n for (let i = Nk; i < xk.length; i++) {\n let t = xk[i - 1];\n if (i % Nk === 0) t = subByte(rotr32_8(t)) ^ xPowers[i / Nk - 1];\n else if (Nk > 6 && i % Nk === 4) t = subByte(t);\n xk[i] = xk[i - Nk] ^ t;\n }\n clean(...toClean);\n return xk;\n}\n\nfunction expandKeyDecLE(key: Uint8Array): Uint32Array {\n const encKey = expandKeyLE(key);\n const xk = encKey.slice();\n const Nk = encKey.length;\n const { sbox2 } = tableEncoding;\n const { T0, T1, T2, T3 } = tableDecoding;\n // Inverse key by chunks of 4 (rounds)\n for (let i = 0; i < Nk; i += 4) {\n for (let j = 0; j < 4; j++) xk[i + j] = encKey[Nk - i - 4 + j];\n }\n clean(encKey);\n // apply InvMixColumn except first & last round\n for (let i = 4; i < Nk - 4; i++) {\n const x = xk[i];\n const w = applySbox(sbox2, x, x, x, x);\n xk[i] = T0[w & 0xff] ^ T1[(w >>> 8) & 0xff] ^ T2[(w >>> 16) & 0xff] ^ T3[w >>> 24];\n }\n return xk;\n}\n\n// Apply tables\nfunction apply0123(\n T01: Uint32Array,\n T23: Uint32Array,\n s0: number,\n s1: number,\n s2: number,\n s3: number\n) {\n return (\n T01[((s0 << 8) & 0xff00) | ((s1 >>> 8) & 0xff)] ^\n T23[((s2 >>> 8) & 0xff00) | ((s3 >>> 24) & 0xff)]\n );\n}\n\nfunction applySbox(sbox2: Uint16Array, s0: number, s1: number, s2: number, s3: number) {\n return (\n sbox2[(s0 & 0xff) | (s1 & 0xff00)] |\n (sbox2[((s2 >>> 16) & 0xff) | ((s3 >>> 16) & 0xff00)] << 16)\n );\n}\n\nfunction encrypt(\n xk: Uint32Array,\n s0: number,\n s1: number,\n s2: number,\n s3: number\n): { s0: number; s1: number; s2: number; s3: number } {\n const { sbox2, T01, T23 } = tableEncoding;\n let k = 0;\n ((s0 ^= xk[k++]), (s1 ^= xk[k++]), (s2 ^= xk[k++]), (s3 ^= xk[k++]));\n const rounds = xk.length / 4 - 2;\n for (let i = 0; i < rounds; i++) {\n const t0 = xk[k++] ^ apply0123(T01, T23, s0, s1, s2, s3);\n const t1 = xk[k++] ^ apply0123(T01, T23, s1, s2, s3, s0);\n const t2 = xk[k++] ^ apply0123(T01, T23, s2, s3, s0, s1);\n const t3 = xk[k++] ^ apply0123(T01, T23, s3, s0, s1, s2);\n ((s0 = t0), (s1 = t1), (s2 = t2), (s3 = t3));\n }\n // last round (without mixcolumns, so using SBOX2 table)\n const t0 = xk[k++] ^ applySbox(sbox2, s0, s1, s2, s3);\n const t1 = xk[k++] ^ applySbox(sbox2, s1, s2, s3, s0);\n const t2 = xk[k++] ^ applySbox(sbox2, s2, s3, s0, s1);\n const t3 = xk[k++] ^ applySbox(sbox2, s3, s0, s1, s2);\n return { s0: t0, s1: t1, s2: t2, s3: t3 };\n}\n\n// Can't be merged with encrypt: arg positions for apply0123 / applySbox are different\nfunction decrypt(\n xk: Uint32Array,\n s0: number,\n s1: number,\n s2: number,\n s3: number\n): {\n s0: number;\n s1: number;\n s2: number;\n s3: number;\n} {\n const { sbox2, T01, T23 } = tableDecoding;\n let k = 0;\n ((s0 ^= xk[k++]), (s1 ^= xk[k++]), (s2 ^= xk[k++]), (s3 ^= xk[k++]));\n const rounds = xk.length / 4 - 2;\n for (let i = 0; i < rounds; i++) {\n const t0 = xk[k++] ^ apply0123(T01, T23, s0, s3, s2, s1);\n const t1 = xk[k++] ^ apply0123(T01, T23, s1, s0, s3, s2);\n const t2 = xk[k++] ^ apply0123(T01, T23, s2, s1, s0, s3);\n const t3 = xk[k++] ^ apply0123(T01, T23, s3, s2, s1, s0);\n ((s0 = t0), (s1 = t1), (s2 = t2), (s3 = t3));\n }\n // Last round\n const t0: number = xk[k++] ^ applySbox(sbox2, s0, s3, s2, s1);\n const t1: number = xk[k++] ^ applySbox(sbox2, s1, s0, s3, s2);\n const t2: number = xk[k++] ^ applySbox(sbox2, s2, s1, s0, s3);\n const t3: number = xk[k++] ^ applySbox(sbox2, s3, s2, s1, s0);\n return { s0: t0, s1: t1, s2: t2, s3: t3 };\n}\n\n// TODO: investigate merging with ctr32\nfunction ctrCounter(\n xk: Uint32Array,\n nonce: Uint8Array,\n src: Uint8Array,\n dst?: Uint8Array\n): Uint8Array {\n abytes(nonce, BLOCK_SIZE, 'nonce');\n abytes(src);\n const srcLen = src.length;\n dst = getOutput(srcLen, dst);\n complexOverlapBytes(src, dst);\n const ctr = nonce;\n const c32 = u32(ctr);\n // Fill block (empty, ctr=0)\n let { s0, s1, s2, s3 } = encrypt(xk, c32[0], c32[1], c32[2], c32[3]);\n const src32 = u32(src);\n const dst32 = u32(dst);\n // process blocks\n for (let i = 0; i + 4 <= src32.length; i += 4) {\n dst32[i + 0] = src32[i + 0] ^ s0;\n dst32[i + 1] = src32[i + 1] ^ s1;\n dst32[i + 2] = src32[i + 2] ^ s2;\n dst32[i + 3] = src32[i + 3] ^ s3;\n incBytes(ctr, false, 1); // Full 128 bit counter with wrap around\n ({ s0, s1, s2, s3 } = encrypt(xk, c32[0], c32[1], c32[2], c32[3]));\n }\n // leftovers (less than block)\n // It's possible to handle > u32 fast, but is it worth it?\n const start = BLOCK_SIZE * Math.floor(src32.length / BLOCK_SIZE32);\n if (start < srcLen) {\n const b32 = new Uint32Array([s0, s1, s2, s3]);\n const buf = u8(b32);\n for (let i = start, pos = 0; i < srcLen; i++, pos++) dst[i] = src[i] ^ buf[pos];\n clean(b32);\n }\n return dst;\n}\n\n// AES CTR with overflowing 32 bit counter\n// It's possible to do 32le significantly simpler (and probably faster) by using u32.\n// But, we need both, and perf bottleneck is in ghash anyway.\nfunction ctr32(\n xk: Uint32Array,\n isLE: boolean,\n nonce: Uint8Array,\n src: Uint8Array,\n dst?: Uint8Array\n): Uint8Array {\n abytes(nonce, BLOCK_SIZE, 'nonce');\n abytes(src);\n dst = getOutput(src.length, dst);\n const ctr = nonce; // write new value to nonce, so it can be re-used\n const c32 = u32(ctr);\n const view = createView(ctr);\n const src32 = u32(src);\n const dst32 = u32(dst);\n const ctrPos = isLE ? 0 : 12;\n const srcLen = src.length;\n // Fill block (empty, ctr=0)\n let ctrNum = view.getUint32(ctrPos, isLE); // read current counter value\n let { s0, s1, s2, s3 } = encrypt(xk, c32[0], c32[1], c32[2], c32[3]);\n // process blocks\n for (let i = 0; i + 4 <= src32.length; i += 4) {\n dst32[i + 0] = src32[i + 0] ^ s0;\n dst32[i + 1] = src32[i + 1] ^ s1;\n dst32[i + 2] = src32[i + 2] ^ s2;\n dst32[i + 3] = src32[i + 3] ^ s3;\n ctrNum = (ctrNum + 1) >>> 0; // u32 wrap\n view.setUint32(ctrPos, ctrNum, isLE);\n ({ s0, s1, s2, s3 } = encrypt(xk, c32[0], c32[1], c32[2], c32[3]));\n }\n // leftovers (less than a block)\n const start = BLOCK_SIZE * Math.floor(src32.length / BLOCK_SIZE32);\n if (start < srcLen) {\n const b32 = new Uint32Array([s0, s1, s2, s3]);\n const buf = u8(b32);\n for (let i = start, pos = 0; i < srcLen; i++, pos++) dst[i] = src[i] ^ buf[pos];\n clean(b32);\n }\n return dst;\n}\n\n/**\n * **CTR** (Counter Mode): Turns a block cipher into a stream cipher using a counter and IV (nonce).\n * Efficient and parallelizable. Requires a unique nonce per encryption. Unauthenticated: needs MAC.\n */\nexport const ctr: ((key: Uint8Array, nonce: Uint8Array) => CipherWithOutput) & {\n blockSize: number;\n nonceLength: number;\n} = /* @__PURE__ */ wrapCipher(\n { blockSize: 16, nonceLength: 16 },\n function aesctr(key: Uint8Array, nonce: Uint8Array): CipherWithOutput {\n function processCtr(buf: Uint8Array, dst?: Uint8Array) {\n abytes(buf);\n if (dst !== undefined) {\n abytes(dst);\n if (!isAligned32(dst)) throw new Error('unaligned destination');\n }\n const xk = expandKeyLE(key);\n const n = copyBytes(nonce); // align + avoid changing\n const toClean = [xk, n];\n if (!isAligned32(buf)) toClean.push((buf = copyBytes(buf)));\n const out = ctrCounter(xk, n, buf, dst);\n clean(...toClean);\n return out;\n }\n return {\n encrypt: (plaintext: Uint8Array, dst?: Uint8Array) => processCtr(plaintext, dst),\n decrypt: (ciphertext: Uint8Array, dst?: Uint8Array) => processCtr(ciphertext, dst),\n };\n }\n);\n\nfunction validateBlockDecrypt(data: Uint8Array) {\n abytes(data);\n if (data.length % BLOCK_SIZE !== 0) {\n throw new Error(\n 'aes-(cbc/ecb).decrypt ciphertext should consist of blocks with size ' + BLOCK_SIZE\n );\n }\n}\n\nfunction validateBlockEncrypt(plaintext: Uint8Array, pcks5: boolean, dst?: Uint8Array) {\n abytes(plaintext);\n let outLen = plaintext.length;\n const remaining = outLen % BLOCK_SIZE;\n if (!pcks5 && remaining !== 0)\n throw new Error('aec/(cbc-ecb): unpadded plaintext with disabled padding');\n if (!isAligned32(plaintext)) plaintext = copyBytes(plaintext);\n const b = u32(plaintext);\n if (pcks5) {\n let left = BLOCK_SIZE - remaining;\n if (!left) left = BLOCK_SIZE; // if no bytes left, create empty padding block\n outLen = outLen + left;\n }\n dst = getOutput(outLen, dst);\n complexOverlapBytes(plaintext, dst);\n const o = u32(dst);\n return { b, o, out: dst };\n}\n\nfunction validatePCKS(data: Uint8Array, pcks5: boolean) {\n if (!pcks5) return data;\n const len = data.length;\n if (!len) throw new Error('aes/pcks5: empty ciphertext not allowed');\n const lastByte = data[len - 1];\n if (lastByte <= 0 || lastByte > 16) throw new Error('aes/pcks5: wrong padding');\n const out = data.subarray(0, -lastByte);\n for (let i = 0; i < lastByte; i++)\n if (data[len - i - 1] !== lastByte) throw new Error('aes/pcks5: wrong padding');\n return out;\n}\n\nfunction padPCKS(left: Uint8Array) {\n const tmp = new Uint8Array(16);\n const tmp32 = u32(tmp);\n tmp.set(left);\n const paddingByte = BLOCK_SIZE - left.length;\n for (let i = BLOCK_SIZE - paddingByte; i < BLOCK_SIZE; i++) tmp[i] = paddingByte;\n return tmp32;\n}\n\n/** Options for ECB and CBC. */\nexport type BlockOpts = { disablePadding?: boolean };\n\n/**\n * **ECB** (Electronic Codebook): Deterministic encryption; identical plaintext blocks yield\n * identical ciphertexts. Not secure due to pattern leakage.\n * See [AES Penguin](https://words.filippo.io/the-ecb-penguin/).\n */\nexport const ecb: ((key: Uint8Array, opts?: BlockOpts) => CipherWithOutput) & {\n blockSize: number;\n} = /* @__PURE__ */ wrapCipher(\n { blockSize: 16 },\n function aesecb(key: Uint8Array, opts: BlockOpts = {}): CipherWithOutput {\n const pcks5 = !opts.disablePadding;\n return {\n encrypt(plaintext: Uint8Array, dst?: Uint8Array) {\n const { b, o, out: _out } = validateBlockEncrypt(plaintext, pcks5, dst);\n const xk = expandKeyLE(key);\n let i = 0;\n for (; i + 4 <= b.length; ) {\n const { s0, s1, s2, s3 } = encrypt(xk, b[i + 0], b[i + 1], b[i + 2], b[i + 3]);\n ((o[i++] = s0), (o[i++] = s1), (o[i++] = s2), (o[i++] = s3));\n }\n if (pcks5) {\n const tmp32 = padPCKS(plaintext.subarray(i * 4));\n const { s0, s1, s2, s3 } = encrypt(xk, tmp32[0], tmp32[1], tmp32[2], tmp32[3]);\n ((o[i++] = s0), (o[i++] = s1), (o[i++] = s2), (o[i++] = s3));\n }\n clean(xk);\n return _out;\n },\n decrypt(ciphertext: Uint8Array, dst?: Uint8Array) {\n validateBlockDecrypt(ciphertext);\n const xk = expandKeyDecLE(key);\n dst = getOutput(ciphertext.length, dst);\n const toClean: (Uint8Array | Uint32Array)[] = [xk];\n if (!isAligned32(ciphertext)) toClean.push((ciphertext = copyBytes(ciphertext)));\n complexOverlapBytes(ciphertext, dst);\n const b = u32(ciphertext);\n const o = u32(dst);\n for (let i = 0; i + 4 <= b.length; ) {\n const { s0, s1, s2, s3 } = decrypt(xk, b[i + 0], b[i + 1], b[i + 2], b[i + 3]);\n ((o[i++] = s0), (o[i++] = s1), (o[i++] = s2), (o[i++] = s3));\n }\n clean(...toClean);\n return validatePCKS(dst, pcks5);\n },\n };\n }\n);\n\n/**\n * **CBC** (Cipher Block Chaining): Each plaintext block is XORed with the\n * previous block of ciphertext before encryption.\n * Hard to use: requires proper padding and an IV. Unauthenticated: needs MAC.\n */\nexport const cbc: ((key: Uint8Array, iv: Uint8Array, opts?: BlockOpts) => CipherWithOutput) & {\n blockSize: number;\n nonceLength: number;\n} = /* @__PURE__ */ wrapCipher(\n { blockSize: 16, nonceLength: 16 },\n function aescbc(key: Uint8Array, iv: Uint8Array, opts: BlockOpts = {}): CipherWithOutput {\n const pcks5 = !opts.disablePadding;\n return {\n encrypt(plaintext: Uint8Array, dst?: Uint8Array) {\n const xk = expandKeyLE(key);\n const { b, o, out: _out } = validateBlockEncrypt(plaintext, pcks5, dst);\n let _iv = iv;\n const toClean: (Uint8Array | Uint32Array)[] = [xk];\n if (!isAligned32(_iv)) toClean.push((_iv = copyBytes(_iv)));\n const n32 = u32(_iv);\n // prettier-ignore\n let s0 = n32[0], s1 = n32[1], s2 = n32[2], s3 = n32[3];\n let i = 0;\n for (; i + 4 <= b.length; ) {\n ((s0 ^= b[i + 0]), (s1 ^= b[i + 1]), (s2 ^= b[i + 2]), (s3 ^= b[i + 3]));\n ({ s0, s1, s2, s3 } = encrypt(xk, s0, s1, s2, s3));\n ((o[i++] = s0), (o[i++] = s1), (o[i++] = s2), (o[i++] = s3));\n }\n if (pcks5) {\n const tmp32 = padPCKS(plaintext.subarray(i * 4));\n ((s0 ^= tmp32[0]), (s1 ^= tmp32[1]), (s2 ^= tmp32[2]), (s3 ^= tmp32[3]));\n ({ s0, s1, s2, s3 } = encrypt(xk, s0, s1, s2, s3));\n ((o[i++] = s0), (o[i++] = s1), (o[i++] = s2), (o[i++] = s3));\n }\n clean(...toClean);\n return _out;\n },\n decrypt(ciphertext: Uint8Array, dst?: Uint8Array) {\n validateBlockDecrypt(ciphertext);\n const xk = expandKeyDecLE(key);\n let _iv = iv;\n const toClean: (Uint8Array | Uint32Array)[] = [xk];\n if (!isAligned32(_iv)) toClean.push((_iv = copyBytes(_iv)));\n const n32 = u32(_iv);\n dst = getOutput(ciphertext.length, dst);\n if (!isAligned32(ciphertext)) toClean.push((ciphertext = copyBytes(ciphertext)));\n complexOverlapBytes(ciphertext, dst);\n const b = u32(ciphertext);\n const o = u32(dst);\n // prettier-ignore\n let s0 = n32[0], s1 = n32[1], s2 = n32[2], s3 = n32[3];\n for (let i = 0; i + 4 <= b.length; ) {\n // prettier-ignore\n const ps0 = s0, ps1 = s1, ps2 = s2, ps3 = s3;\n ((s0 = b[i + 0]), (s1 = b[i + 1]), (s2 = b[i + 2]), (s3 = b[i + 3]));\n const { s0: o0, s1: o1, s2: o2, s3: o3 } = decrypt(xk, s0, s1, s2, s3);\n ((o[i++] = o0 ^ ps0), (o[i++] = o1 ^ ps1), (o[i++] = o2 ^ ps2), (o[i++] = o3 ^ ps3));\n }\n clean(...toClean);\n return validatePCKS(dst, pcks5);\n },\n };\n }\n);\n\n/**\n * CFB: Cipher Feedback Mode. The input for the block cipher is the previous cipher output.\n * Unauthenticated: needs MAC.\n */\nexport const cfb: ((key: Uint8Array, iv: Uint8Array) => CipherWithOutput) & {\n blockSize: number;\n nonceLength: number;\n} = /* @__PURE__ */ wrapCipher(\n { blockSize: 16, nonceLength: 16 },\n function aescfb(key: Uint8Array, iv: Uint8Array): CipherWithOutput {\n function processCfb(src: Uint8Array, isEncrypt: boolean, dst?: Uint8Array) {\n abytes(src);\n const srcLen = src.length;\n dst = getOutput(srcLen, dst);\n if (overlapBytes(src, dst)) throw new Error('overlapping src and dst not supported.');\n const xk = expandKeyLE(key);\n let _iv = iv;\n const toClean: (Uint8Array | Uint32Array)[] = [xk];\n if (!isAligned32(_iv)) toClean.push((_iv = copyBytes(_iv)));\n if (!isAligned32(src)) toClean.push((src = copyBytes(src)));\n const src32 = u32(src);\n const dst32 = u32(dst);\n const next32 = isEncrypt ? dst32 : src32;\n const n32 = u32(_iv);\n // prettier-ignore\n let s0 = n32[0], s1 = n32[1], s2 = n32[2], s3 = n32[3];\n for (let i = 0; i + 4 <= src32.length; ) {\n const { s0: e0, s1: e1, s2: e2, s3: e3 } = encrypt(xk, s0, s1, s2, s3);\n dst32[i + 0] = src32[i + 0] ^ e0;\n dst32[i + 1] = src32[i + 1] ^ e1;\n dst32[i + 2] = src32[i + 2] ^ e2;\n dst32[i + 3] = src32[i + 3] ^ e3;\n ((s0 = next32[i++]), (s1 = next32[i++]), (s2 = next32[i++]), (s3 = next32[i++]));\n }\n // leftovers (less than block)\n const start = BLOCK_SIZE * Math.floor(src32.length / BLOCK_SIZE32);\n if (start < srcLen) {\n ({ s0, s1, s2, s3 } = encrypt(xk, s0, s1, s2, s3));\n const buf = u8(new Uint32Array([s0, s1, s2, s3]));\n for (let i = start, pos = 0; i < srcLen; i++, pos++) dst[i] = src[i] ^ buf[pos];\n clean(buf);\n }\n clean(...toClean);\n return dst;\n }\n return {\n encrypt: (plaintext: Uint8Array, dst?: Uint8Array) => processCfb(plaintext, true, dst),\n decrypt: (ciphertext: Uint8Array, dst?: Uint8Array) => processCfb(ciphertext, false, dst),\n };\n }\n);\n\n// TODO: merge with chacha, however gcm has bitLen while chacha has byteLen\nfunction computeTag(\n fn: typeof ghash,\n isLE: boolean,\n key: Uint8Array,\n data: Uint8Array,\n AAD?: Uint8Array\n) {\n const aadLength = AAD ? AAD.length : 0;\n const h = fn.create(key, data.length + aadLength);\n if (AAD) h.update(AAD);\n const num = u64Lengths(8 * data.length, 8 * aadLength, isLE);\n h.update(data);\n h.update(num);\n const res = h.digest();\n clean(num);\n return res;\n}\n\n/**\n * **GCM** (Galois/Counter Mode): Combines CTR mode with polynomial MAC. Efficient and widely used.\n * Not perfect:\n * a) conservative key wear-out is `2**32` (4B) msgs.\n * b) key wear-out under random nonces is even smaller: `2**23` (8M) messages for `2**-50` chance.\n * c) MAC can be forged: see Poly1305 documentation.\n */\nexport const gcm: ((key: Uint8Array, nonce: Uint8Array, AAD?: Uint8Array) => Cipher) & {\n blockSize: number;\n nonceLength: number;\n tagLength: number;\n varSizeNonce: true;\n} = /* @__PURE__ */ wrapCipher(\n { blockSize: 16, nonceLength: 12, tagLength: 16, varSizeNonce: true },\n function aesgcm(key: Uint8Array, nonce: Uint8Array, AAD?: Uint8Array): Cipher {\n // NIST 800-38d doesn't enforce minimum nonce length.\n // We enforce 8 bytes for compat with openssl.\n // 12 bytes are recommended. More than 12 bytes would be converted into 12.\n if (nonce.length < 8) throw new Error('aes/gcm: invalid nonce length');\n const tagLength = 16;\n function _computeTag(authKey: Uint8Array, tagMask: Uint8Array, data: Uint8Array) {\n const tag = computeTag(ghash, false, authKey, data, AAD);\n for (let i = 0; i < tagMask.length; i++) tag[i] ^= tagMask[i];\n return tag;\n }\n function deriveKeys() {\n const xk = expandKeyLE(key);\n const authKey = EMPTY_BLOCK.slice();\n const counter = EMPTY_BLOCK.slice();\n ctr32(xk, false, counter, counter, authKey);\n // NIST 800-38d, page 15: different behavior for 96-bit and non-96-bit nonces\n if (nonce.length === 12) {\n counter.set(nonce);\n } else {\n const nonceLen = EMPTY_BLOCK.slice();\n const view = createView(nonceLen);\n view.setBigUint64(8, BigInt(nonce.length * 8), false);\n // ghash(nonce || u64be(0) || u64be(nonceLen*8))\n const g = ghash.create(authKey).update(nonce).update(nonceLen);\n g.digestInto(counter); // digestInto doesn't trigger '.destroy'\n g.destroy();\n }\n const tagMask = ctr32(xk, false, counter, EMPTY_BLOCK);\n return { xk, authKey, counter, tagMask };\n }\n return {\n encrypt(plaintext: Uint8Array) {\n const { xk, authKey, counter, tagMask } = deriveKeys();\n const out = new Uint8Array(plaintext.length + tagLength);\n const toClean: (Uint8Array | Uint32Array)[] = [xk, authKey, counter, tagMask];\n if (!isAligned32(plaintext)) toClean.push((plaintext = copyBytes(plaintext)));\n ctr32(xk, false, counter, plaintext, out.subarray(0, plaintext.length));\n const tag = _computeTag(authKey, tagMask, out.subarray(0, out.length - tagLength));\n toClean.push(tag);\n out.set(tag, plaintext.length);\n clean(...toClean);\n return out;\n },\n decrypt(ciphertext: Uint8Array) {\n const { xk, authKey, counter, tagMask } = deriveKeys();\n const toClean: (Uint8Array | Uint32Array)[] = [xk, authKey, tagMask, counter];\n if (!isAligned32(ciphertext)) toClean.push((ciphertext = copyBytes(ciphertext)));\n const data = ciphertext.subarray(0, -tagLength);\n const passedTag = ciphertext.subarray(-tagLength);\n const tag = _computeTag(authKey, tagMask, data);\n toClean.push(tag);\n if (!equalBytes(tag, passedTag)) throw new Error('aes/gcm: invalid ghash tag');\n const out = ctr32(xk, false, counter, data);\n clean(...toClean);\n return out;\n },\n };\n }\n);\n\nconst limit = (name: string, min: number, max: number) => (value: number) => {\n if (!Number.isSafeInteger(value) || min > value || value > max) {\n const minmax = '[' + min + '..' + max + ']';\n throw new Error('' + name + ': expected value in range ' + minmax + ', got ' + value);\n }\n};\n\n/**\n * **SIV** (Synthetic IV): GCM with nonce-misuse resistance.\n * Repeating nonces reveal only the fact plaintexts are identical.\n * Also suffers from GCM issues: key wear-out limits & MAC forging.\n * See [RFC 8452](https://www.rfc-editor.org/rfc/rfc8452).\n */\nexport const gcmsiv: ((key: Uint8Array, nonce: Uint8Array, AAD?: Uint8Array) => Cipher) & {\n blockSize: number;\n nonceLength: number;\n tagLength: number;\n varSizeNonce: true;\n} = /* @__PURE__ */ wrapCipher(\n { blockSize: 16, nonceLength: 12, tagLength: 16, varSizeNonce: true },\n function aessiv(key: Uint8Array, nonce: Uint8Array, AAD?: Uint8Array): Cipher {\n const tagLength = 16;\n // From RFC 8452: Section 6\n const AAD_LIMIT = limit('AAD', 0, 2 ** 36);\n const PLAIN_LIMIT = limit('plaintext', 0, 2 ** 36);\n const NONCE_LIMIT = limit('nonce', 12, 12);\n const CIPHER_LIMIT = limit('ciphertext', 16, 2 ** 36 + 16);\n abytes(key);\n validateKeyLength(key);\n NONCE_LIMIT(nonce.length);\n if (AAD !== undefined) AAD_LIMIT(AAD.length);\n function deriveKeys() {\n const xk = expandKeyLE(key);\n const encKey = new Uint8Array(key.length);\n const authKey = new Uint8Array(16);\n const toClean: (Uint8Array | Uint32Array)[] = [xk, encKey];\n let _nonce = nonce;\n if (!isAligned32(_nonce)) toClean.push((_nonce = copyBytes(_nonce)));\n const n32 = u32(_nonce);\n // prettier-ignore\n let s0 = 0, s1 = n32[0], s2 = n32[1], s3 = n32[2];\n let counter = 0;\n for (const derivedKey of [authKey, encKey].map(u32)) {\n const d32 = u32(derivedKey);\n for (let i = 0; i < d32.length; i += 2) {\n // aes(u32le(0) || nonce)[:8] || aes(u32le(1) || nonce)[:8] ...\n const { s0: o0, s1: o1 } = encrypt(xk, s0, s1, s2, s3);\n d32[i + 0] = o0;\n d32[i + 1] = o1;\n s0 = ++counter; // increment counter inside state\n }\n }\n const res = { authKey, encKey: expandKeyLE(encKey) };\n // Cleanup\n clean(...toClean);\n return res;\n }\n function _computeTag(encKey: Uint32Array, authKey: Uint8Array, data: Uint8Array) {\n const tag = computeTag(polyval, true, authKey, data, AAD);\n // Compute the expected tag by XORing S_s and the nonce, clearing the\n // most significant bit of the last byte and encrypting with the\n // message-encryption key.\n for (let i = 0; i < 12; i++) tag[i] ^= nonce[i];\n tag[15] &= 0x7f; // Clear the highest bit\n // encrypt tag as block\n const t32 = u32(tag);\n // prettier-ignore\n let s0 = t32[0], s1 = t32[1], s2 = t32[2], s3 = t32[3];\n ({ s0, s1, s2, s3 } = encrypt(encKey, s0, s1, s2, s3));\n ((t32[0] = s0), (t32[1] = s1), (t32[2] = s2), (t32[3] = s3));\n return tag;\n }\n // actual decrypt/encrypt of message.\n function processSiv(encKey: Uint32Array, tag: Uint8Array, input: Uint8Array) {\n let block = copyBytes(tag);\n block[15] |= 0x80; // Force highest bit\n const res = ctr32(encKey, true, block, input);\n // Cleanup\n clean(block);\n return res;\n }\n return {\n encrypt(plaintext: Uint8Array) {\n PLAIN_LIMIT(plaintext.length);\n const { encKey, authKey } = deriveKeys();\n const tag = _computeTag(encKey, authKey, plaintext);\n const toClean: (Uint8Array | Uint32Array)[] = [encKey, authKey, tag];\n if (!isAligned32(plaintext)) toClean.push((plaintext = copyBytes(plaintext)));\n const out = new Uint8Array(plaintext.length + tagLength);\n out.set(tag, plaintext.length);\n out.set(processSiv(encKey, tag, plaintext));\n // Cleanup\n clean(...toClean);\n return out;\n },\n decrypt(ciphertext: Uint8Array) {\n CIPHER_LIMIT(ciphertext.length);\n const tag = ciphertext.subarray(-tagLength);\n const { encKey, authKey } = deriveKeys();\n const toClean: (Uint8Array | Uint32Array)[] = [encKey, authKey];\n if (!isAligned32(ciphertext)) toClean.push((ciphertext = copyBytes(ciphertext)));\n const plaintext = processSiv(encKey, tag, ciphertext.subarray(0, -tagLength));\n const expectedTag = _computeTag(encKey, authKey, plaintext);\n toClean.push(expectedTag);\n if (!equalBytes(tag, expectedTag)) {\n clean(...toClean);\n throw new Error('invalid polyval tag');\n }\n // Cleanup\n clean(...toClean);\n return plaintext;\n },\n };\n }\n);\n\nfunction isBytes32(a: unknown): a is Uint32Array {\n return (\n a instanceof Uint32Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint32Array')\n );\n}\n\nfunction encryptBlock(xk: Uint32Array, block: Uint8Array): Uint8Array {\n abytes(block, 16, 'block');\n if (!isBytes32(xk)) throw new Error('_encryptBlock accepts result of expandKeyLE');\n const b32 = u32(block);\n let { s0, s1, s2, s3 } = encrypt(xk, b32[0], b32[1], b32[2], b32[3]);\n ((b32[0] = s0), (b32[1] = s1), (b32[2] = s2), (b32[3] = s3));\n return block;\n}\n\nfunction decryptBlock(xk: Uint32Array, block: Uint8Array): Uint8Array {\n abytes(block, 16, 'block');\n if (!isBytes32(xk)) throw new Error('_decryptBlock accepts result of expandKeyLE');\n const b32 = u32(block);\n let { s0, s1, s2, s3 } = decrypt(xk, b32[0], b32[1], b32[2], b32[3]);\n ((b32[0] = s0), (b32[1] = s1), (b32[2] = s2), (b32[3] = s3));\n return block;\n}\n\n/**\n * AES-W (base for AESKW/AESKWP).\n * Specs: [SP800-38F](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38F.pdf),\n * [RFC 3394](https://www.rfc-editor.org/rfc/rfc3394),\n * [RFC 5649](https://www.rfc-editor.org/rfc/rfc5649).\n */\nconst AESW = {\n /*\n High-level pseudocode:\n ```\n A: u64 = IV\n out = []\n for (let i=0, ctr = 0; i<6; i++) {\n for (const chunk of chunks(plaintext, 8)) {\n A ^= swapEndianess(ctr++)\n [A, res] = chunks(encrypt(A || chunk), 8);\n out ||= res\n }\n }\n out = A || out\n ```\n Decrypt is the same, but reversed.\n */\n encrypt(kek: Uint8Array, out: Uint8Array) {\n // Size is limited to 4GB, otherwise ctr will overflow and we'll need to switch to bigints.\n // If you need it larger, open an issue.\n if (out.length >= 2 ** 32) throw new Error('plaintext should be less than 4gb');\n const xk = expandKeyLE(kek);\n if (out.length === 16) encryptBlock(xk, out);\n else {\n const o32 = u32(out);\n // prettier-ignore\n let a0 = o32[0], a1 = o32[1]; // A\n for (let j = 0, ctr = 1; j < 6; j++) {\n for (let pos = 2; pos < o32.length; pos += 2, ctr++) {\n const { s0, s1, s2, s3 } = encrypt(xk, a0, a1, o32[pos], o32[pos + 1]);\n // A = MSB(64, B) ^ t where t = (n*j)+i\n ((a0 = s0), (a1 = s1 ^ byteSwap(ctr)), (o32[pos] = s2), (o32[pos + 1] = s3));\n }\n }\n ((o32[0] = a0), (o32[1] = a1)); // out = A || out\n }\n xk.fill(0);\n },\n decrypt(kek: Uint8Array, out: Uint8Array) {\n if (out.length - 8 >= 2 ** 32) throw new Error('ciphertext should be less than 4gb');\n const xk = expandKeyDecLE(kek);\n const chunks = out.length / 8 - 1; // first chunk is IV\n if (chunks === 1) decryptBlock(xk, out);\n else {\n const o32 = u32(out);\n // prettier-ignore\n let a0 = o32[0], a1 = o32[1]; // A\n for (let j = 0, ctr = chunks * 6; j < 6; j++) {\n for (let pos = chunks * 2; pos >= 1; pos -= 2, ctr--) {\n a1 ^= byteSwap(ctr);\n const { s0, s1, s2, s3 } = decrypt(xk, a0, a1, o32[pos], o32[pos + 1]);\n ((a0 = s0), (a1 = s1), (o32[pos] = s2), (o32[pos + 1] = s3));\n }\n }\n ((o32[0] = a0), (o32[1] = a1));\n }\n xk.fill(0);\n },\n};\n\nconst AESKW_IV = /* @__PURE__ */ new Uint8Array(8).fill(0xa6); // A6A6A6A6A6A6A6A6\n\n/**\n * AES-KW (key-wrap). Injects static IV into plaintext, adds counter, encrypts 6 times.\n * Reduces block size from 16 to 8 bytes.\n * For padded version, use aeskwp.\n * [RFC 3394](https://www.rfc-editor.org/rfc/rfc3394/),\n * [NIST.SP.800-38F](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38F.pdf).\n */\nexport const aeskw: ((kek: Uint8Array) => Cipher) & {\n blockSize: number;\n} = /* @__PURE__ */ wrapCipher(\n { blockSize: 8 },\n (kek: Uint8Array): Cipher => ({\n encrypt(plaintext: Uint8Array) {\n if (!plaintext.length || plaintext.length % 8 !== 0)\n throw new Error('invalid plaintext length');\n if (plaintext.length === 8)\n throw new Error('8-byte keys not allowed in AESKW, use AESKWP instead');\n const out = concatBytes(AESKW_IV, plaintext);\n AESW.encrypt(kek, out);\n return out;\n },\n decrypt(ciphertext: Uint8Array) {\n // ciphertext must be at least 24 bytes and a multiple of 8 bytes\n // 24 because should have at least two block (1 iv + 2).\n // Replace with 16 to enable '8-byte keys'\n if (ciphertext.length % 8 !== 0 || ciphertext.length < 3 * 8)\n throw new Error('invalid ciphertext length');\n const out = copyBytes(ciphertext);\n AESW.decrypt(kek, out);\n if (!equalBytes(out.subarray(0, 8), AESKW_IV)) throw new Error('integrity check failed');\n out.subarray(0, 8).fill(0); // ciphertext.subarray(0, 8) === IV, but we clean it anyway\n return out.subarray(8);\n },\n })\n);\n\n/*\nWe don't support 8-byte keys. The rabbit hole:\n\n- Wycheproof says: \"NIST SP 800-38F does not define the wrapping of 8 byte keys.\n RFC 3394 Section 2 on the other hand specifies that 8 byte keys are wrapped\n by directly encrypting one block with AES.\"\n - https://github.com/C2SP/wycheproof/blob/master/doc/key_wrap.md\n - \"RFC 3394 specifies in Section 2, that the input for the key wrap\n algorithm must be at least two blocks and otherwise the constant\n field and key are simply encrypted with ECB as a single block\"\n- What RFC 3394 actually says (in Section 2):\n - \"Before being wrapped, the key data is parsed into n blocks of 64 bits.\n The only restriction the key wrap algorithm places on n is that n be\n at least two\"\n - \"For key data with length less than or equal to 64 bits, the constant\n field used in this specification and the key data form a single\n 128-bit codebook input making this key wrap unnecessary.\"\n- Which means \"assert(n >= 2)\" and \"use something else for 8 byte keys\"\n- NIST SP800-38F actually prohibits 8-byte in \"5.3.1 Mandatory Limits\".\n It states that plaintext for KW should be \"2 to 2^54 -1 semiblocks\".\n- So, where does \"directly encrypt single block with AES\" come from?\n - Not RFC 3394. Pseudocode of key wrap in 2.2 explicitly uses\n loop of 6 for any code path\n - There is a weird W3C spec:\n https://www.w3.org/TR/2002/REC-xmlenc-core-20021210/Overview.html#kw-aes128\n - This spec is outdated, as admitted by Wycheproof authors\n - There is RFC 5649 for padded key wrap, which is padding construction on\n top of AESKW. In '4.1.2' it says: \"If the padded plaintext contains exactly\n eight octets, then prepend the AIV as defined in Section 3 above to P[1] and\n encrypt the resulting 128-bit block using AES in ECB mode [Modes] with key\n K (the KEK). In this case, the output is two 64-bit blocks C[0] and C[1]:\"\n - Browser subtle crypto is actually crashes on wrapping keys less than 16 bytes:\n `Error: error:1C8000E6:Provider routines::invalid input length] { opensslErrorStack: [ 'error:030000BD:digital envelope routines::update error' ]`\n\nIn the end, seems like a bug in Wycheproof.\nThe 8-byte check can be easily disabled inside of AES_W.\n*/\n\nconst AESKWP_IV = 0xa65959a6; // single u32le value\n\n/**\n * AES-KW, but with padding and allows random keys.\n * Second u32 of IV is used as counter for length.\n * [RFC 5649](https://www.rfc-editor.org/rfc/rfc5649)\n */\nexport const aeskwp: ((kek: Uint8Array) => Cipher) & {\n blockSize: number;\n} = /* @__PURE__ */ wrapCipher(\n { blockSize: 8 },\n (kek: Uint8Array): Cipher => ({\n encrypt(plaintext: Uint8Array) {\n if (!plaintext.length) throw new Error('invalid plaintext length');\n const padded = Math.ceil(plaintext.length / 8) * 8;\n const out = new Uint8Array(8 + padded);\n out.set(plaintext, 8);\n const out32 = u32(out);\n out32[0] = AESKWP_IV;\n out32[1] = byteSwap(plaintext.length);\n AESW.encrypt(kek, out);\n return out;\n },\n decrypt(ciphertext: Uint8Array) {\n // 16 because should have at least one block\n if (ciphertext.length < 16) throw new Error('invalid ciphertext length');\n const out = copyBytes(ciphertext);\n const o32 = u32(out);\n AESW.decrypt(kek, out);\n const len = byteSwap(o32[1]) >>> 0;\n const padded = Math.ceil(len / 8) * 8;\n if (o32[0] !== AESKWP_IV || out.length - 8 !== padded)\n throw new Error('integrity check failed');\n for (let i = len; i < padded; i++)\n if (out[8 + i] !== 0) throw new Error('integrity check failed');\n out.subarray(0, 8).fill(0); // ciphertext.subarray(0, 8) === IV, but we clean it anyway\n return out.subarray(8, 8 + len);\n },\n })\n);\n\nclass _AesCtrDRBG implements PRG {\n readonly blockLen: number;\n private key: Uint8Array;\n private nonce: Uint8Array;\n private state: Uint8Array;\n private reseedCnt: number;\n constructor(keyLen: number, seed: Uint8Array, personalization?: Uint8Array) {\n this.blockLen = ctr.blockSize;\n const keyLenBytes = keyLen / 8;\n const nonceLen = 16;\n this.state = new Uint8Array(keyLenBytes + nonceLen);\n this.key = this.state.subarray(0, keyLenBytes);\n this.nonce = this.state.subarray(keyLenBytes, keyLenBytes + nonceLen);\n this.reseedCnt = 1;\n incBytes(this.nonce, false, 1);\n this.addEntropy(seed, personalization);\n }\n private update(data?: Uint8Array) {\n // cannot re-use state here, because we will wipe current key\n ctr(this.key, this.nonce).encrypt(new Uint8Array(this.state.length), this.state);\n if (data) {\n abytes(data);\n for (let i = 0; i < data.length; i++) this.state[i] ^= data[i];\n }\n incBytes(this.nonce, false, 1);\n }\n addEntropy(seed: Uint8Array, info?: Uint8Array): void {\n abytes(seed, this.state.length, 'seed');\n const _seed = seed.slice();\n if (info) {\n abytes(info);\n if (info.length > _seed.length) throw new Error('info length is too big');\n for (let i = 0; i < info.length; i++) _seed[i] ^= info[i];\n }\n this.update(_seed);\n _seed.fill(0);\n this.reseedCnt = 1;\n }\n randomBytes(len: number, info?: Uint8Array): Uint8Array {\n anumber(len);\n if (this.reseedCnt++ >= 2 ** 48) throw new Error('entropy exhausted');\n if (info) this.update(info);\n const res = new Uint8Array(len);\n ctr(this.key, this.nonce).encrypt(res, res);\n incBytes(this.nonce, false, Math.ceil(len / this.blockLen));\n this.update(info);\n return res;\n }\n clean(): void {\n this.state.fill(0);\n this.reseedCnt = 0;\n }\n}\n\nexport type AesCtrDrbg = (seed: Uint8Array, personalization?: Uint8Array) => _AesCtrDRBG;\n\nconst createAesDrbg: (keyLen: number) => AesCtrDrbg = (keyLen) => {\n return (seed, personalization = undefined) => new _AesCtrDRBG(keyLen, seed, personalization);\n};\n\n/**\n * AES-CTR DRBG 128-bit - CSPRNG (cryptographically secure pseudorandom number generator).\n * It's best to limit usage to non-production, non-critical cases: for example, test-only.\n */\nexport const rngAesCtrDrbg128: AesCtrDrbg = /* @__PURE__ */ createAesDrbg(128);\n/**\n * AES-CTR DRBG 256-bit - CSPRNG (cryptographically secure pseudorandom number generator).\n * It's best to limit usage to non-production, non-critical cases: for example, test-only.\n */\nexport const rngAesCtrDrbg256: AesCtrDrbg = /* @__PURE__ */ createAesDrbg(256);\n\n//#region CMAC\n\n/**\n * Left-shift by one bit and conditionally XOR with 0x87:\n * ```\n * if MSB(L) is equal to 0\n * then K1 := L << 1;\n * else K1 := (L << 1) XOR const_Rb;\n * ```\n *\n * Specs: [RFC 4493, Section 2.3](https://www.rfc-editor.org/rfc/rfc4493.html#section-2.3),\n * [RFC 5297 Section 2.3](https://datatracker.ietf.org/doc/html/rfc5297.html#section-2.3)\n *\n * @returns modified `block` (for chaining)\n */\nfunction dbl<T extends Uint8Array>(block: T): T {\n let carry = 0;\n\n // Left shift by 1 bit\n for (let i = BLOCK_SIZE - 1; i >= 0; i--) {\n const newCarry = (block[i] & 0x80) >>> 7;\n block[i] = (block[i] << 1) | carry;\n carry = newCarry;\n }\n\n // XOR with 0x87 if there was a carry from the most significant bit\n if (carry) {\n block[BLOCK_SIZE - 1] ^= 0x87;\n }\n\n return block;\n}\n\n/**\n * `a XOR b`, running in-site on `a`.\n * @param a left operand and output\n * @param b right operand\n * @returns `a` (for chaining)\n */\nfunction xorBlock<T extends Uint8Array>(a: T, b: Uint8Array): T {\n if (a.length !== b.length) throw new Error('xorBlock: blocks must have same length');\n for (let i = 0; i < a.length; i++) {\n a[i] = a[i] ^ b[i];\n }\n return a;\n}\n\n/**\n * xorend as defined in [RFC 5297 Section 2.1](https://datatracker.ietf.org/doc/html/rfc5297.html#section-2.1).\n *\n * ```\n * leftmost(A, len(A)-len(B)) || (rightmost(A, len(B)) xor B)\n * ```\n */\nfunction xorend<T extends Uint8Array>(a: T, b: Uint8Array): T {\n if (b.length > a.length) {\n throw new Error('xorend: len(B) must be less than or equal to len(A)');\n }\n // keep leftmost part of `a` unchanged\n // and xor only the rightmost part:\n const offset = a.length - b.length;\n for (let i = 0; i < b.length; i++) {\n a[offset + i] = a[offset + i] ^ b[i];\n }\n return a;\n}\n\n/**\n * Internal CMAC class.\n */\nclass _CMAC {\n private buffer: Uint8Array;\n private destroyed: boolean;\n private k1: Uint8Array;\n private k2: Uint8Array;\n private xk: Uint32Array;\n\n constructor(key: Uint8Array) {\n abytes(key);\n validateKeyLength(key);\n this.xk = expandKeyLE(key);\n this.buffer = new Uint8Array(0);\n this.destroyed = false;\n // L = AES_encrypt(K, const_Zero)\n const L = new Uint8Array(BLOCK_SIZE);\n encryptBlock(this.xk, L);\n // Generate subkeys K1 and K2 from the main key according to\n // [RFC 4493, Section 2.3](https://www.rfc-editor.org/rfc/rfc4493.html#section-2.3)\n // K1\n this.k1 = dbl(L);\n this.k2 = dbl(new Uint8Array(this.k1));\n }\n\n update(data: Uint8Array): _CMAC {\n const { destroyed, buffer } = this;\n if (destroyed) throw new Error('CMAC instance was destroyed');\n abytes(data);\n const newBuffer = new Uint8Array(buffer.length + data.length);\n newBuffer.set(buffer);\n newBuffer.set(data, buffer.length);\n this.buffer = newBuffer;\n return this;\n }\n\n // see https://www.rfc-editor.org/rfc/rfc4493.html#section-2.4\n digest(): Uint8ArrayBuffer {\n if (this.destroyed) throw new Error('CMAC instance was destroyed');\n const { buffer } = this;\n const msgLen = buffer.length;\n\n // Step 2:\n let n = Math.ceil(msgLen / BLOCK_SIZE); // n := ceil(len/const_Bsize);\n\n // Step 3:\n let flag: boolean; // denoting if last block is complete or not\n if (n === 0) {\n n = 1;\n flag = false;\n } else {\n flag = msgLen % BLOCK_SIZE === 0; // if len mod const_Bsize is 0\n }\n\n // Step 4:\n const lastBlockStart = (n - 1) * BLOCK_SIZE;\n const lastBlockData = buffer.subarray(lastBlockStart);\n let m_last: Uint8ArrayBuffer;\n if (flag) {\n // M_last := M_n XOR K1;\n m_last = xorBlock(new Uint8Array(lastBlockData), this.k1);\n } else {\n // M_last := padding(M_n) XOR K2;\n //\n // [...] padding(x) is the concatenation of x and a single '1',\n // followed by the minimum number of '0's, so that the total length is\n // equal to 128 bits.\n const padded = new Uint8Array(BLOCK_SIZE);\n padded.set(lastBlockData);\n padded[lastBlockData.length] = 0x80; // single '1' bit\n m_last = xorBlock(padded, this.k2);\n }\n\n // Step 5:\n let x = new Uint8Array(BLOCK_SIZE); // X := const_Zero;\n\n // Step 6:\n for (let i = 0; i < n - 1; i++) {\n const m_i = buffer.subarray(i * BLOCK_SIZE, (i + 1) * BLOCK_SIZE); // M_i\n xorBlock(x, m_i); // Y := X XOR M_i;\n encryptBlock(this.xk, x); // X := AES-128(K,Y);\n }\n\n // Step 7:\n xorBlock(x, m_last); // Y := M_last XOR X;\n encryptBlock(this.xk, x); // T := AES-128(K,Y);\n\n // cleanup:\n clean(m_last);\n\n return x; // T\n }\n\n destroy(): void {\n const { buffer, destroyed, xk, k1, k2 } = this;\n if (destroyed) return;\n this.destroyed = true;\n clean(buffer, xk, k1, k2);\n }\n}\n\n/**\n * AES-CMAC (Cipher-based Message Authentication Code).\n * Specs: [RFC 4493](https://www.rfc-editor.org/rfc/rfc4493.html).\n */\nexport const cmac: {\n (key: Uint8Array, message: Uint8Array): Uint8Array;\n create(key: Uint8Array): _CMAC;\n} = (key: Uint8Array, message: Uint8Array): Uint8Array => new _CMAC(key).update(message).digest();\ncmac.create = (key: Uint8Array): _CMAC => new _CMAC(key);\n\n/**\n * S2V (Synthetic Initialization Vector) function as described in [RFC 5297 Section 2.4](https://datatracker.ietf.org/doc/html/rfc5297.html#section-2.4).\n *\n * ```\n * S2V(K, S1, ..., Sn) {\n * if n = 0 then\n * return V = AES-CMAC(K, <one>)\n * fi\n * D = AES-CMAC(K, <zero>)\n * for i = 1 to n-1 do\n * D = dbl(D) xor AES-CMAC(K, Si)\n * done\n * if len(Sn) >= 128 then\n * T = Sn xorend D\n * else\n * T = dbl(D) xor pad(Sn)\n * fi\n * return V = AES-CMAC(K, T)\n * }\n * ```\n *\n * S2V takes a key and a vector of strings S1, S2, ..., Sn and returns a 128-bit string.\n * The S2V function is used to generate a synthetic IV for AES-SIV.\n *\n * @param key - AES key (128, 192, or 256 bits)\n * @param strings - Array of byte arrays to process\n * @returns 128-bit synthetic IV\n */\nfunction s2v(key: Uint8Array, strings: Uint8Array[]): Uint8Array {\n validateKeyLength(key);\n const len = strings.length;\n if (len > 127) {\n // see https://datatracker.ietf.org/doc/html/rfc5297.html#section-7\n throw new Error('s2v: number of input strings must be less than or equal to 127');\n }\n\n if (len === 0) return cmac(key, ONE_BLOCK);\n\n // D = AES-CMAC(K, <zero>)\n let d = cmac(key, EMPTY_BLOCK);\n\n // for i = 1 to n-1 do\n // D = dbl(D) xor AES-CMAC(K, Si)\n for (let i = 0; i < len - 1; i++) {\n dbl(d);\n const cmacResult = cmac(key, strings[i]);\n xorBlock(d, cmacResult);\n clean(cmacResult);\n }\n\n const s_n = strings[len - 1];\n let t: Uint8Array;\n\n // if len(Sn) >= 128 then\n if (s_n.byteLength >= BLOCK_SIZE) {\n // T = Sn xorend D\n t = xorend(Uint8Array.from(s_n), d);\n } else {\n // pad(Sn):\n const paddedSn = new Uint8Array(BLOCK_SIZE);\n paddedSn.set(s_n);\n paddedSn[s_n.length] = 0x80; // padding: 0x80 followed by zeros\n\n // T = dbl(D) xor pad(Sn)\n t = xorBlock(dbl(d), paddedSn);\n clean(paddedSn);\n }\n\n // V = AES-CMAC(K, T)\n const result = cmac(key, t);\n clean(d, t);\n return result;\n}\n\n/** Use `gcmsiv` or `aessiv`. */\nexport const siv: () => never = () => {\n throw new Error('\"siv\" from v1 is now \"gcmsiv\"');\n};\n\n/**\n * **SIV**: Synthetic Initialization Vector (SIV) Authenticated Encryption\n * Nonce is derived from the plaintext and AAD using the S2V function.\n * See [RFC 5297](https://datatracker.ietf.org/doc/html/rfc5297.html).\n */\nexport const aessiv: ((key: Uint8Array, ...AAD: Uint8Array[]) => Cipher) & {\n blockSize: number;\n tagLength: number;\n} = /* @__PURE__ */ wrapCipher(\n { blockSize: 16, tagLength: 16 },\n function aessiv(key: Uint8Array, ...AAD: Uint8Array[]): Cipher {\n // From RFC 5297: Section 6.1, 6.2, 6.3:\n const PLAIN_LIMIT = limit('plaintext', 0, 2 ** 132);\n const CIPHER_LIMIT = limit('ciphertext', 16, 2 ** 132 + 16);\n if (AAD.length > 126) {\n // see https://datatracker.ietf.org/doc/html/rfc5297.html#section-7\n throw new Error('\"AAD\" number of elements must be less than or equal to 126');\n }\n AAD.forEach((aad) => abytes(aad));\n abytes(key);\n if (![32, 48, 64].includes(key.length))\n throw new Error('\"aes key\" expected Uint8Array of length 32/48/64, got length=' + key.length);\n\n // The key is split into equal halves, K1 = leftmost(K, len(K)/2) and\n // K2 = rightmost(K, len(K)/2). K1 is used for S2V and K2 is used for CTR.\n const k1 = key.subarray(0, key.length / 2);\n const k2 = key.subarray(key.length / 2);\n\n return {\n // https://datatracker.ietf.org/doc/html/rfc5297.html#section-2.6\n encrypt(plaintext: Uint8Array) {\n PLAIN_LIMIT(plaintext.length);\n\n const v = s2v(k1, [...AAD, plaintext]);\n\n // clear out the 31st and 63rd (rightmost) bit:\n const q = Uint8Array.from(v);\n q[8] &= 0x7f;\n q[12] &= 0x7f;\n\n // encrypt:\n const c = ctr(k2, q).encrypt(plaintext);\n\n return concatBytes(v, c);\n },\n // https://datatracker.ietf.org/doc/html/rfc5297.html#section-2.7\n decrypt(ciphertext: Uint8Array) {\n CIPHER_LIMIT(ciphertext.length);\n const v = ciphertext.subarray(0, BLOCK_SIZE);\n const c = ciphertext.subarray(BLOCK_SIZE);\n\n // clear out the 31st and 63rd (rightmost) bit:\n const q = Uint8Array.from(v);\n q[8] &= 0x7f;\n q[12] &= 0x7f;\n\n // decrypt:\n const p = ctr(k2, q).decrypt(c);\n\n // verify tag:\n const t = s2v(k1, [...AAD, p]);\n\n if (equalBytes(t, v)) {\n return p;\n } else {\n throw new Error('invalid siv tag');\n }\n },\n };\n }\n);\n//#endregion\n\n/** Unsafe low-level internal methods. May change at any time. */\nexport const unsafe: {\n expandKeyLE: typeof expandKeyLE;\n expandKeyDecLE: typeof expandKeyDecLE;\n encrypt: typeof encrypt;\n decrypt: typeof decrypt;\n encryptBlock: typeof encryptBlock;\n decryptBlock: typeof decryptBlock;\n ctrCounter: typeof ctrCounter;\n ctr32: typeof ctr32;\n dbl: typeof dbl;\n xorBlock: typeof xorBlock;\n xorend: typeof xorend;\n s2v: typeof s2v;\n} = {\n expandKeyLE,\n expandKeyDecLE,\n encrypt,\n decrypt,\n encryptBlock,\n decryptBlock,\n ctrCounter,\n ctr32,\n dbl,\n xorBlock,\n xorend,\n s2v,\n};\n","import { gcm } from \"@noble/ciphers/aes.js\";\nimport { generateRandomBytes } from \"@fileverse/crypto/utils\";\n\nconst KEY_LEN = 32;\nconst IV_LEN = 12;\nconst TAG_LEN = 16;\n\nconst b64ToBytes = (b64: string) => Uint8Array.from(Buffer.from(b64, \"base64\"));\nconst bytesToB64 = (b: Uint8Array) => Buffer.from(b).toString(\"base64\");\n\nimport type { DecryptionOptions } from \"../types\";\nexport type { DecryptionOptions };\n\nexport function gcmEncrypt(plaintext: Uint8Array) {\n const key = generateRandomBytes(KEY_LEN);\n const iv = generateRandomBytes(IV_LEN);\n if (key.length !== KEY_LEN) throw new Error(\"key must be 32 bytes\");\n if (iv.length !== IV_LEN) throw new Error(\"iv must be 12 bytes\");\n\n const out = gcm(key, iv).encrypt(plaintext);\n const ciphertext = out.subarray(0, out.length - TAG_LEN);\n const authTag = out.subarray(out.length - TAG_LEN);\n\n return {\n ciphertext,\n authTag: bytesToB64(authTag),\n key: bytesToB64(key),\n iv: bytesToB64(iv),\n };\n}\n\nexport function gcmDecrypt(ciphertext: Uint8Array, opts: DecryptionOptions) {\n const key = b64ToBytes(opts.key);\n const iv = b64ToBytes(opts.iv);\n const tag = b64ToBytes(opts.authTag);\n if (key.length !== KEY_LEN) throw new Error(\"key must be 32 bytes\");\n if (iv.length !== IV_LEN) throw new Error(\"iv must be 12 bytes\");\n if (tag.length !== TAG_LEN) throw new Error(\"authTag must be 16 bytes\");\n\n const combined = new Uint8Array(ciphertext.length + TAG_LEN);\n combined.set(ciphertext, 0);\n combined.set(tag, ciphertext.length);\n\n return gcm(key, iv).decrypt(combined);\n}\n","import { getArgon2idHash } from \"@fileverse/crypto/argon\";\nimport { bytesToBase64, generateRandomBytes } from \"@fileverse/crypto/utils\";\nimport { derivePBKDF2Key, encryptAesCBC } from \"@fileverse/crypto/kdf\";\nimport { secretBoxEncrypt } from \"@fileverse/crypto/nacl\";\nimport hkdf from \"futoin-hkdf\";\n\nimport tweetnacl from \"tweetnacl\";\nimport { fromUint8Array, toUint8Array } from \"js-base64\";\nimport { gcmEncrypt } from \"./file-encryption\";\nimport { toAESKey, aesEncrypt } from \"@fileverse/crypto/webcrypto\";\nimport axios from \"axios\";\nimport { ADD_FILE_METHOD, DELETED_FILE_ABI, EDIT_FILE_METHOD, UPLOAD_SERVER_URL } from \"../constants\";\nimport type { UploadFileAuthParams, FileMetadataParams, UploadFilesParams } from \"../types\";\nimport { encodeFunctionData, type Hex, parseEventLogs, type Abi } from \"viem\";\n\ninterface LinkKeyMaterialParams {\n ddocId: string;\n linkKey: string | undefined;\n linkKeyNonce: string | undefined;\n}\n\nconst deriveKeyFromAg2Hash = async (pass: string, salt: Uint8Array) => {\n const key = await getArgon2idHash(pass, salt);\n\n return hkdf(Buffer.from(key), tweetnacl.secretbox.keyLength, {\n info: Buffer.from(\"encryptionKey\"),\n });\n};\n\nconst decryptSecretKey = async (docId: string, nonce: string, encryptedSecretKey: string) => {\n const derivedKey = await deriveKeyFromAg2Hash(docId, toUint8Array(nonce));\n\n return tweetnacl.secretbox.open(toUint8Array(encryptedSecretKey), toUint8Array(nonce), derivedKey);\n};\n\nconst getExistingEncryptionMaterial = async (\n existingEncryptedSecretKey: string,\n existingNonce: string,\n docId: string,\n) => {\n const secretKey = await decryptSecretKey(docId, existingNonce, existingEncryptedSecretKey);\n return {\n encryptedSecretKey: existingEncryptedSecretKey,\n nonce: toUint8Array(existingNonce),\n secretKey,\n };\n};\n\nconst getNaclSecretKey = async (ddocId: string) => {\n const { secretKey } = tweetnacl.box.keyPair();\n const nonce = tweetnacl.randomBytes(tweetnacl.secretbox.nonceLength);\n\n const derivedKey = await deriveKeyFromAg2Hash(ddocId, nonce);\n\n const encryptedSecretKey = fromUint8Array(tweetnacl.secretbox(secretKey, nonce, derivedKey), true);\n\n return { nonce, encryptedSecretKey, secretKey };\n};\n\nexport const generateLinkKeyMaterial = async (params: LinkKeyMaterialParams) => {\n if (params.linkKeyNonce && params.linkKey) {\n const { encryptedSecretKey, nonce, secretKey } = await getExistingEncryptionMaterial(\n params.linkKey,\n params.linkKeyNonce,\n params.ddocId,\n );\n if (secretKey) return { encryptedSecretKey, nonce, secretKey };\n }\n const { secretKey, nonce, encryptedSecretKey } = await getNaclSecretKey(params.ddocId);\n\n return { secretKey, nonce, encryptedSecretKey };\n};\n\nexport const jsonToFile = (json: any, fileName: string) => {\n const blob = new Blob([JSON.stringify(json)], {\n type: \"application/json\",\n });\n\n const file = new File([blob], fileName, {\n type: \"application/json\",\n });\n\n return file;\n};\n\nconst appendAuthTagIvToBlob = async (blob: Blob, authTag: Uint8Array, iv: Uint8Array) => {\n const encryptedFileBytes = await blob.arrayBuffer();\n const encryptedBytes = new Uint8Array(encryptedFileBytes);\n const combinedLength = encryptedBytes.length + authTag.length + iv.length;\n const combinedArray = new Uint8Array(combinedLength);\n\n let offset = 0;\n combinedArray.set(encryptedBytes, offset);\n offset += encryptedBytes.length;\n\n combinedArray.set(authTag, offset);\n offset += authTag.length;\n\n combinedArray.set(iv, offset);\n\n return new Blob([combinedArray], { type: blob.type });\n};\n\nexport const encryptFile = async (file: File) => {\n const arrayBuffer = await file.arrayBuffer();\n\n const plaintext = new Uint8Array(arrayBuffer);\n\n const { ciphertext, authTag, key, iv } = gcmEncrypt(plaintext);\n\n const encryptedBlob = new Blob([ciphertext], { type: file.type });\n\n const encryptedBlobWithAuthTagIv = await appendAuthTagIvToBlob(\n encryptedBlob,\n toUint8Array(authTag),\n toUint8Array(iv),\n );\n\n return {\n encryptedFile: new File([encryptedBlobWithAuthTagIv], file.name),\n key,\n };\n};\n\nexport const getNonceAppendedCipherText = (nonce: Uint8Array, cipherText: Uint8Array) => {\n return fromUint8Array(nonce, true) + \"__n__\" + fromUint8Array(cipherText, true);\n};\n\nexport const jsonToBytes = (json: Record<string, any>) => new TextEncoder().encode(JSON.stringify(json));\n\nexport const buildLinklock = (key: Uint8Array, fileKey: Uint8Array, commentKey: Uint8Array) => {\n const ikm = generateRandomBytes();\n const kdfSalt = generateRandomBytes();\n const derivedEphermalKey = derivePBKDF2Key(ikm, kdfSalt);\n\n const { iv, cipherText } = encryptAesCBC(\n {\n key: derivedEphermalKey,\n message: fileKey,\n },\n \"base64\",\n );\n\n const { iv: commentIv, cipherText: commentCipherText } = encryptAesCBC(\n {\n key: derivedEphermalKey,\n message: commentKey,\n },\n \"base64\",\n );\n\n const encryptedIkm = secretBoxEncrypt(ikm, key);\n\n const lockedFileKey = iv + \"__n__\" + cipherText;\n\n const lockedChatKey = commentIv + \"__n__\" + commentCipherText;\n\n const keyMaterial = bytesToBase64(kdfSalt) + \"__n__\" + encryptedIkm;\n\n const fileKeyNonce = generateRandomBytes(24);\n const encryptedFileKey = tweetnacl.secretbox(jsonToBytes({ key: fromUint8Array(fileKey) }), fileKeyNonce, key);\n\n const chatKeyNonce = generateRandomBytes(24);\n const encryptedChatKey = tweetnacl.secretbox(commentKey, chatKeyNonce, key);\n\n return {\n lockedFileKey: getNonceAppendedCipherText(fileKeyNonce, encryptedFileKey),\n lockedChatKey: getNonceAppendedCipherText(chatKeyNonce, encryptedChatKey),\n lockedFileKey_v2: lockedFileKey,\n lockedChatKey_v2: lockedChatKey,\n keyMaterial,\n };\n};\n\nexport const encryptTitleWithFileKey = async (args: { title: string; key: string }) => {\n const key = await toAESKey(toUint8Array(args.key));\n if (!key) throw new Error(\"Key is undefined\");\n\n const titleBytes = new TextEncoder().encode(args.title);\n\n const encryptedTitle = await aesEncrypt(key, titleBytes, \"base64\");\n\n return encryptedTitle;\n};\n\ninterface UploadFileParams {\n file: File;\n ipfsType: string;\n appFileId: string;\n}\n\nexport type { UploadFileAuthParams };\n\nexport const uploadFileToIPFS = async (fileParams: UploadFileParams, authParams: UploadFileAuthParams) => {\n const { file, ipfsType, appFileId } = fileParams;\n const { token, invoker, contractAddress } = authParams;\n\n const body = new FormData();\n body.append(\"file\", file);\n body.append(\"ipfsType\", ipfsType);\n body.append(\"appFileId\", appFileId);\n\n body.append(\"sourceApp\", \"ddoc\");\n const uploadEndpoint = UPLOAD_SERVER_URL + \"upload\";\n const response = await axios.post(uploadEndpoint, body, {\n headers: {\n Authorization: `Bearer ${token}`,\n contract: contractAddress,\n invoker: invoker,\n chain: process.env.chainId,\n },\n });\n\n return response.data.ipfsHash;\n};\n\nconst getEditFileTrxCalldata = (args: {\n fileId: number;\n appFileId: string;\n metadataHash: string;\n contentHash: string;\n gateHash: string;\n}) => {\n return encodeFunctionData({\n abi: EDIT_FILE_METHOD,\n functionName: \"editFile\",\n args: [BigInt(args.fileId), args.appFileId, args.metadataHash, args.contentHash, args.gateHash, 2, BigInt(0)],\n });\n};\n\nconst getAddFileTrxCalldata = (args: {\n appFileId: string;\n metadataHash: string;\n contentHash: string;\n gateHash: string;\n}) => {\n return encodeFunctionData({\n abi: ADD_FILE_METHOD,\n functionName: \"addFile\",\n args: [args.appFileId, 2, args.metadataHash, args.contentHash, args.gateHash, BigInt(0)],\n });\n};\n\nexport const prepareCallData = (args: {\n metadataHash: string;\n contentHash: string;\n gateHash: string;\n appFileId: string;\n fileId?: number;\n}) => {\n if (args.fileId) {\n return getEditFileTrxCalldata({\n fileId: args.fileId,\n appFileId: args.appFileId,\n metadataHash: args.metadataHash,\n contentHash: args.contentHash,\n gateHash: args.gateHash,\n });\n }\n return getAddFileTrxCalldata(args);\n};\n\nexport const prepareDeleteFileCallData = (args: { onChainFileId: number }) => {\n return encodeFunctionData({\n abi: DELETED_FILE_ABI,\n functionName: \"deleteFile\",\n args: [BigInt(args.onChainFileId)],\n });\n};\n\nexport const createEncryptedContentFile = async (content: any) => {\n const contentFile = jsonToFile(\n { file: content, source: \"ddoc\" },\n `${fromUint8Array(generateRandomBytes(16))}-CONTENT`,\n );\n return encryptFile(contentFile);\n};\n\nexport type { FileMetadataParams };\n\nexport const buildFileMetadata = (params: FileMetadataParams) => ({\n title: params.encryptedTitle,\n size: params.encryptedFileSize,\n mimeType: \"application/json\",\n appLock: params.appLock,\n ownerLock: params.ownerLock,\n ddocId: params.ddocId,\n nonce: params.nonce,\n owner: params.owner,\n version: \"4\",\n sourceApp: \"fileverse-api\",\n});\n\nexport const parseFileEventLog = (logs: any[], eventName: string, abi: Abi): number => {\n const [parsedLog] = parseEventLogs({ abi, logs, eventName });\n\n if (!parsedLog) throw new Error(`${eventName} event not found`);\n\n const fileId = (parsedLog as any).args.fileId;\n\n if (fileId === undefined || fileId === null) throw new Error(\"FileId not found in event logs\");\n\n return Number(fileId);\n};\n\nexport type { UploadFilesParams };\n\nexport const uploadAllFilesToIPFS = async (params: UploadFilesParams, authParams: UploadFileAuthParams) => {\n const { metadata, encryptedFile, linkLock, ddocId } = params;\n\n const [metadataHash, contentHash, gateHash] = await Promise.all([\n uploadFileToIPFS(\n {\n file: jsonToFile(metadata, `${fromUint8Array(generateRandomBytes(16))}-METADATA`),\n ipfsType: \"METADATA\",\n appFileId: ddocId,\n },\n authParams,\n ),\n uploadFileToIPFS(\n {\n file: encryptedFile,\n ipfsType: \"CONTENT\",\n appFileId: ddocId,\n },\n authParams,\n ),\n uploadFileToIPFS(\n {\n file: jsonToFile(linkLock, `${fromUint8Array(generateRandomBytes(16))}-GATE`),\n ipfsType: \"GATE\",\n appFileId: ddocId,\n },\n authParams,\n ),\n ]);\n\n return { metadataHash, contentHash, gateHash };\n};\n","import { fromUint8Array, toUint8Array } from \"js-base64\";\nimport { KeyStore } from \"./key-store\";\nimport {\n buildLinklock,\n encryptTitleWithFileKey,\n generateLinkKeyMaterial,\n prepareCallData,\n createEncryptedContentFile,\n buildFileMetadata,\n parseFileEventLog,\n uploadAllFilesToIPFS,\n UploadFileAuthParams,\n prepareDeleteFileCallData,\n} from \"./file-utils\";\nimport { AgentClient } from \"./smart-agent\";\nimport { generateAESKey, exportAESKey } from \"@fileverse/crypto/webcrypto\";\nimport { STATIC_CONFIG } from \"../cli/constants\";\nimport { DELETED_FILE_EVENT, EDITED_FILE_EVENT } from \"../constants\";\nimport { markdownToYjs } from \"@fileverse/content-processor\";\nimport { logger } from \"../infra\";\n\nexport class FileManager {\n private keyStore: KeyStore;\n private agentClient: AgentClient;\n\n constructor(keyStore: KeyStore, agentClient: AgentClient) {\n this.keyStore = keyStore;\n this.agentClient = agentClient;\n }\n\n private createLocks(key: string, encryptedSecretKey: string, commentKey: Uint8Array) {\n const appLock = {\n lockedFileKey: this.keyStore.encryptData(toUint8Array(key)),\n lockedLinkKey: this.keyStore.encryptData(toUint8Array(encryptedSecretKey)),\n lockedChatKey: this.keyStore.encryptData(commentKey),\n };\n return { appLock, ownerLock: { ...appLock } };\n }\n\n private async getAuthParams(): Promise<UploadFileAuthParams> {\n return {\n token: await this.keyStore.getAuthToken(STATIC_CONFIG.SERVER_DID),\n contractAddress: this.keyStore.getPortalAddress(),\n invoker: this.agentClient.getAgentAddress(),\n };\n }\n\n private async executeFileOperation(callData: `0x${string}`) {\n return this.agentClient.executeUserOperationRequest(\n {\n contractAddress: this.keyStore.getPortalAddress(),\n data: callData,\n },\n 1000000,\n );\n }\n\n private async sendFileOperation(callData: `0x${string}`) {\n return this.agentClient.sendUserOperation(\n {\n contractAddress: this.keyStore.getPortalAddress(),\n data: callData,\n },\n 1000000,\n );\n }\n\n async getProxyAuthParams() {\n return this.agentClient.getAuthParams();\n }\n\n async submitAddFileTrx(file: any) {\n logger.debug(`Preparing to add file ${file.ddocId}`);\n const { encryptedSecretKey, nonce, secretKey } = await generateLinkKeyMaterial({\n ddocId: file.ddocId,\n linkKey: file.linkKey,\n linkKeyNonce: file.linkKeyNonce,\n });\n\n const yJSContent = markdownToYjs(file.content);\n const { encryptedFile, key } = await createEncryptedContentFile(yJSContent);\n logger.debug(`Generated encrypted content file for file ${file.ddocId}`);\n const commentKey = await exportAESKey(await generateAESKey(128));\n\n const { appLock, ownerLock } = this.createLocks(key, encryptedSecretKey, commentKey);\n const linkLock = buildLinklock(secretKey, toUint8Array(key), commentKey);\n\n const encryptedTitle = await encryptTitleWithFileKey({\n title: file.title || \"Untitled\",\n key,\n });\n const metadata = buildFileMetadata({\n encryptedTitle,\n encryptedFileSize: encryptedFile.size,\n appLock,\n ownerLock,\n ddocId: file.ddocId,\n nonce: fromUint8Array(nonce),\n owner: this.agentClient.getAgentAddress(),\n });\n\n const authParams = await this.getAuthParams();\n const { metadataHash, contentHash, gateHash } = await uploadAllFilesToIPFS(\n { metadata, encryptedFile, linkLock, ddocId: file.ddocId },\n authParams,\n );\n logger.debug(`Uploaded files to IPFS for file ${file.ddocId}`);\n\n const callData = prepareCallData({\n metadataHash,\n contentHash,\n gateHash,\n appFileId: file.ddocId,\n fileId: file.fileId,\n });\n logger.debug(`Prepared call data for file ${file.ddocId}`);\n\n const userOpHash = await this.sendFileOperation(callData);\n logger.debug(`Submitted user op for file ${file.ddocId}`);\n return {\n userOpHash,\n linkKey: encryptedSecretKey,\n linkKeyNonce: fromUint8Array(nonce),\n commentKey: fromUint8Array(commentKey),\n metadata,\n };\n }\n\n async updateFile(file: any) {\n logger.debug(`Updating file ${file.ddocId} with onChainFileId ${file.onChainFileId}`);\n const { encryptedSecretKey, nonce, secretKey } = await generateLinkKeyMaterial({\n ddocId: file.ddocId,\n linkKey: file.linkKey,\n linkKeyNonce: file.linkKeyNonce,\n });\n\n logger.debug(`Generating encrypted content file for file ${file.ddocId} with onChainFileId ${file.onChainFileId}`);\n\n const yjsContent = markdownToYjs(file.content);\n const { encryptedFile, key } = await createEncryptedContentFile(yjsContent);\n const commentKey = toUint8Array(file.commentKey);\n\n const { appLock, ownerLock } = this.createLocks(key, encryptedSecretKey, commentKey);\n const linkLock = buildLinklock(secretKey, toUint8Array(key), commentKey);\n\n const encryptedTitle = await encryptTitleWithFileKey({\n title: file.title || \"Untitled\",\n key,\n });\n const metadata = buildFileMetadata({\n encryptedTitle,\n encryptedFileSize: encryptedFile.size,\n appLock,\n ownerLock,\n ddocId: file.ddocId,\n nonce: fromUint8Array(nonce),\n owner: this.agentClient.getAgentAddress(),\n });\n\n const authParams = await this.getAuthParams();\n logger.debug(`Uploading files to IPFS for file ${file.ddocId} with onChainFileId ${file.onChainFileId}`);\n const { metadataHash, contentHash, gateHash } = await uploadAllFilesToIPFS(\n { metadata, encryptedFile, linkLock, ddocId: file.ddocId },\n authParams,\n );\n\n const callData = prepareCallData({\n metadataHash,\n contentHash,\n gateHash,\n appFileId: file.ddocId,\n fileId: file.onChainFileId,\n });\n logger.debug(`Executing file operation for file ${file.ddocId} with onChainFileId ${file.onChainFileId}`);\n\n const { logs } = await this.executeFileOperation(callData);\n const onChainFileId = parseFileEventLog(logs, \"EditedFile\", EDITED_FILE_EVENT);\n\n return { onChainFileId, metadata };\n }\n\n async deleteFile(file: any) {\n logger.debug(`Deleting file ${file.ddocId} with onChainFileId ${file.onChainFileId}`);\n const callData = prepareDeleteFileCallData({\n onChainFileId: file.onChainFileId,\n });\n logger.debug(`Prepared call data for deleting file ${file.ddocId} with onChainFileId ${file.onChainFileId}`);\n\n const { logs } = await this.executeFileOperation(callData);\n parseFileEventLog(logs, \"DeletedFile\", DELETED_FILE_EVENT);\n logger.debug(`Executed file operation for deleting file ${file.ddocId} with onChainFileId ${file.onChainFileId}`);\n return {\n fileId: file.id,\n onChainFileId: file.onChainFileId,\n metadata: file.metadata,\n };\n }\n}\n","import { FilesModel, PortalsModel } from \"../../infra/database/models\";\nimport { logger } from \"../../infra\";\nimport { KeyStore } from \"../../sdk/key-store\";\nimport { AuthTokenProvider } from \"../../sdk/auth-token-provider\";\nimport { fromUint8Array, toUint8Array } from \"js-base64\";\nimport { Hex, stringToBytes } from \"viem\";\nimport { deriveHKDFKey } from \"@fileverse/crypto/kdf\";\nimport { generateKeyPairFromSeed } from \"@stablelib/ed25519\";\nimport * as ucans from \"@ucans/ucans\";\nimport { AgentClient } from \"../../sdk/smart-agent\";\nimport { FileManager } from \"../../sdk/file-manager\";\nimport { getRuntimeConfig } from \"../../config\";\n\nimport type { PublishResult } from \"../../types\";\nimport type { File, Portal } from \"../../types\";\n\ninterface PublishContext {\n file: File | undefined;\n portalDetails: Portal;\n apiKey: string;\n}\n\nasync function getPortalData(fileId: string): Promise<PublishContext> {\n const file = await FilesModel.findByIdIncludingDeleted(fileId);\n if (!file) {\n throw new Error(`File with _id ${fileId} not found`);\n }\n\n const portalDetails = await PortalsModel.findByPortalAddress(file.portalAddress);\n if (!portalDetails) {\n throw new Error(`Portal with address ${file.portalAddress} not found`);\n }\n\n const apiKey = getRuntimeConfig().API_KEY;\n if (!apiKey) {\n throw new Error(\"API key is not set\");\n }\n\n return { file, portalDetails, apiKey };\n}\n\nfunction deriveCollaboratorKeys(apiKeySeed: Uint8Array) {\n const salt = new Uint8Array([0]);\n\n const privateAccountKey = deriveHKDFKey(apiKeySeed, salt, stringToBytes(\"COLLABORATOR_PRIVATE_KEY\"));\n\n const ucanDerivedSecret = deriveHKDFKey(apiKeySeed, salt, stringToBytes(\"COLLABORATOR_UCAN_SECRET\"));\n\n const { secretKey: ucanSecret } = generateKeyPairFromSeed(ucanDerivedSecret);\n\n return { privateAccountKey, ucanSecret };\n}\n\nconst createFileManager = async (\n portalSeed: string,\n portalAddress: Hex,\n ucanSecret: Uint8Array,\n privateAccountKey: Uint8Array,\n): Promise<FileManager> => {\n const keyPair = ucans.EdKeypair.fromSecretKey(fromUint8Array(ucanSecret), {\n exportable: true,\n });\n\n const authTokenProvider = new AuthTokenProvider(keyPair, portalAddress);\n const keyStore = new KeyStore(toUint8Array(portalSeed), portalAddress, authTokenProvider);\n\n const agentClient = new AgentClient(authTokenProvider);\n await agentClient.initializeAgentClient(privateAccountKey);\n\n return new FileManager(keyStore, agentClient);\n};\n\nconst executeOperation = async (\n fileManager: FileManager,\n file: any,\n operation: \"update\" | \"delete\",\n): Promise<PublishResult> => {\n\n if (operation === \"update\") {\n const result = await fileManager.updateFile(file);\n return { success: true, ...result };\n }\n\n if (operation === \"delete\") {\n const result = await fileManager.deleteFile(file);\n return { success: true, ...result };\n }\n\n throw new Error(`Invalid operation: ${operation}`);\n};\n\nexport const handleExistingFileOp = async (fileId: string, operation: \"update\" | \"delete\"): Promise<PublishResult> => {\n try {\n const { file, portalDetails, apiKey } = await getPortalData(fileId);\n\n const apiKeySeed = toUint8Array(apiKey);\n const { privateAccountKey, ucanSecret } = deriveCollaboratorKeys(apiKeySeed);\n\n const fileManager = await createFileManager(\n portalDetails.portalSeed,\n portalDetails.portalAddress as Hex,\n ucanSecret,\n privateAccountKey,\n );\n\n return executeOperation(fileManager, file, operation);\n } catch (error: any) {\n logger.error(`Failed to publish file ${fileId}:`, error);\n throw error;\n }\n};\n\nexport const handleNewFileOp = async (\n fileId: string,\n): Promise<{\n userOpHash: string;\n linkKey: string;\n linkKeyNonce: string;\n commentKey: string;\n metadata: Record<string, unknown>;\n}> => {\n const { file, portalDetails, apiKey } = await getPortalData(fileId);\n const apiKeySeed = toUint8Array(apiKey);\n const { privateAccountKey, ucanSecret } = deriveCollaboratorKeys(apiKeySeed);\n const fileManager = await createFileManager(\n portalDetails.portalSeed,\n portalDetails.portalAddress as Hex,\n ucanSecret,\n privateAccountKey,\n );\n return fileManager.submitAddFileTrx(file);\n};\n\nexport const getProxyAuthParams = async (\n fileId: string,\n): Promise<{\n authToken: string;\n portalAddress: Hex;\n invokerAddress: Hex;\n}> => {\n const { portalDetails, apiKey } = await getPortalData(fileId);\n const apiKeySeed = toUint8Array(apiKey);\n const { privateAccountKey, ucanSecret } = deriveCollaboratorKeys(apiKeySeed);\n const fileManager = await createFileManager(\n portalDetails.portalSeed,\n portalDetails.portalAddress as Hex,\n ucanSecret,\n privateAccountKey,\n );\n return fileManager.getProxyAuthParams();\n};\n","import { PortalsModel } from \"../../infra/database/models\";\nimport type { Portal, SavePortalInput } from \"../../types\";\n\nexport async function savePortal(input: SavePortalInput): Promise<Portal> {\n if (!input.portalAddress || !input.portalSeed || !input.ownerAddress) {\n throw new Error(\"portalAddress, portalSeed, and ownerAddress are required\");\n }\n\n return PortalsModel.upsert(input);\n}\n","import { ApiKeysModel, PortalsModel } from \"../../infra/database/models\";\nimport type { AddApiKeyInput, ApiKey } from \"../../types\";\n\nexport async function addApiKey(input: AddApiKeyInput): Promise<ApiKey> {\n if (!input.apiKeySeed || !input.name || !input.collaboratorAddress || !input.portalAddress) {\n throw new Error(\"apiKeySeed, name, collaboratorAddress, and portalAddress are required\");\n }\n\n const portal = await PortalsModel.findByPortalAddress(input.portalAddress);\n if (!portal) {\n throw new Error(`Portal with address ${input.portalAddress} does not exist`);\n }\n\n return ApiKeysModel.create(input);\n}\n","import { ApiKeysModel, type ApiKey } from \"../../infra/database/models\";\n\nexport async function removeApiKey(collaboratorAddress: string): Promise<ApiKey> {\n if (!collaboratorAddress) {\n throw new Error(\"collaboratorAddress is required\");\n }\n\n const apiKey = await ApiKeysModel.findByCollaboratorAddress(collaboratorAddress);\n if (!apiKey) {\n throw new Error(\"API key not found\");\n }\n\n await ApiKeysModel.delete(apiKey._id);\n return { ...apiKey, isDeleted: 1 };\n}\n","import { handleExistingFileOp, handleNewFileOp, getProxyAuthParams } from \"./publish\";\nimport { savePortal } from \"./savePortal\";\nimport { addApiKey } from \"./saveApiKey\";\nimport { removeApiKey } from \"./removeApiKey\";\n\nexport { handleExistingFileOp, handleNewFileOp, getProxyAuthParams, savePortal, addApiKey, removeApiKey };\n","import { HttpRequestError } from \"viem\";\n\nexport class RateLimitError extends Error {\n readonly retryAfterSeconds: number;\n\n constructor(retryAfterSeconds: number, message = \"Rate limit exceeded\") {\n super(message);\n this.name = \"RateLimitError\";\n this.retryAfterSeconds = retryAfterSeconds;\n }\n}\n\nconst MAX_RETRY_AFTER_SECONDS = 300;\nconst DEFAULT_RETRY_AFTER_SECONDS = 3600;\n\nfunction parseRetryAfterRaw(raw: string | null): number {\n if (!raw) return DEFAULT_RETRY_AFTER_SECONDS;\n const parsed = parseInt(raw, 10);\n if (!Number.isNaN(parsed) && parsed >= 0) return Math.min(parsed, MAX_RETRY_AFTER_SECONDS);\n const date = Date.parse(raw);\n if (!Number.isNaN(date)) {\n const seconds = Math.max(0, Math.ceil((date - Date.now()) / 1000));\n return Math.min(seconds, MAX_RETRY_AFTER_SECONDS);\n }\n return DEFAULT_RETRY_AFTER_SECONDS;\n}\n\nexport const parseRetryAfterSeconds = (response: Response): number =>\n parseRetryAfterRaw(response.headers.get(\"Retry-After\"));\n\nexport const parseRetryAfterFromHeaders = (headers?: Headers): number =>\n parseRetryAfterRaw(headers?.get(\"Retry-After\") ?? null);\n\nexport function normalizeRateLimitError(error: unknown): unknown {\n if (!(error instanceof HttpRequestError) || error.status !== 429) return error;\n const retryAfter = parseRetryAfterFromHeaders(error.headers);\n const message = \"Beta API rate limit reached. Try again in an hour please!\"\n return new RateLimitError(retryAfter, message);\n}\n","import { getRuntimeConfig } from \"../../config\";\nimport { handleNewFileOp, getProxyAuthParams, handleExistingFileOp } from \"../../domain/portal\";\nimport { FilesModel, EventsModel } from \"../database/models\";\nimport type { Event, ProcessResult, UpdateFilePayload } from \"../../types\";\nimport { logger } from \"../index\";\nimport { waitForUserOpReceipt } from \"../../sdk/pimlico-utils\";\nimport { parseFileEventLog } from \"../../sdk/file-utils\";\nimport { ADDED_FILE_EVENT } from \"../../constants\";\nimport { RateLimitError, normalizeRateLimitError } from \"../../errors/rate-limit\";\n\nexport type { ProcessResult };\n\nexport const processEvent = async (event: Event): Promise<ProcessResult> => {\n const { fileId, type } = event;\n\n try {\n switch (type) {\n case \"create\":\n await processCreateEvent(event);\n break;\n case \"update\":\n await processUpdateEvent(event);\n break;\n case \"delete\":\n await processDeleteEvent(event);\n break;\n default:\n throw new Error(`Unknown event type: ${type}`);\n }\n return { success: true };\n } catch (error) {\n const normalized = normalizeRateLimitError(error);\n if (normalized instanceof RateLimitError) throw normalized;\n const errorMsg = error instanceof Error ? error.message : String(error);\n logger.error(`Error processing ${type} event for file ${fileId}:`, errorMsg);\n return { success: false, error: errorMsg };\n }\n};\n\nconst onTransactionSuccess = async (\n fileId: string,\n file: Awaited<ReturnType<typeof FilesModel.findByIdIncludingDeleted>>,\n onChainFileId: number,\n pending: { linkKey: string; linkKeyNonce: string; commentKey: string; metadata: Record<string, unknown> },\n): Promise<void> => {\n const frontendUrl = getRuntimeConfig().FRONTEND_URL;\n const payload: UpdateFilePayload = {\n onchainVersion: file!.localVersion,\n onChainFileId,\n linkKey: pending.linkKey,\n linkKeyNonce: pending.linkKeyNonce,\n commentKey: pending.commentKey,\n metadata: pending.metadata,\n link: `${frontendUrl}/${file!.portalAddress}/${onChainFileId}#key=${pending.linkKey}`,\n };\n const updatedFile = await FilesModel.update(fileId, payload, file!.portalAddress);\n if (updatedFile.localVersion === updatedFile.onchainVersion) {\n await FilesModel.update(fileId, { syncStatus: \"synced\" }, file!.portalAddress);\n }\n};\n\nconst processCreateEvent = async (event: Event): Promise<void> => {\n const { fileId } = event;\n\n const file = await FilesModel.findByIdIncludingDeleted(fileId);\n if (!file) {\n throw new Error(`File ${fileId} not found`);\n }\n\n if (file.isDeleted === 1) {\n logger.info(`File ${fileId} is deleted, skipping create event`);\n return;\n }\n\n const waitContext = await getProxyAuthParams(fileId);\n const timeout = 120000;\n\n if (event.userOpHash) {\n const receipt = await waitForUserOpReceipt(\n event.userOpHash as `0x${string}`,\n waitContext.authToken,\n waitContext.portalAddress,\n waitContext.invokerAddress,\n timeout,\n );\n if (!receipt.success) {\n await EventsModel.clearEventPendingOp(event._id);\n throw new Error(`User operation failed: ${receipt.reason}`);\n }\n const onChainFileId = parseFileEventLog(receipt.logs, \"AddedFile\", ADDED_FILE_EVENT);\n const pending = JSON.parse(event.pendingPayload!) as {\n linkKey: string;\n linkKeyNonce: string;\n commentKey: string;\n metadata: Record<string, unknown>;\n };\n await onTransactionSuccess(fileId, file, onChainFileId, pending);\n await EventsModel.clearEventPendingOp(event._id);\n logger.info(`File ${file.ddocId} created and published successfully (resumed from pending op)`);\n return;\n }\n\n const result = await handleNewFileOp(fileId);\n await EventsModel.setEventPendingOp(event._id, result.userOpHash, {\n linkKey: result.linkKey,\n linkKeyNonce: result.linkKeyNonce,\n commentKey: result.commentKey,\n metadata: result.metadata,\n });\n\n const receipt = await waitForUserOpReceipt(\n result.userOpHash as `0x${string}`,\n waitContext.authToken,\n waitContext.portalAddress,\n waitContext.invokerAddress,\n timeout,\n );\n if (!receipt.success) {\n await EventsModel.clearEventPendingOp(event._id);\n throw new Error(`User operation failed: ${receipt.reason}`);\n }\n const onChainFileId = parseFileEventLog(receipt.logs, \"AddedFile\", ADDED_FILE_EVENT);\n await onTransactionSuccess(fileId, file, onChainFileId, {\n linkKey: result.linkKey,\n linkKeyNonce: result.linkKeyNonce,\n commentKey: result.commentKey,\n metadata: result.metadata,\n });\n await EventsModel.clearEventPendingOp(event._id);\n logger.info(`File ${file.ddocId} created and published successfully`);\n};\n\nconst processUpdateEvent = async (event: Event): Promise<void> => {\n const { fileId } = event;\n\n const file = await FilesModel.findByIdExcludingDeleted(fileId);\n if (!file) {\n return;\n }\n\n if (file.localVersion <= file.onchainVersion) {\n return;\n }\n\n const result = await handleExistingFileOp(fileId, \"update\");\n if (!result.success) {\n throw new Error(`Publish failed for file ${fileId}`);\n }\n\n const payload: UpdateFilePayload = {\n onchainVersion: file.localVersion,\n metadata: result.metadata,\n };\n const updatedFile = await FilesModel.update(fileId, payload, file.portalAddress);\n\n if (updatedFile.localVersion === updatedFile.onchainVersion) {\n await FilesModel.update(fileId, { syncStatus: \"synced\" }, file.portalAddress);\n }\n logger.info(`File ${file.ddocId} updated and published successfully`);\n};\n\nconst processDeleteEvent = async (event: Event): Promise<void> => {\n const { fileId } = event;\n\n const file = await FilesModel.findByIdIncludingDeleted(fileId);\n if (!file) {\n return;\n }\n\n if (file.isDeleted === 1 && file.syncStatus === \"synced\") {\n logger.info(`File ${fileId} deletion already synced, skipping`);\n return;\n }\n\n const payload: UpdateFilePayload = {\n syncStatus: \"synced\",\n isDeleted: 1,\n };\n\n if (file.onChainFileId !== null || file.onChainFileId !== undefined) {\n const result = await handleExistingFileOp(fileId, \"delete\");\n if (!result.success) {\n throw new Error(`Publish failed for file ${fileId}`);\n }\n\n payload.onchainVersion = file.localVersion;\n payload.metadata = result.metadata;\n payload.isDeleted = 1;\n }\n\n await FilesModel.update(fileId, payload, file.portalAddress);\n\n logger.info(`File ${fileId} delete event processed (syncStatus set to synced)`);\n};\n","import { logger } from \"../index\";\nimport { processEvent } from \"./eventProcessor\";\nimport { onNewEvent } from \"./workerSignal\";\nimport { EventsModel } from \"../database/models\";\nimport type { Event } from \"../database/models\";\nimport { RateLimitError } from \"../../errors/rate-limit\";\n\nconst DEFAULT_CONCURRENCY = 5;\nconst STALE_THRESHOLD_MS = 5 * 60 * 1000;\nconst SIGNAL_RETRY_DELAY_MS = 50;\nconst FALLBACK_POLL_MS = 30000;\nconst MAX_RETRIES = 10;\n\nexport class FileEventsWorker {\n private isRunning = false;\n private concurrency: number;\n private activeProcessors = new Map<string, Promise<void>>();\n private signalCleanup: (() => void) | null = null;\n private pendingSignal = false;\n private wakeResolver: (() => void) | null = null;\n\n constructor(concurrency: number = DEFAULT_CONCURRENCY) {\n this.concurrency = concurrency;\n }\n\n async start(): Promise<void> {\n if (this.isRunning) {\n logger.warn(\"Worker is already running\");\n return;\n }\n this.isRunning = true;\n\n const staleCount = await this.recoverStaleEvents();\n if (staleCount > 0) {\n logger.info(`Recovered ${staleCount} stale event(s)`);\n }\n\n this.signalCleanup = onNewEvent(() => {\n this.pendingSignal = true;\n this.wakeUp();\n });\n\n logger.debug(`File events worker started (concurrency: ${this.concurrency})`);\n this.run();\n }\n\n private async run(): Promise<void> {\n while (this.isRunning) {\n const foundEvents = await this.fillSlots();\n logger.debug(`Found ${foundEvents ? \"events\" : \"no events\"} to process`);\n if (this.activeProcessors.size === 0) {\n if (this.pendingSignal && !foundEvents) {\n this.pendingSignal = false;\n await this.sleep(SIGNAL_RETRY_DELAY_MS);\n continue;\n }\n\n this.pendingSignal = false;\n await this.waitForSignalOrTimeout(FALLBACK_POLL_MS);\n } else {\n await Promise.race(this.activeProcessors.values());\n }\n }\n }\n\n private async fillSlots(): Promise<boolean> {\n let foundAny = false;\n\n while (this.activeProcessors.size < this.concurrency && this.isRunning) {\n const lockedFileIds = Array.from(this.activeProcessors.keys());\n const event = await EventsModel.findNextEligible(lockedFileIds);\n\n if (!event) break;\n\n foundAny = true;\n await EventsModel.markProcessing(event._id);\n const processor = this.processEventWrapper(event);\n this.activeProcessors.set(event.fileId, processor);\n }\n\n logger.debug(`Slots filled: ${this.activeProcessors.size}`);\n return foundAny;\n }\n\n private async processEventWrapper(event: Event): Promise<void> {\n try {\n const result = await processEvent(event);\n if (result.success) {\n await EventsModel.markProcessed(event._id);\n } else {\n await this.handleFailure(event, result.error);\n }\n } catch (err) {\n await this.handleFailure(event, err);\n } finally {\n this.activeProcessors.delete(event.fileId);\n }\n }\n\n private async handleFailure(event: Event, error: unknown): Promise<void> {\n const errorMsg = error instanceof Error ? error.message : String(error);\n if (error instanceof RateLimitError) {\n const retryAfterMs = error.retryAfterSeconds * 1000;\n await EventsModel.scheduleRetryAfter(event._id, errorMsg, retryAfterMs);\n logger.warn(`Event ${event._id} rate limited; retry after ${error.retryAfterSeconds}s`);\n return;\n }\n if (event.retryCount < MAX_RETRIES) {\n await EventsModel.scheduleRetry(event._id, errorMsg);\n logger.warn(`Event ${event._id} failed (retry ${event.retryCount + 1}/${MAX_RETRIES}): ${errorMsg}`);\n } else {\n await EventsModel.markFailed(event._id, errorMsg);\n logger.error(`Event ${event._id} permanently failed after ${MAX_RETRIES} retries: ${errorMsg}`);\n }\n }\n\n private async recoverStaleEvents(): Promise<number> {\n const staleThreshold = Date.now() - STALE_THRESHOLD_MS;\n return EventsModel.resetStaleEvents(staleThreshold);\n }\n\n private wakeUp(): void {\n if (this.wakeResolver) {\n this.wakeResolver();\n this.wakeResolver = null;\n }\n }\n\n private waitForSignalOrTimeout(ms: number): Promise<void> {\n return new Promise((resolve) => {\n const timeout = setTimeout(() => {\n this.wakeResolver = null;\n resolve();\n }, ms);\n\n this.wakeResolver = () => {\n clearTimeout(timeout);\n resolve();\n };\n });\n }\n\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n\n async close(): Promise<void> {\n if (!this.isRunning) {\n return;\n }\n logger.info(\"Closing worker gracefully...\");\n this.isRunning = false;\n\n if (this.signalCleanup) {\n this.signalCleanup();\n this.signalCleanup = null;\n }\n\n this.wakeUp();\n this.wakeResolver = null;\n\n if (this.activeProcessors.size > 0) {\n logger.info(`Waiting for ${this.activeProcessors.size} active processor(s) to complete...`);\n await Promise.all(this.activeProcessors.values());\n }\n\n logger.info(\"Worker closed\");\n }\n\n isActive(): boolean {\n return this.isRunning;\n }\n\n getActiveCount(): number {\n return this.activeProcessors.size;\n }\n}\n\nexport function createWorker(concurrency: number = DEFAULT_CONCURRENCY): FileEventsWorker {\n return new FileEventsWorker(concurrency);\n}\n","export { createWorker, FileEventsWorker } from \"./worker\";\nexport { notifyNewEvent } from \"./workerSignal\";\n","import { createWorker, type FileEventsWorker } from \"./infra/worker\";\n\nconst DEFAULT_CONCURRENCY = 5;\n\nlet worker: FileEventsWorker | null = null;\n\nexport async function startWorker(concurrency: number = DEFAULT_CONCURRENCY): Promise<void> {\n if (worker?.isActive()) {\n return;\n }\n worker = createWorker(concurrency);\n await worker.start();\n}\n\nexport async function closeWorker(): Promise<void> {\n if (worker) {\n await worker.close();\n worker = null;\n }\n}\n\nexport function isWorkerActive(): boolean {\n return worker?.isActive() ?? false;\n}\n\nexport function getWorkerActiveCount(): number {\n return worker?.getActiveCount() ?? 0;\n}\n","// Error reporting service\n// Example: Slack, Sentry, etc.\n\nclass Reporter {\n async reportError(message: string): Promise<void> {\n // Implement your error reporting logic\n console.error(\"Error reported:\", message);\n }\n}\n\nexport default new Reporter();\n","import { logger } from \"./logger\";\nimport { asyncHandler, asyncHandlerArray } from \"./asyncHandler\";\nimport { closeWorker } from \"../appWorker\";\nimport { closeDatabase } from \"./database\";\n\nimport reporter from \"./reporter\";\n\nexport { logger, asyncHandler, asyncHandlerArray, reporter, closeWorker, closeDatabase };\n","import { validateDbConfig } from \"./config\";\nimport { logger } from \"./infra\";\nimport { runMigrations } from \"./infra/database/migrations\";\nimport { closeWorker, isWorkerActive, startWorker } from \"./appWorker\";\n\nconst main = async () => {\n validateDbConfig();\n await runMigrations();\n\n const concurrency = parseInt(process.env.WORKER_CONCURRENCY || \"5\", 10);\n await startWorker(concurrency);\n\n setTimeout(() => {\n if (isWorkerActive()) {\n logger.info(\"File events worker started and active\");\n return;\n }\n\n logger.error(\"Worker failed to start\");\n process.exit(1);\n }, 100);\n};\n\nmain().catch((error) => {\n logger.error(\"Failed to start worker:\", error);\n process.exit(1);\n});\n\nconst shutdown = async () => {\n logger.info(\"Shutting down worker gracefully...\");\n await closeWorker();\n process.exit(0);\n};\n\nprocess.on(\"SIGTERM\", shutdown);\nprocess.on(\"SIGINT\", shutdown);\n","import { getAdapter } from \"../connection.js\";\nimport { logger } from \"../../index.js\";\n\nconst STABLE_SCHEMA = `\nCREATE TABLE IF NOT EXISTS files (\n _id TEXT PRIMARY KEY,\n ddocId TEXT NOT NULL,\n title TEXT NOT NULL,\n content TEXT NOT NULL,\n localVersion INTEGER NOT NULL DEFAULT 1,\n onchainVersion INTEGER NOT NULL DEFAULT 0,\n syncStatus TEXT NOT NULL DEFAULT 'pending',\n createdAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n updatedAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n isDeleted INTEGER NOT NULL DEFAULT 0,\n portalAddress TEXT NOT NULL,\n metadata TEXT DEFAULT '{}',\n onChainFileId INTEGER,\n commentKey TEXT,\n linkKey TEXT,\n linkKeyNonce TEXT,\n link TEXT\n);\nCREATE INDEX IF NOT EXISTS idx_files_createdAt ON files(createdAt);\nCREATE INDEX IF NOT EXISTS idx_files_syncStatus ON files(syncStatus);\nCREATE INDEX IF NOT EXISTS idx_files_title ON files(title);\nCREATE INDEX IF NOT EXISTS idx_files_portalAddress ON files(portalAddress);\n\nCREATE TABLE IF NOT EXISTS portals (\n _id TEXT PRIMARY KEY,\n portalAddress TEXT NOT NULL UNIQUE,\n portalSeed TEXT NOT NULL UNIQUE,\n ownerAddress TEXT NOT NULL,\n createdAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n updatedAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n);\n\nCREATE TABLE IF NOT EXISTS api_keys (\n _id TEXT PRIMARY KEY,\n apiKeySeed TEXT NOT NULL UNIQUE,\n name TEXT NOT NULL,\n collaboratorAddress TEXT NOT NULL UNIQUE,\n portalAddress TEXT NOT NULL,\n createdAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n isDeleted INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE IF NOT EXISTS events (\n _id TEXT PRIMARY KEY,\n type TEXT NOT NULL CHECK (type IN ('create', 'update', 'delete')),\n timestamp BIGINT NOT NULL,\n fileId TEXT NOT NULL,\n status TEXT NOT NULL DEFAULT 'pending' CHECK (status IN ('pending', 'processing', 'processed', 'failed')),\n retryCount INTEGER NOT NULL DEFAULT 0,\n lastError TEXT,\n lockedAt BIGINT,\n nextRetryAt BIGINT,\n userOpHash TEXT,\n pendingPayload TEXT,\n portalAddress TEXT\n);\nCREATE INDEX IF NOT EXISTS idx_events_pending_eligible ON events (status, nextRetryAt, timestamp) WHERE status = 'pending';\nCREATE INDEX IF NOT EXISTS idx_events_file_pending_ts ON events (fileId, status, timestamp) WHERE status = 'pending';\nCREATE INDEX IF NOT EXISTS idx_events_processing_locked ON events (status, lockedAt) WHERE status = 'processing';\nCREATE INDEX IF NOT EXISTS idx_events_failed_portal ON events (portalAddress, status) WHERE status = 'failed';\n\nCREATE TABLE IF NOT EXISTS folders (\n _id TEXT PRIMARY KEY,\n onchainFileId INTEGER NOT NULL,\n folderId TEXT NOT NULL,\n folderRef TEXT NOT NULL,\n folderName TEXT NOT NULL,\n portalAddress TEXT NOT NULL,\n metadataIPFSHash TEXT NOT NULL,\n contentIPFSHash TEXT NOT NULL,\n isDeleted INTEGER NOT NULL DEFAULT 0,\n lastTransactionHash TEXT,\n lastTransactionBlockNumber BIGINT NOT NULL,\n lastTransactionBlockTimestamp BIGINT NOT NULL,\n created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n);\nCREATE INDEX IF NOT EXISTS idx_folders_folderRef_folderId ON folders(folderRef, folderId);\nCREATE INDEX IF NOT EXISTS idx_folders_folderRef ON folders(folderRef);\nCREATE INDEX IF NOT EXISTS idx_folders_created_at ON folders(created_at);\n`;\n\nexport async function runMigrations(): Promise<void> {\n const adapter = await getAdapter();\n await adapter.exec(STABLE_SCHEMA);\n logger.debug(\"Database schema ready\");\n}\n"],"mappings":"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","names":["path","path","fs","PostgresAdapter","SqliteAdapter","init_constants","init_constants","adapter","uuidv7","uuidv7","uuidv7","init_constants","init_constants","toHex","isLE","mul2","POLY","sbox","sbox2","t0","t1","t2","t3","isLE","BLOCK_SIZE","generateRandomBytes","init_constants","encryptedSecretKey","nonce","secretKey","fromUint8Array","toUint8Array","init_constants","fromUint8Array","toUint8Array","ucans","init_constants","receipt","onChainFileId","init_worker","DEFAULT_CONCURRENCY","init_worker","adapter"]}
|