change tests and nips to use the new api.
This commit is contained in:
parent
1908e1ee0d
commit
fe87529646
33
README.md
33
README.md
|
@ -19,36 +19,31 @@ If using TypeScript, this package requires TypeScript >= 5.0.
|
|||
### Generating a private key and a public key
|
||||
|
||||
```js
|
||||
import { generatePrivateKey, getPublicKey } from 'nostr-tools'
|
||||
import { generateSecretKey, getPublicKey } from 'nostr-tools'
|
||||
|
||||
let sk = generatePrivateKey() // `sk` is a hex string
|
||||
let sk = generateSecretKey() // `sk` is a hex string
|
||||
let pk = getPublicKey(sk) // `pk` is a hex string
|
||||
```
|
||||
|
||||
### Creating, signing and verifying events
|
||||
|
||||
```js
|
||||
import { validateEvent, verifySignature, getSignature, getEventHash, getPublicKey } from 'nostr-tools'
|
||||
import { finalizeEvent, verifyEvent } from 'nostr-tools'
|
||||
|
||||
let event = {
|
||||
let event = finalizeEvent({
|
||||
kind: 1,
|
||||
created_at: Math.floor(Date.now() / 1000),
|
||||
tags: [],
|
||||
content: 'hello',
|
||||
pubkey: getPublicKey(privateKey),
|
||||
}
|
||||
}, privateKey)
|
||||
|
||||
event.id = getEventHash(event)
|
||||
event.sig = getSignature(event, privateKey)
|
||||
|
||||
let ok = validateEvent(event)
|
||||
let veryOk = verifySignature(event)
|
||||
let isGood = verifyEvent(event)
|
||||
```
|
||||
|
||||
### Interacting with a relay
|
||||
|
||||
```js
|
||||
import { relayConnect, finishEvent, generatePrivateKey, getPublicKey } from 'nostr-tools'
|
||||
import { relayConnect, finalizeEvent, generateSecretKey, getPublicKey } from 'nostr-tools'
|
||||
|
||||
const relay = await relayConnect('wss://relay.example.com')
|
||||
console.log(`connected to ${relay.url}`)
|
||||
|
@ -68,7 +63,7 @@ const sub = relay.subscribe([
|
|||
})
|
||||
|
||||
// let's publish a new event while simultaneously monitoring the relay for it
|
||||
let sk = generatePrivateKey()
|
||||
let sk = generateSecretKey()
|
||||
let pk = getPublicKey(sk)
|
||||
|
||||
let sub = relay.sub([
|
||||
|
@ -90,7 +85,7 @@ let event = {
|
|||
}
|
||||
|
||||
// this assigns the pubkey, calculates the event id and signs the event in a single step
|
||||
const signedEvent = finishEvent(event, sk)
|
||||
const signedEvent = finalizeEvent(event, sk)
|
||||
await relay.publish(signedEvent)
|
||||
|
||||
let events = await relay.list([{ kinds: [0, 1] }])
|
||||
|
@ -184,21 +179,21 @@ nip05.useFetchImplementation(require('node-fetch'))
|
|||
### Encoding and decoding NIP-19 codes
|
||||
|
||||
```js
|
||||
import { nip19, generatePrivateKey, getPublicKey } from 'nostr-tools'
|
||||
import { nip19, generateSecretKey, getPublicKey } from 'nostr-tools'
|
||||
|
||||
let sk = generatePrivateKey()
|
||||
let sk = generateSecretKey()
|
||||
let nsec = nip19.nsecEncode(sk)
|
||||
let { type, data } = nip19.decode(nsec)
|
||||
assert(type === 'nsec')
|
||||
assert(data === sk)
|
||||
|
||||
let pk = getPublicKey(generatePrivateKey())
|
||||
let pk = getPublicKey(generateSecretKey())
|
||||
let npub = nip19.npubEncode(pk)
|
||||
let { type, data } = nip19.decode(npub)
|
||||
assert(type === 'npub')
|
||||
assert(data === pk)
|
||||
|
||||
let pk = getPublicKey(generatePrivateKey())
|
||||
let pk = getPublicKey(generateSecretKey())
|
||||
let relays = ['wss://relay.nostr.example.mydomain.example.com', 'wss://nostr.banana.com']
|
||||
let nprofile = nip19.nprofileEncode({ pubkey: pk, relays })
|
||||
let { type, data } = nip19.decode(nprofile)
|
||||
|
@ -212,7 +207,7 @@ assert(data.relays.length === 2)
|
|||
```html
|
||||
<script src="https://unpkg.com/nostr-tools/lib/nostr.bundle.js"></script>
|
||||
<script>
|
||||
window.NostrTools.generatePrivateKey('...') // and so on
|
||||
window.NostrTools.generateSecretKey('...') // and so on
|
||||
</script>
|
||||
```
|
||||
|
||||
|
|
|
@ -11,10 +11,10 @@ import {
|
|||
generateSecretKey,
|
||||
} from './pure.ts'
|
||||
import { ShortTextNote } from './kinds.ts'
|
||||
import { hexToBytes } from '@noble/hashes/utils'
|
||||
import { bytesToHex, hexToBytes } from '@noble/hashes/utils'
|
||||
|
||||
test('private key generation', () => {
|
||||
expect(generateSecretKey()).toMatch(/[a-f0-9]{64}/)
|
||||
expect(bytesToHex(generateSecretKey())).toMatch(/[a-f0-9]{64}/)
|
||||
})
|
||||
|
||||
test('public key generation', () => {
|
||||
|
@ -30,7 +30,7 @@ test('public key from private key deterministic', () => {
|
|||
}
|
||||
})
|
||||
|
||||
describe('finishEvent', () => {
|
||||
describe('finalizeEvent', () => {
|
||||
test('should create a signed event from a template', () => {
|
||||
const privateKey = hexToBytes('d217c1ff2f8a65c3e3a1740db3b9f58b8c848bb45e26d00ed4714e4a0f4ceecf')
|
||||
const publicKey = getPublicKey(privateKey)
|
||||
|
@ -211,7 +211,7 @@ describe('validateEvent', () => {
|
|||
})
|
||||
})
|
||||
|
||||
describe('verifySignature', () => {
|
||||
describe('verifyEvent', () => {
|
||||
test('should return true for a valid event signature', () => {
|
||||
const privateKey = hexToBytes('d217c1ff2f8a65c3e3a1740db3b9f58b8c848bb45e26d00ed4714e4a0f4ceecf')
|
||||
const event = finalizeEvent(
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Event } from './event.ts'
|
||||
import { Event } from './pure.ts'
|
||||
|
||||
export type Filter = {
|
||||
ids?: string[]
|
||||
|
|
4
index.ts
4
index.ts
|
@ -1,6 +1,6 @@
|
|||
export * from './keys.ts'
|
||||
export * from './pure.ts'
|
||||
export * from './relay.ts'
|
||||
export * from './event.ts'
|
||||
export * from './pure.ts'
|
||||
export * from './filter.ts'
|
||||
export * from './pool.ts'
|
||||
export * from './references.ts'
|
||||
|
|
|
@ -2,7 +2,8 @@ import { test, expect } from 'bun:test'
|
|||
import crypto from 'node:crypto'
|
||||
|
||||
import { encrypt, decrypt } from './nip04.ts'
|
||||
import { getPublicKey, generatePrivateKey } from './keys.ts'
|
||||
import { getPublicKey, generateSecretKey } from './pure.ts'
|
||||
import { bytesToHex, hexToBytes } from '@noble/hashes/utils'
|
||||
|
||||
try {
|
||||
// @ts-ignore
|
||||
|
@ -13,20 +14,20 @@ try {
|
|||
}
|
||||
|
||||
test('encrypt and decrypt message', async () => {
|
||||
let sk1 = generatePrivateKey()
|
||||
let sk2 = generatePrivateKey()
|
||||
let sk1 = generateSecretKey()
|
||||
let sk2 = generateSecretKey()
|
||||
let pk1 = getPublicKey(sk1)
|
||||
let pk2 = getPublicKey(sk2)
|
||||
|
||||
let ciphertext = await encrypt(sk1, pk2, 'hello')
|
||||
let ciphertext = await encrypt(bytesToHex(sk1), pk2, 'hello')
|
||||
|
||||
expect(await decrypt(sk2, pk1, ciphertext)).toEqual('hello')
|
||||
expect(await decrypt(bytesToHex(sk2), pk1, ciphertext)).toEqual('hello')
|
||||
})
|
||||
|
||||
test('decrypt message from go-nostr', async () => {
|
||||
let sk1 = '91ba716fa9e7ea2fcbad360cf4f8e0d312f73984da63d90f524ad61a6a1e7dbe'
|
||||
let sk2 = '96f6fa197aa07477ab88f6981118466ae3a982faab8ad5db9d5426870c73d220'
|
||||
let pk1 = getPublicKey(sk1)
|
||||
let pk1 = getPublicKey(hexToBytes(sk1))
|
||||
|
||||
let ciphertext = 'zJxfaJ32rN5Dg1ODjOlEew==?iv=EV5bUjcc4OX2Km/zPp4ndQ=='
|
||||
|
||||
|
@ -36,7 +37,7 @@ test('decrypt message from go-nostr', async () => {
|
|||
test('decrypt big payload from go-nostr', async () => {
|
||||
let sk1 = '91ba716fa9e7ea2fcbad360cf4f8e0d312f73984da63d90f524ad61a6a1e7dbe'
|
||||
let sk2 = '96f6fa197aa07477ab88f6981118466ae3a982faab8ad5db9d5426870c73d220'
|
||||
let pk1 = getPublicKey(sk1)
|
||||
let pk1 = getPublicKey(hexToBytes(sk1))
|
||||
|
||||
let ciphertext =
|
||||
'6f8dMstm+udOu7yipSn33orTmwQpWbtfuY95NH+eTU1kArysWJIDkYgI2D25EAGIDJsNd45jOJ2NbVOhFiL3ZP/NWsTwXokk34iyHyA/lkjzugQ1bHXoMD1fP/Ay4hB4al1NHb8HXHKZaxPrErwdRDb8qa/I6dXb/1xxyVvNQBHHvmsM5yIFaPwnCN1DZqXf2KbTA/Ekz7Hy+7R+Sy3TXLQDFpWYqykppkXc7Fs0qSuPRyxz5+anuN0dxZa9GTwTEnBrZPbthKkNRrvZMdTGJ6WumOh9aUq8OJJWy9aOgsXvs7qjN1UqcCqQqYaVnEOhCaqWNDsVtsFrVDj+SaLIBvCiomwF4C4nIgngJ5I69tx0UNI0q+ZnvOGQZ7m1PpW2NYP7Yw43HJNdeUEQAmdCPnh/PJwzLTnIxHmQU7n7SPlMdV0SFa6H8y2HHvex697GAkyE5t8c2uO24OnqIwF1tR3blIqXzTSRl0GA6QvrSj2p4UtnWjvF7xT7RiIEyTtgU/AsihTrXyXzWWZaIBJogpgw6erlZqWjCH7sZy/WoGYEiblobOAqMYxax6vRbeuGtoYksr/myX+x9rfLrYuoDRTw4woXOLmMrrj+Mf0TbAgc3SjdkqdsPU1553rlSqIEZXuFgoWmxvVQDtekgTYyS97G81TDSK9nTJT5ilku8NVq2LgtBXGwsNIw/xekcOUzJke3kpnFPutNaexR1VF3ohIuqRKYRGcd8ADJP2lfwMcaGRiplAmFoaVS1YUhQwYFNq9rMLf7YauRGV4BJg/t9srdGxf5RoKCvRo+XM/nLxxysTR9MVaEP/3lDqjwChMxs+eWfLHE5vRWV8hUEqdrWNZV29gsx5nQpzJ4PARGZVu310pQzc6JAlc2XAhhFk6RamkYJnmCSMnb/RblzIATBi2kNrCVAlaXIon188inB62rEpZGPkRIP7PUfu27S/elLQHBHeGDsxOXsBRo1gl3te+raoBHsxo6zvRnYbwdAQa5taDE63eh+fT6kFI+xYmXNAQkU8Dp0MVhEh4JQI06Ni/AKrvYpC95TXXIphZcF+/Pv/vaGkhG2X9S3uhugwWK?iv=2vWkOQQi0WynNJz/aZ4k2g=='
|
||||
|
|
8
nip04.ts
8
nip04.ts
|
@ -1,4 +1,4 @@
|
|||
import { randomBytes } from '@noble/hashes/utils'
|
||||
import { bytesToHex, randomBytes } from '@noble/hashes/utils'
|
||||
import { secp256k1 } from '@noble/curves/secp256k1'
|
||||
import { base64 } from '@scure/base'
|
||||
|
||||
|
@ -10,7 +10,8 @@ if (typeof crypto !== 'undefined' && !crypto.subtle && crypto.webcrypto) {
|
|||
crypto.subtle = crypto.webcrypto.subtle
|
||||
}
|
||||
|
||||
export async function encrypt(privkey: string, pubkey: string, text: string): Promise<string> {
|
||||
export async function encrypt(secretKey: string | Uint8Array, pubkey: string, text: string): Promise<string> {
|
||||
const privkey: string = secretKey instanceof Uint8Array ? bytesToHex(secretKey) : secretKey
|
||||
const key = secp256k1.getSharedSecret(privkey, '02' + pubkey)
|
||||
const normalizedKey = getNormalizedX(key)
|
||||
|
||||
|
@ -24,7 +25,8 @@ export async function encrypt(privkey: string, pubkey: string, text: string): Pr
|
|||
return `${ctb64}?iv=${ivb64}`
|
||||
}
|
||||
|
||||
export async function decrypt(privkey: string, pubkey: string, data: string): Promise<string> {
|
||||
export async function decrypt(secretKey: string | Uint8Array, pubkey: string, data: string): Promise<string> {
|
||||
const privkey: string = secretKey instanceof Uint8Array ? bytesToHex(secretKey) : secretKey
|
||||
let [ctb64, ivb64] = data.split('?iv=')
|
||||
let key = secp256k1.getSharedSecret(privkey, '02' + pubkey)
|
||||
let normalizedKey = getNormalizedX(key)
|
||||
|
|
2
nip10.ts
2
nip10.ts
|
@ -1,4 +1,4 @@
|
|||
import type { Event } from './event.ts'
|
||||
import type { Event } from './pure.ts'
|
||||
import type { EventPointer, ProfilePointer } from './nip19.ts'
|
||||
|
||||
export type NIP10Result = {
|
||||
|
|
2
nip13.ts
2
nip13.ts
|
@ -1,4 +1,4 @@
|
|||
import { type UnsignedEvent, type Event, getEventHash } from './event.ts'
|
||||
import { type UnsignedEvent, type Event, getEventHash } from './pure.ts'
|
||||
|
||||
/** Get POW difficulty from a Nostr hex ID. */
|
||||
export function getPow(hex: string): number {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { describe, test, expect } from 'bun:test'
|
||||
import { finishEvent } from './event.ts'
|
||||
import { getPublicKey } from './keys.ts'
|
||||
import { hexToBytes } from '@noble/hashes/utils'
|
||||
import { finalizeEvent, getPublicKey } from './pure.ts'
|
||||
import { Repost, ShortTextNote } from './kinds.ts'
|
||||
import { finishRepostEvent, getRepostedEventPointer, getRepostedEvent } from './nip18.ts'
|
||||
import { buildEvent } from './test-helpers.ts'
|
||||
|
@ -8,11 +8,10 @@ import { buildEvent } from './test-helpers.ts'
|
|||
const relayUrl = 'https://relay.example.com'
|
||||
|
||||
describe('finishRepostEvent + getRepostedEventPointer + getRepostedEvent', () => {
|
||||
const privateKey = 'd217c1ff2f8a65c3e3a1740db3b9f58b8c848bb45e26d00ed4714e4a0f4ceecf'
|
||||
|
||||
const privateKey = hexToBytes('d217c1ff2f8a65c3e3a1740db3b9f58b8c848bb45e26d00ed4714e4a0f4ceecf')
|
||||
const publicKey = getPublicKey(privateKey)
|
||||
|
||||
const repostedEvent = finishEvent(
|
||||
const repostedEvent = finalizeEvent(
|
||||
{
|
||||
kind: ShortTextNote,
|
||||
tags: [
|
||||
|
|
8
nip18.ts
8
nip18.ts
|
@ -1,4 +1,4 @@
|
|||
import { Event, finishEvent, verifySignature } from './event.ts'
|
||||
import { Event, finalizeEvent, verifyEvent } from './pure.ts'
|
||||
import { Repost } from './kinds.ts'
|
||||
import { EventPointer } from './nip19.ts'
|
||||
|
||||
|
@ -23,9 +23,9 @@ export function finishRepostEvent(
|
|||
t: RepostEventTemplate,
|
||||
reposted: Event,
|
||||
relayUrl: string,
|
||||
privateKey: string,
|
||||
privateKey: Uint8Array,
|
||||
): Event {
|
||||
return finishEvent(
|
||||
return finalizeEvent(
|
||||
{
|
||||
kind: Repost,
|
||||
tags: [...(t.tags ?? []), ['e', reposted.id, relayUrl], ['p', reposted.pubkey]],
|
||||
|
@ -89,7 +89,7 @@ export function getRepostedEvent(event: Event, { skipVerification }: GetReposted
|
|||
return undefined
|
||||
}
|
||||
|
||||
if (!skipVerification && !verifySignature(repostedEvent)) {
|
||||
if (!skipVerification && !verifyEvent(repostedEvent)) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { test, expect } from 'bun:test'
|
||||
import { generatePrivateKey, getPublicKey } from './keys.ts'
|
||||
import { generateSecretKey, getPublicKey } from './pure.ts'
|
||||
import {
|
||||
decode,
|
||||
naddrEncode,
|
||||
|
@ -14,7 +14,7 @@ import {
|
|||
} from './nip19.ts'
|
||||
|
||||
test('encode and decode nsec', () => {
|
||||
let sk = generatePrivateKey()
|
||||
let sk = generateSecretKey()
|
||||
let nsec = nsecEncode(sk)
|
||||
expect(nsec).toMatch(/nsec1\w+/)
|
||||
let { type, data } = decode(nsec)
|
||||
|
@ -23,7 +23,7 @@ test('encode and decode nsec', () => {
|
|||
})
|
||||
|
||||
test('encode and decode npub', () => {
|
||||
let pk = getPublicKey(generatePrivateKey())
|
||||
let pk = getPublicKey(generateSecretKey())
|
||||
let npub = npubEncode(pk)
|
||||
expect(npub).toMatch(/npub1\w+/)
|
||||
let { type, data } = decode(npub)
|
||||
|
@ -32,7 +32,7 @@ test('encode and decode npub', () => {
|
|||
})
|
||||
|
||||
test('encode and decode nprofile', () => {
|
||||
let pk = getPublicKey(generatePrivateKey())
|
||||
let pk = getPublicKey(generateSecretKey())
|
||||
let relays = ['wss://relay.nostr.example.mydomain.example.com', 'wss://nostr.banana.com']
|
||||
let nprofile = nprofileEncode({ pubkey: pk, relays })
|
||||
expect(nprofile).toMatch(/nprofile1\w+/)
|
||||
|
@ -56,7 +56,7 @@ test('decode nprofile without relays', () => {
|
|||
})
|
||||
|
||||
test('encode and decode naddr', () => {
|
||||
let pk = getPublicKey(generatePrivateKey())
|
||||
let pk = getPublicKey(generateSecretKey())
|
||||
let relays = ['wss://relay.nostr.example.mydomain.example.com', 'wss://nostr.banana.com']
|
||||
let naddr = naddrEncode({
|
||||
pubkey: pk,
|
||||
|
@ -76,7 +76,7 @@ test('encode and decode naddr', () => {
|
|||
})
|
||||
|
||||
test('encode and decode nevent', () => {
|
||||
let pk = getPublicKey(generatePrivateKey())
|
||||
let pk = getPublicKey(generateSecretKey())
|
||||
let relays = ['wss://relay.nostr.example.mydomain.example.com', 'wss://nostr.banana.com']
|
||||
let naddr = neventEncode({
|
||||
id: pk,
|
||||
|
@ -93,7 +93,7 @@ test('encode and decode nevent', () => {
|
|||
})
|
||||
|
||||
test('encode and decode nevent with kind 0', () => {
|
||||
let pk = getPublicKey(generatePrivateKey())
|
||||
let pk = getPublicKey(generateSecretKey())
|
||||
let relays = ['wss://relay.nostr.example.mydomain.example.com', 'wss://nostr.banana.com']
|
||||
let naddr = neventEncode({
|
||||
id: pk,
|
||||
|
|
17
nip19.ts
17
nip19.ts
|
@ -48,7 +48,7 @@ type Prefixes = {
|
|||
nrelay: string
|
||||
nevent: EventPointer
|
||||
naddr: AddressPointer
|
||||
nsec: string
|
||||
nsec: Uint8Array
|
||||
npub: string
|
||||
note: string
|
||||
}
|
||||
|
@ -130,6 +130,8 @@ export function decode(nip19: string): DecodeResult {
|
|||
}
|
||||
|
||||
case 'nsec':
|
||||
return { type: prefix, data }
|
||||
|
||||
case 'npub':
|
||||
case 'note':
|
||||
return { type: prefix, data: bytesToHex(data) }
|
||||
|
@ -157,16 +159,16 @@ function parseTLV(data: Uint8Array): TLV {
|
|||
return result
|
||||
}
|
||||
|
||||
export function nsecEncode(hex: string): `nsec1${string}` {
|
||||
return encodeBytes('nsec', hex)
|
||||
export function nsecEncode(key: Uint8Array): `nsec1${string}` {
|
||||
return encodeBytes('nsec', key)
|
||||
}
|
||||
|
||||
export function npubEncode(hex: string): `npub1${string}` {
|
||||
return encodeBytes('npub', hex)
|
||||
return encodeBytes('npub', hexToBytes(hex))
|
||||
}
|
||||
|
||||
export function noteEncode(hex: string): `note1${string}` {
|
||||
return encodeBytes('note', hex)
|
||||
return encodeBytes('note', hexToBytes(hex))
|
||||
}
|
||||
|
||||
function encodeBech32<Prefix extends string>(prefix: Prefix, data: Uint8Array): `${Prefix}1${string}` {
|
||||
|
@ -174,9 +176,8 @@ function encodeBech32<Prefix extends string>(prefix: Prefix, data: Uint8Array):
|
|||
return bech32.encode(prefix, words, Bech32MaxSize) as `${Prefix}1${string}`
|
||||
}
|
||||
|
||||
function encodeBytes<Prefix extends string>(prefix: Prefix, hex: string): `${Prefix}1${string}` {
|
||||
let data = hexToBytes(hex)
|
||||
return encodeBech32(prefix, data)
|
||||
function encodeBytes<Prefix extends string>(prefix: Prefix, bytes: Uint8Array): `${Prefix}1${string}` {
|
||||
return encodeBech32(prefix, bytes)
|
||||
}
|
||||
|
||||
export function nprofileEncode(profile: ProfilePointer): `nprofile1${string}` {
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
import { describe, test, expect } from 'bun:test'
|
||||
import { finishEvent } from './event.ts'
|
||||
import { getPublicKey } from './keys.ts'
|
||||
import { hexToBytes } from '@noble/hashes/utils'
|
||||
import { finalizeEvent, getPublicKey } from './pure.ts'
|
||||
import { Reaction, ShortTextNote } from './kinds.ts'
|
||||
import { finishReactionEvent, getReactedEventPointer } from './nip25.ts'
|
||||
|
||||
describe('finishReactionEvent + getReactedEventPointer', () => {
|
||||
const privateKey = 'd217c1ff2f8a65c3e3a1740db3b9f58b8c848bb45e26d00ed4714e4a0f4ceecf'
|
||||
|
||||
const privateKey = hexToBytes('d217c1ff2f8a65c3e3a1740db3b9f58b8c848bb45e26d00ed4714e4a0f4ceecf')
|
||||
const publicKey = getPublicKey(privateKey)
|
||||
|
||||
const reactedEvent = finishEvent(
|
||||
const reactedEvent = finalizeEvent(
|
||||
{
|
||||
kind: ShortTextNote,
|
||||
tags: [
|
||||
|
|
6
nip25.ts
6
nip25.ts
|
@ -1,4 +1,4 @@
|
|||
import { Event, finishEvent } from './event.ts'
|
||||
import { Event, finalizeEvent } from './pure.ts'
|
||||
import { Reaction } from './kinds.ts'
|
||||
|
||||
import type { EventPointer } from './nip19.ts'
|
||||
|
@ -17,10 +17,10 @@ export type ReactionEventTemplate = {
|
|||
created_at: number
|
||||
}
|
||||
|
||||
export function finishReactionEvent(t: ReactionEventTemplate, reacted: Event, privateKey: string): Event {
|
||||
export function finishReactionEvent(t: ReactionEventTemplate, reacted: Event, privateKey: Uint8Array): Event {
|
||||
const inheritedTags = reacted.tags.filter(tag => tag.length >= 2 && (tag[0] === 'e' || tag[0] === 'p'))
|
||||
|
||||
return finishEvent(
|
||||
return finalizeEvent(
|
||||
{
|
||||
...t,
|
||||
kind: Reaction,
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { describe, test, expect } from 'bun:test'
|
||||
import { getPublicKey } from './keys.ts'
|
||||
import { hexToBytes } from '@noble/hashes/utils'
|
||||
import { getPublicKey } from './pure.ts'
|
||||
import * as Kind from './kinds.ts'
|
||||
import {
|
||||
channelCreateEvent,
|
||||
|
@ -11,7 +12,7 @@ import {
|
|||
ChannelMessageEventTemplate,
|
||||
} from './nip28.ts'
|
||||
|
||||
const privateKey = 'd217c1ff2f8a65c3e3a1740db3b9f58b8c848bb45e26d00ed4714e4a0f4ceecf'
|
||||
const privateKey = hexToBytes('d217c1ff2f8a65c3e3a1740db3b9f58b8c848bb45e26d00ed4714e4a0f4ceecf')
|
||||
const publicKey = getPublicKey(privateKey)
|
||||
|
||||
describe('NIP-28 Functions', () => {
|
||||
|
|
25
nip28.ts
25
nip28.ts
|
@ -1,4 +1,4 @@
|
|||
import { Event, finishEvent } from './event.ts'
|
||||
import { Event, finalizeEvent } from './pure.ts'
|
||||
import { ChannelCreation, ChannelHideMessage, ChannelMessage, ChannelMetadata, ChannelMuteUser } from './kinds.ts'
|
||||
|
||||
export interface ChannelMetadata {
|
||||
|
@ -45,7 +45,7 @@ export interface ChannelMuteUserEventTemplate {
|
|||
tags?: string[][]
|
||||
}
|
||||
|
||||
export const channelCreateEvent = (t: ChannelCreateEventTemplate, privateKey: string): Event | undefined => {
|
||||
export const channelCreateEvent = (t: ChannelCreateEventTemplate, privateKey: Uint8Array): Event | undefined => {
|
||||
let content: string
|
||||
if (typeof t.content === 'object') {
|
||||
content = JSON.stringify(t.content)
|
||||
|
@ -55,7 +55,7 @@ export const channelCreateEvent = (t: ChannelCreateEventTemplate, privateKey: st
|
|||
return undefined
|
||||
}
|
||||
|
||||
return finishEvent(
|
||||
return finalizeEvent(
|
||||
{
|
||||
kind: ChannelCreation,
|
||||
tags: [...(t.tags ?? [])],
|
||||
|
@ -66,7 +66,7 @@ export const channelCreateEvent = (t: ChannelCreateEventTemplate, privateKey: st
|
|||
)
|
||||
}
|
||||
|
||||
export const channelMetadataEvent = (t: ChannelMetadataEventTemplate, privateKey: string): Event | undefined => {
|
||||
export const channelMetadataEvent = (t: ChannelMetadataEventTemplate, privateKey: Uint8Array): Event | undefined => {
|
||||
let content: string
|
||||
if (typeof t.content === 'object') {
|
||||
content = JSON.stringify(t.content)
|
||||
|
@ -76,7 +76,7 @@ export const channelMetadataEvent = (t: ChannelMetadataEventTemplate, privateKey
|
|||
return undefined
|
||||
}
|
||||
|
||||
return finishEvent(
|
||||
return finalizeEvent(
|
||||
{
|
||||
kind: ChannelMetadata,
|
||||
tags: [['e', t.channel_create_event_id], ...(t.tags ?? [])],
|
||||
|
@ -87,14 +87,14 @@ export const channelMetadataEvent = (t: ChannelMetadataEventTemplate, privateKey
|
|||
)
|
||||
}
|
||||
|
||||
export const channelMessageEvent = (t: ChannelMessageEventTemplate, privateKey: string): Event => {
|
||||
export const channelMessageEvent = (t: ChannelMessageEventTemplate, privateKey: Uint8Array): Event => {
|
||||
const tags = [['e', t.channel_create_event_id, t.relay_url, 'root']]
|
||||
|
||||
if (t.reply_to_channel_message_event_id) {
|
||||
tags.push(['e', t.reply_to_channel_message_event_id, t.relay_url, 'reply'])
|
||||
}
|
||||
|
||||
return finishEvent(
|
||||
return finalizeEvent(
|
||||
{
|
||||
kind: ChannelMessage,
|
||||
tags: [...tags, ...(t.tags ?? [])],
|
||||
|
@ -106,7 +106,10 @@ export const channelMessageEvent = (t: ChannelMessageEventTemplate, privateKey:
|
|||
}
|
||||
|
||||
/* "e" tag should be the kind 42 event to hide */
|
||||
export const channelHideMessageEvent = (t: ChannelHideMessageEventTemplate, privateKey: string): Event | undefined => {
|
||||
export const channelHideMessageEvent = (
|
||||
t: ChannelHideMessageEventTemplate,
|
||||
privateKey: Uint8Array,
|
||||
): Event | undefined => {
|
||||
let content: string
|
||||
if (typeof t.content === 'object') {
|
||||
content = JSON.stringify(t.content)
|
||||
|
@ -116,7 +119,7 @@ export const channelHideMessageEvent = (t: ChannelHideMessageEventTemplate, priv
|
|||
return undefined
|
||||
}
|
||||
|
||||
return finishEvent(
|
||||
return finalizeEvent(
|
||||
{
|
||||
kind: ChannelHideMessage,
|
||||
tags: [['e', t.channel_message_event_id], ...(t.tags ?? [])],
|
||||
|
@ -127,7 +130,7 @@ export const channelHideMessageEvent = (t: ChannelHideMessageEventTemplate, priv
|
|||
)
|
||||
}
|
||||
|
||||
export const channelMuteUserEvent = (t: ChannelMuteUserEventTemplate, privateKey: string): Event | undefined => {
|
||||
export const channelMuteUserEvent = (t: ChannelMuteUserEventTemplate, privateKey: Uint8Array): Event | undefined => {
|
||||
let content: string
|
||||
if (typeof t.content === 'object') {
|
||||
content = JSON.stringify(t.content)
|
||||
|
@ -137,7 +140,7 @@ export const channelMuteUserEvent = (t: ChannelMuteUserEventTemplate, privateKey
|
|||
return undefined
|
||||
}
|
||||
|
||||
return finishEvent(
|
||||
return finalizeEvent(
|
||||
{
|
||||
kind: ChannelMuteUser,
|
||||
tags: [['p', t.pubkey_to_mute], ...(t.tags ?? [])],
|
||||
|
|
2
nip42.ts
2
nip42.ts
|
@ -1,4 +1,4 @@
|
|||
import { EventTemplate } from './event.ts'
|
||||
import { EventTemplate } from './pure.ts'
|
||||
import { ClientAuth } from './kinds.ts'
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import crypto from 'node:crypto'
|
||||
import { describe, test, expect } from 'bun:test'
|
||||
import { hexToBytes } from '@noble/hashes/utils'
|
||||
import { makeNwcRequestEvent, parseConnectionString } from './nip47'
|
||||
import { decrypt } from './nip04.ts'
|
||||
import crypto from 'node:crypto'
|
||||
import { NWCWalletRequest } from './kinds.ts'
|
||||
|
||||
// @ts-ignore
|
||||
|
@ -44,14 +45,10 @@ describe('parseConnectionString', () => {
|
|||
describe('makeNwcRequestEvent', () => {
|
||||
test('returns a valid NWC request event', async () => {
|
||||
const pubkey = 'b889ff5b1513b641e2a139f661a661364979c5beee91842f8f0ef42ab558e9d4'
|
||||
const secret = '71a8c14c1407c113601079c4302dab36460f0ccd0ad506f1f2dc73b5100e4f3c'
|
||||
const secret = hexToBytes('71a8c14c1407c113601079c4302dab36460f0ccd0ad506f1f2dc73b5100e4f3c')
|
||||
const invoice =
|
||||
'lnbc210n1pjdgyvupp5x43awdarnfd4mdlsklelux0nyckwfu5c708ykuet8vcjnjp3rnpqdqu2askcmr9wssx7e3q2dshgmmndp5scqzzsxqyz5vqsp52l7y9peq9pka3vd3j7aps7gjnalsmy46ndj2mlkz00dltjgqfumq9qyyssq5fasr5dxed8l4qjfnqq48a02jzss3asf8sly7sfaqtr9w3yu2q9spsxhghs3y9aqdf44zkrrg9jjjdg6amade4h0hulllkwk33eqpucp6d5jye'
|
||||
const result = await makeNwcRequestEvent({
|
||||
pubkey,
|
||||
secret,
|
||||
invoice,
|
||||
})
|
||||
const result = await makeNwcRequestEvent(pubkey, secret, invoice)
|
||||
expect(result.kind).toBe(NWCWalletRequest)
|
||||
expect(await decrypt(secret, pubkey, result.content)).toEqual(
|
||||
JSON.stringify({
|
||||
|
|
16
nip47.ts
16
nip47.ts
|
@ -1,4 +1,4 @@
|
|||
import { finishEvent } from './event.ts'
|
||||
import { finalizeEvent } from './pure.ts'
|
||||
import { NWCWalletRequest } from './kinds.ts'
|
||||
import { encrypt } from './nip04.ts'
|
||||
|
||||
|
@ -15,22 +15,14 @@ export function parseConnectionString(connectionString: string) {
|
|||
return { pubkey, relay, secret }
|
||||
}
|
||||
|
||||
export async function makeNwcRequestEvent({
|
||||
pubkey,
|
||||
secret,
|
||||
invoice,
|
||||
}: {
|
||||
pubkey: string
|
||||
secret: string
|
||||
invoice: string
|
||||
}) {
|
||||
export async function makeNwcRequestEvent(pubkey: string, secretKey: Uint8Array, invoice: string) {
|
||||
const content = {
|
||||
method: 'pay_invoice',
|
||||
params: {
|
||||
invoice,
|
||||
},
|
||||
}
|
||||
const encryptedContent = await encrypt(secret, pubkey, JSON.stringify(content))
|
||||
const encryptedContent = await encrypt(secretKey, pubkey, JSON.stringify(content))
|
||||
const eventTemplate = {
|
||||
kind: NWCWalletRequest,
|
||||
created_at: Math.round(Date.now() / 1000),
|
||||
|
@ -38,5 +30,5 @@ export async function makeNwcRequestEvent({
|
|||
tags: [['p', pubkey]],
|
||||
}
|
||||
|
||||
return finishEvent(eventTemplate, secret)
|
||||
return finalizeEvent(eventTemplate, secretKey)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { describe, test, expect, mock } from 'bun:test'
|
||||
import { finishEvent } from './event.ts'
|
||||
import { getPublicKey, generatePrivateKey } from './keys.ts'
|
||||
import { finalizeEvent } from './pure.ts'
|
||||
import { getPublicKey, generateSecretKey } from './pure.ts'
|
||||
import { getZapEndpoint, makeZapReceipt, makeZapRequest, useFetchImplementation, validateZapRequest } from './nip57.ts'
|
||||
import { buildEvent } from './test-helpers.ts'
|
||||
|
||||
|
@ -122,7 +122,7 @@ describe('validateZapRequest', () => {
|
|||
})
|
||||
|
||||
test('returns an error message if the signature on the Zap request is invalid', () => {
|
||||
const privateKey = generatePrivateKey()
|
||||
const privateKey = generateSecretKey()
|
||||
const publicKey = getPublicKey(privateKey)
|
||||
|
||||
const zapRequest = {
|
||||
|
@ -141,9 +141,8 @@ describe('validateZapRequest', () => {
|
|||
})
|
||||
|
||||
test('returns an error message if the Zap request does not have a "p" tag', () => {
|
||||
const privateKey = generatePrivateKey()
|
||||
|
||||
const zapRequest = finishEvent(
|
||||
const privateKey = generateSecretKey()
|
||||
const zapRequest = finalizeEvent(
|
||||
{
|
||||
kind: 9734,
|
||||
created_at: Date.now() / 1000,
|
||||
|
@ -160,9 +159,8 @@ describe('validateZapRequest', () => {
|
|||
})
|
||||
|
||||
test('returns an error message if the "p" tag on the Zap request is not valid hex', () => {
|
||||
const privateKey = generatePrivateKey()
|
||||
|
||||
const zapRequest = finishEvent(
|
||||
const privateKey = generateSecretKey()
|
||||
const zapRequest = finalizeEvent(
|
||||
{
|
||||
kind: 9734,
|
||||
created_at: Date.now() / 1000,
|
||||
|
@ -180,10 +178,10 @@ describe('validateZapRequest', () => {
|
|||
})
|
||||
|
||||
test('returns an error message if the "e" tag on the Zap request is not valid hex', () => {
|
||||
const privateKey = generatePrivateKey()
|
||||
const privateKey = generateSecretKey()
|
||||
const publicKey = getPublicKey(privateKey)
|
||||
|
||||
const zapRequest = finishEvent(
|
||||
const zapRequest = finalizeEvent(
|
||||
{
|
||||
kind: 9734,
|
||||
created_at: Date.now() / 1000,
|
||||
|
@ -202,10 +200,10 @@ describe('validateZapRequest', () => {
|
|||
})
|
||||
|
||||
test('returns an error message if the Zap request does not have a relays tag', () => {
|
||||
const privateKey = generatePrivateKey()
|
||||
const privateKey = generateSecretKey()
|
||||
const publicKey = getPublicKey(privateKey)
|
||||
|
||||
const zapRequest = finishEvent(
|
||||
const zapRequest = finalizeEvent(
|
||||
{
|
||||
kind: 9734,
|
||||
created_at: Date.now() / 1000,
|
||||
|
@ -222,10 +220,10 @@ describe('validateZapRequest', () => {
|
|||
})
|
||||
|
||||
test('returns null for a valid Zap request', () => {
|
||||
const privateKey = generatePrivateKey()
|
||||
const privateKey = generateSecretKey()
|
||||
const publicKey = getPublicKey(privateKey)
|
||||
|
||||
const zapRequest = finishEvent(
|
||||
const zapRequest = finalizeEvent(
|
||||
{
|
||||
kind: 9734,
|
||||
created_at: Date.now() / 1000,
|
||||
|
@ -245,11 +243,11 @@ describe('validateZapRequest', () => {
|
|||
|
||||
describe('makeZapReceipt', () => {
|
||||
test('returns a valid Zap receipt with a preimage', () => {
|
||||
const privateKey = generatePrivateKey()
|
||||
const privateKey = generateSecretKey()
|
||||
const publicKey = getPublicKey(privateKey)
|
||||
|
||||
const zapRequest = JSON.stringify(
|
||||
finishEvent(
|
||||
finalizeEvent(
|
||||
{
|
||||
kind: 9734,
|
||||
created_at: Date.now() / 1000,
|
||||
|
@ -283,11 +281,11 @@ describe('makeZapReceipt', () => {
|
|||
})
|
||||
|
||||
test('returns a valid Zap receipt without a preimage', () => {
|
||||
const privateKey = generatePrivateKey()
|
||||
const privateKey = generateSecretKey()
|
||||
const publicKey = getPublicKey(privateKey)
|
||||
|
||||
const zapRequest = JSON.stringify(
|
||||
finishEvent(
|
||||
finalizeEvent(
|
||||
{
|
||||
kind: 9734,
|
||||
created_at: Date.now() / 1000,
|
||||
|
|
4
nip57.ts
4
nip57.ts
|
@ -1,6 +1,6 @@
|
|||
import { bech32 } from '@scure/base'
|
||||
|
||||
import { validateEvent, verifySignature, type Event, type EventTemplate } from './event.ts'
|
||||
import { validateEvent, verifyEvent, type Event, type EventTemplate } from './pure.ts'
|
||||
import { utf8Decoder } from './utils.ts'
|
||||
|
||||
var _fetch: any
|
||||
|
@ -86,7 +86,7 @@ export function validateZapRequest(zapRequestString: string): string | null {
|
|||
|
||||
if (!validateEvent(zapRequest)) return 'Zap request is not a valid Nostr event.'
|
||||
|
||||
if (!verifySignature(zapRequest)) return 'Invalid signature on zap request.'
|
||||
if (!verifyEvent(zapRequest)) return 'Invalid signature on zap request.'
|
||||
|
||||
let p = zapRequest.tags.find(([t, v]) => t === 'p' && v)
|
||||
if (!p) return "Zap request doesn't have a 'p' tag."
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
import { describe, test, expect } from 'bun:test'
|
||||
import { getToken, unpackEventFromToken, validateEvent, validateToken } from './nip98.ts'
|
||||
import { Event, finishEvent } from './event.ts'
|
||||
import { generatePrivateKey, getPublicKey } from './keys.ts'
|
||||
import { Event, finalizeEvent } from './pure.ts'
|
||||
import { generateSecretKey, getPublicKey } from './pure.ts'
|
||||
import { sha256 } from '@noble/hashes/sha256'
|
||||
import { utf8Encoder } from './utils.ts'
|
||||
import { bytesToHex } from '@noble/hashes/utils'
|
||||
import { HTTPAuth } from './kinds.ts'
|
||||
|
||||
const sk = generatePrivateKey()
|
||||
const sk = generateSecretKey()
|
||||
|
||||
describe('getToken', () => {
|
||||
test('getToken GET returns without authorization scheme', async () => {
|
||||
let result = await getToken('http://test.com', 'get', e => finishEvent(e, sk))
|
||||
let result = await getToken('http://test.com', 'get', e => finalizeEvent(e, sk))
|
||||
|
||||
const decodedResult: Event = await unpackEventFromToken(result)
|
||||
|
||||
|
@ -26,7 +26,7 @@ describe('getToken', () => {
|
|||
})
|
||||
|
||||
test('getToken POST returns token without authorization scheme', async () => {
|
||||
let result = await getToken('http://test.com', 'post', e => finishEvent(e, sk))
|
||||
let result = await getToken('http://test.com', 'post', e => finalizeEvent(e, sk))
|
||||
|
||||
const decodedResult: Event = await unpackEventFromToken(result)
|
||||
|
||||
|
@ -43,7 +43,7 @@ describe('getToken', () => {
|
|||
test('getToken GET returns token WITH authorization scheme', async () => {
|
||||
const authorizationScheme = 'Nostr '
|
||||
|
||||
let result = await getToken('http://test.com', 'post', e => finishEvent(e, sk), true)
|
||||
let result = await getToken('http://test.com', 'post', e => finalizeEvent(e, sk), true)
|
||||
|
||||
expect(result.startsWith(authorizationScheme)).toBe(true)
|
||||
|
||||
|
@ -62,7 +62,7 @@ describe('getToken', () => {
|
|||
test('getToken returns token with a valid payload tag when payload is present', async () => {
|
||||
const payload = { test: 'payload' }
|
||||
const payloadHash = bytesToHex(sha256(utf8Encoder.encode(JSON.stringify(payload))))
|
||||
let result = await getToken('http://test.com', 'post', e => finishEvent(e, sk), true, payload)
|
||||
let result = await getToken('http://test.com', 'post', e => finalizeEvent(e, sk), true, payload)
|
||||
|
||||
const decodedResult: Event = await unpackEventFromToken(result)
|
||||
|
||||
|
@ -80,14 +80,14 @@ describe('getToken', () => {
|
|||
|
||||
describe('validateToken', () => {
|
||||
test('validateToken returns true for valid token without authorization scheme', async () => {
|
||||
const validToken = await getToken('http://test.com', 'get', e => finishEvent(e, sk))
|
||||
const validToken = await getToken('http://test.com', 'get', e => finalizeEvent(e, sk))
|
||||
|
||||
const result = await validateToken(validToken, 'http://test.com', 'get')
|
||||
expect(result).toBe(true)
|
||||
})
|
||||
|
||||
test('validateToken returns true for valid token with authorization scheme', async () => {
|
||||
const validToken = await getToken('http://test.com', 'get', e => finishEvent(e, sk), true)
|
||||
const validToken = await getToken('http://test.com', 'get', e => finalizeEvent(e, sk), true)
|
||||
|
||||
const result = await validateToken(validToken, 'http://test.com', 'get')
|
||||
expect(result).toBe(true)
|
||||
|
@ -104,21 +104,21 @@ describe('validateToken', () => {
|
|||
})
|
||||
|
||||
test('validateToken throws an error for a wrong url', async () => {
|
||||
const validToken = await getToken('http://test.com', 'get', e => finishEvent(e, sk))
|
||||
const validToken = await getToken('http://test.com', 'get', e => finalizeEvent(e, sk))
|
||||
|
||||
const result = validateToken(validToken, 'http://wrong-test.com', 'get')
|
||||
expect(result).rejects.toThrow(Error)
|
||||
})
|
||||
|
||||
test('validateToken throws an error for a wrong method', async () => {
|
||||
const validToken = await getToken('http://test.com', 'get', e => finishEvent(e, sk))
|
||||
const validToken = await getToken('http://test.com', 'get', e => finalizeEvent(e, sk))
|
||||
|
||||
const result = validateToken(validToken, 'http://test.com', 'post')
|
||||
expect(result).rejects.toThrow(Error)
|
||||
})
|
||||
|
||||
test('validateEvent returns true for valid decoded token with authorization scheme', async () => {
|
||||
const validToken = await getToken('http://test.com', 'get', e => finishEvent(e, sk), true)
|
||||
const validToken = await getToken('http://test.com', 'get', e => finalizeEvent(e, sk), true)
|
||||
const decodedResult: Event = await unpackEventFromToken(validToken)
|
||||
|
||||
const result = await validateEvent(decodedResult, 'http://test.com', 'get')
|
||||
|
@ -126,7 +126,7 @@ describe('validateToken', () => {
|
|||
})
|
||||
|
||||
test('validateEvent throws an error for a wrong url', async () => {
|
||||
const validToken = await getToken('http://test.com', 'get', e => finishEvent(e, sk), true)
|
||||
const validToken = await getToken('http://test.com', 'get', e => finalizeEvent(e, sk), true)
|
||||
const decodedResult: Event = await unpackEventFromToken(validToken)
|
||||
|
||||
const result = validateEvent(decodedResult, 'http://wrong-test.com', 'get')
|
||||
|
@ -134,7 +134,7 @@ describe('validateToken', () => {
|
|||
})
|
||||
|
||||
test('validateEvent throws an error for a wrong method', async () => {
|
||||
const validToken = await getToken('http://test.com', 'get', e => finishEvent(e, sk), true)
|
||||
const validToken = await getToken('http://test.com', 'get', e => finalizeEvent(e, sk), true)
|
||||
const decodedResult: Event = await unpackEventFromToken(validToken)
|
||||
|
||||
const result = validateEvent(decodedResult, 'http://test.com', 'post')
|
||||
|
@ -142,7 +142,7 @@ describe('validateToken', () => {
|
|||
})
|
||||
|
||||
test('validateEvent returns true for valid payload tag hash', async () => {
|
||||
const validToken = await getToken('http://test.com', 'post', e => finishEvent(e, sk), true, { test: 'payload' })
|
||||
const validToken = await getToken('http://test.com', 'post', e => finalizeEvent(e, sk), true, { test: 'payload' })
|
||||
const decodedResult: Event = await unpackEventFromToken(validToken)
|
||||
|
||||
const result = await validateEvent(decodedResult, 'http://test.com', 'post', { test: 'payload' })
|
||||
|
@ -150,7 +150,7 @@ describe('validateToken', () => {
|
|||
})
|
||||
|
||||
test('validateEvent returns false for invalid payload tag hash', async () => {
|
||||
const validToken = await getToken('http://test.com', 'post', e => finishEvent(e, sk), true, { test: 'a-payload' })
|
||||
const validToken = await getToken('http://test.com', 'post', e => finalizeEvent(e, sk), true, { test: 'a-payload' })
|
||||
const decodedResult: Event = await unpackEventFromToken(validToken)
|
||||
|
||||
const result = validateEvent(decodedResult, 'http://test.com', 'post', { test: 'a-different-payload' })
|
||||
|
|
8
nip98.ts
8
nip98.ts
|
@ -1,9 +1,9 @@
|
|||
import { bytesToHex } from '@noble/hashes/utils'
|
||||
import { sha256 } from '@noble/hashes/sha256'
|
||||
import { base64 } from '@scure/base'
|
||||
import { Event, EventTemplate, verifySignature } from './event'
|
||||
import { utf8Decoder, utf8Encoder } from './utils'
|
||||
import { HTTPAuth } from './kinds'
|
||||
import { Event, EventTemplate, verifyEvent } from './pure.ts'
|
||||
import { utf8Decoder, utf8Encoder } from './utils.ts'
|
||||
import { HTTPAuth } from './kinds.ts'
|
||||
|
||||
const _authorizationScheme = 'Nostr '
|
||||
|
||||
|
@ -83,7 +83,7 @@ export async function validateEvent(event: Event, url: string, method: string, b
|
|||
if (!event) {
|
||||
throw new Error('Invalid nostr event')
|
||||
}
|
||||
if (!verifySignature(event)) {
|
||||
if (!verifyEvent(event)) {
|
||||
throw new Error('Invalid nostr event, signature invalid')
|
||||
}
|
||||
if (event.kind !== HTTPAuth) {
|
||||
|
|
12
pool.test.ts
12
pool.test.ts
|
@ -1,7 +1,7 @@
|
|||
import { test, expect, afterAll } from 'bun:test'
|
||||
|
||||
import { finishEvent, type Event } from './event.ts'
|
||||
import { generatePrivateKey, getPublicKey } from './keys.ts'
|
||||
import { finalizeEvent, type Event } from './pure.ts'
|
||||
import { generateSecretKey, getPublicKey } from './pure.ts'
|
||||
import { SimplePool } from './pool.ts'
|
||||
|
||||
let pool = new SimplePool()
|
||||
|
@ -13,7 +13,7 @@ afterAll(() => {
|
|||
})
|
||||
|
||||
test('removing duplicates when querying', async () => {
|
||||
let priv = generatePrivateKey()
|
||||
let priv = generateSecretKey()
|
||||
let pub = getPublicKey(priv)
|
||||
|
||||
pool.subscribeMany(relays, [{ authors: [pub] }], {
|
||||
|
@ -26,7 +26,7 @@ test('removing duplicates when querying', async () => {
|
|||
})
|
||||
let received: Event[] = []
|
||||
|
||||
let event = finishEvent(
|
||||
let event = finalizeEvent(
|
||||
{
|
||||
created_at: Math.round(Date.now() / 1000),
|
||||
content: 'test',
|
||||
|
@ -44,7 +44,7 @@ test('removing duplicates when querying', async () => {
|
|||
})
|
||||
|
||||
test('same with double querying', async () => {
|
||||
let priv = generatePrivateKey()
|
||||
let priv = generateSecretKey()
|
||||
let pub = getPublicKey(priv)
|
||||
|
||||
pool.subscribeMany(relays, [{ authors: [pub] }], {
|
||||
|
@ -60,7 +60,7 @@ test('same with double querying', async () => {
|
|||
|
||||
let received: Event[] = []
|
||||
|
||||
let event = finishEvent(
|
||||
let event = finalizeEvent(
|
||||
{
|
||||
created_at: Math.round(Date.now() / 1000),
|
||||
content: 'test2',
|
||||
|
|
4
pool.ts
4
pool.ts
|
@ -1,7 +1,7 @@
|
|||
import { Relay, SubscriptionParams, Subscription } from './relay.ts'
|
||||
import { normalizeURL } from './utils.ts'
|
||||
|
||||
import type { Event } from './event.ts'
|
||||
import type { Event } from './pure.ts'
|
||||
import { type Filter } from './filter.ts'
|
||||
|
||||
export type SubCloser = { close: () => void }
|
||||
|
@ -103,7 +103,7 @@ export class SimplePool {
|
|||
return
|
||||
}
|
||||
|
||||
let subscription = await relay.subscribe(filters, {
|
||||
let subscription = relay.subscribe(filters, {
|
||||
...params,
|
||||
oneose: () => handleEose(i),
|
||||
onclose: reason => handleClose(i, reason),
|
||||
|
|
2
pure.ts
2
pure.ts
|
@ -14,7 +14,7 @@ class JS implements Nostr {
|
|||
}
|
||||
finalizeEvent(t: EventTemplate, secretKey: Uint8Array): VerifiedEvent {
|
||||
const event = t as VerifiedEvent
|
||||
event.pubkey = this.getPublicKey(secretKey)
|
||||
event.pubkey = bytesToHex(schnorr.getPublicKey(secretKey))
|
||||
event.id = getEventHash(event)
|
||||
event.sig = bytesToHex(schnorr.sign(getEventHash(event), secretKey))
|
||||
event[verifiedSymbol] = true
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { decode, type AddressPointer, type ProfilePointer, type EventPointer } from './nip19.ts'
|
||||
|
||||
import type { Event } from './event.ts'
|
||||
import type { Event } from './pure.ts'
|
||||
|
||||
type Reference = {
|
||||
text: string
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { test, expect, afterEach, beforeEach } from 'bun:test'
|
||||
|
||||
import { finishEvent } from './event.ts'
|
||||
import { generatePrivateKey, getPublicKey } from './keys.ts'
|
||||
import { finalizeEvent } from './pure.ts'
|
||||
import { generateSecretKey, getPublicKey } from './pure.ts'
|
||||
import { Relay } from './relay.ts'
|
||||
|
||||
let relay = new Relay('wss://public.relaying.io')
|
||||
|
@ -57,7 +57,7 @@ test('querying', async () => {
|
|||
}, 10000)
|
||||
|
||||
test('listening and publishing and closing', async () => {
|
||||
let sk = generatePrivateKey()
|
||||
let sk = generateSecretKey()
|
||||
let pk = getPublicKey(sk)
|
||||
var resolve1: (_: void) => void
|
||||
var resolve2: (_: void) => void
|
||||
|
@ -91,7 +91,7 @@ test('listening and publishing and closing', async () => {
|
|||
},
|
||||
)
|
||||
|
||||
let event = finishEvent(
|
||||
let event = finalizeEvent(
|
||||
{
|
||||
kind: 23571,
|
||||
created_at: Math.floor(Date.now() / 1000),
|
||||
|
|
4
relay.ts
4
relay.ts
|
@ -1,6 +1,6 @@
|
|||
/* global WebSocket */
|
||||
|
||||
import { verifySignature, validateEvent, type Event, EventTemplate } from './event.ts'
|
||||
import { verifyEvent, validateEvent, type Event, EventTemplate } from './pure.ts'
|
||||
import { matchFilters, type Filter } from './filter.ts'
|
||||
import { getHex64, getSubscriptionId } from './fakejson.ts'
|
||||
import { Queue, normalizeURL } from './utils.ts'
|
||||
|
@ -161,7 +161,7 @@ export class Relay {
|
|||
case 'EVENT': {
|
||||
const so = this.openSubs.get(data[1] as string) as Subscription
|
||||
const event = data[2] as Event
|
||||
if ((this.trusted || (validateEvent(event) && verifySignature(event))) && matchFilters(so.filters, event)) {
|
||||
if ((this.trusted || (validateEvent(event) && verifyEvent(event))) && matchFilters(so.filters, event)) {
|
||||
so.onevent(event)
|
||||
}
|
||||
return
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import type { Event } from './event.ts'
|
||||
import type { Event } from './pure.ts'
|
||||
|
||||
/** Build an event for testing purposes. */
|
||||
export function buildEvent(params: Partial<Event>): Event {
|
||||
|
|
|
@ -2,7 +2,7 @@ import { describe, test, expect } from 'bun:test'
|
|||
import { buildEvent } from './test-helpers.ts'
|
||||
import { Queue, insertEventIntoAscendingList, insertEventIntoDescendingList, binarySearch } from './utils.ts'
|
||||
|
||||
import type { Event } from './event.ts'
|
||||
import type { Event } from './pure.ts'
|
||||
|
||||
describe('inserting into a desc sorted list of events', () => {
|
||||
test('insert into an empty list', async () => {
|
||||
|
|
Loading…
Reference in New Issue