refactor(auth): decouple NIP-07 logic and optimize list fetching (agent)

- Moved NIP-07 extension detection and permission logic from `NostrClient` to `nip07` provider.
- Removed redundant `login` method from `NostrClient`.
- Increased concurrency and added timeouts to `fetchListIncrementally` to prevent hanging on slow relays.
- Updated `UserBlocks` to force full fetch on cache miss, fixing "empty list" issues.
- Updated unit tests for login permissions and hashtag preferences to reflect architectural changes.

Co-authored-by: PR0M3TH3AN <[email protected]>
This commit is contained in:
google-labs-jules[bot]andPR0M3TH3AN committed 2026-01-26 21:48:52 +00:00
1 parent 967bb079f5
commit 3c7a396da9
6 files changed
+241 -207

No files matched your search

+20 -15
View File
@@ -242,16 +242,19 @@ test(
const signedEvent = await hashtagPreferences.publish();
assert.equal(signedEvent.id, "signed-event");
assert.equal(plaintextCalls.length, 1);
assert.equal(plaintextCalls[0].target, pubkey);
const payload = JSON.parse(plaintextCalls[0].plaintext);
// Expect 3 calls: addInterest (auto-save), addDisinterest (auto-save), manual publish
assert.equal(plaintextCalls.length, 3);
const lastCall = plaintextCalls[plaintextCalls.length - 1];
assert.equal(lastCall.target, pubkey);
const payload = JSON.parse(lastCall.plaintext);
assert.equal(payload.version, 1);
assert.deepEqual(payload.interests, ["taga"]);
assert.deepEqual(payload.disinterests, ["tagb"]);
assert.equal(publishedEvents.length, 1);
const publishedEvent = publishedEvents[0].event;
assert.deepEqual(publishedEvents[0].urls, ["wss://relay.publish"]);
// Expect 3 publish events
assert.equal(publishedEvents.length, 3);
const publishedEvent = publishedEvents[publishedEvents.length - 1].event;
assert.deepEqual(publishedEvents[publishedEvents.length - 1].urls, ["wss://relay.publish"]);
assert.equal(publishedEvent.kind, 30015);
const encryptedTag = publishedEvent.tags.find(
(tag) => Array.isArray(tag) && tag[0] === "encrypted",
@@ -310,16 +313,18 @@ test(
const signedEvent = await hashtagPreferences.publish();
assert.equal(signedEvent.id, "signed-window");
// We expect 1 call since the first scheme (nip44_v2) succeeds
assert.equal(encryptCalls.length, 1);
assert.equal(encryptCalls[0].scheme, "nip44_call");
assert.equal(encryptCalls[0].target, pubkey);
assert.ok(encryptCalls[0].plaintext.includes("windowtag"));
// Expect 2 calls: addInterest (auto-save) + manual publish
assert.equal(encryptCalls.length, 2);
const lastEncryptCall = encryptCalls[encryptCalls.length - 1];
assert.equal(lastEncryptCall.scheme, "nip44_call");
assert.equal(lastEncryptCall.target, pubkey);
assert.ok(lastEncryptCall.plaintext.includes("windowtag"));
assert.equal(publishedEvents.length, 1);
assert.deepEqual(publishedEvents[0].urls, ["wss://relay.window"]);
assert.equal(publishedEvents[0].event.kind, 30015);
const encryptedTag = publishedEvents[0].event.tags.find(
assert.equal(publishedEvents.length, 2);
const lastPublished = publishedEvents[publishedEvents.length - 1];
assert.deepEqual(lastPublished.urls, ["wss://relay.window"]);
assert.equal(lastPublished.event.kind, 30015);
const encryptedTag = lastPublished.event.tags.find(
(tag) => Array.isArray(tag) && tag[0] === "encrypted",
);
// nip44_v2 is the first tried scheme, so it is the one used
+12 -6
View File
@@ -4,6 +4,7 @@ import test from "node:test";
import { nostrClient } from "../js/nostrClientFacade.js";
import { NostrClient, __testExports } from "../js/nostr/client.js";
import nip07Provider from "../js/services/authProviders/nip07.js";
import { accessControl } from "../js/accessControl.js";
const {
@@ -150,7 +151,8 @@ function setupLoginEnvironment({ enableImpl, getPublicKey = HEX_PUBKEY } = {}) {
test("NIP-07 login requests decrypt permissions upfront", async () => {
const env = setupLoginEnvironment();
try {
const pubkey = await nostrClient.login();
const result = await nip07Provider.login({ nostrClient });
const pubkey = result.pubkey;
assert.equal(pubkey, HEX_PUBKEY);
assert.ok(env.enableCalls.length >= 1, "extension.enable should be invoked");
assert.ok(
@@ -208,7 +210,8 @@ test("NIP-07 decrypt reuses cached extension permissions", async () => {
},
};
const pubkey = await nostrClient.login();
const result = await nip07Provider.login({ nostrClient });
const pubkey = result.pubkey;
assert.equal(pubkey, HEX_PUBKEY);
for (const method of EXPECTED_ENCRYPTION_PERMISSIONS) {
assert.ok(
@@ -306,7 +309,8 @@ test("NIP-07 login falls back when structured permissions fail", async () => {
});
try {
const pubkey = await nostrClient.login();
const result = await nip07Provider.login({ nostrClient });
const pubkey = result.pubkey;
assert.equal(pubkey, HEX_PUBKEY);
assert.ok(env.enableCalls.length >= 2, "should retry with alternate payloads");
const [objectCall, stringCall, plainCall] = env.enableCalls;
@@ -346,7 +350,8 @@ test("NIP-07 login supports extensions that only allow enable() without payload"
});
try {
const pubkey = await nostrClient.login();
const result = await nip07Provider.login({ nostrClient });
const pubkey = result.pubkey;
assert.equal(pubkey, HEX_PUBKEY);
assert.equal(
env.enableCalls.length,
@@ -398,7 +403,8 @@ test("NIP-07 login quickly retries when a permission payload stalls", async () =
try {
const start = Date.now();
const pubkey = await nostrClient.login();
const result = await nip07Provider.login({ nostrClient });
const pubkey = result.pubkey;
const duration = Date.now() - start;
assert.equal(pubkey, HEX_PUBKEY);
assert.ok(
@@ -432,7 +438,7 @@ test("NIP-07 login surfaces enable permission errors", async () => {
});
try {
await assert.rejects(() => nostrClient.login(), /permission denied/);
await assert.rejects(() => nip07Provider.login({ nostrClient }), /permission denied/);
} finally {
env.restore();
nostrClient.logout();