import { Beef, WalletLoggerInterface } from '@bsv/sdk'; import { StorageProvider } from '../StorageProvider'; import { EntityProvenTxReq } from '../schema/entities'; import * as sdk from '../../sdk'; /** * Attempt to post one or more `ProvenTxReq` with status 'unsent' * to the bitcoin network. * * @param reqs */ export declare function attemptToPostReqsToNetwork(storage: StorageProvider, reqs: EntityProvenTxReq[], trx?: sdk.TrxToken, logger?: WalletLoggerInterface): Promise; /** * For each txid in submitted `txids`: * * Based on its aggregate status, and whether broadcast happening in background (isDelayed) or immediately (!isDelayed), * and iff current req.status is not 'unproven' or 'completed': * * 'success': * req.status => 'unmined', tx.status => 'unproven' * 'doubleSpend': * req.status => 'doubleSpend', tx.status => 'failed' * 'invalidTx': * req.status => 'invalid', tx.status => 'failed' * 'serviceError': * increment req.attempts * * @param txids * @param apbrs * @param storage * @param services if valid, doubleSpend results will be verified (but only if not within a trx. e.g. trx must be undefined) * @param trx */ export declare function updateReqsFromAggregateResults(txids: string[], r: PostReqsToNetworkResult, apbrs: Record, storage: StorageProvider, services?: sdk.WalletServices, trx?: sdk.TrxToken, logger?: WalletLoggerInterface): Promise; /** * After any failed broadcast (doubleSpend, invalidTx, etc.), query each * consumed-input outpoint of the failed transaction against on-chain * UTXO state. For inputs the chain authoritatively confirms are spent * (i.e. NOT a UTXO), update the corresponding wallet basket entry to * spendable=false. * * Background: `updateTransactionStatus(failed)` optimistically restores * all consumed-input outputs to spendable=true so the user can retry * with the same inputs. For some failures (genuine doubleSpend, or any * 'missing-inputs' outcome where the input has been spent on chain by * a different transaction), restoration is incorrect — the input is * gone and restoring it produces an infinite missing-inputs loop on * the next createAction → broadcast cycle. Apps cannot evict from the * default basket on app-isolated wallets (admin-only policy), so this * self-heal must run inside the wallet. * * Different broadcasters classify the same on-chain reality differently * (ARC → doubleSpend, WhatsOnChain/Bitails → invalidTx via * 'missing-inputs'); this helper is broadcaster-agnostic because its * decision is based on services.isUtxo, not the aggregate failure * classification. * * Pre-broadcast races where concurrent createActions reach the same * UTXO across separate app processes are out of scope; see PR * description. * * Conservatively scoped: * - Only inputs found in the failing user's basket are touched. * - Inputs whose on-chain UTXO status cannot be determined (service * error / inconclusive) are left spendable=true. Eviction is opt-in * based on positive evidence of stale state. * - Inputs the chain confirms are still UTXOs (e.g. a competing tx * itself failed, or a malformed/fee failure where inputs are intact) * are left spendable=true — preserving the existing transient-retry * semantics callers depend on. * * Returns counts for instrumentation and the set of stale outpoints * that were actually evicted (added to history note for diagnostics). */ export declare function markStaleInputsAsSpent(ar: AggregatePostBeefTxResult, storage: StorageProvider, services: sdk.WalletServices, trx?: sdk.TrxToken, logger?: WalletLoggerInterface): Promise<{ checked: number; staleConfirmed: number; staleOutpoints: string[]; }>; type AggregateStatus = 'success' | 'doubleSpend' | 'invalidTx' | 'serviceError'; export interface AggregatePostBeefTxResult { txid: string; txidResults: sdk.PostTxResultForTxid[]; status: AggregateStatus; vreq: PostReqsToNetworkDetails; successCount: number; doubleSpendCount: number; statusErrorCount: number; serviceErrorCount: number; /** * Any competing double spend txids reported for this txid */ competingTxs: string[]; } /** * Indicates status of a new Action following a `createAction` or `signAction` in immediate mode: * When `acceptDelayedBroadcast` is falses. * * 'success': The action has been broadcast and accepted by the bitcoin processing network. * 'doubleSpend': The action has been confirmed to double spend one or more inputs, and by the "first-seen-rule" is the losing transaction. * 'invalidTx': The action was rejected by the processing network as an invalid bitcoin transaction. * 'serviceError': The broadcast services are currently unable to reach the bitcoin network. The action is now queued for delayed retries. * * 'invalid': The action was in an invalid state for processing, this status should never be seen by user code. * 'unknown': An internal processing error has occured, this status should never be seen by user code. * */ export type PostReqsToNetworkDetailsStatus = 'success' | 'doubleSpend' | 'unknown' | 'invalid' | 'serviceError' | 'invalidTx'; export interface PostReqsToNetworkDetails { txid: string; req: EntityProvenTxReq; status: PostReqsToNetworkDetailsStatus; /** * Any competing double spend txids reported for this txid */ competingTxs?: string[]; } export interface PostReqsToNetworkResult { status: 'success' | 'error'; beef: Beef; details: PostReqsToNetworkDetails[]; log: string; } export {}; //# sourceMappingURL=attemptToPostReqsToNetwork.d.ts.map