refactor: rename extension identity to spirekeeper
Fork of satmachineadmin's v2-bitspire line into its own repo. Renames
both identifiers so this extension is fully independent of the original
satmachineadmin install (which remains in service):
- extension id satmachineadmin -> spirekeeper
(router prefix, static path/static_url_for, module symbols, task
names, templates dir, config/manifest paths)
- database name satoshimachine -> spirekeeper
(Database(ext_spirekeeper), all schema-qualified table refs)
Also resets versioning to 0.1.0, sets the display name + manifest to
spirekeeper/aiolabs, and fixes the placeholder pyproject description.
Historical aiolabs/satmachineadmin#N issue references in comments are
left pointing at the original repo where those issues live.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
9c4d2c1324
commit
a059e3f596
22 changed files with 242 additions and 242 deletions
46
tasks.py
46
tasks.py
|
|
@ -45,7 +45,7 @@ from .crud import (
|
|||
from .distribution import process_settlement
|
||||
from .models import CreateDcaSettlementData, Machine
|
||||
|
||||
LISTENER_NAME = "ext_satmachineadmin"
|
||||
LISTENER_NAME = "ext_spirekeeper"
|
||||
|
||||
# Holds strong refs to in-flight distribution tasks so Python's GC doesn't
|
||||
# collect them mid-flight (asyncio.create_task only weakly references its
|
||||
|
|
@ -58,7 +58,7 @@ async def wait_for_paid_invoices() -> None:
|
|||
invoice_queue: asyncio.Queue = asyncio.Queue()
|
||||
register_invoice_listener(invoice_queue, LISTENER_NAME)
|
||||
logger.info(
|
||||
"satmachineadmin v2: invoice listener registered as "
|
||||
"spirekeeper v2: invoice listener registered as "
|
||||
f"`{LISTENER_NAME}` — waiting for bitSpire settlements."
|
||||
)
|
||||
while True:
|
||||
|
|
@ -67,7 +67,7 @@ async def wait_for_paid_invoices() -> None:
|
|||
await _handle_payment(payment)
|
||||
except Exception as exc: # listener must never die
|
||||
logger.error(
|
||||
f"satmachineadmin: error handling payment "
|
||||
f"spirekeeper: error handling payment "
|
||||
f"{payment.payment_hash[:12]}...: {exc}"
|
||||
)
|
||||
|
||||
|
|
@ -169,12 +169,12 @@ async def _handle_payment(payment: Payment) -> None:
|
|||
settlement = await create_settlement_idempotent(data, initial_status="pending")
|
||||
if settlement is None:
|
||||
logger.error(
|
||||
f"satmachineadmin: failed to insert settlement for "
|
||||
f"spirekeeper: failed to insert settlement for "
|
||||
f"payment_hash={payment.payment_hash[:12]}..."
|
||||
)
|
||||
return
|
||||
logger.info(
|
||||
f"satmachineadmin: landed settlement {settlement.id} for "
|
||||
f"spirekeeper: landed settlement {settlement.id} for "
|
||||
f"machine={machine.machine_npub[:12]}... "
|
||||
f"wire={data.wire_sats}sats principal={data.principal_sats}sats "
|
||||
f"fee={data.fee_sats}sats "
|
||||
|
|
@ -224,12 +224,12 @@ async def _record_rejected(payment: Payment, machine: Machine, exc: Exception) -
|
|||
)
|
||||
if rejected is None:
|
||||
logger.error(
|
||||
f"satmachineadmin: failed to insert rejected settlement for "
|
||||
f"spirekeeper: failed to insert rejected settlement for "
|
||||
f"payment_hash={payment.payment_hash[:12]}..."
|
||||
)
|
||||
return
|
||||
logger.error(
|
||||
f"satmachineadmin: rejected settlement {rejected.id} "
|
||||
f"spirekeeper: rejected settlement {rejected.id} "
|
||||
f"(machine={machine.machine_npub[:12]}..., "
|
||||
f"payment_hash={payment.payment_hash[:12]}...): {exc}"
|
||||
)
|
||||
|
|
@ -245,7 +245,7 @@ async def _record_rejected(payment: Payment, machine: Machine, exc: Exception) -
|
|||
# upserts cassette_configs via apply_bootstrap_state.
|
||||
#
|
||||
# v1 = one-shot per machine (ATM's meta.bootstrapPublishedAt makes the
|
||||
# publish idempotent on ATM-side restart; satmachineadmin's apply_bootstrap_
|
||||
# publish idempotent on ATM-side restart; spirekeeper's apply_bootstrap_
|
||||
# state dedups on state_event_id for relay re-delivery).
|
||||
#
|
||||
# v2 (separate issue) = continuous reverse-channel consumer with a
|
||||
|
|
@ -258,7 +258,7 @@ async def _record_rejected(payment: Payment, machine: Machine, exc: Exception) -
|
|||
# websocket. The relay manager is the same singleton publish_to_atm uses,
|
||||
# so add_subscription registers a filter against the same relay pool.
|
||||
|
||||
CASSETTE_BOOTSTRAP_SUB_ID = "satmachineadmin-cassette-bootstrap"
|
||||
CASSETTE_BOOTSTRAP_SUB_ID = "spirekeeper-cassette-bootstrap"
|
||||
_CASSETTE_POLL_INTERVAL_S = 2.0
|
||||
_CASSETTE_BACKOFF_S = 30.0 # when nostrclient isn't installed yet
|
||||
|
||||
|
|
@ -280,7 +280,7 @@ async def wait_for_cassette_state_events() -> None:
|
|||
- apply_bootstrap_state errors → log + skip
|
||||
"""
|
||||
logger.info(
|
||||
"satmachineadmin v2: cassette bootstrap consumer starting "
|
||||
"spirekeeper v2: cassette bootstrap consumer starting "
|
||||
f"(sub_id={CASSETTE_BOOTSTRAP_SUB_ID})"
|
||||
)
|
||||
current_filter_key: str | None = None
|
||||
|
|
@ -290,7 +290,7 @@ async def wait_for_cassette_state_events() -> None:
|
|||
await asyncio.sleep(_CASSETTE_POLL_INTERVAL_S)
|
||||
except _NostrclientUnavailable:
|
||||
logger.warning(
|
||||
"satmachineadmin: nostrclient extension not installed; "
|
||||
"spirekeeper: nostrclient extension not installed; "
|
||||
f"cassette bootstrap consumer sleeping {_CASSETTE_BACKOFF_S}s "
|
||||
"before retry. Install + activate nostrclient on this "
|
||||
"LNbits instance."
|
||||
|
|
@ -299,7 +299,7 @@ async def wait_for_cassette_state_events() -> None:
|
|||
await asyncio.sleep(_CASSETTE_BACKOFF_S)
|
||||
except Exception as exc: # listener must never die
|
||||
logger.error(
|
||||
f"satmachineadmin: cassette consumer loop error (continuing): " f"{exc}"
|
||||
f"spirekeeper: cassette consumer loop error (continuing): " f"{exc}"
|
||||
)
|
||||
await asyncio.sleep(_CASSETTE_POLL_INTERVAL_S)
|
||||
|
||||
|
|
@ -346,13 +346,13 @@ async def _cassette_consumer_tick(current_filter_key: str | None) -> str:
|
|||
CASSETTE_BOOTSTRAP_SUB_ID, filters # type: ignore[arg-type]
|
||||
)
|
||||
logger.info(
|
||||
"satmachineadmin: (re)registered cassette bootstrap "
|
||||
"spirekeeper: (re)registered cassette bootstrap "
|
||||
f"subscription with {len(d_tags)} d-tag(s)"
|
||||
)
|
||||
else:
|
||||
nostr_client.relay_manager.close_subscription(CASSETTE_BOOTSTRAP_SUB_ID)
|
||||
logger.info(
|
||||
"satmachineadmin: no active machines; closed cassette "
|
||||
"spirekeeper: no active machines; closed cassette "
|
||||
"bootstrap subscription"
|
||||
)
|
||||
|
||||
|
|
@ -368,7 +368,7 @@ async def _cassette_consumer_tick(current_filter_key: str | None) -> str:
|
|||
)
|
||||
except Exception as exc:
|
||||
logger.warning(
|
||||
f"satmachineadmin: cassette state event handler "
|
||||
f"spirekeeper: cassette state event handler "
|
||||
f"failed (skipping): {exc}"
|
||||
)
|
||||
|
||||
|
|
@ -419,14 +419,14 @@ async def _handle_cassette_state_event(
|
|||
event_obj = event_raw
|
||||
else:
|
||||
logger.warning(
|
||||
f"satmachineadmin: cassette event of unexpected type "
|
||||
f"spirekeeper: cassette event of unexpected type "
|
||||
f"{type(event_raw).__name__}; skipping"
|
||||
)
|
||||
return
|
||||
|
||||
if not verify_event(event_obj):
|
||||
logger.warning(
|
||||
f"satmachineadmin: cassette state event sig verify failed "
|
||||
f"spirekeeper: cassette state event sig verify failed "
|
||||
f"(id={event_obj.get('id', '?')[:12]}...)"
|
||||
)
|
||||
return
|
||||
|
|
@ -437,7 +437,7 @@ async def _handle_cassette_state_event(
|
|||
# Unknown sender — could be relay noise or an attacker. Don't
|
||||
# treat as our problem.
|
||||
logger.warning(
|
||||
f"satmachineadmin: cassette state event from unknown ATM "
|
||||
f"spirekeeper: cassette state event from unknown ATM "
|
||||
f"pubkey {sender_pubkey[:12]}... (not in dca_machines); "
|
||||
"skipping"
|
||||
)
|
||||
|
|
@ -448,7 +448,7 @@ async def _handle_cassette_state_event(
|
|||
except CassetteTransportError as exc:
|
||||
# OperatorIdentityMissing / SignerUnavailable — log + skip.
|
||||
logger.warning(
|
||||
f"satmachineadmin: can't resolve signer for operator "
|
||||
f"spirekeeper: can't resolve signer for operator "
|
||||
f"{machine.operator_user_id[:8]}... (machine {machine.id}): "
|
||||
f"{exc}"
|
||||
)
|
||||
|
|
@ -458,13 +458,13 @@ async def _handle_cassette_state_event(
|
|||
payload = await decrypt_and_parse_state_event(event_obj, account, signer)
|
||||
except CassetteEventTransientError as exc:
|
||||
logger.info(
|
||||
f"satmachineadmin: cassette state event for machine {machine.id} "
|
||||
f"spirekeeper: cassette state event for machine {machine.id} "
|
||||
f"hit a transient signer error (will retry next poll): {exc}"
|
||||
)
|
||||
return
|
||||
except CassetteEventDecodeError as exc:
|
||||
logger.warning(
|
||||
f"satmachineadmin: cassette state event decode failed for "
|
||||
f"spirekeeper: cassette state event decode failed for "
|
||||
f"machine {machine.id} (id={event_obj.get('id', '?')[:12]}...): "
|
||||
f"{exc}"
|
||||
)
|
||||
|
|
@ -479,12 +479,12 @@ async def _handle_cassette_state_event(
|
|||
)
|
||||
if applied:
|
||||
logger.info(
|
||||
f"satmachineadmin: applied bootstrap state event {event_id[:12]}... "
|
||||
f"spirekeeper: applied bootstrap state event {event_id[:12]}... "
|
||||
f"to machine {machine.id} ({len(payload.positions)} cassettes)"
|
||||
)
|
||||
else:
|
||||
# Replay: event_id already on file. Normal on relay reconnect.
|
||||
logger.debug(
|
||||
f"satmachineadmin: cassette state event {event_id[:12]}... "
|
||||
f"spirekeeper: cassette state event {event_id[:12]}... "
|
||||
f"already applied to machine {machine.id} (replay no-op)"
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue