changes after self-review
This commit is contained in:
parent
303fa2ff4b
commit
5d66ad9165
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user