From a9f3216102521d18655d2e41864e12f9321895e8 Mon Sep 17 00:00:00 2001 From: Kieran Date: Thu, 15 Jun 2023 15:51:07 +0100 Subject: [PATCH] nip-59 gift wrap construct --- packages/system/src/EventKind.ts | 1 + packages/system/src/EventPublisher.ts | 29 ++++++++++++++++++++++++--- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/packages/system/src/EventKind.ts b/packages/system/src/EventKind.ts index 512a1f0a..263de665 100644 --- a/packages/system/src/EventKind.ts +++ b/packages/system/src/EventKind.ts @@ -11,6 +11,7 @@ enum EventKind { BadgeAward = 8, // NIP-58 SnortSubscriptions = 1000, // NIP-XX Polls = 6969, // NIP-69 + GiftWrap = 1059, // NIP-59 FileHeader = 1063, // NIP-94 Relays = 10002, // NIP-65 Ephemeral = 20_000, diff --git a/packages/system/src/EventPublisher.ts b/packages/system/src/EventPublisher.ts index 19d7475a..5d0d9fa8 100644 --- a/packages/system/src/EventPublisher.ts +++ b/packages/system/src/EventPublisher.ts @@ -1,12 +1,13 @@ import * as secp from "@noble/curves/secp256k1"; import * as utils from "@noble/curves/abstract/utils"; -import { unwrap, barrierQueue, processWorkQueue, WorkQueueItem } from "@snort/shared"; +import { unwrap, barrierQueue, processWorkQueue, WorkQueueItem, getPublicKey } from "@snort/shared"; import { EventKind, FullRelaySettings, HexKey, Lists, + Nip44Encryptor, NostrEvent, RelaySettings, TaggedRawEvent, @@ -16,6 +17,7 @@ import { import { EventBuilder } from "./EventBuilder"; import { EventExt } from "./EventExt"; +import { findTag } from "./Utils"; const Nip7Queue: Array = []; processWorkQueue(Nip7Queue); @@ -58,9 +60,9 @@ export class EventPublisher { * Get a NIP-07 EventPublisher */ static async nip7() { - if("nostr" in window) { + if ("nostr" in window) { const pubkey = await window.nostr?.getPublicKey(); - if(pubkey) { + if (pubkey) { return new EventPublisher(pubkey); } } @@ -309,4 +311,25 @@ export class EventPublisher { fnHook(eb); return await this.#sign(eb); } + + /** + * NIP-59 Gift Wrap event with ephemeral key + */ + async giftWrap(inner: NostrEvent) { + const secret = utils.bytesToHex(secp.secp256k1.utils.randomPrivateKey()); + + const pTag = findTag(inner, "p"); + if (!pTag) throw new Error("Inner event must have a p tag"); + + const eb = new EventBuilder(); + eb.pubKey(getPublicKey(secret)); + eb.kind(EventKind.GiftWrap); + eb.tag(["p", pTag]); + + const enc = new Nip44Encryptor(); + const shared = enc.getSharedSecret(secret, pTag); + eb.content(enc.encryptData(JSON.stringify(inner), shared)); + + return await eb.buildAndSign(secret); + } }