changes after self-review

This commit is contained in:
ennmichael 2023-02-27 14:35:36 +01:00
parent 303fa2ff4b
commit 5d66ad9165
No known key found for this signature in database
GPG Key ID: 6E6E183431A26AF7
3 changed files with 58 additions and 13 deletions

View File

@ -53,7 +53,7 @@ export class Nostr {
} }
/** /**
* Connect and start communicating with a relay. This method recreates all existing * Open a connection and start communicating with a relay. This method recreates all existing
* subscriptions on the new relay as well. If there is already an existing connection, * subscriptions on the new relay as well. If there is already an existing connection,
* this method will only update it with the new options, and an exception will be thrown * this method will only update it with the new options, and an exception will be thrown
* if no options are specified. * if no options are specified.
@ -122,7 +122,7 @@ export class Nostr {
} }
/** /**
* Disconnect from relays. * Close connections to relays.
* *
* @param url If specified, only close the connection to this relay. If the connection does * @param url If specified, only close the connection to this relay. If the connection does
* not exist, an exception will be thrown. If this parameter is not specified, all connections * not exist, an exception will be thrown. If this parameter is not specified, all connections

View File

@ -96,20 +96,30 @@ export class EventId {
} }
} }
// TODO Document /**
* A signed event. Provides access to the event data, ID, and signature.
*/
export class SignedEvent { export class SignedEvent {
#event: Readonly<Event> #event: Readonly<Event>
#eventId: EventId #eventId: EventId
#signature: string #signature: string
/**
* Sign an event using the specified private key. The private key must match the
* public key from the event.
*/
static async sign(event: Event, key: PrivateKey): Promise<SignedEvent> { static async sign(event: Event, key: PrivateKey): Promise<SignedEvent> {
const id = await EventId.create(event) const id = await EventId.create(event)
const sig = secp.utils const sig = secp.utils
.bytesToHex(await secp.schnorr.sign(id.toString(), key.leak())) .bytesToHex(await secp.schnorr.sign(id.toString(), key.hexDangerous()))
.toLowerCase() .toLowerCase()
return new SignedEvent(event, id, sig) return new SignedEvent(event, id, sig)
} }
/**
* Verify the signature of a raw event. Throw a `ProtocolError` if the signature
* is invalid.
*/
static async verify(raw: RawEvent): Promise<SignedEvent> { static async verify(raw: RawEvent): Promise<SignedEvent> {
const id = await EventId.create(raw) const id = await EventId.create(raw)
if (id.toString() !== raw.id) { if (id.toString() !== raw.id) {
@ -122,24 +132,28 @@ export class SignedEvent {
} }
private constructor(event: Event, eventId: EventId, signature: string) { private constructor(event: Event, eventId: EventId, signature: string) {
// TODO Copy the event data and document that it's being copied this.#event = cloneEvent(event)
this.#event = event
this.#eventId = eventId this.#eventId = eventId
this.#signature = signature this.#signature = signature
} }
// TODO Document this /**
* Event ID.
*/
get eventId(): EventId { get eventId(): EventId {
return this.#eventId return this.#eventId
} }
// TODO Document this /**
* Event data.
*/
get event(): Event { get event(): Event {
// TODO Copy the event data and document that it's being copied return cloneEvent(this.#event)
return this.#event
} }
// TODO Document this /**
* Event signature.
*/
get signature(): string { get signature(): string {
return this.#signature return this.#signature
} }
@ -250,6 +264,35 @@ function serializeEventContent(event: Event): string {
} }
} }
function cloneEvent(event: Event): Event {
const common = {
createdAt: structuredClone(event.createdAt),
pubkey: new PublicKey(event.pubkey.toString()),
}
if (event.kind === EventKind.SetMetadata) {
return {
kind: EventKind.SetMetadata,
userMetadata: {
about: event.userMetadata.about,
name: event.userMetadata.name,
picture: event.userMetadata.picture,
},
...common,
}
} else if (event.kind === EventKind.TextNote) {
return {
kind: EventKind.TextNote,
note: event.note,
...common,
}
} else {
return {
kind: event.kind,
...common,
}
}
}
function parseJson(data: string) { function parseJson(data: string) {
try { try {
return JSON.parse(data) return JSON.parse(data)

View File

@ -43,8 +43,10 @@ export class PrivateKey {
return new PublicKey(secp.schnorr.getPublicKey(this.#hex)) return new PublicKey(secp.schnorr.getPublicKey(this.#hex))
} }
// TODO Document this /**
leak(): string { * The hex representation of the private key. Use with caution!
*/
hexDangerous(): string {
return this.#hex return this.#hex
} }
} }