mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-27 07:52:24 +00:00
Serialize repost targets when available
This commit is contained in:
1 parent
ceeabddf11
commit
a59f214aeb
4 files changed
+151
-1
No files matched your search
@@ -12,6 +12,8 @@ that a `kind 1` text note is worth reading.
|
||||
The `content` of a repost event is _the stringified JSON of the reposted note_. It MAY also be empty, but that is not recommended.
|
||||
Reposts of [NIP-70](70.md)-protected events SHOULD always have an empty `content`.
|
||||
|
||||
bitvid follows this guidance by serializing the full source event payload (including non-kind-1 targets) whenever it can be fetched from a relay, and falls back to an empty `content` only when the original note is protected or otherwise unavailable.
|
||||
|
||||
The repost event MUST include an `e` tag with the `id` of the note that is
|
||||
being reposted. That tag MUST include a relay URL as its third entry
|
||||
to indicate where it can be fetched.
|
||||
|
||||
@@ -521,6 +521,21 @@ export async function repostEvent({
|
||||
const cachedVideo = client?.allEvents?.get(normalizedId) || null;
|
||||
const cachedRaw = client?.rawEvents?.get(normalizedId) || null;
|
||||
let resolvedRawEvent = cachedRaw;
|
||||
const serializeEvent = (event) => {
|
||||
if (!event || typeof event !== "object") {
|
||||
return "";
|
||||
}
|
||||
try {
|
||||
return JSON.stringify(event);
|
||||
} catch (error) {
|
||||
devLogger.warn(
|
||||
`[nostr] Failed to serialize repost target ${normalizedId}`,
|
||||
error,
|
||||
);
|
||||
return "";
|
||||
}
|
||||
};
|
||||
let serializedSourceEvent = serializeEvent(resolvedRawEvent);
|
||||
|
||||
let authorPubkey =
|
||||
typeof options.authorPubkey === "string" && options.authorPubkey.trim()
|
||||
@@ -789,6 +804,7 @@ export async function repostEvent({
|
||||
});
|
||||
if (fetched) {
|
||||
resolvedRawEvent = fetched;
|
||||
serializedSourceEvent = serializeEvent(fetched);
|
||||
}
|
||||
} catch (error) {
|
||||
devLogger.warn(
|
||||
@@ -809,6 +825,10 @@ export async function repostEvent({
|
||||
}
|
||||
}
|
||||
|
||||
if (resolvedRawEvent && !serializedSourceEvent) {
|
||||
serializedSourceEvent = serializeEvent(resolvedRawEvent);
|
||||
}
|
||||
|
||||
if (resolvedRawEvent && !eventRelay) {
|
||||
const rawRelay = deriveRelayFromRawEvent(resolvedRawEvent);
|
||||
if (rawRelay) {
|
||||
@@ -893,6 +913,8 @@ export async function repostEvent({
|
||||
additionalTags,
|
||||
repostKind,
|
||||
targetKind,
|
||||
targetEvent: resolvedRawEvent,
|
||||
serializedEvent: serializedSourceEvent,
|
||||
});
|
||||
|
||||
try {
|
||||
@@ -924,6 +946,10 @@ export async function repostEvent({
|
||||
normalizedSigner !== normalizedLogged &&
|
||||
normalizedSigner === sessionPubkey;
|
||||
|
||||
const sourceInfo = serializedSourceEvent
|
||||
? { raw: resolvedRawEvent, serialized: serializedSourceEvent }
|
||||
: null;
|
||||
|
||||
return {
|
||||
ok: true,
|
||||
event: signedEvent,
|
||||
@@ -931,6 +957,7 @@ export async function repostEvent({
|
||||
relays,
|
||||
sessionActor: usedSessionActor,
|
||||
signerPubkey,
|
||||
source: sourceInfo,
|
||||
};
|
||||
} catch (error) {
|
||||
devLogger.warn("[nostr] Repost publish failed:", error);
|
||||
|
||||
+36
-1
@@ -659,6 +659,8 @@ export function buildRepostEvent({
|
||||
additionalTags = [],
|
||||
repostKind,
|
||||
targetKind,
|
||||
targetEvent = null,
|
||||
serializedEvent = "",
|
||||
}) {
|
||||
const schema = getNostrEventSchema(NOTE_TYPES.REPOST);
|
||||
const tags = [];
|
||||
@@ -722,12 +724,45 @@ export function buildRepostEvent({
|
||||
tags.push(["k", String(normalizedTargetKind)]);
|
||||
}
|
||||
|
||||
const normalizedSerializedEvent =
|
||||
typeof serializedEvent === "string" ? serializedEvent : "";
|
||||
let normalizedTargetEvent =
|
||||
targetEvent && typeof targetEvent === "object" ? targetEvent : null;
|
||||
|
||||
if (!normalizedTargetEvent && normalizedSerializedEvent) {
|
||||
try {
|
||||
normalizedTargetEvent = JSON.parse(normalizedSerializedEvent);
|
||||
} catch (error) {
|
||||
void error;
|
||||
}
|
||||
}
|
||||
|
||||
const hasProtectedTag = Array.isArray(normalizedTargetEvent?.tags)
|
||||
? normalizedTargetEvent.tags.some(
|
||||
(tag) => Array.isArray(tag) && tag.length && tag[0] === "-",
|
||||
)
|
||||
: false;
|
||||
|
||||
let content = "";
|
||||
|
||||
if (!hasProtectedTag) {
|
||||
if (normalizedSerializedEvent) {
|
||||
content = normalizedSerializedEvent;
|
||||
} else if (normalizedTargetEvent) {
|
||||
try {
|
||||
content = JSON.stringify(normalizedTargetEvent);
|
||||
} catch (error) {
|
||||
void error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
kind: resolvedKind,
|
||||
pubkey,
|
||||
created_at,
|
||||
tags,
|
||||
content: "",
|
||||
content,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -228,6 +228,92 @@ await (async function testRepostEventFailsWhenRelayMissing() {
|
||||
assert.ok(Array.isArray(result.details?.relays));
|
||||
})();
|
||||
|
||||
await (async function testRepostEventSerializesKindOneTargetsWhenSourceAvailable() {
|
||||
const eventId = "repost-kind1-content";
|
||||
const authorPubkey = "d".repeat(64);
|
||||
const sessionPubkey = "f".repeat(64);
|
||||
const { client } = createPublishClient({ sessionPubkey });
|
||||
|
||||
const rawEvent = {
|
||||
id: eventId,
|
||||
pubkey: authorPubkey,
|
||||
created_at: 1_700_000_100,
|
||||
kind: 1,
|
||||
tags: [],
|
||||
content: "hello from kind1",
|
||||
};
|
||||
|
||||
client.rawEvents.set(eventId, rawEvent);
|
||||
|
||||
const result = await repostEvent({
|
||||
client,
|
||||
eventId,
|
||||
options: {
|
||||
pointer: ["e", eventId, "wss://origin"],
|
||||
authorPubkey,
|
||||
},
|
||||
resolveActiveSigner: resolveActiveSignerStub,
|
||||
shouldRequestExtensionPermissions: shouldRequestExtensionPermissionsStub,
|
||||
signEventWithPrivateKey: signEventWithPrivateKeyStub,
|
||||
eventToAddressPointer: eventToAddressPointerStub,
|
||||
});
|
||||
|
||||
assert.equal(result.ok, true);
|
||||
const expectedContent = JSON.stringify(rawEvent);
|
||||
assert.equal(result.event?.kind, 6);
|
||||
assert.equal(result.event?.content, expectedContent);
|
||||
assert.equal(result.source?.serialized, expectedContent);
|
||||
assert.equal(result.source?.raw, rawEvent);
|
||||
})();
|
||||
|
||||
await (async function testRepostEventSerializesGenericTargetsWhenSourceAvailable() {
|
||||
const eventId = "repost-kind30078-content";
|
||||
const authorPubkey = "e".repeat(64);
|
||||
const sessionPubkey = "g".repeat(64);
|
||||
const { client } = createPublishClient({ sessionPubkey });
|
||||
|
||||
const identifier = "video-identifier";
|
||||
const rawEvent = {
|
||||
id: eventId,
|
||||
pubkey: authorPubkey,
|
||||
created_at: 1_700_000_200,
|
||||
kind: 30078,
|
||||
tags: [["d", identifier]],
|
||||
content: JSON.stringify({ version: 3, title: "Demo" }),
|
||||
};
|
||||
|
||||
client.rawEvents.set(eventId, rawEvent);
|
||||
|
||||
const address = `30078:${authorPubkey}:${identifier}`;
|
||||
|
||||
const result = await repostEvent({
|
||||
client,
|
||||
eventId,
|
||||
options: {
|
||||
pointer: ["e", eventId, "wss://origin"],
|
||||
authorPubkey,
|
||||
address,
|
||||
addressRelay: "wss://origin",
|
||||
},
|
||||
resolveActiveSigner: resolveActiveSignerStub,
|
||||
shouldRequestExtensionPermissions: shouldRequestExtensionPermissionsStub,
|
||||
signEventWithPrivateKey: signEventWithPrivateKeyStub,
|
||||
eventToAddressPointer: eventToAddressPointerStub,
|
||||
});
|
||||
|
||||
assert.equal(result.ok, true);
|
||||
const expectedContent = JSON.stringify(rawEvent);
|
||||
assert.equal(result.event?.kind, 16);
|
||||
assert.equal(result.event?.content, expectedContent);
|
||||
assert.equal(result.source?.serialized, expectedContent);
|
||||
assert.equal(result.source?.raw, rawEvent);
|
||||
|
||||
const kTag = result.event?.tags?.find(
|
||||
(tag) => Array.isArray(tag) && tag[0] === "k",
|
||||
);
|
||||
assert.deepEqual(kTag, ["k", String(rawEvent.kind)]);
|
||||
})();
|
||||
|
||||
await (async function testMirrorEventIncludesHostedMetadata() {
|
||||
const eventId = "mirror-event";
|
||||
const actorPubkey = "1".repeat(64);
|
||||
|
||||
Reference in new issue
Block a user