mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-11-07 13:22:54 +00:00
feat(signer): surface an actionable notice when the signer goes unresponsive
A raw window.nostr probe in the user's browser (getPublicKey → nip04.encrypt
→ nip04.decrypt, bypassing ALL of bitvid) HUNG forever, with the extension's
own console showing `ObjectMultiplex - orphaned data for "background-liveness"`
+ `malformed chunk` + listener-leak warnings. That is the NIP-07 extension's
content-script ↔ background-service-worker channel being dead (classic MV3
worker death) — an extension/environment failure, not a bitvid bug. No client
change can force an unresponsive signer to answer; the fix is to reload/unlock
the extension.
What bitvid CAN do is stop failing silently. Add js/utils/signerHealthNotice.js:
after a few consecutive list-decrypt timeouts while the signer reports itself
present, emit ONE rate-limited, actionable user notice ("your signer isn't
responding to decryption — unlock/reload the extension and refresh") instead of
the silent 15-minute retry loop. Reset on any decrypt success so a transient
blip doesn't warn. Wired into blocks, hashtags, and subscriptions.
Also documents the definitive root-cause + all resilience increments in
KNOWN_BUGS #0. Test: tests/signer-health-notice.test.mjs (threshold, rate-limit,
success-reset). Full unit suite green.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
1 parent
f3bac3066d
commit
8f39b2c479
6 files changed
+202
-6
No files matched your search
+10
-1
@@ -27,6 +27,10 @@ import { getApplication } from "./applicationContext.js";
|
||||
import { VideoListView } from "./ui/views/VideoListView.js";
|
||||
import { ALLOW_NSFW_CONTENT } from "./config.js";
|
||||
import { devLogger, userLogger } from "./utils/logger.js";
|
||||
import {
|
||||
noteSignerDecryptTimeout,
|
||||
noteSignerDecryptSuccess,
|
||||
} from "./utils/signerHealthNotice.js";
|
||||
import moderationService from "./services/moderationService.js";
|
||||
import nostrService from "./services/nostrService.js";
|
||||
import { profileCache } from "./state/profileCache.js";
|
||||
@@ -761,7 +765,11 @@ class SubscriptionsManager {
|
||||
this.uiReady = true;
|
||||
if (isTransientDecryptError(decryptResult.error)) {
|
||||
// Channel/timeout failures recover shortly — retry instead of
|
||||
// abandoning the subscription list until a page refresh.
|
||||
// abandoning the subscription list until a page refresh. A present
|
||||
// signer that won't answer feeds the shared unresponsive notice.
|
||||
if (decryptResult.error?.code === "subscriptions-decrypt-timeout") {
|
||||
noteSignerDecryptTimeout("subscriptions");
|
||||
}
|
||||
this.scheduleDecryptRetry(normalizedUserPubkey, decryptResult.error, {
|
||||
allowPermissionPrompt,
|
||||
signerReadinessGate,
|
||||
@@ -837,6 +845,7 @@ class SubscriptionsManager {
|
||||
}
|
||||
|
||||
this.decryptRetryAttempt = 0;
|
||||
noteSignerDecryptSuccess();
|
||||
|
||||
const decryptedStr = decryptResult.plaintext;
|
||||
const normalized = parseSubscriptionPlaintext(decryptedStr);
|
||||
|
||||
Reference in new issue
Block a user