{"version":3,"sources":["../../../src/repositories/sqlite/transaction.ts","../../../src/repositories/sqlite/walletRepository.ts","../../../src/repositories/sqlite/contractRepository.ts","../../../src/repositories/sqlite/intentRepository.ts","../../../src/repositories/sqlite/virtualTxRepository.ts","../../../src/repositories/sqlite/prefix.ts"],"names":["scriptFromArkAddress","serializeVtxo","isVtxoSpent","isVtxoForScript","serializeUtxo","serializeAssets","deserializeVtxo","deserializeUtxo","deserializeAssets","sanitizePrefix","SAFE_PREFIX","intentMatchesFilter","intentPageBounds","isTerminalIntentState","mergeChainedTxType"],"mappings":"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","file":"index.cjs","sourcesContent":["import { SQLExecutor } from \"./types\";\n\n// One write chain per connection. SQLite (a single connection) cannot nest\n// BEGIN IMMEDIATE, so every transaction on a given executor must run one at a\n// time — across ALL repositories that share it, not just one instance. Keyed\n// by the executor object so callers keep passing a raw SQLExecutor with no\n// wiring change; separate executors (separate connections) get separate chains.\nconst writeChains = new WeakMap<SQLExecutor, Promise<void>>();\n\n/**\n * Run `fn` inside a serialized `BEGIN IMMEDIATE` / `COMMIT` on `db`.\n *\n * `fn` must issue only raw `db.run`/`db.all` calls: calling `runInTransaction`\n * again on the same `db` from within `fn` would wait on the chain it is part of\n * and deadlock.\n */\nexport function runInTransaction(db: SQLExecutor, fn: () => Promise<void>): Promise<void> {\n    // Chain onto the previous transaction; no await between get and set, so the\n    // enqueue is atomic.\n    const prev = writeChains.get(db) ?? Promise.resolve();\n    const run = prev.then(async () => {\n        await db.run(\"BEGIN IMMEDIATE\");\n        try {\n            await fn();\n            await db.run(\"COMMIT\");\n        } catch (e) {\n            try {\n                await db.run(\"ROLLBACK\");\n            } catch {\n                /* already rolled back */\n            }\n            throw e;\n        }\n    });\n    // Keep the chain alive regardless of this run's outcome so a failed\n    // transaction doesn't wedge every subsequent writer.\n    writeChains.set(\n        db,\n        run.catch(() => {}),\n    );\n    return run;\n}\n","import { ArkTransaction, ExtendedCoin, ExtendedVirtualCoin } from \"../../wallet\";\nimport { WalletRepository, WalletState, VtxoRepositoryKey } from \"../walletRepository\";\nimport {\n    serializeVtxo,\n    serializeUtxo,\n    deserializeVtxo,\n    deserializeUtxo,\n    serializeAssets,\n    deserializeAssets,\n    SerializedTapLeaf,\n} from \"../serialization\";\nimport { scriptFromArkAddress } from \"../scriptFromAddress\";\nimport { SQLExecutor } from \"./types\";\nimport { runInTransaction } from \"./transaction\";\nimport { isVtxoForScript } from \"../../contracts/vtxoOwnership\";\nimport { isVtxoSpent } from \"../../wallet/vtxo\";\n\ninterface SQLiteWalletRepositoryOptions {\n    /** Table name prefix (default: \"ark_\") */\n    prefix?: string;\n}\n\n/**\n * SQLite-based implementation of WalletRepository.\n *\n * Uses the SQLExecutor interface so consumers can plug in any SQLite driver\n * (expo-sqlite, better-sqlite3, etc.).\n *\n * Tables are created lazily on first operation via `ensureInit()`.\n * The consumer owns the SQLExecutor lifecycle — `[Symbol.asyncDispose]` is a no-op.\n */\nexport class SQLiteWalletRepository implements WalletRepository {\n    readonly version = 1 as const;\n    private initPromise: Promise<void> | null = null;\n    private readonly prefix: string;\n    private readonly tables: {\n        vtxos: string;\n        utxos: string;\n        transactions: string;\n        walletState: string;\n    };\n\n    constructor(\n        private readonly db: SQLExecutor,\n        options?: SQLiteWalletRepositoryOptions,\n    ) {\n        this.prefix = sanitizePrefix(options?.prefix ?? \"ark_\");\n        this.tables = {\n            vtxos: `${this.prefix}vtxos`,\n            utxos: `${this.prefix}utxos`,\n            transactions: `${this.prefix}transactions`,\n            walletState: `${this.prefix}wallet_state`,\n        };\n    }\n\n    // ── Lifecycle ──────────────────────────────────────────────────────\n\n    private ensureInit(): Promise<void> {\n        if (!this.initPromise) {\n            this.initPromise = this.init();\n        }\n        return this.initPromise;\n    }\n\n    private async init(): Promise<void> {\n        await this.migrateVtxosTable();\n\n        await this.db.run(`\n            CREATE TABLE IF NOT EXISTS ${this.tables.utxos} (\n                txid TEXT NOT NULL,\n                vout INTEGER NOT NULL,\n                value INTEGER NOT NULL,\n                address TEXT NOT NULL,\n                tap_tree TEXT NOT NULL,\n                forfeit_cb TEXT NOT NULL,\n                forfeit_s TEXT NOT NULL,\n                intent_cb TEXT NOT NULL,\n                intent_s TEXT NOT NULL,\n                status_json TEXT NOT NULL,\n                extra_witness_json TEXT,\n                PRIMARY KEY (txid, vout)\n            )\n        `);\n\n        await this.db.run(`\n            CREATE TABLE IF NOT EXISTS ${this.tables.transactions} (\n                address TEXT NOT NULL,\n                boarding_txid TEXT NOT NULL,\n                commitment_txid TEXT NOT NULL,\n                ark_txid TEXT NOT NULL,\n                type TEXT NOT NULL,\n                amount INTEGER NOT NULL,\n                settled INTEGER NOT NULL DEFAULT 0,\n                created_at INTEGER NOT NULL,\n                assets_json TEXT,\n                PRIMARY KEY (address, boarding_txid, commitment_txid, ark_txid)\n            )\n        `);\n\n        await this.db.run(`\n            CREATE TABLE IF NOT EXISTS ${this.tables.walletState} (\n                key TEXT PRIMARY KEY,\n                settings_json TEXT,\n                last_sync_time INTEGER\n            )\n        `);\n\n        await this.db.run(\n            `CREATE INDEX IF NOT EXISTS idx_${this.prefix}vtxos_address ON ${this.tables.vtxos} (address)`,\n        );\n        await this.db.run(\n            `CREATE INDEX IF NOT EXISTS idx_${this.prefix}vtxos_script ON ${this.tables.vtxos} (script)`,\n        );\n        await this.db.run(\n            `CREATE INDEX IF NOT EXISTS idx_${this.prefix}vtxos_live_script ON ${this.tables.vtxos} (script)\n             WHERE (is_spent IS NULL OR is_spent = 0)\n               AND (spent_by IS NULL OR spent_by = '')\n               AND (settled_by IS NULL OR settled_by = '')`,\n        );\n        await this.db.run(\n            `CREATE INDEX IF NOT EXISTS idx_${this.prefix}utxos_address ON ${this.tables.utxos} (address)`,\n        );\n        await this.db.run(\n            `CREATE INDEX IF NOT EXISTS idx_${this.prefix}transactions_address ON ${this.tables.transactions} (address)`,\n        );\n    }\n\n    /**\n     * Bring the `vtxos` table to the current schema (v1 = `script` NOT NULL).\n     *\n     * Three cases:\n     *   - Fresh install: create the v1 schema directly.\n     *   - Legacy install without a `script` column: add it, backfill from\n     *     `address`, then rebuild the table with NOT NULL (SQLite cannot add\n     *     the NOT NULL constraint in place).\n     *   - Legacy install with a nullable `script` column: backfill the NULLs\n     *     and rebuild.\n     *\n     * The backfill derives `script` from the Ark address, matching what the\n     * indexer would have returned — new rows from the indexer always carry a\n     * populated `script`, so the migration is idempotent.\n     *\n     * The whole check-and-migrate runs inside one transaction, not just the\n     * rebuild: the schema inspection is the decision point, so a second\n     * concurrent init on the same connection must not read a pre-migration\n     * schema and then re-run `ADD COLUMN` (duplicate column) after the first\n     * migration already committed. It also guards the crash window between the\n     * `DROP TABLE vtxos` and the `RENAME tmp → vtxos`, which would otherwise\n     * leave the next startup seeing no `vtxos` table.\n     */\n    private async migrateVtxosTable(): Promise<void> {\n        await runInTransaction(this.db, async () => {\n            const tableExists = await this.db.get<{ name: string }>(\n                `SELECT name FROM sqlite_master WHERE type='table' AND name=?`,\n                [this.tables.vtxos],\n            );\n            if (!tableExists) {\n                await this.db.run(this.vtxosCreateSql(this.tables.vtxos));\n                return;\n            }\n\n            const cols = await this.db.all<{ name: string; notnull: number }>(\n                `PRAGMA table_info(${this.tables.vtxos})`,\n            );\n            const scriptCol = cols.find((c) => c.name === \"script\");\n            if (scriptCol && scriptCol.notnull === 1) {\n                // Already on v1 schema.\n                return;\n            }\n\n            if (!scriptCol) {\n                await this.db.run(`ALTER TABLE ${this.tables.vtxos} ADD COLUMN script TEXT`);\n            }\n\n            // Backfill any NULL scripts from the owning address. Derivation\n            // is deterministic, so re-running after a rolled-back attempt\n            // produces the same values.\n            const nullRows = await this.db.all<{\n                txid: string;\n                vout: number;\n                address: string;\n            }>(`SELECT txid, vout, address FROM ${this.tables.vtxos} WHERE script IS NULL`);\n            for (const row of nullRows) {\n                await this.db.run(\n                    `UPDATE ${this.tables.vtxos} SET script = ? WHERE txid = ? AND vout = ?`,\n                    [scriptFromArkAddress(row.address), row.txid, row.vout],\n                );\n            }\n\n            // SQLite can't turn a nullable column into NOT NULL in place —\n            // do the canonical 12-step table rebuild. Drop any stale temp\n            // table from a prior aborted attempt first.\n            const tempName = `${this.tables.vtxos}__migrate_tmp`;\n            await this.db.run(`DROP TABLE IF EXISTS ${tempName}`);\n            await this.db.run(this.vtxosCreateSql(tempName));\n            await this.db.run(`\n                INSERT INTO ${tempName}\n                    (txid, vout, value, address, tap_tree,\n                     forfeit_cb, forfeit_s, intent_cb, intent_s,\n                     status_json, virtual_status_json, created_at,\n                     is_unrolled, is_spent, spent_by, settled_by, ark_tx_id,\n                     extra_witness_json, assets_json, script)\n                SELECT txid, vout, value, address, tap_tree,\n                       forfeit_cb, forfeit_s, intent_cb, intent_s,\n                       status_json, virtual_status_json, created_at,\n                       is_unrolled, is_spent, spent_by, settled_by, ark_tx_id,\n                       extra_witness_json, assets_json, script\n                FROM ${this.tables.vtxos}\n            `);\n            await this.db.run(`DROP TABLE ${this.tables.vtxos}`);\n            await this.db.run(`ALTER TABLE ${tempName} RENAME TO ${this.tables.vtxos}`);\n        });\n    }\n\n    private vtxosCreateSql(tableName: string): string {\n        return `CREATE TABLE ${tableName} (\n            txid TEXT NOT NULL,\n            vout INTEGER NOT NULL,\n            value INTEGER NOT NULL,\n            address TEXT NOT NULL,\n            tap_tree TEXT NOT NULL,\n            forfeit_cb TEXT NOT NULL,\n            forfeit_s TEXT NOT NULL,\n            intent_cb TEXT NOT NULL,\n            intent_s TEXT NOT NULL,\n            status_json TEXT NOT NULL,\n            virtual_status_json TEXT NOT NULL,\n            created_at TEXT NOT NULL,\n            is_unrolled INTEGER NOT NULL DEFAULT 0,\n            is_spent INTEGER,\n            spent_by TEXT,\n            settled_by TEXT,\n            ark_tx_id TEXT,\n            extra_witness_json TEXT,\n            assets_json TEXT,\n            script TEXT NOT NULL,\n            PRIMARY KEY (txid, vout)\n        )`;\n    }\n\n    async [Symbol.asyncDispose](): Promise<void> {\n        // no-op — consumer owns the SQLExecutor lifecycle\n    }\n\n    // ── Clear ──────────────────────────────────────────────────────────\n\n    async clear(): Promise<void> {\n        await this.ensureInit();\n        await this.db.run(`DELETE FROM ${this.tables.vtxos}`);\n        await this.db.run(`DELETE FROM ${this.tables.utxos}`);\n        await this.db.run(`DELETE FROM ${this.tables.transactions}`);\n        await this.db.run(`DELETE FROM ${this.tables.walletState}`);\n    }\n\n    // ── VTXO management ────────────────────────────────────────────────\n\n    async getVtxos(address: string): Promise<ExtendedVirtualCoin[]> {\n        await this.ensureInit();\n        const rows = await this.db.all<VtxoRow>(\n            `SELECT * FROM ${this.tables.vtxos} WHERE address = ?`,\n            [address],\n        );\n        return rows.map(vtxoRowToDomain);\n    }\n\n    async saveVtxos(address: string, vtxos: ExtendedVirtualCoin[]): Promise<void> {\n        await this.ensureInit();\n        for (const vtxo of vtxos) {\n            const s = serializeVtxo(vtxo);\n            await this.db.run(\n                `INSERT OR REPLACE INTO ${this.tables.vtxos}\n                    (txid, vout, value, address,\n                     tap_tree, forfeit_cb, forfeit_s, intent_cb, intent_s,\n                     status_json, virtual_status_json, created_at,\n                     is_unrolled, is_spent, spent_by, settled_by, ark_tx_id,\n                     extra_witness_json, assets_json, script)\n                 VALUES (?, ?, ?, ?,\n                         ?, ?, ?, ?, ?,\n                         ?, ?, ?,\n                         ?, ?, ?, ?, ?,\n                         ?, ?, ?)`,\n                [\n                    s.txid,\n                    s.vout,\n                    s.value,\n                    address,\n                    s.tapTree,\n                    s.forfeitTapLeafScript.cb,\n                    s.forfeitTapLeafScript.s,\n                    s.intentTapLeafScript.cb,\n                    s.intentTapLeafScript.s,\n                    JSON.stringify(s.status),\n                    JSON.stringify(s.virtualStatus),\n                    typeof s.createdAt === \"string\"\n                        ? s.createdAt\n                        : s.createdAt instanceof Date\n                          ? s.createdAt.toISOString()\n                          : new Date(s.createdAt).toISOString(),\n                    s.isUnrolled ? 1 : 0,\n                    s.isSpent === undefined ? null : s.isSpent ? 1 : 0,\n                    s.spentBy ?? null,\n                    s.settledBy ?? null,\n                    s.arkTxId ?? null,\n                    s.extraWitness ? JSON.stringify(s.extraWitness) : null,\n                    s.assets ? JSON.stringify(s.assets) : null,\n                    s.script ?? null,\n                ],\n            );\n        }\n    }\n\n    async deleteVtxos(address: string): Promise<void> {\n        await this.ensureInit();\n        await this.db.run(`DELETE FROM ${this.tables.vtxos} WHERE address = ?`, [address]);\n    }\n\n    async getVtxosForScript(script: string): Promise<ExtendedVirtualCoin[]> {\n        await this.ensureInit();\n        const rows = await this.db.all<VtxoRow>(\n            `SELECT * FROM ${this.tables.vtxos} WHERE script = ?`,\n            [script],\n        );\n        return rows.map(vtxoRowToDomain);\n    }\n\n    async getVtxosForScripts(\n        scripts: string[],\n        options?: { unspentOnly?: boolean },\n    ): Promise<ExtendedVirtualCoin[]> {\n        if (scripts.length === 0) return [];\n        await this.ensureInit();\n        const unique = [...new Set(scripts)];\n        const result: ExtendedVirtualCoin[] = [];\n        for (let i = 0; i < unique.length; i += 500) {\n            const chunk = unique.slice(i, i + 500);\n            const rows = await this.db.all<VtxoRow>(\n                `SELECT * FROM ${this.tables.vtxos} WHERE script IN (${chunk.map(() => \"?\").join(\",\")})${\n                    options?.unspentOnly\n                        ? \" AND (is_spent IS NULL OR is_spent = 0) AND (spent_by IS NULL OR spent_by = '') AND (settled_by IS NULL OR settled_by = '')\"\n                        : \"\"\n                }`,\n                chunk,\n            );\n            const decoded = rows.map(vtxoRowToDomain);\n            result.push(\n                ...(options?.unspentOnly ? decoded.filter((vtxo) => !isVtxoSpent(vtxo)) : decoded),\n            );\n        }\n        return result;\n    }\n\n    async saveVtxosForScript(key: VtxoRepositoryKey, vtxos: ExtendedVirtualCoin[]): Promise<void> {\n        if (!key.address) {\n            throw new Error(\"SQLiteWalletRepository requires an address\");\n        }\n        for (const vtxo of vtxos) {\n            if (!isVtxoForScript(vtxo, key.script)) {\n                throw new Error(\n                    `VTXO ${vtxo.txid}:${vtxo.vout} script mismatch: expected ${key.script}, got ${vtxo.script}`,\n                );\n            }\n        }\n        return this.saveVtxos(key.address, vtxos);\n    }\n\n    async deleteVtxosForScript(script: string): Promise<void> {\n        await this.ensureInit();\n        await this.db.run(`DELETE FROM ${this.tables.vtxos} WHERE script = ?`, [script]);\n    }\n\n    // ── UTXO management ────────────────────────────────────────────────\n\n    async getUtxos(address: string): Promise<ExtendedCoin[]> {\n        await this.ensureInit();\n        const rows = await this.db.all<UtxoRow>(\n            `SELECT * FROM ${this.tables.utxos} WHERE address = ?`,\n            [address],\n        );\n        return rows.map(utxoRowToDomain);\n    }\n\n    async saveUtxos(address: string, utxos: ExtendedCoin[]): Promise<void> {\n        await this.ensureInit();\n        for (const utxo of utxos) {\n            const s = serializeUtxo(utxo);\n            await this.db.run(\n                `INSERT OR REPLACE INTO ${this.tables.utxos}\n                    (txid, vout, value, address,\n                     tap_tree, forfeit_cb, forfeit_s, intent_cb, intent_s,\n                     status_json, extra_witness_json)\n                 VALUES (?, ?, ?, ?,\n                         ?, ?, ?, ?, ?,\n                         ?, ?)`,\n                [\n                    s.txid,\n                    s.vout,\n                    s.value,\n                    address,\n                    s.tapTree,\n                    s.forfeitTapLeafScript.cb,\n                    s.forfeitTapLeafScript.s,\n                    s.intentTapLeafScript.cb,\n                    s.intentTapLeafScript.s,\n                    JSON.stringify(s.status),\n                    s.extraWitness ? JSON.stringify(s.extraWitness) : null,\n                ],\n            );\n        }\n    }\n\n    async deleteUtxos(address: string): Promise<void> {\n        await this.ensureInit();\n        await this.db.run(`DELETE FROM ${this.tables.utxos} WHERE address = ?`, [address]);\n    }\n\n    // ── Transaction history ────────────────────────────────────────────\n\n    async getTransactionHistory(address: string): Promise<ArkTransaction[]> {\n        await this.ensureInit();\n        const rows = await this.db.all<TransactionRow>(\n            `SELECT * FROM ${this.tables.transactions} WHERE address = ? ORDER BY created_at ASC`,\n            [address],\n        );\n        return rows.map(txRowToDomain);\n    }\n\n    async saveTransactions(address: string, txs: ArkTransaction[]): Promise<void> {\n        await this.ensureInit();\n        for (const tx of txs) {\n            await this.db.run(\n                `INSERT OR REPLACE INTO ${this.tables.transactions}\n                    (address, boarding_txid, commitment_txid, ark_txid,\n                     type, amount, settled, created_at, assets_json)\n                 VALUES (?, ?, ?, ?,\n                         ?, ?, ?, ?, ?)`,\n                [\n                    address,\n                    tx.key.boardingTxid,\n                    tx.key.commitmentTxid,\n                    tx.key.arkTxid,\n                    tx.type,\n                    tx.amount,\n                    tx.settled ? 1 : 0,\n                    tx.createdAt,\n                    tx.assets ? JSON.stringify(serializeAssets(tx.assets)) : null,\n                ],\n            );\n        }\n    }\n\n    async deleteTransactions(address: string): Promise<void> {\n        await this.ensureInit();\n        await this.db.run(`DELETE FROM ${this.tables.transactions} WHERE address = ?`, [address]);\n    }\n\n    // ── Wallet state ───────────────────────────────────────────────────\n\n    async getWalletState(): Promise<WalletState | null> {\n        await this.ensureInit();\n        const row = await this.db.get<WalletStateRow>(\n            `SELECT * FROM ${this.tables.walletState} WHERE key = ?`,\n            [\"state\"],\n        );\n        if (!row) return null;\n\n        const state: WalletState = {};\n        if (row.settings_json) {\n            state.settings = JSON.parse(row.settings_json);\n        }\n        state.lastSyncTime = row.last_sync_time ?? undefined;\n        return state;\n    }\n\n    async saveWalletState(state: WalletState): Promise<void> {\n        await this.ensureInit();\n        await this.db.run(\n            `INSERT OR REPLACE INTO ${this.tables.walletState}\n                (key, settings_json, last_sync_time)\n             VALUES (?, ?, ?)`,\n            [\n                \"state\",\n                state.settings ? JSON.stringify(state.settings) : null,\n                state.lastSyncTime ?? null,\n            ],\n        );\n    }\n}\n\n// ── Row types ──────────────────────────────────────────────────────────\n\ninterface VtxoRow {\n    txid: string;\n    vout: number;\n    value: number;\n    address: string;\n    tap_tree: string;\n    forfeit_cb: string;\n    forfeit_s: string;\n    intent_cb: string;\n    intent_s: string;\n    status_json: string;\n    virtual_status_json: string;\n    created_at: string;\n    is_unrolled: number;\n    is_spent: number | null;\n    spent_by: string | null;\n    settled_by: string | null;\n    ark_tx_id: string | null;\n    extra_witness_json: string | null;\n    assets_json: string | null;\n    script: string | null;\n}\n\ninterface UtxoRow {\n    txid: string;\n    vout: number;\n    value: number;\n    address: string;\n    tap_tree: string;\n    forfeit_cb: string;\n    forfeit_s: string;\n    intent_cb: string;\n    intent_s: string;\n    status_json: string;\n    extra_witness_json: string | null;\n}\n\ninterface TransactionRow {\n    address: string;\n    boarding_txid: string;\n    commitment_txid: string;\n    ark_txid: string;\n    type: string;\n    amount: number;\n    settled: number;\n    created_at: number;\n    assets_json: string | null;\n}\n\ninterface WalletStateRow {\n    key: string;\n    settings_json: string | null;\n    last_sync_time: number | null;\n}\n\nconst SAFE_PREFIX = /^[a-zA-Z0-9_]+$/;\n\nfunction sanitizePrefix(prefix: string): string {\n    if (!SAFE_PREFIX.test(prefix)) {\n        throw new Error(\n            `Invalid table prefix \"${prefix}\": only letters, digits, and underscores are allowed`,\n        );\n    }\n    return prefix;\n}\n\n// ── Row → Domain converters ────────────────────────────────────────────\n\nfunction vtxoRowToDomain(row: VtxoRow): ExtendedVirtualCoin {\n    const serialized = {\n        txid: row.txid,\n        vout: row.vout,\n        value: row.value,\n        tapTree: row.tap_tree,\n        forfeitTapLeafScript: {\n            cb: row.forfeit_cb,\n            s: row.forfeit_s,\n        } as SerializedTapLeaf,\n        intentTapLeafScript: {\n            cb: row.intent_cb,\n            s: row.intent_s,\n        } as SerializedTapLeaf,\n        status: JSON.parse(row.status_json),\n        virtualStatus: JSON.parse(row.virtual_status_json),\n        createdAt: new Date(row.created_at),\n        isUnrolled: row.is_unrolled === 1,\n        isSpent: row.is_spent === null ? undefined : row.is_spent === 1,\n        spentBy: row.spent_by ?? undefined,\n        settledBy: row.settled_by ?? undefined,\n        arkTxId: row.ark_tx_id ?? undefined,\n        extraWitness: row.extra_witness_json ? JSON.parse(row.extra_witness_json) : undefined,\n        assets: row.assets_json ? JSON.parse(row.assets_json) : undefined,\n        // Post-migration every row has `script`, but the backfill is\n        // idempotent: derive from `address` if the legacy column is still\n        // null (e.g. the migration hasn't run yet on this handle).\n        script: row.script ?? scriptFromArkAddress(row.address),\n    };\n\n    return deserializeVtxo(serialized);\n}\n\nfunction utxoRowToDomain(row: UtxoRow): ExtendedCoin {\n    const serialized = {\n        txid: row.txid,\n        vout: row.vout,\n        value: row.value,\n        tapTree: row.tap_tree,\n        forfeitTapLeafScript: {\n            cb: row.forfeit_cb,\n            s: row.forfeit_s,\n        } as SerializedTapLeaf,\n        intentTapLeafScript: {\n            cb: row.intent_cb,\n            s: row.intent_s,\n        } as SerializedTapLeaf,\n        status: JSON.parse(row.status_json),\n        extraWitness: row.extra_witness_json ? JSON.parse(row.extra_witness_json) : undefined,\n    };\n\n    return deserializeUtxo(serialized);\n}\n\nfunction txRowToDomain(row: TransactionRow): ArkTransaction {\n    const tx: ArkTransaction = {\n        key: {\n            boardingTxid: row.boarding_txid,\n            commitmentTxid: row.commitment_txid,\n            arkTxid: row.ark_txid,\n        },\n        type: row.type as ArkTransaction[\"type\"],\n        amount: row.amount,\n        settled: row.settled === 1,\n        createdAt: row.created_at,\n    };\n    if (row.assets_json) {\n        tx.assets = deserializeAssets(JSON.parse(row.assets_json));\n    }\n    return tx;\n}\n","import { Contract, ContractState, ContractWatchState } from \"../../contracts/types\";\nimport { ContractFilter, ContractRepository } from \"../contractRepository\";\nimport { SQLExecutor } from \"./types\";\n\ninterface SQLiteContractRepositoryOptions {\n    /** Table name prefix (default: \"ark_\") */\n    prefix?: string;\n}\n\n/**\n * SQLite-based implementation of ContractRepository.\n *\n * Uses the SQLExecutor interface so consumers can plug in any SQLite driver\n * (expo-sqlite, better-sqlite3, etc.).\n *\n * Tables are created lazily on first operation via `ensureInit()`.\n * The consumer owns the SQLExecutor lifecycle — `[Symbol.asyncDispose]` is a no-op.\n */\nexport class SQLiteContractRepository implements ContractRepository {\n    readonly version = 2 as const;\n    private initPromise: Promise<void> | null = null;\n    private readonly prefix: string;\n    private readonly table: string;\n\n    constructor(\n        private readonly db: SQLExecutor,\n        options?: SQLiteContractRepositoryOptions,\n    ) {\n        this.prefix = sanitizePrefix(options?.prefix ?? \"ark_\");\n        this.table = `${this.prefix}contracts`;\n    }\n\n    // ── Lifecycle ──────────────────────────────────────────────────────\n\n    private ensureInit(): Promise<void> {\n        if (!this.initPromise) {\n            this.initPromise = this.init();\n        }\n        return this.initPromise;\n    }\n\n    private async init(): Promise<void> {\n        await this.db.run(`\n            CREATE TABLE IF NOT EXISTS ${this.table} (\n                script TEXT PRIMARY KEY,\n                address TEXT NOT NULL,\n                type TEXT NOT NULL,\n                state TEXT NOT NULL,\n                params_json TEXT NOT NULL,\n                created_at INTEGER NOT NULL,\n                expires_at INTEGER,\n                label TEXT,\n                metadata_json TEXT,\n                watch TEXT\n            )\n        `);\n\n        // Nullable and added in place, so a table created before the\n        // column existed keeps every row and reads back as \"watched\" —\n        // the coverage those rows have today.\n        await this.addColumnIfMissing(\"watch\", \"TEXT\");\n\n        await this.db.run(\n            `CREATE INDEX IF NOT EXISTS idx_${this.prefix}contracts_type ON ${this.table} (type)`,\n        );\n        await this.db.run(\n            `CREATE INDEX IF NOT EXISTS idx_${this.prefix}contracts_state ON ${this.table} (state)`,\n        );\n    }\n\n    private async addColumnIfMissing(column: string, type: string): Promise<void> {\n        const columns = await this.db.all<{ name: string }>(`PRAGMA table_info(${this.table})`);\n        if (columns.some((c) => c.name === column)) return;\n        await this.db.run(`ALTER TABLE ${this.table} ADD COLUMN ${column} ${type}`);\n    }\n\n    async [Symbol.asyncDispose](): Promise<void> {\n        // no-op — consumer owns the SQLExecutor lifecycle\n    }\n\n    // ── Clear ──────────────────────────────────────────────────────────\n\n    async clear(): Promise<void> {\n        await this.ensureInit();\n        await this.db.run(`DELETE FROM ${this.table}`);\n    }\n\n    // ── Contract management ────────────────────────────────────────────\n\n    async getContracts(filter?: ContractFilter): Promise<Contract[]> {\n        await this.ensureInit();\n\n        const conditions: string[] = [];\n        const params: unknown[] = [];\n\n        if (filter) {\n            this.addFilterCondition(conditions, params, \"script\", filter.script);\n            this.addFilterCondition(conditions, params, \"state\", filter.state);\n            this.addFilterCondition(conditions, params, \"type\", filter.type);\n            this.addWatchCondition(conditions, params, filter.watch);\n        }\n\n        let sql = `SELECT * FROM ${this.table}`;\n        if (conditions.length > 0) {\n            sql += ` WHERE ${conditions.join(\" AND \")}`;\n        }\n\n        const rows = await this.db.all<ContractRow>(sql, params);\n        return rows.map(contractRowToDomain);\n    }\n\n    async saveContract(contract: Contract): Promise<void> {\n        await this.ensureInit();\n        await this.db.run(\n            `INSERT OR REPLACE INTO ${this.table}\n                (script, address, type, state, params_json,\n                 created_at, label, metadata_json, watch)\n             VALUES (?, ?, ?, ?, ?,\n                     ?, ?, ?, ?)`,\n            [\n                contract.script,\n                contract.address,\n                contract.type,\n                contract.state,\n                JSON.stringify(contract.params),\n                contract.createdAt,\n                contract.label ?? null,\n                contract.metadata ? JSON.stringify(contract.metadata) : null,\n                contract.watch ?? null,\n            ],\n        );\n    }\n\n    async deleteContract(script: string): Promise<void> {\n        await this.ensureInit();\n        await this.db.run(`DELETE FROM ${this.table} WHERE script = ?`, [script]);\n    }\n\n    // ── Helpers ─────────────────────────────────────────────────────────\n\n    private addFilterCondition(\n        conditions: string[],\n        params: unknown[],\n        column: string,\n        value?: string | string[],\n    ): void {\n        if (value === undefined) return;\n\n        if (Array.isArray(value)) {\n            if (value.length === 0) return;\n            const placeholders = value.map(() => \"?\").join(\", \");\n            conditions.push(`${column} IN (${placeholders})`);\n            params.push(...value);\n        } else {\n            conditions.push(`${column} = ?`);\n            params.push(value);\n        }\n    }\n\n    /**\n     * Same as {@link addFilterCondition}, except a row predating the\n     * column stores NULL and must match `\"watched\"`.\n     */\n    private addWatchCondition(\n        conditions: string[],\n        params: unknown[],\n        value?: ContractWatchState | ContractWatchState[],\n    ): void {\n        if (value === undefined) return;\n\n        const wanted = Array.isArray(value) ? value : [value];\n        if (wanted.length === 0) return;\n\n        const placeholders = wanted.map(() => \"?\").join(\", \");\n        const clause = `watch IN (${placeholders})`;\n        conditions.push(wanted.includes(\"watched\") ? `(${clause} OR watch IS NULL)` : clause);\n        params.push(...wanted);\n    }\n}\n\n// ── Row type ────────────────────────────────────────────────────────────\n\ninterface ContractRow {\n    script: string;\n    address: string;\n    type: string;\n    state: string;\n    params_json: string;\n    created_at: number;\n    label: string | null;\n    metadata_json: string | null;\n    watch: string | null;\n}\n\n// ── Row → Domain converter ──────────────────────────────────────────────\n\nconst SAFE_PREFIX = /^[a-zA-Z0-9_]+$/;\n\nfunction sanitizePrefix(prefix: string): string {\n    if (!SAFE_PREFIX.test(prefix)) {\n        throw new Error(\n            `Invalid table prefix \"${prefix}\": only letters, digits, and underscores are allowed`,\n        );\n    }\n    return prefix;\n}\n\nfunction contractRowToDomain(row: ContractRow): Contract {\n    const contract: Contract = {\n        script: row.script,\n        address: row.address,\n        type: row.type,\n        state: row.state as ContractState,\n        params: JSON.parse(row.params_json),\n        createdAt: row.created_at,\n    };\n\n    if (row.label !== null) {\n        contract.label = row.label;\n    }\n    if (row.metadata_json !== null) {\n        contract.metadata = JSON.parse(row.metadata_json);\n    }\n    if (row.watch !== null && row.watch !== undefined) {\n        contract.watch = row.watch as ContractWatchState;\n    }\n\n    return contract;\n}\n","import { Outpoint } from \"../../wallet\";\nimport {\n    ArkIntent,\n    ArkIntentState,\n    IntentFilter,\n    IntentRepository,\n    intentMatchesFilter,\n    intentPageBounds,\n    isTerminalIntentState,\n} from \"../intentRepository\";\nimport { SQLExecutor } from \"./types\";\nimport { runInTransaction } from \"./transaction\";\n\nconst SAFE_PREFIX = /^[a-zA-Z_][a-zA-Z0-9_]*$/;\nfunction sanitizePrefix(p: string): string {\n    if (!SAFE_PREFIX.test(p)) throw new Error(`Invalid table prefix \"${p}\"`);\n    return p;\n}\n\ninterface IntentRow {\n    intent_tx_id: string;\n    intent_id: string | null;\n    state: string;\n    valid_from: number | null;\n    valid_until: number | null;\n    created_at: number;\n    updated_at: number;\n    register_proof: string;\n    register_proof_message: string;\n    delete_proof: string;\n    delete_proof_message: string;\n    batch_id: string | null;\n    commitment_txid: string | null;\n    cancellation_reason: string | null;\n    partial_forfeits_json: string;\n    signer_descriptor: string | null;\n    intent_vtxos_json: string;\n}\n\nexport class SQLiteIntentRepository implements IntentRepository {\n    readonly version = 1 as const;\n    private initPromise: Promise<void> | null = null;\n    private readonly prefix: string;\n    private readonly t: string;\n\n    constructor(\n        private readonly db: SQLExecutor,\n        options?: { prefix?: string },\n    ) {\n        this.prefix = sanitizePrefix(options?.prefix ?? \"ark_\");\n        this.t = `${this.prefix}intents`;\n    }\n\n    private ensureInit(): Promise<void> {\n        if (!this.initPromise) this.initPromise = this.init();\n        return this.initPromise;\n    }\n\n    private async init(): Promise<void> {\n        await this.db.run(`CREATE TABLE IF NOT EXISTS ${this.t} (\n            intent_tx_id TEXT PRIMARY KEY,\n            intent_id TEXT,\n            state TEXT NOT NULL,\n            valid_from INTEGER,\n            valid_until INTEGER,\n            created_at INTEGER NOT NULL,\n            updated_at INTEGER NOT NULL,\n            register_proof TEXT NOT NULL,\n            register_proof_message TEXT NOT NULL,\n            delete_proof TEXT NOT NULL,\n            delete_proof_message TEXT NOT NULL,\n            batch_id TEXT,\n            commitment_txid TEXT,\n            cancellation_reason TEXT,\n            partial_forfeits_json TEXT NOT NULL,\n            signer_descriptor TEXT,\n            intent_vtxos_json TEXT NOT NULL\n        )`);\n        await this.db.run(\n            `CREATE UNIQUE INDEX IF NOT EXISTS idx_${this.prefix}intent_id ON ${this.t} (intent_id) WHERE intent_id IS NOT NULL`,\n        );\n        await this.db.run(\n            `CREATE INDEX IF NOT EXISTS idx_${this.prefix}intent_state ON ${this.t} (state)`,\n        );\n    }\n\n    private withTx(fn: () => Promise<void>): Promise<void> {\n        return runInTransaction(this.db, fn);\n    }\n\n    async clear(): Promise<void> {\n        await this.ensureInit();\n        // Route through the same serialized write chain as saveIntent so a\n        // clear can't interleave with an in-flight transaction on this executor.\n        await this.withTx(async () => {\n            await this.db.run(`DELETE FROM ${this.t}`);\n        });\n    }\n\n    async saveIntent(intent: ArkIntent): Promise<void> {\n        await this.ensureInit();\n        const now = Date.now();\n        await this.withTx(async () => {\n            // Upsert by the primary key only. INSERT OR REPLACE would also fire\n            // on the intent_id unique index, silently deleting the *other* row\n            // that holds it; ON CONFLICT(intent_tx_id) updates in place and lets\n            // an intent_id collision surface as a constraint error instead.\n            await this.db.run(\n                `INSERT INTO ${this.t}\n                 (intent_tx_id, intent_id, state, valid_from, valid_until,\n                  created_at, updated_at, register_proof, register_proof_message,\n                  delete_proof, delete_proof_message, batch_id, commitment_txid,\n                  cancellation_reason, partial_forfeits_json, signer_descriptor,\n                  intent_vtxos_json)\n                 VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n                 ON CONFLICT(intent_tx_id) DO UPDATE SET\n                  intent_id = excluded.intent_id,\n                  state = excluded.state,\n                  valid_from = excluded.valid_from,\n                  valid_until = excluded.valid_until,\n                  created_at = excluded.created_at,\n                  updated_at = excluded.updated_at,\n                  register_proof = excluded.register_proof,\n                  register_proof_message = excluded.register_proof_message,\n                  delete_proof = excluded.delete_proof,\n                  delete_proof_message = excluded.delete_proof_message,\n                  batch_id = excluded.batch_id,\n                  commitment_txid = excluded.commitment_txid,\n                  cancellation_reason = excluded.cancellation_reason,\n                  partial_forfeits_json = excluded.partial_forfeits_json,\n                  signer_descriptor = excluded.signer_descriptor,\n                  intent_vtxos_json = excluded.intent_vtxos_json`,\n                [\n                    intent.intentTxId,\n                    intent.intentId ?? null,\n                    intent.state,\n                    intent.validFrom ?? null,\n                    intent.validUntil ?? null,\n                    intent.createdAt,\n                    now,\n                    intent.registerProof,\n                    intent.registerProofMessage,\n                    intent.deleteProof,\n                    intent.deleteProofMessage,\n                    intent.batchId ?? null,\n                    intent.commitmentTransactionId ?? null,\n                    intent.cancellationReason ?? null,\n                    JSON.stringify(intent.partialForfeits),\n                    intent.signerDescriptor ?? null,\n                    JSON.stringify(intent.intentVtxos),\n                ],\n            );\n        });\n    }\n\n    async getIntents(filter?: IntentFilter): Promise<ArkIntent[]> {\n        await this.ensureInit();\n        const rows = await this.db.all<IntentRow>(\n            `SELECT * FROM ${this.t} ORDER BY created_at ASC, intent_tx_id ASC`,\n        );\n        let out = rows.map(rowToIntent);\n        if (filter) out = out.filter((i) => intentMatchesFilter(i, filter));\n        const { skip, end } = intentPageBounds(filter, out.length);\n        return out.slice(skip, end);\n    }\n\n    async getLockedVtxoOutpoints(): Promise<Outpoint[]> {\n        await this.ensureInit();\n        const rows = await this.db.all<IntentRow>(`SELECT * FROM ${this.t}`);\n        const out: Outpoint[] = [];\n        for (const r of rows) {\n            if (isTerminalIntentState(r.state as ArkIntentState)) continue;\n            for (const o of JSON.parse(r.intent_vtxos_json) as Outpoint[]) out.push(o);\n        }\n        return out;\n    }\n\n    async [Symbol.asyncDispose](): Promise<void> {}\n}\n\nfunction rowToIntent(r: IntentRow): ArkIntent {\n    return {\n        intentTxId: r.intent_tx_id,\n        intentId: r.intent_id ?? undefined,\n        state: r.state as ArkIntentState,\n        validFrom: r.valid_from ?? undefined,\n        validUntil: r.valid_until ?? undefined,\n        createdAt: r.created_at,\n        updatedAt: r.updated_at,\n        registerProof: r.register_proof,\n        registerProofMessage: r.register_proof_message,\n        deleteProof: r.delete_proof,\n        deleteProofMessage: r.delete_proof_message,\n        batchId: r.batch_id ?? undefined,\n        commitmentTransactionId: r.commitment_txid ?? undefined,\n        cancellationReason: r.cancellation_reason ?? undefined,\n        partialForfeits: JSON.parse(r.partial_forfeits_json),\n        signerDescriptor: r.signer_descriptor ?? undefined,\n        intentVtxos: JSON.parse(r.intent_vtxos_json),\n    };\n}\n","import { Outpoint } from \"../../wallet\";\nimport {\n    ChainedTxType,\n    mergeChainedTxType,\n    VirtualTx,\n    VirtualTxRepository,\n    VtxoBranch,\n} from \"../virtualTxRepository\";\nimport { SQLExecutor } from \"./types\";\nimport { runInTransaction } from \"./transaction\";\n\nconst SAFE_PREFIX = /^[a-zA-Z_][a-zA-Z0-9_]*$/;\nfunction sanitizePrefix(p: string): string {\n    if (!SAFE_PREFIX.test(p)) throw new Error(`Invalid table prefix \"${p}\"`);\n    return p;\n}\n\ninterface VtxRow {\n    txid: string;\n    psbt: string | null;\n    expires_at: number | null;\n    type: number;\n}\nexport class SQLiteVirtualTxRepository implements VirtualTxRepository {\n    readonly version = 1 as const;\n    private initPromise: Promise<void> | null = null;\n    private readonly prefix: string;\n    private readonly tTx: string;\n    private readonly tBranch: string;\n\n    constructor(\n        private readonly db: SQLExecutor,\n        options?: { prefix?: string },\n    ) {\n        this.prefix = sanitizePrefix(options?.prefix ?? \"ark_\");\n        this.tTx = `${this.prefix}virtual_txs`;\n        this.tBranch = `${this.prefix}vtxo_branches`;\n    }\n\n    private ensureInit(): Promise<void> {\n        if (!this.initPromise) this.initPromise = this.init();\n        return this.initPromise;\n    }\n\n    private async init(): Promise<void> {\n        await this.db.run(`CREATE TABLE IF NOT EXISTS ${this.tTx} (\n            txid TEXT PRIMARY KEY,\n            psbt TEXT,\n            expires_at INTEGER,\n            type INTEGER NOT NULL DEFAULT 0\n        )`);\n        await this.db.run(`CREATE TABLE IF NOT EXISTS ${this.tBranch} (\n            vtxo_txid TEXT NOT NULL,\n            vtxo_vout INTEGER NOT NULL,\n            virtual_txid TEXT NOT NULL,\n            position INTEGER NOT NULL,\n            PRIMARY KEY (vtxo_txid, vtxo_vout, position)\n        )`);\n        await this.db.run(\n            `CREATE INDEX IF NOT EXISTS idx_${this.prefix}branch_vtxid ON ${this.tBranch} (virtual_txid)`,\n        );\n    }\n\n    private tx(fn: () => Promise<void>): Promise<void> {\n        return runInTransaction(this.db, fn);\n    }\n\n    async clear(): Promise<void> {\n        await this.ensureInit();\n        await this.tx(async () => {\n            await this.db.run(`DELETE FROM ${this.tTx}`);\n            await this.db.run(`DELETE FROM ${this.tBranch}`);\n        });\n    }\n\n    async upsertVirtualTxs(txs: VirtualTx[]): Promise<void> {\n        if (txs.length === 0) return;\n        await this.ensureInit();\n        await this.tx(async () => {\n            // Prefetch existing rows in one query instead of a SELECT per tx,\n            // then merge (new value wins, else keep the stored one) in memory.\n            const placeholders = txs.map(() => \"?\").join(\", \");\n            const existing = await this.db.all<VtxRow>(\n                `SELECT * FROM ${this.tTx} WHERE txid IN (${placeholders})`,\n                txs.map((t) => t.txid),\n            );\n            const prevByTxid = new Map(existing.map((r) => [r.txid, r]));\n            for (const t of txs) {\n                const prev = prevByTxid.get(t.txid);\n                const psbt = t.psbt ?? prev?.psbt ?? null;\n                const expires = t.expiresAt ?? prev?.expires_at ?? null;\n                const type = mergeChainedTxType(t.type, prev?.type);\n                await this.db.run(\n                    `INSERT OR REPLACE INTO ${this.tTx} (txid, psbt, expires_at, type) VALUES (?, ?, ?, ?)`,\n                    [t.txid, psbt, expires, type],\n                );\n                // A txid repeated later in the same batch must merge onto this\n                // just-written row, matching the original per-tx-read behavior.\n                prevByTxid.set(t.txid, { txid: t.txid, psbt, expires_at: expires, type });\n            }\n        });\n    }\n\n    async getVirtualTx(txid: string): Promise<VirtualTx | null> {\n        await this.ensureInit();\n        const row = await this.db.get<VtxRow>(`SELECT * FROM ${this.tTx} WHERE txid = ?`, [txid]);\n        return row ? rowToTx(row) : null;\n    }\n\n    async setBranch(vtxo: Outpoint, branch: VtxoBranch[]): Promise<void> {\n        await this.ensureInit();\n        await this.tx(async () => {\n            await this.db.run(`DELETE FROM ${this.tBranch} WHERE vtxo_txid = ? AND vtxo_vout = ?`, [\n                vtxo.txid,\n                vtxo.vout,\n            ]);\n            for (const b of branch) {\n                await this.db.run(\n                    `INSERT OR REPLACE INTO ${this.tBranch} (vtxo_txid, vtxo_vout, virtual_txid, position) VALUES (?, ?, ?, ?)`,\n                    [b.vtxoTxid, b.vtxoVout, b.virtualTxid, b.position],\n                );\n            }\n        });\n    }\n\n    async getBranch(vtxo: Outpoint): Promise<VirtualTx[]> {\n        await this.ensureInit();\n        // Single JOIN instead of one lookup per branch row; the inner join\n        // naturally drops branch rows whose tx no longer exists.\n        const rows = await this.db.all<VtxRow>(\n            `SELECT t.txid, t.psbt, t.expires_at, t.type\n             FROM ${this.tBranch} b\n             JOIN ${this.tTx} t ON t.txid = b.virtual_txid\n             WHERE b.vtxo_txid = ? AND b.vtxo_vout = ?\n             ORDER BY b.position ASC`,\n            [vtxo.txid, vtxo.vout],\n        );\n        return rows.map(rowToTx);\n    }\n\n    async hasBranch(vtxo: Outpoint): Promise<boolean> {\n        await this.ensureInit();\n        const r = await this.db.get<{ c: number }>(\n            `SELECT COUNT(*) AS c FROM ${this.tBranch} WHERE vtxo_txid = ? AND vtxo_vout = ?`,\n            [vtxo.txid, vtxo.vout],\n        );\n        return (r?.c ?? 0) > 0;\n    }\n\n    async pruneForSpentVtxo(vtxo: Outpoint): Promise<void> {\n        await this.ensureInit();\n        await this.tx(async () => {\n            // Capture the txs this vtxo's branch referenced, then delete its\n            // branch rows and — in one set-based pass — drop only those txs\n            // that no other branch still references. Scoping the delete to the\n            // captured txids preserves txs inserted without a branch.\n            const removed = await this.db.all<{ virtual_txid: string }>(\n                `SELECT DISTINCT virtual_txid FROM ${this.tBranch} WHERE vtxo_txid = ? AND vtxo_vout = ?`,\n                [vtxo.txid, vtxo.vout],\n            );\n            await this.db.run(`DELETE FROM ${this.tBranch} WHERE vtxo_txid = ? AND vtxo_vout = ?`, [\n                vtxo.txid,\n                vtxo.vout,\n            ]);\n            if (removed.length === 0) return;\n            const placeholders = removed.map(() => \"?\").join(\", \");\n            await this.db.run(\n                `DELETE FROM ${this.tTx}\n                 WHERE txid IN (${placeholders})\n                 AND NOT EXISTS (\n                     SELECT 1 FROM ${this.tBranch} b WHERE b.virtual_txid = ${this.tTx}.txid\n                 )`,\n                removed.map((r) => r.virtual_txid),\n            );\n        });\n    }\n\n    async [Symbol.asyncDispose](): Promise<void> {}\n}\n\nfunction rowToTx(r: VtxRow): VirtualTx {\n    return {\n        txid: r.txid,\n        psbt: r.psbt ?? null,\n        expiresAt: r.expires_at ?? null,\n        type: r.type as ChainedTxType,\n    };\n}\n","// A table name cannot be a bound parameter, so every prefixed repository\n// interpolates it into SQL. This is the check that keeps that safe.\nconst SAFE_PREFIX = /^[a-zA-Z_][a-zA-Z0-9_]*$/;\n\n/**\n * Validate a SQLite table prefix and return it unchanged.\n *\n * Rejects a leading digit as well as punctuation: `1_vtxos` is not a valid SQL\n * identifier either.\n */\nexport function sanitizeTablePrefix(p: string): string {\n    if (!SAFE_PREFIX.test(p)) throw new Error(`Invalid table prefix \"${p}\"`);\n    return p;\n}\n"]}