# pip install requests; save as rpc_events.py and run `python rpc_events.py` (Ctrl-C to stop)
import os
import time
import requests
rpc_url, pool = os.environ["RPC_URL"], os.environ["POOL"]
headers = {"Authorization": f"Bearer {os.environ['LUMEUS_API_KEY']}"}
def rpc(method, params=None):
"""One JSON-RPC call. Retries 429 and 503 after Retry-After, at most 5 times."""
body = {"jsonrpc": "2.0", "id": 1, "method": method}
if params is not None:
body["params"] = params
for attempt in range(1, 6):
response = requests.post(rpc_url, json=body, headers=headers, timeout=60)
try:
reply = response.json()
except ValueError:
reply = {}
if response.ok and "error" not in reply:
return reply["result"]
wait = int(response.headers.get("Retry-After", "2"))
# A wait over 60 s is the daily Testnet cap (resets at 00:00 UTC): stop instead.
if response.status_code not in (429, 503) or attempt == 5 or wait > 60:
error = reply.get("error", {})
raise SystemExit(f"{response.status_code} {error.get('data')}: {error.get('message')} ({error.get('request_id')})")
time.sleep(wait)
filters = [{"type": "contract", "contractIds": [pool]}]
latest = rpc("getHealth")["latestLedger"]
params = {"startLedger": latest - 100, "filters": filters, "xdrFormat": "json", "pagination": {"limit": 100}}
while True:
page = rpc("getEvents", params)
for e in page["events"]:
print(e["ledger"], e["topicJson"][0]["symbol"], e["id"], flush=True)
params = {"filters": filters, "xdrFormat": "json", "pagination": {"cursor": page["cursor"], "limit": 100}}
# A short page means you have caught up: wait for new ledgers (about 5 s each).
if len(page["events"]) < 100:
time.sleep(30)