import { type ValidListActionsArgs, type ValidListOutputsArgs } from '@bsv/sdk/wallet/validationHelpers'; import { InternalizeActionArgs, ListActionsResult, ListOutputsResult, TelemetrySpan } from '@bsv/sdk'; import { TableCertificate, TableCertificateField, TableCertificateX, TableCommission, TableMonitorEvent, TableOutput, TableOutputBasket, TableOutputTag, TableOutputTagMap, TableProvenTx, TableProvenTxReq, TableSettings, TableSyncState, TableTransaction, TableTxLabel, TableTxLabelMap, TableUser } from './schema/tables'; import { TableActionBatch, TableActionBatchBlob, TableActionBatchOutput } from './schema/tables/TableActionBatch'; import { TablePreparedBeef } from './schema/tables/TablePreparedBeef.interfaces'; import { Knex } from 'knex'; import { AdminStatsResult, StorageProvider, StorageProviderOptions } from './StorageProvider'; import { DBType } from './StorageReader'; import { WalletServices } from '../sdk/WalletServices.interfaces'; import { AuthId, StorageInternalizeActionResult, FindCertificateFieldsArgs, FindCertificatesArgs, FindCommissionsArgs, FindForUserSincePagedArgs, FindMonitorEventsArgs, FindOutputBasketsArgs, FindOutputsArgs, FindOutputTagMapsArgs, FindOutputTagsArgs, FindPartialSincePagedArgs, FindProvenTxReqsArgs, FindProvenTxsArgs, FindStaleMerkleRootsArgs, FindSyncStatesArgs, FindTransactionsArgs, FindTxLabelMapsArgs, FindTxLabelsArgs, FindUsersArgs, ProvenOrRawTx, PurgeParams, PurgeResults, TrxToken, RequestSyncChunkArgs, SyncChunkTotals, WalletStorageProvider } from '../sdk/WalletStorage.interfaces'; import { EntityTimeStamp, TransactionStatus } from '../sdk/types'; import type { ManagedChangeInputCandidate } from './methods/availableManagedChange'; import { PreparedBeefLookupResult, PreparedBeefOptions, PreparedBeefPolicy, PreparedBeefPreparation, PreparedBeefRoot } from './methods/preparedBeef'; import type { Brc177NoSendExpiryState } from '../utility/brc177NoSendExpiry'; export interface StorageKnexOptions extends StorageProviderOptions { /** * Knex database interface initialized with valid connection configuration. */ knex: Knex; /** Optional prepared-BEEF (COOK) rollout controls. Disabled by default. */ preparedBeef?: PreparedBeefOptions; } export declare class StorageKnex extends StorageProvider implements WalletStorageProvider { knex: Knex; readonly preparedBeefPolicy: PreparedBeefPolicy; private readonly preparedBeefCoordinator; private readonly preparedBeefReadSuspensions; private nextPreparedBeefReadSuspension; private readonly querySpans; private readonly onQuery; private readonly onQueryResponse; private readonly onQueryError; constructor(options: StorageKnexOptions); private receiptClockMs; private receiptLeaseMs; private acquireInternalizeReceipt; internalizeAction(auth: AuthId, args: InternalizeActionArgs): Promise; private databaseSystem; private endQuerySpan; protected supportsActionBatchPersistence(): boolean; protected supportsNoSendExpiryPersistence(): boolean; protected requiresActionBatchCleanupBeforeCreateAction(): boolean; makeAvailable(): Promise; setServices(services: WalletServices): void; readSettings(trx?: TrxToken): Promise; getProvenOrRawTx(txid: string, trx?: TrxToken): Promise; getProvenOrRawTxs(txids: string[], trx?: TrxToken): Promise>; findPreparedBeefs(userId: number, rootTxids: string[], trx?: TrxToken): Promise; /** * Metadata-only foreground preflight for fragmented actions. SQL computes * the actual blob lengths; BEEF bytes are not transferred to the process. */ readPreparedBeefLookupByteLength(userId: number, rootTxids: string[]): Promise; readPreparedBeefProofEpoch(trx?: TrxToken): Promise; /** * Cheap worker preflight. It prevents a large tenant-controlled no-send BEEF * from being loaded and parsed merely to discover that COOK will reject it. */ readPreparedBeefSourceByteLength(rootTxid: string): Promise; upsertPreparedBeef(artifact: TablePreparedBeef, expectedProofEpoch: number): Promise; findPreparedBeefBackfillRoots(limit: number, formatVersion: number): Promise; invalidatePreparedBeefs(trx?: TrxToken): Promise; lookupPreparedBeefs(userId: number, rootTxids: string[], parent?: TelemetrySpan): Promise; preparedBeefReadsEnabled(): boolean; /** * Synchronously close the local prepared-read gate before asynchronous reorg * invalidation waits for manager/database locks. The returned release is * idempotent; callers release it only after invalidation commits. */ suspendPreparedBeefReads(): () => void; preparedBeefWritesEnabled(): boolean; /** Queue best-effort preparation after foreground action work has completed. */ enqueuePreparedBeef(preparation: PreparedBeefPreparation): boolean; /** Start the optional, rate-limited existing-wallet backfill. */ startPreparedBeefBackfill(): void; /** Test/operator hook for waiting until currently queued work is complete. */ waitForPreparedBeefTasks(): Promise; /** Stop accepting background work and settle an active preparation before shutdown. */ stopPreparedBeefTasks(): Promise; private rawTxSliceExpression; private getRawTxSlice; getRawTxOfKnownValidTransaction(txid?: string, offset?: number, length?: number, trx?: TrxToken): Promise; getProvenTxsForUserQuery(args: FindForUserSincePagedArgs): Knex.QueryBuilder; getProvenTxsForUser(args: FindForUserSincePagedArgs): Promise; getProvenTxReqsForUserQuery(args: FindForUserSincePagedArgs): Knex.QueryBuilder; getProvenTxReqsForUser(args: FindForUserSincePagedArgs): Promise; getTxLabelMapsForUserQuery(args: FindForUserSincePagedArgs): Knex.QueryBuilder; getTxLabelMapsForUser(args: FindForUserSincePagedArgs): Promise; getOutputTagMapsForUserQuery(args: FindForUserSincePagedArgs): Knex.QueryBuilder; getOutputTagMapsForUser(args: FindForUserSincePagedArgs): Promise; private countSyncQuery; getSyncChunkTotals(args: RequestSyncChunkArgs, userId: number): Promise; listActions(auth: AuthId, vargs: ValidListActionsArgs): Promise; listOutputs(auth: AuthId, vargs: ValidListOutputsArgs): Promise; /** * Insert one row and return its auto-increment primary key. MySQL and SQLite * report the id as the insert result; Postgres requires a RETURNING clause. */ private insertReturningId; /** * The findOrInsert helpers catch a failed insert and find the row again in * the same transaction. MySQL and SQLite allow that. Postgres aborts the * whole transaction on any statement error, so there the insert runs in a * savepoint that is rolled back on its own. */ private inSavepoint; insertProvenTx(tx: TableProvenTx, trx?: TrxToken): Promise; insertActionBatch(batch: TableActionBatch, trx?: TrxToken): Promise; findActionBatch(userId: number, batchId: string, trx?: TrxToken): Promise; findActionBatchForUpdate(userId: number, batchId: string, trx: TrxToken): Promise; findExpiredActionBatches(now: Date, trx?: TrxToken): Promise; updateActionBatch(actionBatchId: number, update: Partial, trx?: TrxToken): Promise; deleteActionBatch(actionBatchId: number, trx?: TrxToken): Promise; reserveActionBatchOutputs(reservations: TableActionBatchOutput[], trx?: TrxToken): Promise; findActionBatchOutputIds(actionBatchId: number, trx?: TrxToken): Promise; findReservedActionBatchOutputIds(outputIds: number[], trx?: TrxToken): Promise; deleteActionBatchOutputReservations(actionBatchId: number, trx?: TrxToken): Promise; putActionBatchBlobRecord(blob: TableActionBatchBlob, trx?: TrxToken): Promise; findActionBatchBlobRecord(actionBatchId: number, digest: string, trx?: TrxToken): Promise; findActionBatchBlobRecords(actionBatchId: number, digests: string[], trx?: TrxToken): Promise; putActionBatchBlobRecords(blobs: TableActionBatchBlob[], trx?: TrxToken): Promise; deleteActionBatchBlobRecords(actionBatchId: number, trx?: TrxToken): Promise; insertProvenTxReq(tx: TableProvenTxReq, trx?: TrxToken): Promise; insertUser(user: TableUser, trx?: TrxToken): Promise; insertCertificateAuth(auth: AuthId, certificate: TableCertificateX): Promise; insertCertificate(certificate: TableCertificateX, trx?: TrxToken): Promise; insertCertificateField(certificateField: TableCertificateField, trx?: TrxToken): Promise; insertOutputBasket(basket: TableOutputBasket, trx?: TrxToken): Promise; insertTransaction(tx: TableTransaction, trx?: TrxToken): Promise; insertCommission(commission: TableCommission, trx?: TrxToken): Promise; insertOutput(output: TableOutput, trx?: TrxToken): Promise; insertOutputs(outputs: TableOutput[], trx?: TrxToken): Promise; insertOutputTag(tag: TableOutputTag, trx?: TrxToken): Promise; insertOutputTagMap(tagMap: TableOutputTagMap, trx?: TrxToken): Promise; insertTxLabel(label: TableTxLabel, trx?: TrxToken): Promise; insertTxLabelMap(labelMap: TableTxLabelMap, trx?: TrxToken): Promise; insertMonitorEvent(event: TableMonitorEvent, trx?: TrxToken): Promise; insertSyncState(syncState: TableSyncState, trx?: TrxToken): Promise; updateCertificateField(certificateId: number, fieldName: string, update: Partial, trx?: TrxToken): Promise; updateCertificate(id: number, update: Partial, trx?: TrxToken): Promise; updateCommission(id: number, update: Partial, trx?: TrxToken): Promise; updateOutputBasket(id: number, update: Partial, trx?: TrxToken): Promise; updateOutput(id: number, update: Partial, trx?: TrxToken): Promise; updateOutputTagMap(outputId: number, tagId: number, update: Partial, trx?: TrxToken): Promise; updateOutputTag(id: number, update: Partial, trx?: TrxToken): Promise; updateProvenTxReq(id: number | number[], update: Partial, trx?: TrxToken): Promise; updateProvenTx(id: number, update: Partial, trx?: TrxToken): Promise; updateSyncState(id: number, update: Partial, trx?: TrxToken): Promise; updateTransaction(id: number | number[], update: Partial, trx?: TrxToken): Promise; compareAndSetNoSendExpiryState(transactionId: number, expected: Brc177NoSendExpiryState, next: Brc177NoSendExpiryState, trx?: TrxToken): Promise; updateTxLabelMap(transactionId: number, txLabelId: number, update: Partial, trx?: TrxToken): Promise; updateTxLabel(id: number, update: Partial, trx?: TrxToken): Promise; updateUser(id: number, update: Partial, trx?: TrxToken): Promise; updateMonitorEvent(id: number, update: Partial, trx?: TrxToken): Promise; setupQuery(table: string, args: FindPartialSincePagedArgs): Knex.QueryBuilder; findCertificateFieldsQuery(args: FindCertificateFieldsArgs): Knex.QueryBuilder; findCertificatesQuery(args: FindCertificatesArgs): Knex.QueryBuilder; findCommissionsQuery(args: FindCommissionsArgs): Knex.QueryBuilder; findOutputBasketsQuery(args: FindOutputBasketsArgs): Knex.QueryBuilder; findOutputsQuery(args: FindOutputsArgs, count?: boolean): Knex.QueryBuilder; findOutputTagMapsQuery(args: FindOutputTagMapsArgs): Knex.QueryBuilder; findOutputTagsQuery(args: FindOutputTagsArgs): Knex.QueryBuilder; findProvenTxReqsQuery(args: FindProvenTxReqsArgs): Knex.QueryBuilder; findProvenTxsQuery(args: FindProvenTxsArgs): Knex.QueryBuilder; findStaleMerkleRootsQuery(args: FindStaleMerkleRootsArgs): Knex.QueryBuilder; findSyncStatesQuery(args: FindSyncStatesArgs): Knex.QueryBuilder; findTransactionsQuery(args: FindTransactionsArgs, count?: boolean): Knex.QueryBuilder; findTxLabelMapsQuery(args: FindTxLabelMapsArgs): Knex.QueryBuilder; findTxLabelsQuery(args: FindTxLabelsArgs): Knex.QueryBuilder; findUsersQuery(args: FindUsersArgs): Knex.QueryBuilder; findMonitorEventsQuery(args: FindMonitorEventsArgs): Knex.QueryBuilder; findCertificatesAuth(auth: AuthId, args: FindCertificatesArgs): Promise; findProvenTxReqsAuth(auth: AuthId, args: FindProvenTxReqsArgs): Promise; findOutputBasketsAuth(auth: AuthId, args: FindOutputBasketsArgs): Promise; findOutputsAuth(auth: AuthId, args: FindOutputsArgs): Promise; findCertificateFields(args: FindCertificateFieldsArgs): Promise; findCertificates(args: FindCertificatesArgs): Promise; findCommissions(args: FindCommissionsArgs): Promise; findOutputBaskets(args: FindOutputBasketsArgs): Promise; findOutputs(args: FindOutputsArgs): Promise; findOutputTagMaps(args: FindOutputTagMapsArgs): Promise; findOutputTags(args: FindOutputTagsArgs): Promise; findProvenTxReqs(args: FindProvenTxReqsArgs): Promise; findProvenTxs(args: FindProvenTxsArgs): Promise; findStaleMerkleRoots(args: FindStaleMerkleRootsArgs): Promise; findSyncStates(args: FindSyncStatesArgs): Promise; findTransactions(args: FindTransactionsArgs): Promise; findTxLabelMaps(args: FindTxLabelMapsArgs): Promise; findTxLabels(args: FindTxLabelsArgs): Promise; findUsers(args: FindUsersArgs): Promise; recentlyActiveUsers(limit?: number, trx?: TrxToken): Promise; findMonitorEvents(args: FindMonitorEventsArgs): Promise; getCount(q: Knex.QueryBuilder): Promise; countCertificateFields(args: FindCertificateFieldsArgs): Promise; countCertificates(args: FindCertificatesArgs): Promise; countCommissions(args: FindCommissionsArgs): Promise; countOutputBaskets(args: FindOutputBasketsArgs): Promise; countOutputs(args: FindOutputsArgs): Promise; countOutputTagMaps(args: FindOutputTagMapsArgs): Promise; countOutputTags(args: FindOutputTagsArgs): Promise; countProvenTxReqs(args: FindProvenTxReqsArgs): Promise; countProvenTxs(args: FindProvenTxsArgs): Promise; countSyncStates(args: FindSyncStatesArgs): Promise; countTransactions(args: FindTransactionsArgs): Promise; countTxLabelMaps(args: FindTxLabelMapsArgs): Promise; countTxLabels(args: FindTxLabelsArgs): Promise; countUsers(args: FindUsersArgs): Promise; countMonitorEvents(args: FindMonitorEventsArgs): Promise; destroy(): Promise; migrate(storageName: string, storageIdentityKey: string): Promise; dropAllData(): Promise; transaction(scope: (trx: TrxToken) => Promise, trx?: TrxToken): Promise; /** * Convert the standard optional `TrxToken` parameter into either a direct knex database instance, * or a Knex.Transaction as appropriate. */ toDb(trx?: TrxToken): Knex | Knex.Transaction; validateRawTransaction(t: TableTransaction, trx?: TrxToken): Promise; _verifiedReadyForDatabaseAccess: boolean; /** * Make sure database is ready for access: * * - dateScheme is known * - foreign key constraints are enabled * * @param trx */ verifyReadyForDatabaseAccess(trx?: TrxToken): Promise; /** Convert every byte-array value to a Buffer and every undefined to null on an arbitrary object. */ private serialiseForKnex; /** Apply optional date-field coercion list in-place. */ private coerceDateFields; /** Apply optional boolean-field coercion list in-place. */ private coerceBooleanFields; /** * Helper to force uniform behavior across database engines. * Use to process the update template for entities being updated. */ validatePartialForUpdate(update: Partial, dateFields?: string[], booleanFields?: string[]): Partial; /** * Helper to force uniform behavior across database engines. * Use to process new entities being inserted into the database. */ validateEntityForInsert(entity: T, trx?: TrxToken, dateFields?: string[], booleanFields?: string[]): Promise; getLabelsForTransactionId(transactionId?: number, trx?: TrxToken): Promise; getTagsForOutputId(outputId: number, trx?: TrxToken): Promise; purgeData(params: PurgeParams, trx?: TrxToken): Promise; reviewStatus(args: { agedLimit: Date; trx?: TrxToken; }): Promise<{ log: string; }>; /** * Counts wallet-managed BRC-29 change outputs for userId in basketId that * are currently eligible for automatic allocation * AND whose transaction status is one of: * - completed * - unproven * - sending (if excludeSending is false) */ countChangeInputs(userId: number, basketId: number, excludeSending: boolean): Promise; findAvailableManagedChangeInputs(userId: number, basketId: number, excludeSending: boolean, trx?: TrxToken): Promise; findAvailableManagedChangeInputCandidates(userId: number, basketId: number, excludeSending: boolean, trx?: TrxToken): Promise; findOutputsByIds(outputIds: number[], trx?: TrxToken): Promise>; findOutputsByOutpoints(userId: number, outpoints: Array<{ txid: string; vout: number; }>, trx?: TrxToken): Promise>; findOutputsByOutpointsForUpdate(userId: number, outpoints: Array<{ txid: string; vout: number; }>, trx: TrxToken, noScript?: boolean): Promise>; findTransactionStatusesByIds(userId: number, transactionIds: number[], trx?: TrxToken): Promise>; findFundingOutputsForUpdate(userId: number, outputIds: number[], statuses: TransactionStatus[], trx: TrxToken): Promise>; findOrInsertOutputBasketsBulk(userId: number, names: string[], trx?: TrxToken): Promise>; findOrInsertOutputTagsBulk(userId: number, tags: string[], trx?: TrxToken): Promise>; findOrInsertTxLabelsBulk(userId: number, labels: string[], trx?: TrxToken): Promise>; sumSpendableSatoshisInBasket(userId: number, basketId: number, excludeSending: boolean, trx?: TrxToken): Promise; /** * Finds closest matching available change output to use as input for new transaction. * * Transactionally allocate the output such that */ allocateChangeInput(userId: number, basketId: number, targetSatoshis: number, exactSatoshis: number | undefined, excludeSending: boolean, transactionId: number): Promise; markChangeInputsSpent(outputIds: number[], transactionId: number, trx: TrxToken): Promise; /** Convert null→undefined and Buffer→number[] on a retrieved entity in-place. */ private deserialiseFromKnex; /** * Helper to force uniform behavior across database engines. * Use to process all individual records with time stamps retreived from database. */ validateEntity(entity: T, dateFields?: string[], booleanFields?: string[]): T; /** * Helper to force uniform behavior across database engines. * Use to process all arrays of records with time stamps retreived from database. * @returns input `entities` array with contained values validated. */ validateEntities(entities: T[], dateFields?: string[], booleanFields?: string[]): T[]; adminStats(adminIdentityKey: string): Promise; } //# sourceMappingURL=StorageKnex.d.ts.map