Description
When an integration needs to process dozens of invoices simultaneously (e.g. month-end batch billing), running all submissions concurrently overwhelms Horizon's rate limits and produces cascading 429 errors. The SDK must provide a batch processor that submits invoices with a configurable concurrency ceiling, respects rate-limit backoff signals, and reports per-invoice results as they settle rather than waiting for the entire batch.
Technical Context
Add src/invoiceBatchProcessor.ts. Extends src/requestBatcher.ts patterns. Uses a semaphore pattern (configurable maxConcurrent, default 3) wrapping src/client.ts submitPayment(). Integrates with src/rateLimiter.ts to detect and honour Retry-After headers. Emits batchInvoiceSettled and batchInvoiceFailed via src/events.ts. Returns AsyncIterableIterator<BatchInvoiceResult>.
Acceptance Criteria
Description
When an integration needs to process dozens of invoices simultaneously (e.g. month-end batch billing), running all submissions concurrently overwhelms Horizon's rate limits and produces cascading
429errors. The SDK must provide a batch processor that submits invoices with a configurable concurrency ceiling, respects rate-limit backoff signals, and reports per-invoice results as they settle rather than waiting for the entire batch.Technical Context
Add
src/invoiceBatchProcessor.ts. Extendssrc/requestBatcher.tspatterns. Uses a semaphore pattern (configurablemaxConcurrent, default 3) wrappingsrc/client.tssubmitPayment(). Integrates withsrc/rateLimiter.tsto detect and honourRetry-Afterheaders. EmitsbatchInvoiceSettledandbatchInvoiceFailedviasrc/events.ts. ReturnsAsyncIterableIterator<BatchInvoiceResult>.Acceptance Criteria
InvoiceBatchProcessor.process(invoiceIds: string[], config): AsyncIterableIterator<BatchInvoiceResult>yields results as each invoice settlesmaxConcurrentinvoice submissions are in-flight simultaneously429response from Horizon, pauses all in-flight submissions for the duration specified inRetry-Afterand resumesBatchInvoiceResultincludesinvoiceId,status: 'success' | 'failed',txHash?, anderror?