import type { Invoice, IdentityVerificationRequest, IdentityVerificationResponse, IdentityVerificationAcknowledgment, Settlement, Receipt, Termination, RemittanceEnvelope, ThreadId, UnixMillis, LoggerLike, RemittanceOptionId, RemittanceThreadState } from './types.js'; import type { CommsLayer } from './CommsLayer.js'; import type { IdentityLayer } from './IdentityLayer.js'; import type { RemittanceModule } from './RemittanceModule.js'; import { OriginatorDomainNameStringUnder250Bytes, PubKeyHex, WalletInterface } from '../wallet/Wallet.interfaces.js'; export declare const DEFAULT_REMITTANCE_MESSAGEBOX = "remittance_inbox"; export interface RemittanceManagerRuntimeOptions { /** Identity verification options. */ identityOptions?: { /** At what point should a maker request identity verification? */ makerRequestIdentity?: 'never' | 'beforeInvoicing' | 'beforeSettlement'; /** At what point should a taker request identity verification? */ takerRequestIdentity?: 'never' | 'beforeInvoicing' | 'beforeSettlement'; }; /** If true, payees are expected to send receipts. */ receiptProvided: boolean; /** If true, manager auto-sends receipts as soon as a settlement is processed. */ autoIssueReceipt: boolean; /** Invoice expiry in seconds, or -1 for no expiry. */ invoiceExpirySeconds: number; /** Identity verification timeout in milliseconds. */ identityTimeoutMs: number; /** Identity verification poll interval in milliseconds. */ identityPollIntervalMs: number; } export interface RemittanceManagerConfig { /** Optional message box name to use for communication. */ messageBox?: string; /** Optional originator forwarded to wallet APIs. */ originator?: OriginatorDomainNameStringUnder250Bytes; /** * Provide a logger. If omitted, RemittanceManager stays quiet. * * The manager itself never throws on network/message parsing errors; it will mark threads as errored. */ logger?: LoggerLike; /** Runtime options that influence core behavior. */ options?: Partial; /** Modules (remittance options) available to this manager. */ remittanceModules: Array>; /** Optional identity layer for exchanging certificates before transacting. */ identityLayer?: IdentityLayer; /** Optional event callback for remittance lifecycle events. */ onEvent?: (event: RemittanceEvent) => void; /** Optional event callbacks keyed by process. */ events?: RemittanceEventHandlers; /** Persist manager state (threads). */ stateSaver?: (state: RemittanceManagerState) => Promise | void; /** Load manager state (threads). */ stateLoader?: () => Promise | RemittanceManagerState | undefined; /** Injectable clock for tests. */ now?: () => UnixMillis; /** Injectable thread id factory for tests. */ threadIdFactory?: () => ThreadId; } export type RemittanceEvent = { type: 'threadCreated'; threadId: ThreadId; thread: Thread; } | { type: 'stateChanged'; threadId: ThreadId; previous: RemittanceThreadState; next: RemittanceThreadState; reason?: string; } | { type: 'envelopeSent'; threadId: ThreadId; envelope: RemittanceEnvelope; transportMessageId: string; } | { type: 'envelopeReceived'; threadId: ThreadId; envelope: RemittanceEnvelope; transportMessageId: string; } | { type: 'identityRequested'; threadId: ThreadId; direction: 'in' | 'out'; request: IdentityVerificationRequest; } | { type: 'identityResponded'; threadId: ThreadId; direction: 'in' | 'out'; response: IdentityVerificationResponse; } | { type: 'identityAcknowledged'; threadId: ThreadId; direction: 'in' | 'out'; acknowledgment: IdentityVerificationAcknowledgment; } | { type: 'invoiceSent'; threadId: ThreadId; invoice: Invoice; } | { type: 'invoiceReceived'; threadId: ThreadId; invoice: Invoice; } | { type: 'settlementSent'; threadId: ThreadId; settlement: Settlement; } | { type: 'settlementReceived'; threadId: ThreadId; settlement: Settlement; } | { type: 'receiptSent'; threadId: ThreadId; receipt: Receipt; } | { type: 'receiptReceived'; threadId: ThreadId; receipt: Receipt; } | { type: 'terminationSent'; threadId: ThreadId; termination: Termination; } | { type: 'terminationReceived'; threadId: ThreadId; termination: Termination; } | { type: 'error'; threadId: ThreadId; error: string; }; export interface RemittanceEventHandlers { onThreadCreated?: (event: Extract) => void; onStateChanged?: (event: Extract) => void; onEnvelopeSent?: (event: Extract) => void; onEnvelopeReceived?: (event: Extract) => void; onIdentityRequested?: (event: Extract) => void; onIdentityResponded?: (event: Extract) => void; onIdentityAcknowledged?: (event: Extract) => void; onInvoiceSent?: (event: Extract) => void; onInvoiceReceived?: (event: Extract) => void; onSettlementSent?: (event: Extract) => void; onSettlementReceived?: (event: Extract) => void; onReceiptSent?: (event: Extract) => void; onReceiptReceived?: (event: Extract) => void; onTerminationSent?: (event: Extract) => void; onTerminationReceived?: (event: Extract) => void; onError?: (event: Extract) => void; } export interface Thread { threadId: ThreadId; counterparty: PubKeyHex; myRole: 'maker' | 'taker'; theirRole: 'maker' | 'taker'; createdAt: UnixMillis; updatedAt: UnixMillis; state: RemittanceThreadState; /** State transition log for audit purposes. */ stateLog: Array<{ at: UnixMillis; from: RemittanceThreadState; to: RemittanceThreadState; reason?: string; }>; /** Transport messageIds processed for this thread (dedupe across retries). */ processedMessageIds: string[]; /** Protocol envelopes received/sent (for debugging/audit). */ protocolLog: Array<{ direction: 'in' | 'out'; envelope: RemittanceEnvelope; transportMessageId: string; }>; identity: { certsSent: IdentityVerificationResponse['certificates']; certsReceived: IdentityVerificationResponse['certificates']; requestSent: boolean; responseSent: boolean; acknowledgmentSent: boolean; acknowledgmentReceived: boolean; }; invoice?: Invoice; settlement?: Settlement; receipt?: Receipt; termination?: Termination; flags: { hasIdentified: boolean; hasInvoiced: boolean; hasPaid: boolean; hasReceipted: boolean; error: boolean; }; lastError?: { message: string; at: UnixMillis; }; } export interface RemittanceManagerState { v: 1; threads: Thread[]; defaultPaymentOptionId?: string; } export interface ComposeInvoiceInput { /** Human note/memo. */ note?: string; /** Line items. */ lineItems: Invoice['lineItems']; /** Total amount. */ total: Invoice['total']; invoiceNumber?: string; arbitrary?: Record; } /** * RemittanceManager. * * Responsibilities: * - message transport via CommsLayer * - thread lifecycle and persistence (via stateSaver/stateLoader) * - invoice creation and transmission (when invoices are used) * - settlement and settlement routing to the appropriate module * - receipt issuance and receipt routing to the appropriate module * - identity and identity certificate exchange (when identity layer is used) * * Non-responsibilities (left to modules): * - transaction structure (whether UTXO “offer” formats, token logic, BRC-98/99 specifics, etc.) * - validation rules for settlement (e.g. partial tx templates, UTXO validity, etc.) * - on-chain broadcasting strategy or non-chain settlement specifics (like legacy payment protocols) * - Providing option terms for invoices * - Building settlement artifacts * - Accepting/rejecting settlements * - Deciding which identity certificates to request * - Deciding about sufficiency of identity certificates * - Preparing/processing specific receipt formats * - Internal business logic like order fulfillment, refunds, etc. */ export declare class RemittanceManager { readonly wallet: WalletInterface; readonly comms: CommsLayer; readonly cfg: RemittanceManagerConfig; private readonly messageBox; private readonly now; private readonly threadIdFactory; private readonly moduleRegistry; private readonly runtime; private readonly eventListeners; private readonly stateWaiters; private readonly eventHandlers?; /** Default option id used when paying an invoice, if not overridden per-call. */ private defaultPaymentOptionId?; /** Mutable threads list (persisted via stateSaver). */ threads: Thread[]; /** Cached identity key if wallet provides it. */ private myIdentityKey?; constructor(cfg: RemittanceManagerConfig, wallet: WalletInterface, commsLayer: CommsLayer, threads?: Thread[]); /** * Loads persisted state from cfg.stateLoader (if provided). * * Safe to call multiple times. */ init(): Promise; /** * Registers a remittance event listener. */ onEvent(listener: (event: RemittanceEvent) => void): () => void; /** * Sets a default payment option (module id) to use when paying invoices. */ preselectPaymentOption(optionId: string): void; /** * Returns an immutable snapshot of current manager state suitable for persistence. */ saveState(): RemittanceManagerState; /** * Loads state from an object previously produced by saveState(). */ loadState(state: RemittanceManagerState): void; /** * Persists current state via cfg.stateSaver (if provided). */ persistState(): Promise; /** * Syncs threads by fetching pending messages from the comms layer and processing them. * * Processing is idempotent using transport messageIds tracked per thread. * Messages are acknowledged after they are successfully applied to local state. */ syncThreads(hostOverride?: string): Promise; /** * Starts listening for live messages (if the CommsLayer supports it). */ startListening(hostOverride?: string): Promise; /** * Creates, records, and sends an invoice to a counterparty. * * Returns a handle you can use to wait for payment/receipt. */ sendInvoice(to: PubKeyHex, input: ComposeInvoiceInput, hostOverride?: string): Promise; /** * Sends an invoice for an existing thread, e.g. after an identity request was received. */ sendInvoiceForThread(threadId: ThreadId, input: ComposeInvoiceInput, hostOverride?: string): Promise; /** * Returns invoice handles that this manager can pay (we are the taker/payer). */ findInvoicesPayable(counterparty?: PubKeyHex): InvoiceHandle[]; /** * Returns invoice handles that we issued and are waiting to receive settlement for. */ findReceivableInvoices(counterparty?: PubKeyHex): InvoiceHandle[]; /** * Pays an invoice by selecting a remittance option and sending a settlement message. * * If receipts are enabled (receiptProvided), this method will optionally wait for a receipt. */ pay(threadId: ThreadId, optionId?: string, hostOverride?: string): Promise; /** * Waits for a receipt to arrive for a thread. * * Uses polling via syncThreads because live listeners are optional. */ waitForReceipt(threadId: ThreadId, opts?: { timeoutMs?: number; pollIntervalMs?: number; }): Promise; /** * Waits for a thread to reach a specific state. */ waitForState(threadId: ThreadId, state: RemittanceThreadState, opts?: { timeoutMs?: number; pollIntervalMs?: number; }): Promise; /** * Waits for identity exchange to complete for a thread. */ waitForIdentity(threadId: ThreadId, opts?: { timeoutMs?: number; pollIntervalMs?: number; }): Promise; /** * Waits for a settlement to arrive for a thread. */ waitForSettlement(threadId: ThreadId, opts?: { timeoutMs?: number; pollIntervalMs?: number; }): Promise; /** * Sends an unsolicited settlement to a counterparty. */ sendUnsolicitedSettlement(to: PubKeyHex, args: { moduleId: RemittanceOptionId; option: unknown; optionId?: RemittanceOptionId; note?: string; }, hostOverride?: string): Promise; /** * Returns a thread by id (if present). */ getThread(threadId: ThreadId): Thread | undefined; /** * Returns a thread handle by id, or throws if the thread does not exist. */ getThreadHandle(threadId: ThreadId): ThreadHandle; /** * Returns a thread by id or throws. * * Public so helper handles (e.g. InvoiceHandle) can call it. */ getThreadOrThrow(threadId: ThreadId): Thread; private moduleContext; private makeEnvelope; private sendEnvelope; private getOrCreateThreadFromInboundEnvelope; private handleInboundMessage; private applyInboundEnvelope; private maybeSendTermination; private sendTermination; private shouldRequestIdentity; private shouldRequireIdentityBeforeSettlement; private ensureIdentityExchange; private waitForIdentityAcknowledgment; private safeAck; private markThreadError; private ensureThreadState; private deriveThreadState; private transitionThreadState; private resolveStateWaiters; private rejectStateWaiters; private emitEvent; private refreshMyIdentityKey; private requireMyIdentityKey; private composeInvoice; } /** * A lightweight wrapper around a thread's invoice, with convenience methods. */ export declare class ThreadHandle { protected readonly manager: RemittanceManager; readonly threadId: ThreadId; constructor(manager: RemittanceManager, threadId: ThreadId); get thread(): Thread; waitForState(state: RemittanceThreadState, opts?: { timeoutMs?: number; pollIntervalMs?: number; }): Promise; waitForIdentity(opts?: { timeoutMs?: number; pollIntervalMs?: number; }): Promise; waitForSettlement(opts?: { timeoutMs?: number; pollIntervalMs?: number; }): Promise; waitForReceipt(opts?: { timeoutMs?: number; pollIntervalMs?: number; }): Promise; } export declare class InvoiceHandle extends ThreadHandle { get invoice(): Invoice; /** * Pays the invoice using the selected remittance option. */ pay(optionId?: string): Promise; } //# sourceMappingURL=RemittanceManager.d.ts.map