From 90ce6def59b9b6ab5ec7c445c7595d3657d09b84 Mon Sep 17 00:00:00 2001 From: thePR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> Date: Sun, 2 Aug 2026 12:13:13 -0400 Subject: [PATCH] Add archive & rebroadcast for relay migration A salvage tool in Settings. Sweeps every Artstr design still readable, saves the signed events to a JSON bundle, and re-publishes them to the current relays so designs survive a relay going dark. Reads as widely as possible: the user's relays plus the old defaults, deliberately including relays marked dead, since one unreachable from this network may answer from another and a dying relay is exactly the one holding events worth rescuing. Signed in, it also sweeps the signer's own events by author, which is the only way to reach private and premium designs - those carry randomised d-tags and no public tag. The pubkey is requested from the signer directly rather than read from state.community.myPubkey: a connected extension does not populate that, and during testing the tool reported "0 of mine" while the key in fact had 233 authored designs, 18 of them encrypted. Every private design would have been skipped. Two rules the tool will not bend, because getting them wrong is worse than not running: - Retractions are honoured. A blanket `#k: 30078` deletion filter came back with 670 unrelated kind-5 events from across the network, all of which would have been rebroadcast; the lookup is now scoped to the authors actually collected and further filtered to deletions that target this archive. Those go out first, so a relay learns a design was withdrawn before anything can put an older copy back. - Only the newest revision of each addressable design is sent. Publishing uses one socket per relay - publishToRelays opens a fresh connection per event, which for 230 events across 6 relays would be ~1400 connections and immediate rate-limiting. Each event is awaited individually with a bounded in-flight window and a single retry on rate-limit, so every one is accounted as accepted / rejected / unanswered. That last part took three attempts. Fire-and-forget with an idle-timeout completion check kept closing the socket on the unsent tail once designs ran to megabytes and acknowledgements lagged the sends - runs reported 26, 46 and 202 acceptances out of 230 while claiming success. Verified against a local mock relay that simulates rate-limiting: 230/230 accepted, 0 unanswered, relay-side counts matching exactly, and end-to-end 238 found / 230 sent / 230 accepted. Co-Authored-By: Claude Opus 5 (1M context) --- README.md | 1 + src/index.html | 301 ++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 300 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 814ee97..ed29f5d 100644 --- a/README.md +++ b/README.md @@ -116,6 +116,7 @@ Every design surface participates in the same Nostr-backed community feed. - **Replies** (kind-1), **reactions** (kind-7), **reposts** (kind-6), and **follows** (kind-3) all work from inside the app. - **Soft moderation** — kind-10000 mute lists and kind-1984 reports from your hop-1 follows blur cards by default, with a one-click reveal. - **Block list** — local first, syncs to your kind-10000 on the next login. +- **Archive & rebroadcast** (Settings) — a relay-migration tool. Sweeps every Artstr design still readable across your relays *and* the old defaults (deliberately including relays currently marked dead, since a relay unreachable from one network may answer from another), saves the signed events to a JSON bundle, then re-publishes them to your current relays. Signed in, it also picks up your own **private and premium** designs, which carry randomised `d`-tags and are findable only by their author — the pubkey is requested from the signer directly rather than read from app state, because a connected extension alone does not populate it and getting that wrong silently skips every private design. Retracted designs are never resurrected (kind-5 deletions are honoured and relayed alongside, scoped to the archive's own authors), and only the newest revision of each addressable design is sent. Publishing uses one socket per relay with a bounded in-flight window, per-event acknowledgement, and a single retry on rate-limit, so every event is accounted as accepted / rejected / unanswered. - **Edit published designs** — owners can republish a kind-30078 with the same d-tag to supersede the original on relays via NIP-33 semantics. The publish-confirm modal explains the trade-off (reactions and Lightning zaps on the old version stay on relays but orphan to the new event id). - **Fork / remix** — every published design has a Fork button that loads it into the editor as a starting point under your own pubkey. - **Share links** — `/share/` or `/share/` URLs resolve cold. diff --git a/src/index.html b/src/index.html index 545747d..5b47594 100644 --- a/src/index.html +++ b/src/index.html @@ -5636,6 +5636,17 @@

Separate multiple relays with commas. Changing relays clears the template cache.

+
+ Archive & rebroadcast +

Reads every Artstr design still reachable — across your relays and the old defaults, including ones currently marked dead — saves them to a JSON file, then re-publishes them to your current relays so nothing is lost when a relay goes dark.

+

Sign in first to include your own private and premium designs; those are only findable by their author. Retracted designs are never re-published, and only the newest version of each design is sent.

+

This publishes to external relays and cannot be undone. Your private designs stay encrypted — relays can't read them — but they will exist on the new relays, which can see your pubkey, timestamps and identifiers.

+
+ +
+

+
+