/** * SDK-owned withdrawal lifecycle persistence + reconciliation helpers (ENG-1791). * * Records are persisted in the `withdrawals` state segment and are append-only * with id-keyed updates. This module is the single boundary that owns the * read/append/replace contract for `WithdrawalRecord`s — call sites in account * clients and the LibQC facade go through these helpers rather than mutating * the segment directly. */ import type { AccountId } from 'caip'; import type { VaultEncryptionKeyWithMetadata } from './cryptography'; import { type LibQCStorage } from './storage'; import type { Address, WithdrawalLifecycleStatus, WithdrawalRecord, WithdrawalTxIdentifier } from './types'; /** * Ms-epoch clock used to stamp lifecycle transitions. Wrapped so tests can * replace it via module mocks if deterministic timestamps are required. */ export declare function nowMs(): number; /** * Generates a UUID v4 for a new withdrawal record. * * Uses the Web Crypto `randomUUID` available in modern Node and browser runtimes. */ export declare function createWithdrawalId(): string; /** * Parameters for creating a new withdrawal record at submission time. * * `initialStatus` differs by chain: BTC starts at 'pending' (broadcast but * not confirmed); EVM starts at 'sent' (userop receipt already returned). */ export interface NewWithdrawalRecordInput { accountId: AccountId; destinationAddress: Address; destinationChain: string; txRefs: WithdrawalTxIdentifier[]; initialStatus: Extract; } /** * Builds and persists a new withdrawal record for an `emptyVault` call. */ export declare function recordWithdrawal(storage: LibQCStorage, encryptionKey: VaultEncryptionKeyWithMetadata, input: NewWithdrawalRecordInput): Promise; /** * Reads withdrawals from the encrypted state, optionally filtered by account. * * Records are returned newest-first by `initiatedAt`. */ export declare function listWithdrawalRecords(storage: LibQCStorage, encryptionKey: VaultEncryptionKeyWithMetadata, accountId?: AccountId): Promise; /** * Replaces a single record by id. Throws if the id is not found, since * reconciliation is expected to operate on records it just read. */ export declare function replaceWithdrawalRecord(storage: LibQCStorage, encryptionKey: VaultEncryptionKeyWithMetadata, updated: WithdrawalRecord): Promise; /** * Reconciliation observation for a withdrawal record (ENG-1791). * * The `confirmed` flag is true when every submitted tx has reached the chain's * canonical confirmation criterion (≥1 confirmation on Bitcoin, receipt * status='success' on EVM). The `sourceBalanceZero` flag is true when no * withdrawable balance remains on the source account. Callers persist * transitions via {@link applyReconciliation}. */ export interface WithdrawalReconciliation { confirmed: boolean; sourceBalanceZero: boolean; /** Set when reconciliation observed an explicit non-throw failure. */ failed?: boolean; } /** * Applies a reconciliation observation to a record and returns the next * record value (or the original record if no transition is warranted). * * Lifecycle transitions are deterministic: * - failed (any → failed) is terminal and short-circuits other transitions * - pending → sent when confirmed * - sent → withdrawn when source balance is zero (post-confirmation) */ export declare function applyReconciliation(record: WithdrawalRecord, reconciliation: WithdrawalReconciliation): WithdrawalRecord;