Three trigger points wire fee_transport.publish_fee_config into the
satmachineadmin API endpoints per the #39 spec. All three soft-fail on
transport errors — the underlying CRUD operation (machine create /
update / super-config save) succeeds even when the publish couldn't
reach the relay or the signer, and the operator can re-trigger by
editing again.
views_api.py:
- api_create_machine — publishes always after create, even when
operator fees default to 0/0 (the resulting super-only payload is
what unblocks the ATM past its `awaiting-fees` maintenance gate).
Reads super_config singleton; if absent (m001 should have inserted
it, so this is an impossible state), skips the publish to avoid
crashing create.
- api_update_machine — publishes only when either
operator_cash_*_fee_fraction is in the patch payload. Skip on
name/location/wallet_id/is_active/fiat_code edits since those don't
affect the fee model the ATM enforces (avoids unnecessary relay
churn).
- api_update_super_config — publishes to every active machine when
either super fraction changes. Per-machine: that machine's
operator_user_id is the signer (machines owned by different
operators sign with different keys); each soft-fail is independent.
Skip if only super_fee_wallet_id changed (no fee-model impact).
Tests (9 cases, all green):
- 3 create-machine triggers: default 0/0 operator fees still publishes
super-only payload, nonzero operator fees publish full payload,
None super_config short-circuits without crashing
- 4 update-machine triggers: publishes on cash_in change, publishes on
cash_out change, skips on name-only, skips on is_active-only
- 2 super-config triggers: publishes per-active-machine signed by
each machine's operator on fraction change, skips entirely on
wallet-id-only change (with an assertion that list_all_active_machines
is never called, proving the short-circuit path)
191/191 tests green. Layer 2 (#39) complete; ready for joint smoke
once bitspire fixes the three deploy gaps from coord-log §2026-06-01T18:30Z
(`relay.aiolabs.dev` default, `VITE_LNBITS_HTTP_URL` dead echo,
operator-fees subscriber not running in maintenance state).
Refs: aiolabs/satmachineadmin#37 (parent), #39 (closes Layer 2),
aiolabs/lamassu-next#57 (Layer 3 consumer — blocked on bitspire-side
gaps).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>