update nostr package to support nip45 messages

This commit is contained in:
w3irdrobot 2023-05-05 11:41:29 -04:00
parent e480e74882
commit 88020abe00
Signed by: w3irdrobot
GPG Key ID: 3E6DBBB622F3155C
4 changed files with 75 additions and 2 deletions

View File

@ -9,6 +9,7 @@
"clean": "rm -rf dist",
"test": "ts-mocha --type-check -j 1 --timeout 5s test/test.*.ts",
"test-browser": "ts-node test/browser/server.ts",
"format": "prettier --write .",
"lint": "eslint ."
},
"devDependencies": {

View File

@ -118,8 +118,9 @@ export type IncomingMessage =
| IncomingOk
| IncomingEose
| IncomingAuth
| IncomingCount
export type IncomingKind = "event" | "notice" | "ok" | "eose" | "auth"
export type IncomingKind = "event" | "notice" | "ok" | "eose" | "auth" | "count"
/**
* Incoming "EVENT" message.
@ -163,6 +164,15 @@ export interface IncomingAuth {
kind: "auth"
}
/**
* Incoming "COUNT" message.
*/
export interface IncomingCount {
kind: "count"
subscriptionId: SubscriptionId
count: number
}
/**
* A message sent from the client to a relay.
*/
@ -170,8 +180,13 @@ export type OutgoingMessage =
| OutgoingEvent
| OutgoingOpenSubscription
| OutgoingCloseSubscription
| OutgoingCount
export type OutgoingKind = "event" | "openSubscription" | "closeSubscription"
export type OutgoingKind =
| "event"
| "openSubscription"
| "closeSubscription"
| "count"
/**
* Outgoing "EVENT" message.
@ -198,6 +213,16 @@ export interface OutgoingCloseSubscription {
id: SubscriptionId
}
/**
* Outgoing "COUNT" message, which requests a count
* of events matching the given filters
*/
export interface OutgoingCount {
kind: "count"
id: SubscriptionId
filters: Filters[]
}
function serializeOutgoingMessage(msg: OutgoingMessage): string {
if (msg.kind === "event") {
return JSON.stringify(["EVENT", msg.event])
@ -207,6 +232,9 @@ function serializeOutgoingMessage(msg: OutgoingMessage): string {
return JSON.stringify(["REQ", msg.id.toString(), ...filters])
} else if (msg.kind === "closeSubscription") {
return JSON.stringify(["CLOSE", msg.id.toString()])
} else if (msg.kind === "count") {
const filters = msg.filters.length === 0 ? [{}] : msg.filters
return JSON.stringify(["COUNT", msg.id.toString(), ...filters])
} else {
throw new NostrError(`invalid message: ${JSON.stringify(msg)}`)
}
@ -301,6 +329,27 @@ function parseIncomingMessage(data: string): IncomingMessage {
}
}
// Handle incoming "COUNT" messages.
if (json[0] === "COUNT") {
if (typeof json[1] !== "string") {
throw new NostrError(
`second element of "COUNT" should be a string, but wasn't: ${data}`
)
}
if (typeof json[2] !== "object") {
throw new NostrError(
`second element of "COUNT" should be an object, but wasn't: ${data}`
)
}
const { count } = json[2]
return {
kind: "count",
subscriptionId: json[1],
count,
}
}
throw new NostrError(`unknown incoming message: ${data}`)
}

View File

@ -22,6 +22,7 @@ export class EventEmitter extends Base {
override addListener(eventName: "ok", listener: OkListener): this
override addListener(eventName: "eose", listener: EoseListener): this
override addListener(eventName: "error", listener: ErrorListener): this
override addListener(eventName: "count", listener: ErrorListener): this
override addListener(eventName: EventName, listener: Listener): this {
return super.addListener(eventName, listener)
}
@ -39,6 +40,7 @@ export class EventEmitter extends Base {
nostr: Nostr
): boolean
override emit(eventName: "error", err: unknown, nostr: Nostr): boolean
override emit(eventName: "count", params: CountParams, nostr: Nostr): boolean
override emit(eventName: EventName, ...args: unknown[]): boolean {
return super.emit(eventName, ...args)
}
@ -56,6 +58,7 @@ export class EventEmitter extends Base {
override listeners(eventName: "ok"): OkListener[]
override listeners(eventName: "eose"): EoseListener[]
override listeners(eventName: "error"): ErrorListener[]
override listeners(eventName: "count"): ErrorListener[]
override listeners(eventName: EventName): Listener[] {
return super.listeners(eventName) as Listener[]
}
@ -69,6 +72,7 @@ export class EventEmitter extends Base {
override off(eventName: "ok", listener: OkListener): this
override off(eventName: "eose", listener: EoseListener): this
override off(eventName: "error", listener: ErrorListener): this
override off(eventName: "count", listener: ErrorListener): this
override off(eventName: EventName, listener: Listener): this {
return super.off(eventName, listener)
}
@ -82,6 +86,7 @@ export class EventEmitter extends Base {
override on(eventName: "ok", listener: OkListener): this
override on(eventName: "eose", listener: EoseListener): this
override on(eventName: "error", listener: ErrorListener): this
override on(eventName: "count", listener: ErrorListener): this
override on(eventName: EventName, listener: Listener): this {
return super.on(eventName, listener)
}
@ -95,6 +100,7 @@ export class EventEmitter extends Base {
override once(eventName: "ok", listener: OkListener): this
override once(eventName: "eose", listener: EoseListener): this
override once(eventName: "error", listener: ErrorListener): this
override once(eventName: "count", listener: ErrorListener): this
override once(eventName: EventName, listener: Listener): this {
return super.once(eventName, listener)
}
@ -114,6 +120,7 @@ export class EventEmitter extends Base {
override prependListener(eventName: "ok", listener: OkListener): this
override prependListener(eventName: "eose", listener: EoseListener): this
override prependListener(eventName: "error", listener: ErrorListener): this
override prependListener(eventName: "count", listener: ErrorListener): this
override prependListener(eventName: EventName, listener: Listener): this {
return super.prependListener(eventName, listener)
}
@ -145,6 +152,7 @@ export class EventEmitter extends Base {
eventName: "error",
listener: ErrorListener
): this
override prependOnceListener(eventName: "count", listener: EoseListener): this
override prependOnceListener(eventName: EventName, listener: Listener): this {
return super.prependOnceListener(eventName, listener)
}
@ -165,6 +173,7 @@ export class EventEmitter extends Base {
override removeListener(eventName: "ok", listener: OkListener): this
override removeListener(eventName: "eose", listener: EoseListener): this
override removeListener(eventName: "error", listener: ErrorListener): this
override removeListener(eventName: "count", listener: ErrorListener): this
override removeListener(eventName: EventName, listener: Listener): this {
return super.removeListener(eventName, listener)
}
@ -189,6 +198,7 @@ type EventName =
| "ok"
| "eose"
| "error"
| "count"
type NewListener = (eventName: EventName, listener: Listener) => void
type RemoveListener = (eventName: EventName, listener: Listener) => void
@ -199,6 +209,7 @@ type NoticeListener = (notice: string, nostr: Nostr) => void
type OkListener = (params: OkParams, nostr: Nostr) => void
type EoseListener = (subscriptionId: SubscriptionId, nostr: Nostr) => void
type ErrorListener = (error: unknown, nostr: Nostr) => void
type CountListener = (params: CountParams, nostr: Nostr) => void
type Listener =
| NewListener
@ -224,3 +235,9 @@ export interface OkParams {
ok: boolean
message: string
}
// TODO Document this
export interface CountParams {
count: number
subscriptionId: SubscriptionId
}

View File

@ -107,6 +107,12 @@ export class Nostr extends EventEmitter {
this.emit("eose", msg.subscriptionId, this)
} else if (msg.kind === "auth") {
// TODO This is incomplete
} else if (msg.kind === "count") {
this.emit(
"count",
{ subscriptionId: msg.subscriptionId, count: msg.count },
this
)
} else {
this.#error(new NostrError(`invalid message ${JSON.stringify(msg)}`))
}