chore(base): delete nostr-metadata-service + retire webapp-side kind-0 broadcast paths #82

Merged
padreug merged 3 commits from chore/delete-nostr-metadata-service into dev 2026-05-30 15:25:47 +00:00
Owner

Summary

LNbits's cascade now publishes kind-0 user metadata server-side on account creation AND on every PATCH /api/v1/auth (aiolabs/lnbits commit 869f67c3 folded into PR #26, deployed to aio-demo via server-deploy:e2eed9c). The webapp no longer needs its own kind-0 publish surface — this PR retires it.

This is the webapp's first bucket-A leg per aiolabs/lnbits#9 phase-1.

Changes

  • Delete src/modules/base/nostr/nostr-metadata-service.ts (162 lines). Server now owns kind-0 lifecycle via NostrSigner.sign_event.
  • Delete src/modules/base/composables/useNostrMetadata.ts (had zero callers; was a thin wrapper around the deleted service).
  • Remove NOSTR_METADATA_SERVICE token from src/core/di-container.ts.
  • Remove all NostrMetadataService imports / instantiations / registrations / dispose calls from src/modules/base/index.ts.
  • src/modules/base/auth/auth-service.ts:
    • Drop the broadcastNostrMetadata() helper entirely.
    • Drop its callers in login() and register() — both flagged for removal by lnbits in the log:2026-05-29T01:45Z coordination handoff. Login-time republish was always redundant for kind-0 (replaceable event); register-time is covered by lnbits's create_user_account → _publish_nostr_metadata_event path.
    • Drop the auto-broadcast in updateProfile() too — covered by the PATCH /api/v1/auth handler's _publish_nostr_metadata_event call per the gap-fill commit.
    • Leave the prvkey/pubkey preservation in updateProfile() in place for now. The prvkey field removal is the atomic phase-1 final PR per design doc Q1.2 Option (b).
  • src/modules/base/components/ProfileSettings.vue:
    • Remove the "Broadcast to Nostr" button + isBroadcasting state + Radio icon + broadcastMetadata() handler. The manual re-broadcast was a local-testing safety net for relay resets and is no longer needed now that the server publishes automatically on profile save.
    • Simplify the post-save toast to a generic "Profile updated!".
    • Update the helper text accordingly.

Diff stat

 src/core/di-container.ts                         |   3 -
 src/modules/base/auth/auth-service.ts            |  35 +----
 src/modules/base/components/ProfileSettings.vue  |  68 ++--------
 src/modules/base/composables/useNostrMetadata.ts |  39 ------
 src/modules/base/index.ts                        |  10 --
 src/modules/base/nostr/nostr-metadata-service.ts | 162 -----------------------
 6 files changed, 17 insertions(+), 300 deletions(-)

What's NOT in this PR

  • User.prvkey field removal — that's the atomic final-step PR per design doc Q1.2 Option (b). Coming after the second bucket-A PR (ActivitiesNostrService deletion + CreateActivityDialog reroute) merges.
  • auth-service.ts:191-195 prvkey threading deletion — same gating; ships with the field removal so it's an atomic commit.

Server-side compensation (confirmed live on aio-demo)

Trigger Server-side action
New account signup create_user_account_publish_nostr_metadata_event(account) → kind-0 with name + display_name + picture + nip05 + lud16 (latter two gated on LNBITS_NOSTR_IDENTITY_DOMAIN)
PATCH /api/v1/auth (profile edit) update_user_account_publish_nostr_metadata_event(account) → kind-0 re-publish via signer
Login alone (no content change) No publish (kind-0 is replaceable; existing events on relays are still valid)

So all three places the webapp used to broadcast are now covered server-side.

LNBITS_NOSTR_IDENTITY_DOMAIN is set to aiolabs.dev on demo per the topology PR addendum (server-deploy:25e9d44), so nip05 and lud16 fields show up as <username>@aiolabs.dev for users registered on this deploy.

Test plan

  • vue-tsc --noEmit clean post-change
  • Manual smoke on aio-demo after dev deploy:
    • Edit profile (display_name + picture) → save → toast "Profile updated!" shows → check relay logs for a kind-0 from the user's pubkey containing the updated fields
    • Confirm no stray references to the deleted service in the JS console
    • Confirm the "Broadcast to Nostr" button is gone from the profile settings UI
  • Verify register flow → check relay logs for a kind-0 published immediately after signup with nip05 = <username>@aiolabs.dev

Refs

  • log:2026-05-29T01:45Z (lnbits handoff identifying the auth-service line numbers to drop)
  • ~/dev/coordination/webapp-design-questions.md Q2.3 (full decision context)
  • aiolabs/lnbits PR #26 commit 869f67c3 (server-side kind-0 publish + LNBITS_NOSTR_IDENTITY_DOMAIN)
  • aiolabs/lnbits dev tip 861f427c, deployed to aio-demo via server-deploy:e2eed9c
  • Parent initiative: aiolabs/lnbits#9 (signer abstraction / bunker integration)
  • Sibling open PRs: #80 (ReactionService dedup), #81 (ScheduledEventService dedup)

🤖 Generated with Claude Code

## Summary LNbits's cascade now publishes kind-0 user metadata server-side on account creation AND on every `PATCH /api/v1/auth` (`aiolabs/lnbits` commit `869f67c3` folded into PR #26, deployed to `aio-demo` via `server-deploy:e2eed9c`). The webapp no longer needs its own kind-0 publish surface — this PR retires it. This is the webapp's first bucket-A leg per `aiolabs/lnbits#9` phase-1. ## Changes - **Delete** `src/modules/base/nostr/nostr-metadata-service.ts` (162 lines). Server now owns kind-0 lifecycle via `NostrSigner.sign_event`. - **Delete** `src/modules/base/composables/useNostrMetadata.ts` (had zero callers; was a thin wrapper around the deleted service). - **Remove** `NOSTR_METADATA_SERVICE` token from `src/core/di-container.ts`. - **Remove** all `NostrMetadataService` imports / instantiations / registrations / dispose calls from `src/modules/base/index.ts`. - **`src/modules/base/auth/auth-service.ts`**: - Drop the `broadcastNostrMetadata()` helper entirely. - Drop its callers in `login()` and `register()` — both flagged for removal by lnbits in the `log:2026-05-29T01:45Z` coordination handoff. Login-time republish was always redundant for kind-0 (replaceable event); register-time is covered by lnbits's `create_user_account → _publish_nostr_metadata_event` path. - Drop the auto-broadcast in `updateProfile()` too — covered by the `PATCH /api/v1/auth` handler's `_publish_nostr_metadata_event` call per the gap-fill commit. - **Leave the `prvkey`/`pubkey` preservation in `updateProfile()` in place for now.** The prvkey field removal is the atomic phase-1 final PR per design doc Q1.2 Option (b). - **`src/modules/base/components/ProfileSettings.vue`**: - Remove the "Broadcast to Nostr" button + `isBroadcasting` state + `Radio` icon + `broadcastMetadata()` handler. The manual re-broadcast was a local-testing safety net for relay resets and is no longer needed now that the server publishes automatically on profile save. - Simplify the post-save toast to a generic `"Profile updated!"`. - Update the helper text accordingly. ## Diff stat ``` src/core/di-container.ts | 3 - src/modules/base/auth/auth-service.ts | 35 +---- src/modules/base/components/ProfileSettings.vue | 68 ++-------- src/modules/base/composables/useNostrMetadata.ts | 39 ------ src/modules/base/index.ts | 10 -- src/modules/base/nostr/nostr-metadata-service.ts | 162 ----------------------- 6 files changed, 17 insertions(+), 300 deletions(-) ``` ## What's NOT in this PR - **`User.prvkey` field removal** — that's the atomic final-step PR per design doc Q1.2 Option (b). Coming after the second bucket-A PR (`ActivitiesNostrService` deletion + `CreateActivityDialog` reroute) merges. - **`auth-service.ts:191-195` prvkey threading deletion** — same gating; ships with the field removal so it's an atomic commit. ## Server-side compensation (confirmed live on `aio-demo`) | Trigger | Server-side action | |---|---| | New account signup | `create_user_account` → `_publish_nostr_metadata_event(account)` → kind-0 with `name + display_name + picture + nip05 + lud16` (latter two gated on `LNBITS_NOSTR_IDENTITY_DOMAIN`) | | `PATCH /api/v1/auth` (profile edit) | `update_user_account` → `_publish_nostr_metadata_event(account)` → kind-0 re-publish via signer | | Login alone (no content change) | No publish (kind-0 is replaceable; existing events on relays are still valid) | So all three places the webapp used to broadcast are now covered server-side. `LNBITS_NOSTR_IDENTITY_DOMAIN` is set to `aiolabs.dev` on demo per the topology PR addendum (`server-deploy:25e9d44`), so `nip05` and `lud16` fields show up as `<username>@aiolabs.dev` for users registered on this deploy. ## Test plan - [x] `vue-tsc --noEmit` clean post-change - [ ] Manual smoke on `aio-demo` after `dev` deploy: - Edit profile (display_name + picture) → save → toast `"Profile updated!"` shows → check relay logs for a kind-0 from the user's pubkey containing the updated fields - Confirm no stray references to the deleted service in the JS console - Confirm the "Broadcast to Nostr" button is gone from the profile settings UI - [ ] Verify register flow → check relay logs for a kind-0 published immediately after signup with `nip05 = <username>@aiolabs.dev` ## Refs - `log:2026-05-29T01:45Z` (lnbits handoff identifying the auth-service line numbers to drop) - `~/dev/coordination/webapp-design-questions.md` Q2.3 (full decision context) - `aiolabs/lnbits` PR #26 commit `869f67c3` (server-side kind-0 publish + `LNBITS_NOSTR_IDENTITY_DOMAIN`) - `aiolabs/lnbits` dev tip `861f427c`, deployed to `aio-demo` via `server-deploy:e2eed9c` - Parent initiative: `aiolabs/lnbits#9` (signer abstraction / bunker integration) - Sibling open PRs: `#80` (ReactionService dedup), `#81` (ScheduledEventService dedup) 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Lnbits's cascade now publishes kind-0 user metadata server-side on
account creation AND on every PATCH /api/v1/auth (aiolabs/lnbits commit
869f67c3 folded into PR #26, deployed to aio-demo via server-deploy
e2eed9c). The webapp no longer needs its own kind-0 publish surface.

Changes:
- Delete src/modules/base/nostr/nostr-metadata-service.ts (162 lines).
  Server now owns kind-0 lifecycle via NostrSigner.sign_event.
- Delete src/modules/base/composables/useNostrMetadata.ts (had zero
  callers; was just a thin wrapper around the deleted service).
- Remove NOSTR_METADATA_SERVICE token from di-container.ts.
- Remove all NostrMetadataService imports / instantiations /
  registrations / dispose calls from src/modules/base/index.ts.
- src/modules/base/auth/auth-service.ts:
  - Drop the broadcastNostrMetadata() helper entirely.
  - Drop its callers in login() (was line 118 pre-edit) and register()
    (was line 142 pre-edit) — both flagged for removal by lnbits in the
    01:45Z coordination handoff. Login-time republish was always
    redundant for kind-0 (replaceable event); register-time is covered
    by lnbits's create_user_account -> _publish_nostr_metadata_event
    path.
  - Drop the auto-broadcast in updateProfile() too — covered by the
    PATCH /api/v1/auth handler's _publish_nostr_metadata_event call
    per the gap-fill commit.
  - Leave the prvkey/pubkey preservation in updateProfile() in place
    for now; the prvkey field removal is the atomic phase-1 final PR
    per design doc Q1.2 Option (b).
- src/modules/base/components/ProfileSettings.vue:
  - Remove the "Broadcast to Nostr" button + isBroadcasting state +
    Radio icon + broadcastMetadata() handler. Manual re-broadcast was
    a local-testing safety net for relay resets that's no longer
    needed once the server publishes automatically on profile save.
  - Simplify the post-save toast to a generic "Profile updated!".
  - Update the helper text accordingly.

This is webapp's bucket-A leg per aiolabs/lnbits#9 phase-1 plan.

Refs:
- log:2026-05-29T01:45Z (lnbits handoff identifying the auth-service
  line numbers to drop)
- ~/dev/coordination/webapp-design-questions.md Q2.3 (decision context)
- aiolabs/lnbits PR #26 commit 869f67c3 (server-side kind-0 publish)
- aiolabs/lnbits dev tip 861f427c, deployed to aio-demo

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
padreug force-pushed chore/delete-nostr-metadata-service from 5619a58c73 to 414b79565c 2026-05-29 19:38:48 +00:00 Compare
Two fixes that together make the kind-0 server-side publish path (this
PR's whole reason for existing) actually work end-to-end against the
deployed cascade:

1. **updateProfile() uses PATCH /api/v1/auth, not PUT /auth/update.**
   aiolabs/lnbits PR #26 gap-fill (869f67c3) wired
   _publish_nostr_metadata_event into the PATCH handler at
   auth_api.py:546. The legacy `/auth/update` route doesn't exist on
   the post-cascade server — a `PUT /auth/update` request gets routed
   into the `/auth/{provider}` SSO wildcard which only allows GET and
   returns 405. Caught while smoke-testing this PR against a local
   regtest pointed at the issue-18-phase-2.3 branch.

2. **request<T>() parses FastAPI's `{"detail": "..."}` error shape.**
   The old error path threw `API request failed: 405 Method Not Allowed`
   for the regtest's 405 above — useful only if you also opened the
   network panel and read the response body manually. Now we parse the
   detail (string or pydantic-validation array), include the endpoint
   path, and throw `LNbits /auth 405: Method Not Allowed`. Falls back
   to raw text for non-JSON bodies.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
`useActivityDetail.load()` previously asked every relay for every
kind-31922/31923 event and raced a 5s timeout to find the one
matching the route param. On a cold refresh of the detail page, the
race was often lost — the store starts empty (no feed subscription
to populate it), the relay sprays the whole calendar, and the
matching event may arrive after the timeout, leaving the user with
"Activity not found" on a valid URL.

Add a `dTags` field to `CalendarEventFilters` and emit it as the
nostr `#d` tag filter. Detail-page subscribe + query both scope to
the single activity, so the relay resolves a parameterized-replaceable
lookup in milliseconds instead of streaming the whole calendar.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
padreug deleted branch chore/delete-nostr-metadata-service 2026-05-30 15:25:48 +00:00
Sign in to join this conversation.
No description provided.