Profile / Thread styles
This commit is contained in:
@ -226,12 +226,12 @@ function parseIncomingMessage(data: string): IncomingMessage {
|
||||
if (json[0] === "EVENT") {
|
||||
if (typeof json[1] !== "string") {
|
||||
throw new NostrError(
|
||||
`second element of "EVENT" should be a string, but wasn't: ${data}`
|
||||
`second element of "EVENT" should be a string, but wasn't: ${data}`,
|
||||
)
|
||||
}
|
||||
if (typeof json[2] !== "object") {
|
||||
throw new NostrError(
|
||||
`second element of "EVENT" should be an object, but wasn't: ${data}`
|
||||
`second element of "EVENT" should be an object, but wasn't: ${data}`,
|
||||
)
|
||||
}
|
||||
const event = parseEventData(json[2])
|
||||
@ -246,7 +246,7 @@ function parseIncomingMessage(data: string): IncomingMessage {
|
||||
if (json[0] === "NOTICE") {
|
||||
if (typeof json[1] !== "string") {
|
||||
throw new NostrError(
|
||||
`second element of "NOTICE" should be a string, but wasn't: ${data}`
|
||||
`second element of "NOTICE" should be a string, but wasn't: ${data}`,
|
||||
)
|
||||
}
|
||||
return {
|
||||
@ -259,17 +259,17 @@ function parseIncomingMessage(data: string): IncomingMessage {
|
||||
if (json[0] === "OK") {
|
||||
if (typeof json[1] !== "string") {
|
||||
throw new NostrError(
|
||||
`second element of "OK" should be a string, but wasn't: ${data}`
|
||||
`second element of "OK" should be a string, but wasn't: ${data}`,
|
||||
)
|
||||
}
|
||||
if (typeof json[2] !== "boolean") {
|
||||
throw new NostrError(
|
||||
`third element of "OK" should be a boolean, but wasn't: ${data}`
|
||||
`third element of "OK" should be a boolean, but wasn't: ${data}`,
|
||||
)
|
||||
}
|
||||
if (typeof json[3] !== "string") {
|
||||
throw new NostrError(
|
||||
`fourth element of "OK" should be a string, but wasn't: ${data}`
|
||||
`fourth element of "OK" should be a string, but wasn't: ${data}`,
|
||||
)
|
||||
}
|
||||
return {
|
||||
@ -284,7 +284,7 @@ function parseIncomingMessage(data: string): IncomingMessage {
|
||||
if (json[0] === "EOSE") {
|
||||
if (typeof json[1] !== "string") {
|
||||
throw new NostrError(
|
||||
`second element of "EOSE" should be a string, but wasn't: ${data}`
|
||||
`second element of "EOSE" should be a string, but wasn't: ${data}`,
|
||||
)
|
||||
}
|
||||
return {
|
||||
@ -312,7 +312,7 @@ function parseEventData(json: { [key: string]: unknown }): RawEvent {
|
||||
typeof json["kind"] !== "number" ||
|
||||
!(json["tags"] instanceof Array) ||
|
||||
!json["tags"].every(
|
||||
(x) => x instanceof Array && x.every((y) => typeof y === "string")
|
||||
(x) => x instanceof Array && x.every((y) => typeof y === "string"),
|
||||
) ||
|
||||
typeof json["content"] !== "string" ||
|
||||
typeof json["sig"] !== "string"
|
||||
|
@ -13,7 +13,7 @@ export class EventEmitter extends Base {
|
||||
override addListener(eventName: "newListener", listener: NewListener): this
|
||||
override addListener(
|
||||
eventName: "removeListener",
|
||||
listener: RemoveListener
|
||||
listener: RemoveListener,
|
||||
): this
|
||||
override addListener(eventName: "open", listener: OpenListener): this
|
||||
override addListener(eventName: "close", listener: CloseListener): this
|
||||
@ -36,7 +36,7 @@ export class EventEmitter extends Base {
|
||||
override emit(
|
||||
eventName: "eose",
|
||||
subscriptionId: SubscriptionId,
|
||||
nostr: Nostr
|
||||
nostr: Nostr,
|
||||
): boolean
|
||||
override emit(eventName: "error", err: unknown, nostr: Nostr): boolean
|
||||
override emit(eventName: EventName, ...args: unknown[]): boolean {
|
||||
@ -101,11 +101,11 @@ export class EventEmitter extends Base {
|
||||
|
||||
override prependListener(
|
||||
eventName: "newListener",
|
||||
listener: NewListener
|
||||
listener: NewListener,
|
||||
): this
|
||||
override prependListener(
|
||||
eventName: "removeListener",
|
||||
listener: RemoveListener
|
||||
listener: RemoveListener,
|
||||
): this
|
||||
override prependListener(eventName: "open", listener: OpenListener): this
|
||||
override prependListener(eventName: "close", listener: CloseListener): this
|
||||
@ -120,30 +120,30 @@ export class EventEmitter extends Base {
|
||||
|
||||
override prependOnceListener(
|
||||
eventName: "newListener",
|
||||
listener: NewListener
|
||||
listener: NewListener,
|
||||
): this
|
||||
override prependOnceListener(
|
||||
eventName: "removeListener",
|
||||
listener: RemoveListener
|
||||
listener: RemoveListener,
|
||||
): this
|
||||
override prependOnceListener(eventName: "open", listener: OpenListener): this
|
||||
override prependOnceListener(
|
||||
eventName: "close",
|
||||
listener: CloseListener
|
||||
listener: CloseListener,
|
||||
): this
|
||||
override prependOnceListener(
|
||||
eventName: "event",
|
||||
listener: EventListener
|
||||
listener: EventListener,
|
||||
): this
|
||||
override prependOnceListener(
|
||||
eventName: "notice",
|
||||
listener: NoticeListener
|
||||
listener: NoticeListener,
|
||||
): this
|
||||
override prependOnceListener(eventName: "ok", listener: OkListener): this
|
||||
override prependOnceListener(eventName: "eose", listener: EoseListener): this
|
||||
override prependOnceListener(
|
||||
eventName: "error",
|
||||
listener: ErrorListener
|
||||
listener: ErrorListener,
|
||||
): this
|
||||
override prependOnceListener(eventName: EventName, listener: Listener): this {
|
||||
return super.prependOnceListener(eventName, listener)
|
||||
@ -156,7 +156,7 @@ export class EventEmitter extends Base {
|
||||
override removeListener(eventName: "newListener", listener: NewListener): this
|
||||
override removeListener(
|
||||
eventName: "removeListener",
|
||||
listener: RemoveListener
|
||||
listener: RemoveListener,
|
||||
): this
|
||||
override removeListener(eventName: "open", listener: OpenListener): this
|
||||
override removeListener(eventName: "close", listener: CloseListener): this
|
||||
|
@ -43,18 +43,18 @@ export class Nostr extends EventEmitter {
|
||||
*/
|
||||
open(
|
||||
url: URL | string,
|
||||
opts?: { read?: boolean; write?: boolean; fetchInfo?: boolean }
|
||||
opts?: { read?: boolean; write?: boolean; fetchInfo?: boolean },
|
||||
): void {
|
||||
const relayUrl = new URL(url)
|
||||
|
||||
// If the connection already exists, update the options.
|
||||
const existingConn = this.#conns.find(
|
||||
(c) => c.relay.url.toString() === relayUrl.toString()
|
||||
(c) => c.relay.url.toString() === relayUrl.toString(),
|
||||
)
|
||||
if (existingConn !== undefined) {
|
||||
if (opts === undefined) {
|
||||
throw new NostrError(
|
||||
`called connect with existing connection ${url}, but options were not specified`
|
||||
`called connect with existing connection ${url}, but options were not specified`,
|
||||
)
|
||||
}
|
||||
if (opts.read !== undefined) {
|
||||
@ -88,7 +88,7 @@ export class Nostr extends EventEmitter {
|
||||
event: parseEvent(msg.event),
|
||||
subscriptionId: msg.subscriptionId,
|
||||
},
|
||||
this
|
||||
this,
|
||||
)
|
||||
} else if (msg.kind === "notice") {
|
||||
this.emit("notice", msg.notice, this)
|
||||
@ -101,7 +101,7 @@ export class Nostr extends EventEmitter {
|
||||
ok: msg.ok,
|
||||
message: msg.message,
|
||||
},
|
||||
this
|
||||
this,
|
||||
)
|
||||
} else if (msg.kind === "eose") {
|
||||
this.emit("eose", msg.subscriptionId, this)
|
||||
@ -116,13 +116,13 @@ export class Nostr extends EventEmitter {
|
||||
onOpen: async () => {
|
||||
// Update the connection readyState.
|
||||
const conn = this.#conns.find(
|
||||
(c) => c.relay.url.toString() === relayUrl.toString()
|
||||
(c) => c.relay.url.toString() === relayUrl.toString(),
|
||||
)
|
||||
if (conn === undefined) {
|
||||
this.#error(
|
||||
new NostrError(
|
||||
`bug: expected connection to ${relayUrl.toString()} to be in the map`
|
||||
)
|
||||
`bug: expected connection to ${relayUrl.toString()} to be in the map`,
|
||||
),
|
||||
)
|
||||
} else {
|
||||
if (conn.relay.readyState !== ReadyState.CONNECTING) {
|
||||
@ -130,8 +130,8 @@ export class Nostr extends EventEmitter {
|
||||
new NostrError(
|
||||
`bug: expected connection to ${relayUrl.toString()} to have readyState CONNECTING, got ${
|
||||
conn.relay.readyState
|
||||
}`
|
||||
)
|
||||
}`,
|
||||
),
|
||||
)
|
||||
}
|
||||
conn.relay = {
|
||||
@ -148,13 +148,13 @@ export class Nostr extends EventEmitter {
|
||||
onClose: () => {
|
||||
// Update the connection readyState.
|
||||
const conn = this.#conns.find(
|
||||
(c) => c.relay.url.toString() === relayUrl.toString()
|
||||
(c) => c.relay.url.toString() === relayUrl.toString(),
|
||||
)
|
||||
if (conn === undefined) {
|
||||
this.#error(
|
||||
new NostrError(
|
||||
`bug: expected connection to ${relayUrl.toString()} to be in the map`
|
||||
)
|
||||
`bug: expected connection to ${relayUrl.toString()} to be in the map`,
|
||||
),
|
||||
)
|
||||
} else {
|
||||
conn.relay.readyState = ReadyState.CLOSED
|
||||
@ -207,7 +207,7 @@ export class Nostr extends EventEmitter {
|
||||
}
|
||||
const relayUrl = new URL(url)
|
||||
const c = this.#conns.find(
|
||||
(c) => c.relay.url.toString() === relayUrl.toString()
|
||||
(c) => c.relay.url.toString() === relayUrl.toString(),
|
||||
)
|
||||
if (c === undefined) {
|
||||
throw new NostrError(`connection to ${url} doesn't exist`)
|
||||
@ -231,7 +231,7 @@ export class Nostr extends EventEmitter {
|
||||
*/
|
||||
subscribe(
|
||||
filters: Filters[],
|
||||
subscriptionId: SubscriptionId = randomSubscriptionId()
|
||||
subscriptionId: SubscriptionId = randomSubscriptionId(),
|
||||
): SubscriptionId {
|
||||
this.#subscriptions.set(subscriptionId, filters)
|
||||
for (const { conn, read } of this.#conns.values()) {
|
||||
|
@ -75,32 +75,32 @@ export async function fetchRelayInfo(url: URL | string): Promise<RelayInfo> {
|
||||
info.name = undefined
|
||||
throw new NostrError(
|
||||
`invalid relay info, expected "name" to be a string: ${JSON.stringify(
|
||||
info
|
||||
)}`
|
||||
info,
|
||||
)}`,
|
||||
)
|
||||
}
|
||||
if (info.description !== undefined && typeof info.description !== "string") {
|
||||
info.description = undefined
|
||||
throw new NostrError(
|
||||
`invalid relay info, expected "description" to be a string: ${JSON.stringify(
|
||||
info
|
||||
)}`
|
||||
info,
|
||||
)}`,
|
||||
)
|
||||
}
|
||||
if (info.pubkey !== undefined && typeof info.pubkey !== "string") {
|
||||
info.pubkey = undefined
|
||||
throw new NostrError(
|
||||
`invalid relay info, expected "pubkey" to be a string: ${JSON.stringify(
|
||||
info
|
||||
)}`
|
||||
info,
|
||||
)}`,
|
||||
)
|
||||
}
|
||||
if (info.contact !== undefined && typeof info.contact !== "string") {
|
||||
info.contact = undefined
|
||||
throw new NostrError(
|
||||
`invalid relay info, expected "contact" to be a string: ${JSON.stringify(
|
||||
info
|
||||
)}`
|
||||
info,
|
||||
)}`,
|
||||
)
|
||||
}
|
||||
if (info.supported_nips !== undefined) {
|
||||
@ -109,16 +109,16 @@ export async function fetchRelayInfo(url: URL | string): Promise<RelayInfo> {
|
||||
info.supported_nips = undefined
|
||||
throw new NostrError(
|
||||
`invalid relay info, expected "supported_nips" elements to be numbers: ${JSON.stringify(
|
||||
info
|
||||
)}`
|
||||
info,
|
||||
)}`,
|
||||
)
|
||||
}
|
||||
} else {
|
||||
info.supported_nips = undefined
|
||||
throw new NostrError(
|
||||
`invalid relay info, expected "supported_nips" to be an array: ${JSON.stringify(
|
||||
info
|
||||
)}`
|
||||
info,
|
||||
)}`,
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -126,16 +126,16 @@ export async function fetchRelayInfo(url: URL | string): Promise<RelayInfo> {
|
||||
info.software = undefined
|
||||
throw new NostrError(
|
||||
`invalid relay info, expected "software" to be a string: ${JSON.stringify(
|
||||
info
|
||||
)}`
|
||||
info,
|
||||
)}`,
|
||||
)
|
||||
}
|
||||
if (info.version !== undefined && typeof info.version !== "string") {
|
||||
info.version = undefined
|
||||
throw new NostrError(
|
||||
`invalid relay info, expected "version" to be a string: ${JSON.stringify(
|
||||
info
|
||||
)}`
|
||||
info,
|
||||
)}`,
|
||||
)
|
||||
}
|
||||
return info
|
||||
|
@ -99,7 +99,7 @@ export function schnorrVerify(sig: Hex, data: Hex, key: PublicKey): boolean {
|
||||
export async function aesEncryptBase64(
|
||||
sender: PrivateKey,
|
||||
recipient: PublicKey,
|
||||
plaintext: string
|
||||
plaintext: string,
|
||||
): Promise<AesEncryptedBase64> {
|
||||
const sharedPoint = secp.secp256k1.getSharedSecret(sender, "02" + recipient)
|
||||
const sharedKey = sharedPoint.slice(1, 33)
|
||||
@ -109,7 +109,7 @@ export async function aesEncryptBase64(
|
||||
sharedKey,
|
||||
{ name: "AES-CBC" },
|
||||
false,
|
||||
["encrypt"]
|
||||
["encrypt"],
|
||||
)
|
||||
const iv = window.crypto.getRandomValues(new Uint8Array(16))
|
||||
const data = new TextEncoder().encode(plaintext)
|
||||
@ -119,7 +119,7 @@ export async function aesEncryptBase64(
|
||||
iv,
|
||||
},
|
||||
key,
|
||||
data
|
||||
data,
|
||||
)
|
||||
return {
|
||||
data: base64.fromByteArray(new Uint8Array(encrypted)),
|
||||
@ -131,7 +131,7 @@ export async function aesEncryptBase64(
|
||||
const cipher = crypto.createCipheriv(
|
||||
"aes-256-cbc",
|
||||
Buffer.from(sharedKey),
|
||||
iv
|
||||
iv,
|
||||
)
|
||||
let encrypted = cipher.update(plaintext, "utf8", "base64")
|
||||
encrypted += cipher.final("base64")
|
||||
@ -145,7 +145,7 @@ export async function aesEncryptBase64(
|
||||
export async function aesDecryptBase64(
|
||||
sender: PublicKey,
|
||||
recipient: PrivateKey,
|
||||
{ data, iv }: AesEncryptedBase64
|
||||
{ data, iv }: AesEncryptedBase64,
|
||||
): Promise<string> {
|
||||
const sharedPoint = secp.secp256k1.getSharedSecret(recipient, "02" + sender)
|
||||
const sharedKey = sharedPoint.slice(1, 33)
|
||||
@ -157,7 +157,7 @@ export async function aesDecryptBase64(
|
||||
sharedKey,
|
||||
{ name: "AES-CBC" },
|
||||
false,
|
||||
["decrypt"]
|
||||
["decrypt"],
|
||||
)
|
||||
const plaintext = await window.crypto.subtle.decrypt(
|
||||
{
|
||||
@ -165,7 +165,7 @@ export async function aesDecryptBase64(
|
||||
iv: decodedIv,
|
||||
},
|
||||
importedKey,
|
||||
decodedData
|
||||
decodedData,
|
||||
)
|
||||
return new TextDecoder().decode(plaintext)
|
||||
} else {
|
||||
@ -173,7 +173,7 @@ export async function aesDecryptBase64(
|
||||
const decipher = crypto.createDecipheriv(
|
||||
"aes-256-cbc",
|
||||
Buffer.from(sharedKey),
|
||||
base64.toByteArray(iv)
|
||||
base64.toByteArray(iv),
|
||||
)
|
||||
const plaintext = decipher.update(data, "base64", "utf8")
|
||||
return plaintext + decipher.final()
|
||||
|
@ -30,7 +30,7 @@ export interface Contact {
|
||||
*/
|
||||
export function createContactList(
|
||||
contacts: Contact[],
|
||||
priv?: HexOrBechPrivateKey
|
||||
priv?: HexOrBechPrivateKey,
|
||||
): Promise<ContactList> {
|
||||
return signEvent(
|
||||
{
|
||||
@ -44,7 +44,7 @@ export function createContactList(
|
||||
content: "",
|
||||
getContacts,
|
||||
},
|
||||
priv
|
||||
priv,
|
||||
)
|
||||
}
|
||||
|
||||
@ -57,8 +57,8 @@ export function getContacts(this: ContactList): Contact[] {
|
||||
if (pubkey === undefined) {
|
||||
throw new NostrError(
|
||||
`missing contact pubkey for contact list event: ${JSON.stringify(
|
||||
this
|
||||
)}`
|
||||
this,
|
||||
)}`,
|
||||
)
|
||||
}
|
||||
|
||||
@ -70,7 +70,7 @@ export function getContacts(this: ContactList): Contact[] {
|
||||
}
|
||||
} catch (e) {
|
||||
throw new NostrError(
|
||||
`invalid relay URL for contact list event: ${JSON.stringify(this)}`
|
||||
`invalid relay URL for contact list event: ${JSON.stringify(this)}`,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,7 @@ export interface Deletion extends RawEvent {
|
||||
*/
|
||||
export function createDeletion(
|
||||
{ events, content }: { events: EventId[]; content?: string },
|
||||
priv?: HexOrBechPrivateKey
|
||||
priv?: HexOrBechPrivateKey,
|
||||
): Promise<Deletion> {
|
||||
return signEvent(
|
||||
{
|
||||
@ -30,7 +30,7 @@ export function createDeletion(
|
||||
content: content ?? "",
|
||||
getEvents,
|
||||
},
|
||||
priv
|
||||
priv,
|
||||
)
|
||||
}
|
||||
|
||||
@ -40,7 +40,7 @@ export function getEvents(this: Deletion): EventId[] {
|
||||
.map((tag) => {
|
||||
if (tag[1] === undefined) {
|
||||
throw new NostrError(
|
||||
`invalid deletion event tag: ${JSON.stringify(tag)}`
|
||||
`invalid deletion event tag: ${JSON.stringify(tag)}`,
|
||||
)
|
||||
}
|
||||
return tag[1]
|
||||
|
@ -46,7 +46,7 @@ export async function createDirectMessage(
|
||||
message: string
|
||||
recipient: PublicKey
|
||||
},
|
||||
priv?: PrivateKey
|
||||
priv?: PrivateKey,
|
||||
): Promise<DirectMessage> {
|
||||
recipient = parsePublicKey(recipient)
|
||||
if (priv === undefined) {
|
||||
@ -66,7 +66,7 @@ export async function createDirectMessage(
|
||||
getRecipient,
|
||||
getPrevious,
|
||||
},
|
||||
priv
|
||||
priv,
|
||||
)
|
||||
} else {
|
||||
priv = parsePrivateKey(priv)
|
||||
@ -80,14 +80,14 @@ export async function createDirectMessage(
|
||||
getRecipient,
|
||||
getPrevious,
|
||||
},
|
||||
priv
|
||||
priv,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export async function getMessage(
|
||||
this: DirectMessage,
|
||||
priv?: HexOrBechPrivateKey
|
||||
priv?: HexOrBechPrivateKey,
|
||||
): Promise<string | undefined> {
|
||||
if (priv !== undefined) {
|
||||
priv = parsePrivateKey(priv)
|
||||
@ -114,9 +114,9 @@ export function getRecipient(this: DirectMessage): PublicKey {
|
||||
const recipientTag = this.tags.find((tag) => tag[0] === "p")
|
||||
if (typeof recipientTag?.[1] !== "string") {
|
||||
throw new NostrError(
|
||||
`expected "p" tag to be of type string, but got ${
|
||||
recipientTag?.[1]
|
||||
} in ${JSON.stringify(this)}`
|
||||
`expected "p" tag to be of type string, but got ${recipientTag?.[1]} in ${JSON.stringify(
|
||||
this,
|
||||
)}`,
|
||||
)
|
||||
}
|
||||
return recipientTag[1]
|
||||
@ -129,9 +129,9 @@ export function getPrevious(this: DirectMessage): EventId | undefined {
|
||||
}
|
||||
if (typeof previousTag[1] !== "string") {
|
||||
throw new NostrError(
|
||||
`expected "e" tag to be of type string, but got ${
|
||||
previousTag?.[1]
|
||||
} in ${JSON.stringify(this)}`
|
||||
`expected "e" tag to be of type string, but got ${previousTag?.[1]} in ${JSON.stringify(
|
||||
this,
|
||||
)}`,
|
||||
)
|
||||
}
|
||||
return previousTag[1]
|
||||
|
@ -122,7 +122,7 @@ type UnsignedWithPubkey<T extends Event | RawEvent> = {
|
||||
*/
|
||||
export async function signEvent<T extends RawEvent>(
|
||||
event: Unsigned<T>,
|
||||
priv?: HexOrBechPrivateKey
|
||||
priv?: HexOrBechPrivateKey,
|
||||
): Promise<T> {
|
||||
event.created_at ??= unixTimestamp()
|
||||
if (priv !== undefined) {
|
||||
@ -130,7 +130,7 @@ export async function signEvent<T extends RawEvent>(
|
||||
event.pubkey = getPublicKey(priv)
|
||||
const id = serializeEventId(
|
||||
// This conversion is safe because the pubkey field is set above.
|
||||
event as unknown as UnsignedWithPubkey<T>
|
||||
event as unknown as UnsignedWithPubkey<T>,
|
||||
)
|
||||
event.id = id
|
||||
event.sig = schnorrSign(id, priv)
|
||||
@ -162,8 +162,8 @@ export function parseEvent(event: RawEvent): Event {
|
||||
if (event.id !== serializeEventId(event)) {
|
||||
throw new NostrError(
|
||||
`invalid id ${event.id} for event ${JSON.stringify(
|
||||
event
|
||||
)}, expected ${serializeEventId(event)}`
|
||||
event,
|
||||
)}, expected ${serializeEventId(event)}`,
|
||||
)
|
||||
}
|
||||
if (!schnorrVerify(event.sig, event.id, event.pubkey)) {
|
||||
|
@ -22,7 +22,7 @@ export interface SetMetadata extends RawEvent {
|
||||
* @return The internet identifier. `undefined` if there is no internet identifier.
|
||||
*/
|
||||
verifyInternetIdentifier(
|
||||
opts?: VerificationOptions
|
||||
opts?: VerificationOptions,
|
||||
): Promise<InternetIdentifier | undefined>
|
||||
}
|
||||
|
||||
@ -38,7 +38,7 @@ export interface UserMetadata {
|
||||
*/
|
||||
export function createSetMetadata(
|
||||
content: UserMetadata,
|
||||
priv?: HexOrBechPrivateKey
|
||||
priv?: HexOrBechPrivateKey,
|
||||
): Promise<SetMetadata> {
|
||||
return signEvent(
|
||||
{
|
||||
@ -48,7 +48,7 @@ export function createSetMetadata(
|
||||
getUserMetadata,
|
||||
verifyInternetIdentifier,
|
||||
},
|
||||
priv
|
||||
priv,
|
||||
)
|
||||
}
|
||||
|
||||
@ -60,7 +60,7 @@ export function getUserMetadata(this: SetMetadata): UserMetadata {
|
||||
typeof userMetadata.picture !== "string"
|
||||
) {
|
||||
throw new NostrError(
|
||||
`invalid user metadata ${userMetadata} in ${JSON.stringify(this)}`
|
||||
`invalid user metadata ${userMetadata} in ${JSON.stringify(this)}`,
|
||||
)
|
||||
}
|
||||
return userMetadata
|
||||
@ -68,7 +68,7 @@ export function getUserMetadata(this: SetMetadata): UserMetadata {
|
||||
|
||||
export async function verifyInternetIdentifier(
|
||||
this: SetMetadata,
|
||||
opts?: VerificationOptions
|
||||
opts?: VerificationOptions,
|
||||
): Promise<InternetIdentifier | undefined> {
|
||||
const metadata = this.getUserMetadata()
|
||||
if (metadata.nip05 === undefined) {
|
||||
@ -81,14 +81,14 @@ export async function verifyInternetIdentifier(
|
||||
!/^[a-zA-Z0-9-_]+$/.test(name)
|
||||
) {
|
||||
throw new NostrError(
|
||||
`invalid NIP-05 internet identifier: ${metadata.nip05}`
|
||||
`invalid NIP-05 internet identifier: ${metadata.nip05}`,
|
||||
)
|
||||
}
|
||||
const res = await fetch(
|
||||
`${
|
||||
opts?.https === false ? "http" : "https"
|
||||
}://${domain}/.well-known/nostr.json?name=${name}`,
|
||||
{ redirect: "error" }
|
||||
{ redirect: "error" },
|
||||
)
|
||||
const wellKnown = await res.json()
|
||||
const pubkey = wellKnown.names?.[name]
|
||||
@ -96,7 +96,7 @@ export async function verifyInternetIdentifier(
|
||||
throw new NostrError(
|
||||
`invalid NIP-05 internet identifier: ${
|
||||
metadata.nip05
|
||||
} pubkey does not match, ${JSON.stringify(wellKnown)}`
|
||||
} pubkey does not match, ${JSON.stringify(wellKnown)}`,
|
||||
)
|
||||
}
|
||||
const relays = wellKnown.relays?.[pubkey]
|
||||
|
@ -12,7 +12,7 @@ export interface TextNote extends RawEvent {
|
||||
|
||||
export function createTextNote(
|
||||
content: string,
|
||||
priv?: HexOrBechPrivateKey
|
||||
priv?: HexOrBechPrivateKey,
|
||||
): Promise<TextNote> {
|
||||
return signEvent(
|
||||
{
|
||||
@ -20,6 +20,6 @@ export function createTextNote(
|
||||
tags: [],
|
||||
content,
|
||||
},
|
||||
priv
|
||||
priv,
|
||||
)
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
<!DOCTYPE html>
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
@ -18,7 +18,7 @@ app.use("/", (req: express.Request, res: express.Response) => {
|
||||
.readdirSync(path.join(__dirname, "..", "..", "dist", "test"))
|
||||
.filter(
|
||||
(f) =>
|
||||
f.startsWith("test.") && !f.endsWith(".map") && !f.endsWith(".d.ts")
|
||||
f.startsWith("test.") && !f.endsWith(".map") && !f.endsWith(".d.ts"),
|
||||
)
|
||||
.map((src) => `<script src="${src}"></script>`)
|
||||
.join("\n")
|
||||
|
@ -30,7 +30,7 @@ export interface Setup {
|
||||
|
||||
export async function setup(
|
||||
done: (e?: unknown) => void,
|
||||
test: (setup: Setup) => void | Promise<void>
|
||||
test: (setup: Setup) => void | Promise<void>,
|
||||
) {
|
||||
try {
|
||||
await restartRelay()
|
||||
@ -55,7 +55,7 @@ export async function setup(
|
||||
const { data, iv } = await aesEncryptBase64(
|
||||
parsePrivateKey(publisherSecret),
|
||||
pubkey,
|
||||
plaintext
|
||||
plaintext,
|
||||
)
|
||||
return `${data}?iv=${iv}`
|
||||
},
|
||||
@ -67,7 +67,7 @@ export async function setup(
|
||||
{
|
||||
data,
|
||||
iv,
|
||||
}
|
||||
},
|
||||
)
|
||||
},
|
||||
},
|
||||
|
@ -52,7 +52,7 @@ describe("deletion", () => {
|
||||
// After the text note has been published, delete it.
|
||||
const deletion = await createDeletion(
|
||||
{ events: [textNoteId] },
|
||||
publisherSecret
|
||||
publisherSecret,
|
||||
)
|
||||
deletionId = deletion.id
|
||||
publisher.publish({
|
||||
@ -66,7 +66,7 @@ describe("deletion", () => {
|
||||
subscriber.subscribe([])
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
)
|
||||
})
|
||||
})
|
||||
|
@ -34,16 +34,16 @@ describe("direct-message", () => {
|
||||
if (event.kind === EventKind.DirectMessage) {
|
||||
assert.strictEqual(
|
||||
event.getRecipient(),
|
||||
parsePublicKey(subscriberPubkey)
|
||||
parsePublicKey(subscriberPubkey),
|
||||
)
|
||||
assert.strictEqual(
|
||||
await event.getMessage(subscriberSecret),
|
||||
message
|
||||
message,
|
||||
)
|
||||
}
|
||||
|
||||
done()
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
const subscriptionId = subscriber.subscribe([])
|
||||
@ -54,11 +54,11 @@ describe("direct-message", () => {
|
||||
message,
|
||||
recipient: subscriberPubkey,
|
||||
},
|
||||
publisherSecret
|
||||
publisherSecret,
|
||||
)
|
||||
publisher.publish(event)
|
||||
})
|
||||
}
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
@ -92,11 +92,11 @@ describe("direct-message", () => {
|
||||
if (event.kind === EventKind.DirectMessage) {
|
||||
assert.strictEqual(
|
||||
event.getRecipient(),
|
||||
parsePublicKey(recipientPubkey)
|
||||
parsePublicKey(recipientPubkey),
|
||||
)
|
||||
assert.strictEqual(
|
||||
await event.getMessage(subscriberSecret),
|
||||
undefined
|
||||
undefined,
|
||||
)
|
||||
}
|
||||
|
||||
@ -104,7 +104,7 @@ describe("direct-message", () => {
|
||||
} catch (e) {
|
||||
done(e)
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
const subscriptionId = subscriber.subscribe([])
|
||||
@ -116,11 +116,11 @@ describe("direct-message", () => {
|
||||
message,
|
||||
recipient: recipientPubkey,
|
||||
},
|
||||
publisherSecret
|
||||
publisherSecret,
|
||||
)
|
||||
publisher.publish(event)
|
||||
})
|
||||
}
|
||||
},
|
||||
)
|
||||
})
|
||||
})
|
||||
|
@ -34,7 +34,7 @@ describe("internet-identifier", () => {
|
||||
picture: "",
|
||||
nip05: "bob@localhost:12647",
|
||||
},
|
||||
publisherSecret
|
||||
publisherSecret,
|
||||
)),
|
||||
})
|
||||
})
|
||||
@ -66,7 +66,7 @@ describe("internet-identifier", () => {
|
||||
name: "",
|
||||
picture: "",
|
||||
},
|
||||
publisherSecret
|
||||
publisherSecret,
|
||||
)),
|
||||
})
|
||||
})
|
||||
|
@ -16,7 +16,7 @@ describe("relay info", () => {
|
||||
assert.ok((relay.info.supported_nips?.length ?? 0) > 0)
|
||||
assert.strictEqual(
|
||||
relay.info.software,
|
||||
"https://git.sr.ht/~gheartsfield/nostr-rs-relay"
|
||||
"https://git.sr.ht/~gheartsfield/nostr-rs-relay",
|
||||
)
|
||||
assert.strictEqual(relay.info.version, "0.8.8")
|
||||
}
|
||||
|
@ -43,12 +43,12 @@ describe("set metadata", () => {
|
||||
publisher.publish({
|
||||
...(await createSetMetadata(
|
||||
{ name, about, picture },
|
||||
publisherSecret
|
||||
publisherSecret,
|
||||
)),
|
||||
created_at: timestamp,
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
)
|
||||
})
|
||||
})
|
||||
|
@ -30,7 +30,7 @@ describe("text note", () => {
|
||||
assert.strictEqual(event.content, note)
|
||||
assert.strictEqual(actualSubscriptionId, subscriptionId)
|
||||
done()
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
const subscriptionId = subscriber.subscribe([])
|
||||
@ -45,7 +45,7 @@ describe("text note", () => {
|
||||
created_at: timestamp,
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
|
Reference in New Issue
Block a user