what problem would this feature solve, if any?
On slow devices or with high difficulty settings, proof-of-work solving can run indefinitely. The user sees a spinner with no way to abort, and workers keep burning CPU with no upper bound. The expires field exists in the challenge response but is only enforced server-side — the widget ignores it during solving.
describe the solution you'd like
Make the challenge expiration (expires) configurable via CHALLENGE_TTL_MS environment variable and per-key expiresMs config. Have the widget respect the expires timestamp as a solve deadline — aborting workers and showing an error state when time runs out. No new fields in the challenge response; reuses the existing expires.
describe alternatives you've considered
- Widget-only configuration (HTML attribute) — simpler but requires every integrator to manually set the right value based on server difficulty, which they may not know.
- Automatic timeout derived from difficulty/challengeCount — would remove the need for manual config, but the relationship between difficulty and solve time varies too much across devices to pick a reliable formula.
additional context:
- expiresMs already exists as a parameter in @cap.js/server's createChallenge() — this PR brings the same configurability to standalone.
- Priority: per-key expiresMs > CHALLENGE_TTL_MS env var > default 15 minutes.
- The widget terminates Web Worker pools on timeout to stop wasting CPU.
what problem would this feature solve, if any?
On slow devices or with high difficulty settings, proof-of-work solving can run indefinitely. The user sees a spinner with no way to abort, and workers keep burning CPU with no upper bound. The expires field exists in the challenge response but is only enforced server-side — the widget ignores it during solving.
describe the solution you'd like
Make the challenge expiration (expires) configurable via CHALLENGE_TTL_MS environment variable and per-key expiresMs config. Have the widget respect the expires timestamp as a solve deadline — aborting workers and showing an error state when time runs out. No new fields in the challenge response; reuses the existing expires.
describe alternatives you've considered
additional context: