Description
Invoices carry an expiresAt timestamp, but the SDK does not enforce this on the transaction side by setting timebounds.maxTime on built transactions. A payment submitted after an invoice expires should be rejected at the ledger level, not merely by SDK-side checks. The expiry guard must translate invoice expiry into transaction timebounds and reject submission attempts where the expiry has already passed.
Technical Context
Extend src/txBuilder.ts to set timeBounds using TransactionBuilder.setTimeout() from @stellar/stellar-sdk. Reads InvoiceRecord.expiresAt from src/types.ts. Add PaymentExpiredError to src/errors.ts. Pre-submission check added to src/preflightChecker.ts. src/deadlineEngine.ts provides the remaining-seconds calculation that feeds into setTimeout().
Acceptance Criteria
Description
Invoices carry an
expiresAttimestamp, but the SDK does not enforce this on the transaction side by settingtimebounds.maxTimeon built transactions. A payment submitted after an invoice expires should be rejected at the ledger level, not merely by SDK-side checks. The expiry guard must translate invoice expiry into transactiontimeboundsand reject submission attempts where the expiry has already passed.Technical Context
Extend
src/txBuilder.tsto settimeBoundsusingTransactionBuilder.setTimeout()from@stellar/stellar-sdk. ReadsInvoiceRecord.expiresAtfromsrc/types.ts. AddPaymentExpiredErrortosrc/errors.ts. Pre-submission check added tosrc/preflightChecker.ts.src/deadlineEngine.tsprovides the remaining-seconds calculation that feeds intosetTimeout().Acceptance Criteria
txBuilder.build()automatically callssetTimeout(remainingSeconds)when building a payment for an invoice withexpiresAtsetPaymentExpiredErrorsynchronously whenexpiresAtis in the past at build time, before any network callexpiryBufferSeconds(default 30) subtracted from the remaining time to account for clock skewPaymentExpiredErrorwith a human-readable message including the expired timestamp