From 839ab937afbd0c68d1a4366e10145274b6f62d31 Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Wed, 9 Sep 2026 23:06:35 -0700 Subject: Sync: oversized domains ride Blossom blobs — plus a coinos-hosted server. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A wallet with deep Ark coins had a 633KB ark sync domain against the relay's 40KB budget: the publish silently failed forever, the slot stayed stale, and every boot retried. Relays can't carry it (64KB event cap) and neither can NIP-44 (64KB plaintext), so a domain over budget now goes to Blossom (nostr blob storage, BUD-01/02/06/11/12): sealed into an envelope ("CSB1" + xchacha20poly1305 under an HKDF of the wallet's NIP-44 self-key), uploaded to the configured servers, and the kind-30078 event carries only { blob: { sha256, size, servers } }. Readers resolve pointers from their own outbox copy first, else from the pointer's servers plus the configured list, hash-verified. Small domains are unchanged. The outbox uploads before it publishes (upload/delete authorizations are kind-24242 events signed at enqueue time, so delivery after logout still holds no key), keeps a local copy for recovery, and deletes superseded blobs once the replacement is acknowledged. Servers: Settings → Nostr → Sync storage (any Blossom server; a typed list is kept), else the user's BUD-03 list (kind 10063) with the coinos server as mirror, else blossom.coinos.io. blossom/server.js is that default: a Bun Blossom server that stores ONLY these envelopes (magic check → 415 for anything else), serves every blob as an octet-stream attachment with nosniff, requires signed auth for upload/list/delete, and enforces per-blob size, per-key quota (oldest evicted), rate limits, a disk cap and unused-blob expiry — it cannot serve as a file host. tools/sync-blob-test.js spawns it and covers the policy, the outbox flow and a fresh device resolving a pointer. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_01Nw1Dijik1tLVKRM1WkU7xE --- src/i18n.js | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/i18n.js') diff --git a/src/i18n.js b/src/i18n.js index 2177385..4d11dd8 100644 --- a/src/i18n.js +++ b/src/i18n.js @@ -329,6 +329,13 @@ const STR = { msgBadInvite: 'Not a valid invite link', msgInviteLoading: 'Fetching invite…', msgInviteNotFound: 'Invite not found on its relays', + syncStorageTitle: 'Sync storage', + syncStorageHow: 'Wallet state too large for a relay event is encrypted and stored as a blob on these Blossom servers (one per line). Any Blossom server works — run your own or use another provider.', + syncStorageSave: 'Save servers', + syncStorageReset: 'Use default', + syncStorageSaved: 'Sync storage servers saved', + syncStorageInvalid: 'Enter at least one https:// server', + syncStoragePending: '{n} snapshot(s) waiting to upload', msgInviteRevoked: 'This invite has been revoked', msgInviteExpired: 'This invite has expired', msgInviteTo: 'You are invited to {name}', -- cgit v1.2.3