nostr-tools
Advanced tools
Comparing version 1.10.1 to 1.11.1
@@ -8,2 +8,3 @@ export declare enum Kind { | ||
EventDeletion = 5, | ||
Repost = 6, | ||
Reaction = 7, | ||
@@ -16,2 +17,3 @@ BadgeAward = 8, | ||
ChannelMuteUser = 44, | ||
Blank = 255, | ||
Report = 1984, | ||
@@ -26,4 +28,4 @@ ZapRequest = 9734, | ||
} | ||
export type EventTemplate = { | ||
kind: Kind; | ||
export type EventTemplate<K extends number = Kind> = { | ||
kind: K; | ||
tags: string[][]; | ||
@@ -33,15 +35,19 @@ content: string; | ||
}; | ||
export type UnsignedEvent = EventTemplate & { | ||
export type UnsignedEvent<K extends number = Kind> = EventTemplate<K> & { | ||
pubkey: string; | ||
}; | ||
export type Event = UnsignedEvent & { | ||
export type Event<K extends number = Kind> = UnsignedEvent<K> & { | ||
id: string; | ||
sig: string; | ||
}; | ||
export declare function getBlankEvent(): EventTemplate; | ||
export declare function finishEvent(t: EventTemplate, privateKey: string): Event; | ||
export declare function serializeEvent(evt: UnsignedEvent): string; | ||
export declare function getEventHash(event: UnsignedEvent): string; | ||
export declare function validateEvent<T>(event: T): event is T & UnsignedEvent; | ||
export declare function verifySignature(event: Event): boolean; | ||
export declare function signEvent(event: UnsignedEvent, key: string): string; | ||
export declare function getBlankEvent(): EventTemplate<Kind.Blank>; | ||
export declare function getBlankEvent<K extends number>(kind: K): EventTemplate<K>; | ||
export declare function finishEvent<K extends number = Kind>(t: EventTemplate<K>, privateKey: string): Event<K>; | ||
export declare function serializeEvent(evt: UnsignedEvent<number>): string; | ||
export declare function getEventHash(event: UnsignedEvent<number>): string; | ||
export declare function validateEvent<T>(event: T): event is T & UnsignedEvent<number>; | ||
export declare function verifySignature(event: Event<number>): boolean; | ||
/** @deprecated Use `getSignature` instead. */ | ||
export declare function signEvent(event: UnsignedEvent<number>, key: string): string; | ||
/** Calculate the signature for an event. */ | ||
export declare function getSignature(event: UnsignedEvent<number>, key: string): string; |
@@ -1,5 +0,5 @@ | ||
import { Event } from './event'; | ||
export type Filter = { | ||
import { Event, type Kind } from './event.ts'; | ||
export type Filter<K extends number = Kind> = { | ||
ids?: string[]; | ||
kinds?: number[]; | ||
kinds?: K[]; | ||
authors?: string[]; | ||
@@ -12,3 +12,3 @@ since?: number; | ||
}; | ||
export declare function matchFilter(filter: Filter, event: Event): boolean; | ||
export declare function matchFilters(filters: Filter[], event: Event): boolean; | ||
export declare function matchFilter(filter: Filter<number>, event: Event<number>): boolean; | ||
export declare function matchFilters(filters: Filter<number>[], event: Event<number>): boolean; |
@@ -1,20 +0,22 @@ | ||
export * from './keys'; | ||
export * from './relay'; | ||
export * from './event'; | ||
export * from './filter'; | ||
export * from './pool'; | ||
export * from './references'; | ||
export * as nip04 from './nip04'; | ||
export * as nip05 from './nip05'; | ||
export * as nip06 from './nip06'; | ||
export * as nip10 from './nip10'; | ||
export * as nip13 from './nip13'; | ||
export * as nip19 from './nip19'; | ||
export * as nip21 from './nip21'; | ||
export * as nip26 from './nip26'; | ||
export * as nip27 from './nip27'; | ||
export * as nip39 from './nip39'; | ||
export * as nip42 from './nip42'; | ||
export * as nip57 from './nip57'; | ||
export * as fj from './fakejson'; | ||
export * as utils from './utils'; | ||
export * from './keys.ts'; | ||
export * from './relay.ts'; | ||
export * from './event.ts'; | ||
export * from './filter.ts'; | ||
export * from './pool.ts'; | ||
export * from './references.ts'; | ||
export * as nip04 from './nip04.ts'; | ||
export * as nip05 from './nip05.ts'; | ||
export * as nip06 from './nip06.ts'; | ||
export * as nip10 from './nip10.ts'; | ||
export * as nip13 from './nip13.ts'; | ||
export * as nip18 from './nip18.ts'; | ||
export * as nip19 from './nip19.ts'; | ||
export * as nip21 from './nip21.ts'; | ||
export * as nip25 from './nip25.ts'; | ||
export * as nip26 from './nip26.ts'; | ||
export * as nip27 from './nip27.ts'; | ||
export * as nip39 from './nip39.ts'; | ||
export * as nip42 from './nip42.ts'; | ||
export * as nip57 from './nip57.ts'; | ||
export * as fj from './fakejson.ts'; | ||
export * as utils from './utils.ts'; |
@@ -1,2 +0,10 @@ | ||
import { ProfilePointer } from './nip19'; | ||
import { ProfilePointer } from './nip19.ts'; | ||
/** | ||
* NIP-05 regex. The localpart is optional, and should be assumed to be `_` otherwise. | ||
* | ||
* - 0: full match | ||
* - 1: name (optional) | ||
* - 2: domain | ||
*/ | ||
export declare const NIP05_REGEX: RegExp; | ||
export declare function useFetchImplementation(fetchImplementation: any): void; | ||
@@ -7,1 +15,10 @@ export declare function searchDomain(domain: string, query?: string): Promise<{ | ||
export declare function queryProfile(fullname: string): Promise<ProfilePointer | null>; | ||
/** nostr.json result. */ | ||
export interface NIP05Result { | ||
names: { | ||
[name: string]: string; | ||
}; | ||
relays?: { | ||
[pubkey: string]: string[]; | ||
}; | ||
} |
@@ -1,3 +0,3 @@ | ||
import type { Event } from './event'; | ||
import type { EventPointer, ProfilePointer } from './nip19'; | ||
import type { Event } from './event.ts'; | ||
import type { EventPointer, ProfilePointer } from './nip19.ts'; | ||
export type NIP10Result = { | ||
@@ -4,0 +4,0 @@ /** |
@@ -0,1 +1,6 @@ | ||
/** | ||
* Bech32 regex. | ||
* @see https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki#bech32 | ||
*/ | ||
export declare const BECH32_REGEX: RegExp; | ||
export type ProfilePointer = { | ||
@@ -2,0 +7,0 @@ pubkey: string; |
@@ -1,7 +0,2 @@ | ||
import * as nip19 from './nip19'; | ||
/** | ||
* Bech32 regex. | ||
* @see https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki#bech32 | ||
*/ | ||
export declare const BECH32_REGEX: RegExp; | ||
import { type DecodeResult } from './nip19.ts'; | ||
/** Nostr URI regex, eg `nostr:npub1...` */ | ||
@@ -18,5 +13,5 @@ export declare const NOSTR_URI_REGEX: RegExp; | ||
/** Decoded bech32 string, according to NIP-19. */ | ||
decoded: nip19.DecodeResult; | ||
decoded: DecodeResult; | ||
} | ||
/** Parse and decode a Nostr URI. */ | ||
export declare function parse(uri: string): NostrURI; |
@@ -1,7 +0,7 @@ | ||
import { Event } from './event'; | ||
import type { Event } from './event.ts'; | ||
export type Parameters = { | ||
pubkey: string; | ||
kind: number | undefined; | ||
until: number | undefined; | ||
since: number | undefined; | ||
kind?: number; | ||
until?: number; | ||
since?: number; | ||
}; | ||
@@ -15,2 +15,2 @@ export type Delegation = { | ||
export declare function createDelegation(privateKey: string, parameters: Parameters): Delegation; | ||
export declare function getDelegator(event: Event): string | null; | ||
export declare function getDelegator(event: Event<number>): string | null; |
@@ -1,6 +0,6 @@ | ||
import * as nip21 from './nip21'; | ||
import { type NostrURI } from './nip21.ts'; | ||
/** Regex to find NIP-21 URIs inside event content. */ | ||
export declare const regex: () => RegExp; | ||
/** Match result for a Nostr URI in event content. */ | ||
export interface NostrURIMatch extends nip21.NostrURI { | ||
export interface NostrURIMatch extends NostrURI { | ||
/** Index where the URI begins in the event content. */ | ||
@@ -32,2 +32,2 @@ start: number; | ||
*/ | ||
export declare function replaceAll(content: string, replacer: (match: nip21.NostrURI) => string): string; | ||
export declare function replaceAll(content: string, replacer: (match: NostrURI) => string): string; |
@@ -1,3 +0,3 @@ | ||
import { EventTemplate, Event } from './event'; | ||
import { Relay } from './relay'; | ||
import { type EventTemplate, type Event } from './event.ts'; | ||
import { Relay } from './relay.ts'; | ||
/** | ||
@@ -15,3 +15,3 @@ * Authenticate via NIP-42 flow. | ||
relay: Relay; | ||
sign: (e: EventTemplate) => Promise<Event>; | ||
sign: <K extends number = number>(e: EventTemplate<K>) => Event<K> | Promise<Event<K>>; | ||
}) => Promise<void>; |
@@ -1,4 +0,4 @@ | ||
import { Event, EventTemplate } from './event'; | ||
import { Kind, type Event, type EventTemplate } from './event.ts'; | ||
export declare function useFetchImplementation(fetchImplementation: any): void; | ||
export declare function getZapEndpoint(metadata: Event): Promise<null | string>; | ||
export declare function getZapEndpoint(metadata: Event<Kind.Metadata>): Promise<null | string>; | ||
export declare function makeZapRequest({ profile, event, amount, relays, comment }: { | ||
@@ -10,9 +10,9 @@ profile: string; | ||
relays: string[]; | ||
}): EventTemplate; | ||
}): EventTemplate<Kind.ZapRequest>; | ||
export declare function validateZapRequest(zapRequestString: string): string | null; | ||
export declare function makeZapReceipt({ zapRequest, preimage, bolt11, paidAt }: { | ||
zapRequest: string; | ||
preimage: string | null; | ||
preimage?: string; | ||
bolt11: string; | ||
paidAt: Date; | ||
}): EventTemplate; | ||
}): EventTemplate<Kind.Zap>; |
"use strict"; | ||
var __create = Object.create; | ||
var __defProp = Object.defineProperty; | ||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | ||
var __getOwnPropNames = Object.getOwnPropertyNames; | ||
var __getProtoOf = Object.getPrototypeOf; | ||
var __hasOwnProp = Object.prototype.hasOwnProperty; | ||
@@ -20,6 +18,2 @@ var __export = (target, all) => { | ||
}; | ||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( | ||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, | ||
mod | ||
)); | ||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); | ||
@@ -38,2 +32,3 @@ | ||
getPublicKey: () => getPublicKey, | ||
getSignature: () => getSignature, | ||
matchFilter: () => matchFilter, | ||
@@ -46,4 +41,6 @@ matchFilters: () => matchFilters, | ||
nip13: () => nip13_exports, | ||
nip18: () => nip18_exports, | ||
nip19: () => nip19_exports, | ||
nip21: () => nip21_exports, | ||
nip25: () => nip25_exports, | ||
nip26: () => nip26_exports, | ||
@@ -65,13 +62,15 @@ nip27: () => nip27_exports, | ||
// keys.ts | ||
var secp256k1 = __toESM(require("@noble/secp256k1")); | ||
var import_secp256k1 = require("@noble/curves/secp256k1"); | ||
var import_utils = require("@noble/hashes/utils"); | ||
function generatePrivateKey() { | ||
return secp256k1.utils.bytesToHex(secp256k1.utils.randomPrivateKey()); | ||
return (0, import_utils.bytesToHex)(import_secp256k1.schnorr.utils.randomPrivateKey()); | ||
} | ||
function getPublicKey(privateKey) { | ||
return secp256k1.utils.bytesToHex(secp256k1.schnorr.getPublicKey(privateKey)); | ||
return (0, import_utils.bytesToHex)(import_secp256k1.schnorr.getPublicKey(privateKey)); | ||
} | ||
// event.ts | ||
var secp256k12 = __toESM(require("@noble/secp256k1")); | ||
var import_secp256k12 = require("@noble/curves/secp256k1"); | ||
var import_sha256 = require("@noble/hashes/sha256"); | ||
var import_utils2 = require("@noble/hashes/utils"); | ||
@@ -174,29 +173,31 @@ // utils.ts | ||
// event.ts | ||
var Kind = /* @__PURE__ */ ((Kind2) => { | ||
Kind2[Kind2["Metadata"] = 0] = "Metadata"; | ||
Kind2[Kind2["Text"] = 1] = "Text"; | ||
Kind2[Kind2["RecommendRelay"] = 2] = "RecommendRelay"; | ||
Kind2[Kind2["Contacts"] = 3] = "Contacts"; | ||
Kind2[Kind2["EncryptedDirectMessage"] = 4] = "EncryptedDirectMessage"; | ||
Kind2[Kind2["EventDeletion"] = 5] = "EventDeletion"; | ||
Kind2[Kind2["Reaction"] = 7] = "Reaction"; | ||
Kind2[Kind2["BadgeAward"] = 8] = "BadgeAward"; | ||
Kind2[Kind2["ChannelCreation"] = 40] = "ChannelCreation"; | ||
Kind2[Kind2["ChannelMetadata"] = 41] = "ChannelMetadata"; | ||
Kind2[Kind2["ChannelMessage"] = 42] = "ChannelMessage"; | ||
Kind2[Kind2["ChannelHideMessage"] = 43] = "ChannelHideMessage"; | ||
Kind2[Kind2["ChannelMuteUser"] = 44] = "ChannelMuteUser"; | ||
Kind2[Kind2["Report"] = 1984] = "Report"; | ||
Kind2[Kind2["ZapRequest"] = 9734] = "ZapRequest"; | ||
Kind2[Kind2["Zap"] = 9735] = "Zap"; | ||
Kind2[Kind2["RelayList"] = 10002] = "RelayList"; | ||
Kind2[Kind2["ClientAuth"] = 22242] = "ClientAuth"; | ||
Kind2[Kind2["BadgeDefinition"] = 30008] = "BadgeDefinition"; | ||
Kind2[Kind2["ProfileBadge"] = 30009] = "ProfileBadge"; | ||
Kind2[Kind2["Article"] = 30023] = "Article"; | ||
return Kind2; | ||
var Kind = /* @__PURE__ */ ((Kind3) => { | ||
Kind3[Kind3["Metadata"] = 0] = "Metadata"; | ||
Kind3[Kind3["Text"] = 1] = "Text"; | ||
Kind3[Kind3["RecommendRelay"] = 2] = "RecommendRelay"; | ||
Kind3[Kind3["Contacts"] = 3] = "Contacts"; | ||
Kind3[Kind3["EncryptedDirectMessage"] = 4] = "EncryptedDirectMessage"; | ||
Kind3[Kind3["EventDeletion"] = 5] = "EventDeletion"; | ||
Kind3[Kind3["Repost"] = 6] = "Repost"; | ||
Kind3[Kind3["Reaction"] = 7] = "Reaction"; | ||
Kind3[Kind3["BadgeAward"] = 8] = "BadgeAward"; | ||
Kind3[Kind3["ChannelCreation"] = 40] = "ChannelCreation"; | ||
Kind3[Kind3["ChannelMetadata"] = 41] = "ChannelMetadata"; | ||
Kind3[Kind3["ChannelMessage"] = 42] = "ChannelMessage"; | ||
Kind3[Kind3["ChannelHideMessage"] = 43] = "ChannelHideMessage"; | ||
Kind3[Kind3["ChannelMuteUser"] = 44] = "ChannelMuteUser"; | ||
Kind3[Kind3["Blank"] = 255] = "Blank"; | ||
Kind3[Kind3["Report"] = 1984] = "Report"; | ||
Kind3[Kind3["ZapRequest"] = 9734] = "ZapRequest"; | ||
Kind3[Kind3["Zap"] = 9735] = "Zap"; | ||
Kind3[Kind3["RelayList"] = 10002] = "RelayList"; | ||
Kind3[Kind3["ClientAuth"] = 22242] = "ClientAuth"; | ||
Kind3[Kind3["BadgeDefinition"] = 30008] = "BadgeDefinition"; | ||
Kind3[Kind3["ProfileBadge"] = 30009] = "ProfileBadge"; | ||
Kind3[Kind3["Article"] = 30023] = "Article"; | ||
return Kind3; | ||
})(Kind || {}); | ||
function getBlankEvent() { | ||
function getBlankEvent(kind = 255 /* Blank */) { | ||
return { | ||
kind: 255, | ||
kind, | ||
content: "", | ||
@@ -211,3 +212,3 @@ tags: [], | ||
event.id = getEventHash(event); | ||
event.sig = signEvent(event, privateKey); | ||
event.sig = getSignature(event, privateKey); | ||
return event; | ||
@@ -229,3 +230,3 @@ } | ||
let eventHash = (0, import_sha256.sha256)(utf8Encoder.encode(serializeEvent(event))); | ||
return secp256k12.utils.bytesToHex(eventHash); | ||
return (0, import_utils2.bytesToHex)(eventHash); | ||
} | ||
@@ -260,13 +261,17 @@ var isRecord = (obj) => obj instanceof Object; | ||
function verifySignature(event) { | ||
return secp256k12.schnorr.verifySync( | ||
event.sig, | ||
getEventHash(event), | ||
event.pubkey | ||
); | ||
try { | ||
return import_secp256k12.schnorr.verify(event.sig, getEventHash(event), event.pubkey); | ||
} catch (err) { | ||
return false; | ||
} | ||
} | ||
function signEvent(event, key) { | ||
return secp256k12.utils.bytesToHex( | ||
secp256k12.schnorr.signSync(getEventHash(event), key) | ||
console.warn( | ||
"nostr-tools: `signEvent` is deprecated and will be removed or changed in the future. Please use `getSignature` instead." | ||
); | ||
return getSignature(event, key); | ||
} | ||
function getSignature(event, key) { | ||
return (0, import_utils2.bytesToHex)(import_secp256k12.schnorr.sign(getEventHash(event), key)); | ||
} | ||
@@ -816,2 +821,3 @@ // filter.ts | ||
__export(nip19_exports, { | ||
BECH32_REGEX: () => BECH32_REGEX, | ||
decode: () => decode, | ||
@@ -826,5 +832,6 @@ naddrEncode: () => naddrEncode, | ||
}); | ||
var secp256k13 = __toESM(require("@noble/secp256k1")); | ||
var import_utils5 = require("@noble/hashes/utils"); | ||
var import_base = require("@scure/base"); | ||
var Bech32MaxSize = 5e3; | ||
var BECH32_REGEX = /[\x21-\x7E]{1,83}1[023456789acdefghjklmnpqrstuvwxyz]{6,}/; | ||
function decode(nip19) { | ||
@@ -843,3 +850,3 @@ let { prefix, words } = import_base.bech32.decode(nip19, Bech32MaxSize); | ||
data: { | ||
pubkey: secp256k13.utils.bytesToHex(tlv[0][0]), | ||
pubkey: (0, import_utils5.bytesToHex)(tlv[0][0]), | ||
relays: tlv[1] ? tlv[1].map((d) => utf8Decoder.decode(d)) : [] | ||
@@ -860,5 +867,5 @@ } | ||
data: { | ||
id: secp256k13.utils.bytesToHex(tlv[0][0]), | ||
id: (0, import_utils5.bytesToHex)(tlv[0][0]), | ||
relays: tlv[1] ? tlv[1].map((d) => utf8Decoder.decode(d)) : [], | ||
author: tlv[2]?.[0] ? secp256k13.utils.bytesToHex(tlv[2][0]) : void 0 | ||
author: tlv[2]?.[0] ? (0, import_utils5.bytesToHex)(tlv[2][0]) : void 0 | ||
} | ||
@@ -883,4 +890,4 @@ }; | ||
identifier: utf8Decoder.decode(tlv[0][0]), | ||
pubkey: secp256k13.utils.bytesToHex(tlv[2][0]), | ||
kind: parseInt(secp256k13.utils.bytesToHex(tlv[3][0]), 16), | ||
pubkey: (0, import_utils5.bytesToHex)(tlv[2][0]), | ||
kind: parseInt((0, import_utils5.bytesToHex)(tlv[3][0]), 16), | ||
relays: tlv[1] ? tlv[1].map((d) => utf8Decoder.decode(d)) : [] | ||
@@ -902,3 +909,3 @@ } | ||
case "note": | ||
return { type: prefix, data: secp256k13.utils.bytesToHex(data) }; | ||
return { type: prefix, data: (0, import_utils5.bytesToHex)(data) }; | ||
default: | ||
@@ -933,3 +940,3 @@ throw new Error(`unknown prefix ${prefix}`); | ||
function encodeBytes(prefix, hex) { | ||
let data = secp256k13.utils.hexToBytes(hex); | ||
let data = (0, import_utils5.hexToBytes)(hex); | ||
let words = import_base.bech32.toWords(data); | ||
@@ -940,3 +947,3 @@ return import_base.bech32.encode(prefix, words, Bech32MaxSize); | ||
let data = encodeTLV({ | ||
0: [secp256k13.utils.hexToBytes(profile.pubkey)], | ||
0: [(0, import_utils5.hexToBytes)(profile.pubkey)], | ||
1: (profile.relays || []).map((url) => utf8Encoder.encode(url)) | ||
@@ -949,5 +956,5 @@ }); | ||
let data = encodeTLV({ | ||
0: [secp256k13.utils.hexToBytes(event.id)], | ||
0: [(0, import_utils5.hexToBytes)(event.id)], | ||
1: (event.relays || []).map((url) => utf8Encoder.encode(url)), | ||
2: event.author ? [secp256k13.utils.hexToBytes(event.author)] : [] | ||
2: event.author ? [(0, import_utils5.hexToBytes)(event.author)] : [] | ||
}); | ||
@@ -963,3 +970,3 @@ let words = import_base.bech32.toWords(data); | ||
1: (addr.relays || []).map((url) => utf8Encoder.encode(url)), | ||
2: [secp256k13.utils.hexToBytes(addr.pubkey)], | ||
2: [(0, import_utils5.hexToBytes)(addr.pubkey)], | ||
3: [new Uint8Array(kind)] | ||
@@ -988,3 +995,3 @@ }); | ||
}); | ||
return secp256k13.utils.concatBytes(...entries); | ||
return (0, import_utils5.concatBytes)(...entries); | ||
} | ||
@@ -1087,9 +1094,12 @@ | ||
}); | ||
var import_utils4 = require("@noble/hashes/utils"); | ||
var secp256k14 = __toESM(require("@noble/secp256k1")); | ||
var import_utils7 = require("@noble/hashes/utils"); | ||
var import_secp256k13 = require("@noble/curves/secp256k1"); | ||
var import_base2 = require("@scure/base"); | ||
if (typeof crypto !== "undefined" && !crypto.subtle && crypto.webcrypto) { | ||
crypto.subtle = crypto.webcrypto.subtle; | ||
} | ||
async function encrypt(privkey, pubkey, text) { | ||
const key = secp256k14.getSharedSecret(privkey, "02" + pubkey); | ||
const key = import_secp256k13.secp256k1.getSharedSecret(privkey, "02" + pubkey); | ||
const normalizedKey = getNormalizedX(key); | ||
let iv = Uint8Array.from((0, import_utils4.randomBytes)(16)); | ||
let iv = Uint8Array.from((0, import_utils7.randomBytes)(16)); | ||
let plaintext = utf8Encoder.encode(text); | ||
@@ -1114,3 +1124,3 @@ let cryptoKey = await crypto.subtle.importKey( | ||
let [ctb64, ivb64] = data.split("?iv="); | ||
let key = secp256k14.getSharedSecret(privkey, "02" + pubkey); | ||
let key = import_secp256k13.secp256k1.getSharedSecret(privkey, "02" + pubkey); | ||
let normalizedKey = getNormalizedX(key); | ||
@@ -1141,2 +1151,3 @@ let cryptoKey = await crypto.subtle.importKey( | ||
__export(nip05_exports, { | ||
NIP05_REGEX: () => NIP05_REGEX, | ||
queryProfile: () => queryProfile, | ||
@@ -1146,2 +1157,3 @@ searchDomain: () => searchDomain, | ||
}); | ||
var NIP05_REGEX = /^(?:([\w.+-]+)@)?([\w.-]+)$/; | ||
var _fetch; | ||
@@ -1164,25 +1176,33 @@ try { | ||
async function queryProfile(fullname) { | ||
let [name, domain] = fullname.split("@"); | ||
if (!domain) { | ||
domain = name; | ||
name = "_"; | ||
} | ||
if (!name.match(/^[A-Za-z0-9-_.]+$/)) | ||
const match = fullname.match(NIP05_REGEX); | ||
if (!match) | ||
return null; | ||
if (!domain.includes(".")) | ||
return null; | ||
let res; | ||
const [_, name = "_", domain] = match; | ||
try { | ||
res = await (await _fetch(`https://${domain}/.well-known/nostr.json?name=${name}`)).json(); | ||
} catch (err) { | ||
const res = await _fetch(`https://${domain}/.well-known/nostr.json?name=${name}`); | ||
const { names, relays } = parseNIP05Result(await res.json()); | ||
const pubkey = names[name]; | ||
return pubkey ? { pubkey, relays: relays?.[pubkey] } : null; | ||
} catch (_e) { | ||
return null; | ||
} | ||
if (!res?.names?.[name]) | ||
return null; | ||
let pubkey = res.names[name]; | ||
let relays = res.relays?.[pubkey] || []; | ||
return { | ||
pubkey, | ||
relays | ||
} | ||
function parseNIP05Result(json) { | ||
const result = { | ||
names: {} | ||
}; | ||
for (const [name, pubkey] of Object.entries(json.names)) { | ||
if (typeof name === "string" && typeof pubkey === "string") { | ||
result.names[name] = pubkey; | ||
} | ||
} | ||
if (json.relays) { | ||
result.relays = {}; | ||
for (const [pubkey, relays] of Object.entries(json.relays)) { | ||
if (typeof pubkey === "string" && Array.isArray(relays)) { | ||
result.relays[pubkey] = relays.filter((relay) => typeof relay === "string"); | ||
} | ||
} | ||
} | ||
return result; | ||
} | ||
@@ -1197,3 +1217,3 @@ | ||
}); | ||
var secp256k15 = __toESM(require("@noble/secp256k1")); | ||
var import_utils9 = require("@noble/hashes/utils"); | ||
var import_english = require("@scure/bip39/wordlists/english.js"); | ||
@@ -1207,3 +1227,3 @@ var import_bip39 = require("@scure/bip39"); | ||
throw new Error("could not derive private key"); | ||
return secp256k15.utils.bytesToHex(privateKey); | ||
return (0, import_utils9.bytesToHex)(privateKey); | ||
} | ||
@@ -1280,5 +1300,5 @@ function generateSeedWords() { | ||
}); | ||
var secp256k16 = __toESM(require("@noble/secp256k1")); | ||
var import_utils10 = require("@noble/hashes/utils"); | ||
function getPow(id) { | ||
return getLeadingZeroBits(secp256k16.utils.hexToBytes(id)); | ||
return getLeadingZeroBits((0, import_utils10.hexToBytes)(id)); | ||
} | ||
@@ -1307,6 +1327,69 @@ function getLeadingZeroBits(hash) { | ||
// nip18.ts | ||
var nip18_exports = {}; | ||
__export(nip18_exports, { | ||
finishRepostEvent: () => finishRepostEvent, | ||
getRepostedEvent: () => getRepostedEvent, | ||
getRepostedEventPointer: () => getRepostedEventPointer | ||
}); | ||
function finishRepostEvent(t, reposted, relayUrl, privateKey) { | ||
return finishEvent({ | ||
kind: 6 /* Repost */, | ||
tags: [ | ||
...t.tags ?? [], | ||
["e", reposted.id, relayUrl], | ||
["p", reposted.pubkey] | ||
], | ||
content: t.content === "" ? "" : JSON.stringify(reposted), | ||
created_at: t.created_at | ||
}, privateKey); | ||
} | ||
function getRepostedEventPointer(event) { | ||
if (event.kind !== 6 /* Repost */) { | ||
return void 0; | ||
} | ||
let lastETag; | ||
let lastPTag; | ||
for (let i = event.tags.length - 1; i >= 0 && (lastETag === void 0 || lastPTag === void 0); i--) { | ||
const tag = event.tags[i]; | ||
if (tag.length >= 2) { | ||
if (tag[0] === "e" && lastETag === void 0) { | ||
lastETag = tag; | ||
} else if (tag[0] === "p" && lastPTag === void 0) { | ||
lastPTag = tag; | ||
} | ||
} | ||
} | ||
if (lastETag === void 0) { | ||
return void 0; | ||
} | ||
return { | ||
id: lastETag[1], | ||
relays: [lastETag[2], lastPTag?.[2]].filter((x) => typeof x === "string"), | ||
author: lastPTag?.[1] | ||
}; | ||
} | ||
function getRepostedEvent(event, { skipVerification } = {}) { | ||
const pointer = getRepostedEventPointer(event); | ||
if (pointer === void 0 || event.content === "") { | ||
return void 0; | ||
} | ||
let repostedEvent; | ||
try { | ||
repostedEvent = JSON.parse(event.content); | ||
} catch (error) { | ||
return void 0; | ||
} | ||
if (repostedEvent.id !== pointer.id) { | ||
return void 0; | ||
} | ||
if (!skipVerification && !verifySignature(repostedEvent)) { | ||
return void 0; | ||
} | ||
return repostedEvent; | ||
} | ||
// nip21.ts | ||
var nip21_exports = {}; | ||
__export(nip21_exports, { | ||
BECH32_REGEX: () => BECH32_REGEX, | ||
NOSTR_URI_REGEX: () => NOSTR_URI_REGEX, | ||
@@ -1316,3 +1399,2 @@ parse: () => parse2, | ||
}); | ||
var BECH32_REGEX = /[\x21-\x7E]{1,83}1[023456789acdefghjklmnpqrstuvwxyz]{6,}/; | ||
var NOSTR_URI_REGEX = new RegExp(`nostr:(${BECH32_REGEX.source})`); | ||
@@ -1333,2 +1415,50 @@ function test(value) { | ||
// nip25.ts | ||
var nip25_exports = {}; | ||
__export(nip25_exports, { | ||
finishReactionEvent: () => finishReactionEvent, | ||
getReactedEventPointer: () => getReactedEventPointer | ||
}); | ||
function finishReactionEvent(t, reacted, privateKey) { | ||
const inheritedTags = reacted.tags.filter( | ||
(tag) => tag.length >= 2 && (tag[0] === "e" || tag[0] === "p") | ||
); | ||
return finishEvent({ | ||
...t, | ||
kind: 7 /* Reaction */, | ||
tags: [ | ||
...t.tags ?? [], | ||
...inheritedTags, | ||
["e", reacted.id], | ||
["p", reacted.pubkey] | ||
], | ||
content: t.content ?? "+" | ||
}, privateKey); | ||
} | ||
function getReactedEventPointer(event) { | ||
if (event.kind !== 7 /* Reaction */) { | ||
return void 0; | ||
} | ||
let lastETag; | ||
let lastPTag; | ||
for (let i = event.tags.length - 1; i >= 0 && (lastETag === void 0 || lastPTag === void 0); i--) { | ||
const tag = event.tags[i]; | ||
if (tag.length >= 2) { | ||
if (tag[0] === "e" && lastETag === void 0) { | ||
lastETag = tag; | ||
} else if (tag[0] === "p" && lastPTag === void 0) { | ||
lastPTag = tag; | ||
} | ||
} | ||
} | ||
if (lastETag === void 0 || lastPTag === void 0) { | ||
return void 0; | ||
} | ||
return { | ||
id: lastETag[1], | ||
relays: [lastETag[2], lastPTag[2]].filter((x) => x !== void 0), | ||
author: lastPTag[1] | ||
}; | ||
} | ||
// nip26.ts | ||
@@ -1340,3 +1470,4 @@ var nip26_exports = {}; | ||
}); | ||
var secp256k17 = __toESM(require("@noble/secp256k1")); | ||
var import_secp256k14 = require("@noble/curves/secp256k1"); | ||
var import_utils11 = require("@noble/hashes/utils"); | ||
var import_sha2562 = require("@noble/hashes/sha256"); | ||
@@ -1357,4 +1488,4 @@ function createDelegation(privateKey, parameters) { | ||
); | ||
let sig = secp256k17.utils.bytesToHex( | ||
secp256k17.schnorr.signSync(sighash, privateKey) | ||
let sig = (0, import_utils11.bytesToHex)( | ||
import_secp256k14.schnorr.sign(sighash, privateKey) | ||
); | ||
@@ -1390,3 +1521,3 @@ return { | ||
); | ||
if (!secp256k17.schnorr.verifySync(sig, sighash, pubkey)) | ||
if (!import_secp256k14.schnorr.verify(sig, sighash, pubkey)) | ||
return null; | ||
@@ -1598,8 +1729,1 @@ return pubkey; | ||
} | ||
// index.ts | ||
var secp256k18 = __toESM(require("@noble/secp256k1")); | ||
var import_hmac = require("@noble/hashes/hmac"); | ||
var import_sha2563 = require("@noble/hashes/sha256"); | ||
secp256k18.utils.hmacSha256Sync = (key, ...msgs) => (0, import_hmac.hmac)(import_sha2563.sha256, key, secp256k18.utils.concatBytes(...msgs)); | ||
secp256k18.utils.sha256Sync = (...msgs) => (0, import_sha2563.sha256)(secp256k18.utils.concatBytes(...msgs)); |
@@ -1,5 +0,4 @@ | ||
import { Relay } from './relay'; | ||
import { Filter } from './filter'; | ||
import { Event } from './event'; | ||
import { SubscriptionOptions, Sub, Pub } from './relay'; | ||
import { type Pub, type Relay, type Sub, type SubscriptionOptions } from './relay.ts'; | ||
import type { Event } from './event.ts'; | ||
import type { Filter } from './filter.ts'; | ||
export declare class SimplePool { | ||
@@ -16,7 +15,7 @@ private _conn; | ||
ensureRelay(url: string): Promise<Relay>; | ||
sub(relays: string[], filters: Filter[], opts?: SubscriptionOptions): Sub; | ||
get(relays: string[], filter: Filter, opts?: SubscriptionOptions): Promise<Event | null>; | ||
list(relays: string[], filters: Filter[], opts?: SubscriptionOptions): Promise<Event[]>; | ||
publish(relays: string[], event: Event): Pub; | ||
sub<K extends number = number>(relays: string[], filters: Filter<K>[], opts?: SubscriptionOptions): Sub<K>; | ||
get<K extends number = number>(relays: string[], filter: Filter<K>, opts?: SubscriptionOptions): Promise<Event<K> | null>; | ||
list<K extends number = number>(relays: string[], filters: Filter<K>[], opts?: SubscriptionOptions): Promise<Event<K>[]>; | ||
publish(relays: string[], event: Event<number>): Pub; | ||
seenOn(id: string): string[]; | ||
} |
@@ -1,3 +0,3 @@ | ||
import { Event } from './event'; | ||
import { AddressPointer, ProfilePointer, EventPointer } from './nip19'; | ||
import { type AddressPointer, type ProfilePointer, type EventPointer } from './nip19.ts'; | ||
import type { Event } from './event.ts'; | ||
type Reference = { | ||
@@ -4,0 +4,0 @@ text: string; |
@@ -1,3 +0,3 @@ | ||
import { Event } from './event'; | ||
import { Filter } from './filter'; | ||
import { type Event } from './event.ts'; | ||
import { type Filter } from './filter.ts'; | ||
type RelayEvent = { | ||
@@ -13,4 +13,4 @@ connect: () => void | Promise<void>; | ||
}; | ||
type SubEvent = { | ||
event: (event: Event) => void | Promise<void>; | ||
type SubEvent<K extends number> = { | ||
event: (event: Event<K>) => void | Promise<void>; | ||
count: (payload: CountPayload) => void | Promise<void>; | ||
@@ -24,8 +24,8 @@ eose: () => void | Promise<void>; | ||
close: () => void; | ||
sub: (filters: Filter[], opts?: SubscriptionOptions) => Sub; | ||
list: (filters: Filter[], opts?: SubscriptionOptions) => Promise<Event[]>; | ||
get: (filter: Filter, opts?: SubscriptionOptions) => Promise<Event | null>; | ||
sub: <K extends number = number>(filters: Filter<K>[], opts?: SubscriptionOptions) => Sub<K>; | ||
list: <K extends number = number>(filters: Filter<K>[], opts?: SubscriptionOptions) => Promise<Event<K>[]>; | ||
get: <K extends number = number>(filter: Filter<K>, opts?: SubscriptionOptions) => Promise<Event<K> | null>; | ||
count: (filters: Filter[], opts?: SubscriptionOptions) => Promise<CountPayload | null>; | ||
publish: (event: Event) => Pub; | ||
auth: (event: Event) => Pub; | ||
publish: (event: Event<number>) => Pub; | ||
auth: (event: Event<number>) => Pub; | ||
off: <T extends keyof RelayEvent, U extends RelayEvent[T]>(event: T, listener: U) => void; | ||
@@ -38,7 +38,7 @@ on: <T extends keyof RelayEvent, U extends RelayEvent[T]>(event: T, listener: U) => void; | ||
}; | ||
export type Sub = { | ||
sub: (filters: Filter[], opts: SubscriptionOptions) => Sub; | ||
export type Sub<K extends number = number> = { | ||
sub: <K extends number = number>(filters: Filter<K>[], opts: SubscriptionOptions) => Sub<K>; | ||
unsub: () => void; | ||
on: <T extends keyof SubEvent, U extends SubEvent[T]>(event: T, listener: U) => void; | ||
off: <T extends keyof SubEvent, U extends SubEvent[T]>(event: T, listener: U) => void; | ||
on: <T extends keyof SubEvent<K>, U extends SubEvent<K>[T]>(event: T, listener: U) => void; | ||
off: <T extends keyof SubEvent<K>, U extends SubEvent<K>[T]>(event: T, listener: U) => void; | ||
}; | ||
@@ -45,0 +45,0 @@ export type SubscriptionOptions = { |
@@ -1,6 +0,6 @@ | ||
import { Event } from './event'; | ||
import type { Event } from './event.ts'; | ||
export declare const utf8Decoder: TextDecoder; | ||
export declare const utf8Encoder: TextEncoder; | ||
export declare function normalizeURL(url: string): string; | ||
export declare function insertEventIntoDescendingList(sortedArray: Event[], event: Event): Event[]; | ||
export declare function insertEventIntoAscendingList(sortedArray: Event[], event: Event): Event[]; | ||
export declare function insertEventIntoDescendingList(sortedArray: Event<number>[], event: Event<number>): Event<number>[]; | ||
export declare function insertEventIntoAscendingList(sortedArray: Event<number>[], event: Event<number>): Event<number>[]; |
{ | ||
"name": "nostr-tools", | ||
"version": "1.10.1", | ||
"version": "1.11.1", | ||
"description": "Tools for making a Nostr client.", | ||
@@ -17,11 +17,12 @@ "repository": { | ||
"import": "./lib/esm/nostr.mjs", | ||
"require": "./lib/nostr.cjs.js" | ||
"require": "./lib/nostr.cjs.js", | ||
"types": "./lib/index.d.ts" | ||
}, | ||
"license": "Unlicense", | ||
"dependencies": { | ||
"@noble/hashes": "1.2.0", | ||
"@noble/secp256k1": "1.7.1", | ||
"@noble/curves": "1.0.0", | ||
"@noble/hashes": "1.3.0", | ||
"@scure/base": "1.1.1", | ||
"@scure/bip32": "1.1.4", | ||
"@scure/bip39": "1.1.1" | ||
"@scure/bip32": "1.3.0", | ||
"@scure/bip39": "1.2.0" | ||
}, | ||
@@ -38,6 +39,8 @@ "keywords": [ | ||
"format": "prettier --plugin-search-dir . --write .", | ||
"test": "node build && jest" | ||
"test": "jest" | ||
}, | ||
"devDependencies": { | ||
"@types/jest": "^29.5.1", | ||
"@types/node": "^18.13.0", | ||
"@types/node-fetch": "^2.6.3", | ||
"@typescript-eslint/eslint-plugin": "^5.51.0", | ||
@@ -47,14 +50,15 @@ "@typescript-eslint/parser": "^5.51.0", | ||
"esbuild-plugin-alias": "^0.2.1", | ||
"eslint": "^8.33.0", | ||
"eslint": "^8.40.0", | ||
"eslint-plugin-babel": "^5.3.1", | ||
"eslint-plugin-jest": "^27.2.1", | ||
"esm-loader-typescript": "^1.0.3", | ||
"events": "^3.3.0", | ||
"jest": "^29.4.2", | ||
"jest": "^29.5.0", | ||
"node-fetch": "^2.6.9", | ||
"prettier": "^2.8.4", | ||
"ts-jest": "^29.0.5", | ||
"ts-jest": "^29.1.0", | ||
"tsd": "^0.22.0", | ||
"typescript": "^4.9.5", | ||
"typescript": "^5.0.4", | ||
"websocket-polyfill": "^0.0.3" | ||
} | ||
} |
@@ -30,3 +30,3 @@ # nostr-tools | ||
verifySignature, | ||
signEvent, | ||
getSignature, | ||
getEventHash, | ||
@@ -45,3 +45,3 @@ getPublicKey | ||
event.id = getEventHash(event) | ||
event.sig = signEvent(event, privateKey) | ||
event.sig = getSignature(event, privateKey) | ||
@@ -60,3 +60,3 @@ let ok = validateEvent(event) | ||
getEventHash, | ||
signEvent | ||
getSignature | ||
} from 'nostr-tools' | ||
@@ -110,3 +110,3 @@ | ||
event.id = getEventHash(event) | ||
event.sig = signEvent(event, sk) | ||
event.sig = getSignature(event, sk) | ||
@@ -273,3 +273,3 @@ let pub = relay.publish(event) | ||
sub.on('event', event => { | ||
let sender = event.tags.find(([k, v]) => k === 'p' && v && v !== '')[1] | ||
let sender = event.pubkey | ||
pk1 === sender | ||
@@ -276,0 +276,0 @@ let plaintext = await nip04.decrypt(sk2, pk1, event.content) |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1005746
56
12248
19
+ Added@noble/curves@1.0.0
+ Added@noble/curves@1.0.0(transitive)
+ Added@noble/hashes@1.3.0(transitive)
+ Added@scure/bip32@1.3.0(transitive)
+ Added@scure/bip39@1.2.0(transitive)
- Removed@noble/secp256k1@1.7.1
- Removed@noble/hashes@1.2.0(transitive)
- Removed@noble/secp256k1@1.7.1(transitive)
- Removed@scure/bip32@1.1.4(transitive)
- Removed@scure/bip39@1.1.1(transitive)
Updated@noble/hashes@1.3.0
Updated@scure/bip32@1.3.0
Updated@scure/bip39@1.2.0