Skip to content

Commit 02085eb

Browse files
beacon: real-data compat with imported nostr-beacon dump
Surfaced by importing the 2.5GB prod nostr-beacon DB locally and pointing beacon at it: - db.js: tolerate a pre-existing pubkey index. The prod dump ships a *unique* pubkey_1; our createIndex({pubkey:1}) then fails with IndexKeySpecsConflict (code 86) and crashed boot. Ignore that one code — the index already serves. - diddoc.js: accept both follows shapes. Our indexer writes the raw kind-3 event ({tags:[["p",hex]]}); the prod 'follows' collection stores a derived shape ({follows:[hex,...], count}). Build did:nostr follows from either. - test: regression for the derived {follows:[...]} shape (8/8 pass).
1 parent 84dc21a commit 02085eb

3 files changed

Lines changed: 26 additions & 7 deletions

File tree

src/db.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,16 @@ export async function connect() {
2626
client = new MongoClient(uri);
2727
await client.connect();
2828
db = client.db(dbName);
29-
// non-unique index for query/dedupe perf — does not change the doc shape
29+
// pubkey index for query/dedupe perf — does not change the doc shape.
30+
// Tolerate a pre-existing index (e.g. an imported nostr-beacon dump already
31+
// carries a *unique* pubkey_1); a spec conflict (code 86) just means it's
32+
// already there and serving lookups, so it is safe to ignore.
3033
for (const name of new Set(Object.values(COLLECTIONS))) {
31-
await db.collection(name).createIndex({ pubkey: 1 });
34+
try {
35+
await db.collection(name).createIndex({ pubkey: 1 });
36+
} catch (e) {
37+
if (e?.code !== 86) throw e;
38+
}
3239
}
3340
return db;
3441
}

src/diddoc.js

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,19 @@ export function buildDidDocument(pubkey, { profile, follows, relays } = {}) {
4545
} catch { /* malformed kind-0 content */ }
4646
}
4747

48-
// kind 3 -> follows (did:nostr of each p-tag)
48+
// kind 3 -> follows (did:nostr of each followed key). Accept both the raw
49+
// kind-3 event ({tags:[["p",hex],…]}, what our indexer writes) and the
50+
// derived nostr-beacon shape ({follows:[hex,…], count}, from an imported dump).
51+
let followHexes = [];
4952
if (Array.isArray(follows?.tags)) {
50-
const f = follows.tags
51-
.filter((t) => t[0] === 'p' && HEX64.test(String(t[1]).toLowerCase()))
52-
.map((t) => `did:nostr:${String(t[1]).toLowerCase()}`);
53-
if (f.length) doc.follows = f;
53+
followHexes = follows.tags.filter((t) => t[0] === 'p').map((t) => t[1]);
54+
} else if (Array.isArray(follows?.follows)) {
55+
followHexes = follows.follows;
5456
}
57+
const f = followHexes
58+
.filter((h) => HEX64.test(String(h).toLowerCase()))
59+
.map((h) => `did:nostr:${String(h).toLowerCase()}`);
60+
if (f.length) doc.follows = f;
5561

5662
// kind 10002 -> service (Relay)
5763
if (Array.isArray(relays?.tags)) {

test/diddoc.test.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,12 @@ test('enhanced: profile (kind 0), follows (kind 3), service (kind 10002)', () =>
3232
assert.equal(d.service[0].serviceEndpoint, 'wss://relay.example/');
3333
});
3434

35+
test('follows: derived nostr-beacon shape ({follows:[hex,…]}) also resolves', () => {
36+
const a = 'a'.repeat(64), b = 'b'.repeat(64);
37+
const d = buildDidDocument(PK, { follows: { follows: [a, b], count: 2 } });
38+
assert.deepEqual(d.follows, [`did:nostr:${a}`, `did:nostr:${b}`]);
39+
});
40+
3541
test('rejects a non-hex (e.g. npub) identifier', () => {
3642
assert.equal(buildDidDocument('npub1xxx'), null);
3743
assert.equal(buildDidDocument(''), null);

0 commit comments

Comments
 (0)