diff --git a/js/nostr/publishHelpers.js b/js/nostr/publishHelpers.js index fd9b6749..8b75b61f 100644 --- a/js/nostr/publishHelpers.js +++ b/js/nostr/publishHelpers.js @@ -626,6 +626,7 @@ export async function repostEvent({ : client?.relays, ); const relays = relaysOverride.length ? relaysOverride : Array.from(RELAY_URLS); + const chosenPublishRelay = relays.length ? relays[0] : ""; let actorPubkey = typeof options.actorPubkey === "string" && options.actorPubkey.trim() @@ -671,15 +672,23 @@ export async function repostEvent({ ? options.additionalTags.filter((tag) => Array.isArray(tag) && tag.length >= 2) : []; + const repostKind = + Number.isFinite(targetKind) && targetKind !== 1 + ? 16 + : 6; + const repostEventPayload = buildRepostEvent({ pubkey: actorPubkey, created_at: createdAt, eventId: normalizedId, eventRelay, + publishRelay: chosenPublishRelay, address, addressRelay, authorPubkey, additionalTags, + repostKind, + targetKind, }); try { diff --git a/js/nostrEventSchemas.js b/js/nostrEventSchemas.js index d0fed019..3ccfaba9 100644 --- a/js/nostrEventSchemas.js +++ b/js/nostrEventSchemas.js @@ -651,22 +651,25 @@ export function buildRepostEvent({ created_at, eventId = "", eventRelay = "", + publishRelay = "", address = "", addressRelay = "", authorPubkey = "", additionalTags = [], + repostKind, + targetKind, }) { const schema = getNostrEventSchema(NOTE_TYPES.REPOST); const tags = []; const normalizedEventId = typeof eventId === "string" ? eventId.trim() : ""; - const normalizedEventRelay = typeof eventRelay === "string" ? eventRelay.trim() : ""; - if (normalizedEventId) { - if (normalizedEventRelay) { - tags.push(["e", normalizedEventId, normalizedEventRelay]); - } else { - tags.push(["e", normalizedEventId]); - } + const normalizedEventRelay = + typeof eventRelay === "string" ? eventRelay.trim() : ""; + const normalizedPublishRelay = + typeof publishRelay === "string" ? publishRelay.trim() : ""; + const resolvedEventRelay = normalizedEventRelay || normalizedPublishRelay; + if (normalizedEventId && resolvedEventRelay) { + tags.push(["e", normalizedEventId, resolvedEventRelay]); } const normalizedAddress = typeof address === "string" ? address.trim() : ""; @@ -695,8 +698,26 @@ export function buildRepostEvent({ }); } + const normalizedRepostKind = + Number.isFinite(repostKind) && repostKind !== null + ? Math.floor(repostKind) + : null; + const normalizedTargetKind = + Number.isFinite(targetKind) && targetKind !== null + ? Math.floor(targetKind) + : null; + const resolvedKind = (() => { + if (normalizedRepostKind) { + return normalizedRepostKind; + } + if (normalizedTargetKind !== null) { + return normalizedTargetKind === 1 ? schema?.kind ?? 6 : 16; + } + return schema?.kind ?? 6; + })(); + return { - kind: schema?.kind ?? 6, + kind: resolvedKind, pubkey, created_at, tags, diff --git a/tests/nostr-boost-actions.test.mjs b/tests/nostr-boost-actions.test.mjs index 714813be..701400a4 100644 --- a/tests/nostr-boost-actions.test.mjs +++ b/tests/nostr-boost-actions.test.mjs @@ -84,9 +84,11 @@ function createPublishClient({ actorPubkey = "", sessionPubkey = "", failPublish created_at: createdAt, eventId: "event123", eventRelay: "wss://origin", + publishRelay: "wss://relay.example", address: "30078:deadbeef:identifier", addressRelay: "wss://address", authorPubkey: "deadbeef", + targetKind: 1, }); assert.equal(event.kind, 6); @@ -98,6 +100,22 @@ function createPublishClient({ actorPubkey = "", sessionPubkey = "", failPublish assert.deepEqual(event.tags[2], ["p", "deadbeef"]); })(); +(function testBuildRepostEventFallsBackToPublishRelay() { + const createdAt = 1_700_000_001; + const event = buildRepostEvent({ + pubkey: "actorpubkey", + created_at: createdAt, + eventId: "event456", + publishRelay: "wss://relay.example", + authorPubkey: "cafebabe", + targetKind: 30078, + }); + + assert.equal(event.kind, 16); + assert.deepEqual(event.tags[0], ["e", "event456", "wss://relay.example"]); + assert.deepEqual(event.tags[1], ["p", "cafebabe"]); +})(); + await (async function testRepostEventUsesSessionActorAndDerivesAddress() { const eventId = "test-event"; const authorPubkey = "f".repeat(64); @@ -117,7 +135,7 @@ await (async function testRepostEventUsesSessionActorAndDerivesAddress() { client, eventId, options: { - pointer: ["e", eventId, "wss://origin"], + pointer: ["e", eventId], authorPubkey, }, resolveActiveSigner: () => null, @@ -129,9 +147,10 @@ await (async function testRepostEventUsesSessionActorAndDerivesAddress() { assert.equal(result.ok, true); assert.equal(result.sessionActor, true); assert.equal(result.signerPubkey, sessionPubkey); + assert.equal(result.event?.kind, 16); const tags = result.event?.tags || []; assert.ok(Array.isArray(tags), "Repost event should include tags"); - assert.deepEqual(tags[0], ["e", eventId, "wss://origin"]); + assert.deepEqual(tags[0], ["e", eventId, "wss://relay.example"]); assert.equal( tags.some((tag) => Array.isArray(tag) && tag[0] === "a" && tag[1].startsWith("30078:")), true,