Repository navigation
fix: poll on-chain balances periodically and persist before webhook - #91
Open
dadofsambonzuki wants to merge 1 commit into
Open
dadofsambonzuki wants to merge 1 commit into
dadofsambonzuki wants to merge 1 commit into
Conversation
dadofsambonzuki
force-pushed
the
fix/onchain-payment-poll
branch
from
September 21, 2026 16:55
4d5096d to
39f25c0
Compare
On-chain payment detection relied entirely on the mempool websocket push feed. When tracking breaks (e.g. the per-connection tracked-address limit is exceeded) payments were only detected at the next process restart. Run the existing restart_address_tracking() as a permanent periodic task so balances are re-checked by REST as a fallback.
- tasks.py: restart_address_tracking() now loops on a 120s cadence, isolates per-charge errors, and drops paid/expired addresses from websocket tracking so the list stays under mempool's per-connection address cap.
- helpers.py: check_charge_balance() persists the settled charge before firing the webhook so handlers that re-fetch the charge (e.g. GET /satspay/api/v1/charge/{id}) observe it as paid, mirroring tasks._handle_ws_message(). The webhook now fires only when a charge becomes paid instead of on every balance check.
- __init__.py: register the poll with create_permanent_unique_task so it auto-restarts, and include it in scheduled_tasks so satspay_stop() cancels it.
dadofsambonzuki
force-pushed
the
fix/onchain-payment-poll
branch
from
September 21, 2026 17:57
39f25c0 to
2c47a8b
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Recovers on-chain charge payments that currently only get detected via the mempool websocket push feed.
restart_address_tracking()only ran once at extension startup. If websocket tracking broke after that (for example once the number of tracked addresses hit mempool's per-connection limit andtrack-addressesstarted being rejected), on-chain payments were never detected until the next process restart. Each new charge then grew the rejected tracking list further, so the failure was permanent.This PR converts that one-shot pass into a permanent periodic REST balance poll and hardens the settlement/webhook path:
restart_address_tracking()now loops on a 120s cadence for the lifetime of the process, isolates per-charge errors, and drops paid and expired addresses from the websocket tracking list each pass so the list stays under mempool's per-connection address cap.check_charge_balance()now persists the settled charge before firing the webhook (mirroringtasks._handle_ws_message), so webhook handlers that re-fetch the charge (e.g.GET /satspay/api/v1/charge/{id}) observe it as paid. The webhook now fires only when a charge becomes paid, instead of on every balance check (which previously pinged the webhook endpoint on every poll of unpaid charges).create_permanent_unique_task(auto-restarts on failure) and includes it inscheduled_taskssosatspay_stop()cancels it.Note
This is a stopgap for the public mempool.space feed. #88 (feat: use blockexplorer) supersedes this by moving on-chain tracking to a local block explorer.