Refactor imports: use file extension, improve tree shaking, update tests
This commit is contained in:
parent
9f896479d0
commit
08885ab8da
|
@ -6,9 +6,9 @@ import {
|
|||
validateEvent,
|
||||
verifySignature,
|
||||
getSignature,
|
||||
getPublicKey,
|
||||
Kind
|
||||
} from '.'
|
||||
Kind,
|
||||
} from './event.ts'
|
||||
import {getPublicKey} from './keys.ts'
|
||||
|
||||
describe('Event', () => {
|
||||
describe('getBlankEvent', () => {
|
||||
|
|
4
event.ts
4
event.ts
|
@ -2,8 +2,8 @@ import {schnorr} from '@noble/curves/secp256k1'
|
|||
import {sha256} from '@noble/hashes/sha256'
|
||||
import {bytesToHex} from '@noble/hashes/utils'
|
||||
|
||||
import {utf8Encoder} from './utils'
|
||||
import {getPublicKey} from './keys'
|
||||
import {getPublicKey} from './keys.ts'
|
||||
import {utf8Encoder} from './utils.ts'
|
||||
|
||||
/* eslint-disable no-unused-vars */
|
||||
export enum Kind {
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
import {fj} from '.'
|
||||
import {matchEventId, matchEventKind, getSubscriptionId} from './fakejson.ts'
|
||||
|
||||
test('match id', () => {
|
||||
expect(
|
||||
fj.matchEventId(
|
||||
matchEventId(
|
||||
`["EVENT","nostril-query",{"tags":[],"content":"so did we cut all corners and p2p stuff in order to make a decentralized social network that was fast and worked, but in the end what we got was a lot of very slow clients that can't handle the traffic of one jack dorsey tweet?","sig":"ca62629d189edebb8f0811cfa0ac53015013df5f305dcba3f411ba15cfc4074d8c2d517ee7d9e81c9eb72a7328bfbe31c9122156397565ac55e740404e2b1fe7","id":"fef2a50f7d9d3d5a5f38ee761bc087ec16198d3f0140df6d1e8193abf7c2b146","kind":1,"pubkey":"3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d","created_at":1671150419}]`,
|
||||
'fef2a50f7d9d3d5a5f38ee761bc087ec16198d3f0140df6d1e8193abf7c2b146'
|
||||
)
|
||||
).toBeTruthy()
|
||||
|
||||
expect(
|
||||
fj.matchEventId(
|
||||
matchEventId(
|
||||
`["EVENT","nostril-query",{"content":"a bunch of mfs interacted with my post using what I assume were \"likes\": https://nostr.build/i/964.png","created_at":1672506879,"id":"f40bdd0905137ad60482537e260890ab50b0863bf16e67cf9383f203bd26c96f","kind":1,"pubkey":"3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d","sig":"8b825d2d4096f0643b18ca39da59ec07a682cd8a3e717f119c845037573d98099f5bea94ec7ddedd5600c8020144a255ed52882a911f7f7ada6d6abb3c0a1eb4","tags":[]}]`,
|
||||
'fef2a50f7d9d3d5a5f38ee761bc087ec16198d3f0140df6d1e8193abf7c2b146'
|
||||
)
|
||||
|
@ -18,14 +18,14 @@ test('match id', () => {
|
|||
|
||||
test('match kind', () => {
|
||||
expect(
|
||||
fj.matchEventKind(
|
||||
matchEventKind(
|
||||
`["EVENT","nostril-query",{"tags":[],"content":"so did we cut all corners and p2p stuff in order to make a decentralized social network that was fast and worked, but in the end what we got was a lot of very slow clients that can't handle the traffic of one jack dorsey tweet?","sig":"ca62629d189edebb8f0811cfa0ac53015013df5f305dcba3f411ba15cfc4074d8c2d517ee7d9e81c9eb72a7328bfbe31c9122156397565ac55e740404e2b1fe7","id":"fef2a50f7d9d3d5a5f38ee761bc087ec16198d3f0140df6d1e8193abf7c2b146","kind":1,"pubkey":"3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d","created_at":1671150419}]`,
|
||||
1
|
||||
)
|
||||
).toBeTruthy()
|
||||
|
||||
expect(
|
||||
fj.matchEventKind(
|
||||
matchEventKind(
|
||||
`["EVENT","nostril-query",{"content":"{\"name\":\"fiatjaf\",\"about\":\"buy my merch at fiatjaf store\",\"picture\":\"https://fiatjaf.com/static/favicon.jpg\",\"nip05\":\"_@fiatjaf.com\"}","created_at":1671217411,"id":"b52f93f6dfecf9d81f59062827cd941412a0e8398dda60baf960b17499b88900","kind":12720,"pubkey":"3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d","sig":"fc1ea5d45fa5ed0526faed06e8fc7a558e60d1b213e9714f440828584ee999b93407092f9b04deea7e504fa034fc0428f31f7f0f95417b3280ebe6004b80b470","tags":[]}]`,
|
||||
12720
|
||||
)
|
||||
|
@ -33,14 +33,14 @@ test('match kind', () => {
|
|||
})
|
||||
|
||||
test('match subscription id', () => {
|
||||
expect(fj.getSubscriptionId('["EVENT","",{}]')).toEqual('')
|
||||
expect(fj.getSubscriptionId('["EVENT","_",{}]')).toEqual('_')
|
||||
expect(fj.getSubscriptionId('["EVENT","subname",{}]')).toEqual('subname')
|
||||
expect(fj.getSubscriptionId('["EVENT", "kasjbdjkav", {}]')).toEqual(
|
||||
expect(getSubscriptionId('["EVENT","",{}]')).toEqual('')
|
||||
expect(getSubscriptionId('["EVENT","_",{}]')).toEqual('_')
|
||||
expect(getSubscriptionId('["EVENT","subname",{}]')).toEqual('subname')
|
||||
expect(getSubscriptionId('["EVENT", "kasjbdjkav", {}]')).toEqual(
|
||||
'kasjbdjkav'
|
||||
)
|
||||
expect(
|
||||
fj.getSubscriptionId(
|
||||
getSubscriptionId(
|
||||
' [ \n\n "EVENT" , \n\n "y4d5ow45gfwoiudfÇA VSADLKAN KLDASB[12312535]SFMZSNJKLH" , {}]'
|
||||
)
|
||||
).toEqual('y4d5ow45gfwoiudfÇA VSADLKAN KLDASB[12312535]SFMZSNJKLH')
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import {matchFilter, matchFilters} from '.'
|
||||
import {buildEvent} from './test-helpers'
|
||||
import {matchFilter, matchFilters} from './filter.ts'
|
||||
import {buildEvent} from './test-helpers.ts'
|
||||
|
||||
describe('Filter', () => {
|
||||
describe('matchFilter', () => {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {Event, type Kind} from './event'
|
||||
import {Event, type Kind} from './event.ts'
|
||||
|
||||
export type Filter<K extends number = Kind> = {
|
||||
ids?: string[]
|
||||
|
|
44
index.ts
44
index.ts
|
@ -1,24 +1,24 @@
|
|||
export * from './keys'
|
||||
export * from './relay'
|
||||
export * from './event'
|
||||
export * from './filter'
|
||||
export * from './pool'
|
||||
export * from './references'
|
||||
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'
|
||||
export * as nip05 from './nip05'
|
||||
export * as nip06 from './nip06'
|
||||
export * as nip10 from './nip10'
|
||||
export * as nip13 from './nip13'
|
||||
export * as nip18 from './nip18'
|
||||
export * as nip19 from './nip19'
|
||||
export * as nip21 from './nip21'
|
||||
export * as nip25 from './nip25'
|
||||
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 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'
|
||||
export * as utils from './utils'
|
||||
export * as fj from './fakejson.ts'
|
||||
export * as utils from './utils.ts'
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {generatePrivateKey, getPublicKey} from '.'
|
||||
import {generatePrivateKey, getPublicKey} from './keys.ts'
|
||||
|
||||
test('private key generation', () => {
|
||||
expect(generatePrivateKey()).toMatch(/[a-f0-9]{64}/)
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import {nip04, getPublicKey, generatePrivateKey} from '.'
|
||||
import crypto from 'crypto'
|
||||
import crypto from 'node:crypto'
|
||||
|
||||
import {encrypt, decrypt} from './nip04.ts'
|
||||
import {getPublicKey, generatePrivateKey} from './keys.ts'
|
||||
|
||||
// @ts-ignore
|
||||
// eslint-disable-next-line no-undef
|
||||
|
@ -12,6 +14,6 @@ test('encrypt and decrypt message', async () => {
|
|||
let pk2 = getPublicKey(sk2)
|
||||
|
||||
expect(
|
||||
await nip04.decrypt(sk2, pk1, await nip04.encrypt(sk1, pk2, 'hello'))
|
||||
await decrypt(sk2, pk1, await encrypt(sk1, pk2, 'hello'))
|
||||
).toEqual('hello')
|
||||
})
|
||||
|
|
2
nip04.ts
2
nip04.ts
|
@ -2,7 +2,7 @@ import {randomBytes} from '@noble/hashes/utils'
|
|||
import {secp256k1} from '@noble/curves/secp256k1'
|
||||
import {base64} from '@scure/base'
|
||||
|
||||
import {utf8Decoder, utf8Encoder} from './utils'
|
||||
import {utf8Decoder, utf8Encoder} from './utils.ts'
|
||||
|
||||
// @ts-ignore
|
||||
if (typeof crypto !== 'undefined' && !crypto.subtle && crypto.webcrypto) {
|
||||
|
|
|
@ -1,28 +1,29 @@
|
|||
import fetch from 'node-fetch'
|
||||
import {nip05} from '.'
|
||||
|
||||
import {useFetchImplementation, queryProfile} from './nip05.ts'
|
||||
|
||||
test('fetch nip05 profiles', async () => {
|
||||
nip05.useFetchImplementation(fetch)
|
||||
useFetchImplementation(fetch)
|
||||
|
||||
let p1 = await nip05.queryProfile('jb55.com')
|
||||
let p1 = await queryProfile('jb55.com')
|
||||
expect(p1!.pubkey).toEqual(
|
||||
'32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245'
|
||||
)
|
||||
expect(p1!.relays).toEqual(['wss://relay.damus.io'])
|
||||
|
||||
let p2 = await nip05.queryProfile('jb55@jb55.com')
|
||||
let p2 = await queryProfile('jb55@jb55.com')
|
||||
expect(p2!.pubkey).toEqual(
|
||||
'32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245'
|
||||
)
|
||||
expect(p2!.relays).toEqual(['wss://relay.damus.io'])
|
||||
|
||||
let p3 = await nip05.queryProfile('channel.ninja@channel.ninja')
|
||||
let p3 = await queryProfile('channel.ninja@channel.ninja')
|
||||
expect(p3!.pubkey).toEqual(
|
||||
'36e65b503eba8a6b698e724a59137603101166a1cddb45ddc704247fc8aa0fce'
|
||||
)
|
||||
expect(p3!.relays).toEqual(undefined)
|
||||
|
||||
let p4 = await nip05.queryProfile('_@fiatjaf.com')
|
||||
let p4 = await queryProfile('_@fiatjaf.com')
|
||||
expect(p4!.pubkey).toEqual(
|
||||
'3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d'
|
||||
)
|
||||
|
|
2
nip05.ts
2
nip05.ts
|
@ -1,4 +1,4 @@
|
|||
import {ProfilePointer} from './nip19'
|
||||
import {ProfilePointer} from './nip19.ts'
|
||||
|
||||
/**
|
||||
* NIP-05 regex. The localpart is optional, and should be assumed to be `_` otherwise.
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import {nip06} from '.'
|
||||
import {privateKeyFromSeedWords} from './nip06.ts'
|
||||
|
||||
test('generate private key from a mnemonic', async () => {
|
||||
const mnemonic = 'zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo wrong'
|
||||
const privateKey = nip06.privateKeyFromSeedWords(mnemonic)
|
||||
const privateKey = privateKeyFromSeedWords(mnemonic)
|
||||
expect(privateKey).toEqual(
|
||||
'c26cf31d8ba425b555ca27d00ca71b5008004f2f662470f8c8131822ec129fe2'
|
||||
)
|
||||
|
@ -11,7 +11,7 @@ test('generate private key from a mnemonic', async () => {
|
|||
test('generate private key from a mnemonic and passphrase', async () => {
|
||||
const mnemonic = 'zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo wrong'
|
||||
const passphrase = '123'
|
||||
const privateKey = nip06.privateKeyFromSeedWords(mnemonic, passphrase)
|
||||
const privateKey = privateKeyFromSeedWords(mnemonic, passphrase)
|
||||
expect(privateKey).toEqual(
|
||||
'55a22b8203273d0aaf24c22c8fbe99608e70c524b17265641074281c8b978ae4'
|
||||
)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {nip10} from '.'
|
||||
import {parse} from './nip10.ts'
|
||||
|
||||
describe('parse NIP10-referenced events', () => {
|
||||
test('legacy + a lot of events', () => {
|
||||
|
@ -47,7 +47,7 @@ describe('parse NIP10-referenced events', () => {
|
|||
]
|
||||
}
|
||||
|
||||
expect(nip10.parse(event)).toEqual({
|
||||
expect(parse(event)).toEqual({
|
||||
mentions: [
|
||||
{
|
||||
id: 'bbd72f0ae14374aa8fb166b483cfcf99b57d7f4cf1600ccbf17c350040834631',
|
||||
|
@ -128,7 +128,7 @@ describe('parse NIP10-referenced events', () => {
|
|||
]
|
||||
}
|
||||
|
||||
expect(nip10.parse(event)).toEqual({
|
||||
expect(parse(event)).toEqual({
|
||||
mentions: [
|
||||
{
|
||||
id: 'bbd72f0ae14374aa8fb166b483cfcf99b57d7f4cf1600ccbf17c350040834631',
|
||||
|
@ -189,7 +189,7 @@ describe('parse NIP10-referenced events', () => {
|
|||
]
|
||||
}
|
||||
|
||||
expect(nip10.parse(event)).toEqual({
|
||||
expect(parse(event)).toEqual({
|
||||
mentions: [],
|
||||
profiles: [
|
||||
{
|
||||
|
@ -233,7 +233,7 @@ describe('parse NIP10-referenced events', () => {
|
|||
]
|
||||
}
|
||||
|
||||
expect(nip10.parse(event)).toEqual({
|
||||
expect(parse(event)).toEqual({
|
||||
mentions: [],
|
||||
profiles: [
|
||||
{
|
||||
|
@ -302,7 +302,7 @@ describe('parse NIP10-referenced events', () => {
|
|||
]
|
||||
}
|
||||
|
||||
expect(nip10.parse(event)).toEqual({
|
||||
expect(parse(event)).toEqual({
|
||||
mentions: [],
|
||||
profiles: [
|
||||
{
|
||||
|
|
4
nip10.ts
4
nip10.ts
|
@ -1,5 +1,5 @@
|
|||
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 = {
|
||||
/**
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import {nip13} from '.'
|
||||
import {getPow} from './nip13.ts'
|
||||
|
||||
test('identifies proof-of-work difficulty', async () => {
|
||||
const id = '000006d8c378af1779d2feebc7603a125d99eca0ccf1085959b307f64e5dd358'
|
||||
const difficulty = nip13.getPow(id)
|
||||
const difficulty = getPow(id)
|
||||
expect(difficulty).toEqual(21)
|
||||
})
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import {nip18, finishEvent, getPublicKey, Kind} from '.'
|
||||
import { buildEvent } from './test-helpers'
|
||||
import {finishEvent, Kind} from './event.ts'
|
||||
import {getPublicKey} from './keys.ts'
|
||||
import {finishRepostEvent, getRepostedEventPointer, getRepostedEvent} from './nip18.ts'
|
||||
import {buildEvent} from './test-helpers.ts'
|
||||
|
||||
const relayUrl = 'https://relay.example.com'
|
||||
|
||||
|
@ -27,7 +29,7 @@ describe('finishRepostEvent + getRepostedEventPointer + getRepostedEvent', () =>
|
|||
created_at: 1617932115
|
||||
}
|
||||
|
||||
const event = nip18.finishRepostEvent(
|
||||
const event = finishRepostEvent(
|
||||
template,
|
||||
repostedEvent,
|
||||
relayUrl,
|
||||
|
@ -45,13 +47,13 @@ describe('finishRepostEvent + getRepostedEventPointer + getRepostedEvent', () =>
|
|||
expect(typeof event.id).toEqual('string')
|
||||
expect(typeof event.sig).toEqual('string')
|
||||
|
||||
const repostedEventPointer = nip18.getRepostedEventPointer(event)
|
||||
const repostedEventPointer = getRepostedEventPointer(event)
|
||||
|
||||
expect(repostedEventPointer!.id).toEqual(repostedEvent.id)
|
||||
expect(repostedEventPointer!.author).toEqual(repostedEvent.pubkey)
|
||||
expect(repostedEventPointer!.relays).toEqual([relayUrl])
|
||||
|
||||
const repostedEventFromContent = nip18.getRepostedEvent(event)
|
||||
const repostedEventFromContent = getRepostedEvent(event)
|
||||
|
||||
expect(repostedEventFromContent).toEqual(repostedEvent)
|
||||
})
|
||||
|
@ -63,7 +65,7 @@ describe('finishRepostEvent + getRepostedEventPointer + getRepostedEvent', () =>
|
|||
created_at: 1617932115
|
||||
}
|
||||
|
||||
const event = nip18.finishRepostEvent(
|
||||
const event = finishRepostEvent(
|
||||
template,
|
||||
repostedEvent,
|
||||
relayUrl,
|
||||
|
@ -82,13 +84,13 @@ describe('finishRepostEvent + getRepostedEventPointer + getRepostedEvent', () =>
|
|||
expect(typeof event.id).toEqual('string')
|
||||
expect(typeof event.sig).toEqual('string')
|
||||
|
||||
const repostedEventPointer = nip18.getRepostedEventPointer(event)
|
||||
const repostedEventPointer = getRepostedEventPointer(event)
|
||||
|
||||
expect(repostedEventPointer!.id).toEqual(repostedEvent.id)
|
||||
expect(repostedEventPointer!.author).toEqual(repostedEvent.pubkey)
|
||||
expect(repostedEventPointer!.relays).toEqual([relayUrl])
|
||||
|
||||
const repostedEventFromContent = nip18.getRepostedEvent(event)
|
||||
const repostedEventFromContent = getRepostedEvent(event)
|
||||
|
||||
expect(repostedEventFromContent).toEqual(undefined)
|
||||
})
|
||||
|
@ -101,7 +103,7 @@ describe('getRepostedEventPointer', () => {
|
|||
tags: [['e', 'reposted event id', relayUrl]],
|
||||
})
|
||||
|
||||
const repostedEventPointer = nip18.getRepostedEventPointer(event)
|
||||
const repostedEventPointer = getRepostedEventPointer(event)
|
||||
|
||||
expect(repostedEventPointer!.id).toEqual('reposted event id')
|
||||
expect(repostedEventPointer!.author).toEqual(undefined)
|
||||
|
|
4
nip18.ts
4
nip18.ts
|
@ -1,5 +1,5 @@
|
|||
import { Event, finishEvent, Kind, verifySignature } from './event'
|
||||
import { EventPointer } from './nip19'
|
||||
import {Event, finishEvent, Kind, verifySignature} from './event.ts'
|
||||
import {EventPointer} from './nip19.ts'
|
||||
|
||||
export type RepostEventTemplate = {
|
||||
/**
|
||||
|
|
|
@ -1,19 +1,29 @@
|
|||
import {nip19, generatePrivateKey, getPublicKey} from '.'
|
||||
import {generatePrivateKey, getPublicKey} from './keys.ts'
|
||||
import {
|
||||
decode,
|
||||
naddrEncode,
|
||||
nprofileEncode,
|
||||
npubEncode,
|
||||
nrelayEncode,
|
||||
nsecEncode,
|
||||
type AddressPointer,
|
||||
type ProfilePointer,
|
||||
} from './nip19.ts'
|
||||
|
||||
test('encode and decode nsec', () => {
|
||||
let sk = generatePrivateKey()
|
||||
let nsec = nip19.nsecEncode(sk)
|
||||
let nsec = nsecEncode(sk)
|
||||
expect(nsec).toMatch(/nsec1\w+/)
|
||||
let {type, data} = nip19.decode(nsec)
|
||||
let {type, data} = decode(nsec)
|
||||
expect(type).toEqual('nsec')
|
||||
expect(data).toEqual(sk)
|
||||
})
|
||||
|
||||
test('encode and decode npub', () => {
|
||||
let pk = getPublicKey(generatePrivateKey())
|
||||
let npub = nip19.npubEncode(pk)
|
||||
let npub = npubEncode(pk)
|
||||
expect(npub).toMatch(/npub1\w+/)
|
||||
let {type, data} = nip19.decode(npub)
|
||||
let {type, data} = decode(npub)
|
||||
expect(type).toEqual('npub')
|
||||
expect(data).toEqual(pk)
|
||||
})
|
||||
|
@ -24,11 +34,11 @@ test('encode and decode nprofile', () => {
|
|||
'wss://relay.nostr.example.mydomain.example.com',
|
||||
'wss://nostr.banana.com'
|
||||
]
|
||||
let nprofile = nip19.nprofileEncode({pubkey: pk, relays})
|
||||
let nprofile = nprofileEncode({pubkey: pk, relays})
|
||||
expect(nprofile).toMatch(/nprofile1\w+/)
|
||||
let {type, data} = nip19.decode(nprofile)
|
||||
let {type, data} = decode(nprofile)
|
||||
expect(type).toEqual('nprofile')
|
||||
const pointer = data as nip19.ProfilePointer
|
||||
const pointer = data as ProfilePointer
|
||||
expect(pointer.pubkey).toEqual(pk)
|
||||
expect(pointer.relays).toContain(relays[0])
|
||||
expect(pointer.relays).toContain(relays[1])
|
||||
|
@ -36,8 +46,8 @@ test('encode and decode nprofile', () => {
|
|||
|
||||
test('decode nprofile without relays', () => {
|
||||
expect(
|
||||
nip19.decode(
|
||||
nip19.nprofileEncode({
|
||||
decode(
|
||||
nprofileEncode({
|
||||
pubkey:
|
||||
'97c70a44366a6535c145b333f973ea86dfdc2d7a99da618c40c64705ad98e322',
|
||||
relays: []
|
||||
|
@ -55,16 +65,16 @@ test('encode and decode naddr', () => {
|
|||
'wss://relay.nostr.example.mydomain.example.com',
|
||||
'wss://nostr.banana.com'
|
||||
]
|
||||
let naddr = nip19.naddrEncode({
|
||||
let naddr = naddrEncode({
|
||||
pubkey: pk,
|
||||
relays,
|
||||
kind: 30023,
|
||||
identifier: 'banana'
|
||||
})
|
||||
expect(naddr).toMatch(/naddr1\w+/)
|
||||
let {type, data} = nip19.decode(naddr)
|
||||
let {type, data} = decode(naddr)
|
||||
expect(type).toEqual('naddr')
|
||||
const pointer = data as nip19.AddressPointer
|
||||
const pointer = data as AddressPointer
|
||||
expect(pointer.pubkey).toEqual(pk)
|
||||
expect(pointer.relays).toContain(relays[0])
|
||||
expect(pointer.relays).toContain(relays[1])
|
||||
|
@ -73,11 +83,11 @@ test('encode and decode naddr', () => {
|
|||
})
|
||||
|
||||
test('decode naddr from habla.news', () => {
|
||||
let {type, data} = nip19.decode(
|
||||
let {type, data} = decode(
|
||||
'naddr1qq98yetxv4ex2mnrv4esygrl54h466tz4v0re4pyuavvxqptsejl0vxcmnhfl60z3rth2xkpjspsgqqqw4rsf34vl5'
|
||||
)
|
||||
expect(type).toEqual('naddr')
|
||||
const pointer = data as nip19.AddressPointer
|
||||
const pointer = data as AddressPointer
|
||||
expect(pointer.pubkey).toEqual(
|
||||
'7fa56f5d6962ab1e3cd424e758c3002b8665f7b0d8dcee9fe9e288d7751ac194'
|
||||
)
|
||||
|
@ -86,12 +96,12 @@ test('decode naddr from habla.news', () => {
|
|||
})
|
||||
|
||||
test('decode naddr from go-nostr with different TLV ordering', () => {
|
||||
let {type, data} = nip19.decode(
|
||||
let {type, data} = decode(
|
||||
'naddr1qqrxyctwv9hxzq3q80cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkwsxpqqqp65wqfwwaehxw309aex2mrp0yhxummnw3ezuetcv9khqmr99ekhjer0d4skjm3wv4uxzmtsd3jjucm0d5q3vamnwvaz7tmwdaehgu3wvfskuctwvyhxxmmd0zfmwx'
|
||||
)
|
||||
|
||||
expect(type).toEqual('naddr')
|
||||
const pointer = data as nip19.AddressPointer
|
||||
const pointer = data as AddressPointer
|
||||
expect(pointer.pubkey).toEqual(
|
||||
'3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d'
|
||||
)
|
||||
|
@ -105,9 +115,9 @@ test('decode naddr from go-nostr with different TLV ordering', () => {
|
|||
|
||||
test('encode and decode nrelay', () => {
|
||||
let url = 'wss://relay.nostr.example'
|
||||
let nrelay = nip19.nrelayEncode(url)
|
||||
let nrelay = nrelayEncode(url)
|
||||
expect(nrelay).toMatch(/nrelay1\w+/)
|
||||
let {type, data} = nip19.decode(nrelay)
|
||||
let {type, data} = decode(nrelay)
|
||||
expect(type).toEqual('nrelay')
|
||||
expect(data).toEqual(url)
|
||||
})
|
||||
|
|
2
nip19.ts
2
nip19.ts
|
@ -1,7 +1,7 @@
|
|||
import {bytesToHex, concatBytes, hexToBytes} from '@noble/hashes/utils'
|
||||
import {bech32} from '@scure/base'
|
||||
|
||||
import {utf8Decoder, utf8Encoder} from './utils'
|
||||
import {utf8Decoder, utf8Encoder} from './utils.ts'
|
||||
|
||||
const Bech32MaxSize = 5000
|
||||
|
||||
|
|
|
@ -1,32 +1,32 @@
|
|||
import {nip21} from '.'
|
||||
import {test as testRegex, parse} from './nip21.ts'
|
||||
|
||||
test('test()', () => {
|
||||
expect(
|
||||
nip21.test(
|
||||
testRegex(
|
||||
'nostr:npub108pv4cg5ag52nq082kd5leu9ffrn2gdg6g4xdwatn73y36uzplmq9uyev6'
|
||||
)
|
||||
).toBe(true)
|
||||
expect(
|
||||
nip21.test(
|
||||
testRegex(
|
||||
'nostr:note1gmtnz6q2m55epmlpe3semjdcq987av3jvx4emmjsa8g3s9x7tg4sclreky'
|
||||
)
|
||||
).toBe(true)
|
||||
expect(
|
||||
nip21.test(
|
||||
testRegex(
|
||||
' nostr:npub108pv4cg5ag52nq082kd5leu9ffrn2gdg6g4xdwatn73y36uzplmq9uyev6'
|
||||
)
|
||||
).toBe(false)
|
||||
expect(nip21.test('nostr:')).toBe(false)
|
||||
expect(testRegex('nostr:')).toBe(false)
|
||||
expect(
|
||||
nip21.test(
|
||||
testRegex(
|
||||
'nostr:npub108pv4cg5ag52nQq082kd5leu9ffrn2gdg6g4xdwatn73y36uzplmq9uyev6'
|
||||
)
|
||||
).toBe(false)
|
||||
expect(nip21.test('gggggg')).toBe(false)
|
||||
expect(testRegex('gggggg')).toBe(false)
|
||||
})
|
||||
|
||||
test('parse', () => {
|
||||
const result = nip21.parse(
|
||||
const result = parse(
|
||||
'nostr:note1gmtnz6q2m55epmlpe3semjdcq987av3jvx4emmjsa8g3s9x7tg4sclreky'
|
||||
)
|
||||
|
||||
|
|
11
nip21.ts
11
nip21.ts
|
@ -1,8 +1,7 @@
|
|||
import * as nip19 from './nip19'
|
||||
import * as nip21 from './nip21'
|
||||
import {BECH32_REGEX, decode, type DecodeResult} from './nip19.ts'
|
||||
|
||||
/** Nostr URI regex, eg `nostr:npub1...` */
|
||||
export const NOSTR_URI_REGEX = new RegExp(`nostr:(${nip19.BECH32_REGEX.source})`)
|
||||
export const NOSTR_URI_REGEX = new RegExp(`nostr:(${BECH32_REGEX.source})`)
|
||||
|
||||
/** Test whether the value is a Nostr URI. */
|
||||
export function test(value: unknown): value is `nostr:${string}` {
|
||||
|
@ -19,16 +18,16 @@ export interface NostrURI {
|
|||
/** The bech32-encoded data (eg `npub1...`). */
|
||||
value: string
|
||||
/** Decoded bech32 string, according to NIP-19. */
|
||||
decoded: nip19.DecodeResult
|
||||
decoded: DecodeResult
|
||||
}
|
||||
|
||||
/** Parse and decode a Nostr URI. */
|
||||
export function parse(uri: string): NostrURI {
|
||||
const match = uri.match(new RegExp(`^${nip21.NOSTR_URI_REGEX.source}$`))
|
||||
const match = uri.match(new RegExp(`^${NOSTR_URI_REGEX.source}$`))
|
||||
if (!match) throw new Error(`Invalid Nostr URI: ${uri}`)
|
||||
return {
|
||||
uri: match[0] as `nostr:${string}`,
|
||||
value: match[1],
|
||||
decoded: nip19.decode(match[1])
|
||||
decoded: decode(match[1])
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
import {nip25, finishEvent, getPublicKey, Kind} from '.'
|
||||
import {finishEvent, Kind} from './event.ts'
|
||||
import {getPublicKey} from './keys.ts'
|
||||
import {finishReactionEvent, getReactedEventPointer} from './nip25.ts'
|
||||
|
||||
describe('finishReactionEvent + getReactedEventPointer', () => {
|
||||
const privateKey =
|
||||
|
@ -24,7 +26,7 @@ describe('finishReactionEvent + getReactedEventPointer', () => {
|
|||
created_at: 1617932115
|
||||
}
|
||||
|
||||
const event = nip25.finishReactionEvent(template, reactedEvent, privateKey)
|
||||
const event = finishReactionEvent(template, reactedEvent, privateKey)
|
||||
|
||||
expect(event.kind).toEqual(Kind.Reaction)
|
||||
expect(event.tags).toEqual([
|
||||
|
@ -39,7 +41,7 @@ describe('finishReactionEvent + getReactedEventPointer', () => {
|
|||
expect(typeof event.id).toEqual('string')
|
||||
expect(typeof event.sig).toEqual('string')
|
||||
|
||||
const reactedEventPointer = nip25.getReactedEventPointer(event)
|
||||
const reactedEventPointer = getReactedEventPointer(event)
|
||||
|
||||
expect(reactedEventPointer!.id).toEqual(reactedEvent.id)
|
||||
expect(reactedEventPointer!.author).toEqual(reactedEvent.pubkey)
|
||||
|
@ -52,7 +54,7 @@ describe('finishReactionEvent + getReactedEventPointer', () => {
|
|||
created_at: 1617932115
|
||||
}
|
||||
|
||||
const event = nip25.finishReactionEvent(template, reactedEvent, privateKey)
|
||||
const event = finishReactionEvent(template, reactedEvent, privateKey)
|
||||
|
||||
expect(event.kind).toEqual(Kind.Reaction)
|
||||
expect(event.tags).toEqual([
|
||||
|
@ -68,7 +70,7 @@ describe('finishReactionEvent + getReactedEventPointer', () => {
|
|||
expect(typeof event.id).toEqual('string')
|
||||
expect(typeof event.sig).toEqual('string')
|
||||
|
||||
const reactedEventPointer = nip25.getReactedEventPointer(event)
|
||||
const reactedEventPointer = getReactedEventPointer(event)
|
||||
|
||||
expect(reactedEventPointer!.id).toEqual(reactedEvent.id)
|
||||
expect(reactedEventPointer!.author).toEqual(reactedEvent.pubkey)
|
||||
|
|
5
nip25.ts
5
nip25.ts
|
@ -1,5 +1,6 @@
|
|||
import { Event, finishEvent, Kind } from './event'
|
||||
import { EventPointer } from './nip19'
|
||||
import {Event, finishEvent, Kind} from './event.ts'
|
||||
|
||||
import type {EventPointer} from './nip19.ts'
|
||||
|
||||
export type ReactionEventTemplate = {
|
||||
/**
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import {nip26, getPublicKey, generatePrivateKey} from '.'
|
||||
import { buildEvent } from './test-helpers'
|
||||
import {getPublicKey, generatePrivateKey} from './keys.ts'
|
||||
import {getDelegator, createDelegation} from './nip26.ts'
|
||||
import {buildEvent} from './test-helpers.ts'
|
||||
|
||||
test('parse good delegation from NIP', async () => {
|
||||
expect(
|
||||
nip26.getDelegator({
|
||||
getDelegator({
|
||||
id: 'a080fd288b60ac2225ff2e2d815291bd730911e583e177302cc949a15dc2b2dc',
|
||||
pubkey:
|
||||
'62903b1ff41559daf9ee98ef1ae67cc52f301bb5ce26d14baba3052f649c3f49',
|
||||
|
@ -25,7 +26,7 @@ test('parse good delegation from NIP', async () => {
|
|||
|
||||
test('parse bad delegations', async () => {
|
||||
expect(
|
||||
nip26.getDelegator({
|
||||
getDelegator({
|
||||
id: 'a080fd288b60ac2225ff2e2d815291bd730911e583e177302cc949a15dc2b2dc',
|
||||
pubkey:
|
||||
'62903b1ff41559daf9ee98ef1ae67cc52f301bb5ce26d14baba3052f649c3f49',
|
||||
|
@ -45,7 +46,7 @@ test('parse bad delegations', async () => {
|
|||
).toEqual(null)
|
||||
|
||||
expect(
|
||||
nip26.getDelegator({
|
||||
getDelegator({
|
||||
id: 'a080fd288b60ac2225ff2e2d815291bd730911e583e177302cc949a15dc2b2dc',
|
||||
pubkey:
|
||||
'62903b1ff41559daf9ee98ef1ae67cc52f301bb5ce26d14baba3052f649c3f49',
|
||||
|
@ -65,7 +66,7 @@ test('parse bad delegations', async () => {
|
|||
).toEqual(null)
|
||||
|
||||
expect(
|
||||
nip26.getDelegator({
|
||||
getDelegator({
|
||||
id: 'a080fd288b60ac2225ff2e2d815291bd730911e583e177302cc949a15dc2b2dc',
|
||||
pubkey:
|
||||
'62903b1ff41559daf9ee98ef1ae67c152f301bb5ce26d14baba3052f649c3f49',
|
||||
|
@ -90,7 +91,7 @@ test('create and verify delegation', async () => {
|
|||
let pk1 = getPublicKey(sk1)
|
||||
let sk2 = generatePrivateKey()
|
||||
let pk2 = getPublicKey(sk2)
|
||||
let delegation = nip26.createDelegation(sk1, {pubkey: pk2, kind: 1})
|
||||
let delegation = createDelegation(sk1, {pubkey: pk2, kind: 1})
|
||||
expect(delegation).toHaveProperty('from', pk1)
|
||||
expect(delegation).toHaveProperty('to', pk2)
|
||||
expect(delegation).toHaveProperty('cond', 'kind=1')
|
||||
|
@ -100,5 +101,5 @@ test('create and verify delegation', async () => {
|
|||
tags: [['delegation', delegation.from, delegation.cond, delegation.sig]],
|
||||
pubkey: pk2,
|
||||
})
|
||||
expect(nip26.getDelegator(event)).toEqual(pk1)
|
||||
expect(getDelegator(event)).toEqual(pk1)
|
||||
})
|
||||
|
|
7
nip26.ts
7
nip26.ts
|
@ -2,9 +2,10 @@ import {schnorr} from '@noble/curves/secp256k1'
|
|||
import {bytesToHex} from '@noble/hashes/utils'
|
||||
import {sha256} from '@noble/hashes/sha256'
|
||||
|
||||
import {Event} from './event'
|
||||
import {utf8Encoder} from './utils'
|
||||
import {getPublicKey} from './keys'
|
||||
import {utf8Encoder} from './utils.ts'
|
||||
import {getPublicKey} from './keys.ts'
|
||||
|
||||
import type {Event} from './event.ts'
|
||||
|
||||
export type Parameters = {
|
||||
pubkey: string // the key to whom the delegation will be given
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import {nip27} from '.'
|
||||
import {matchAll, replaceAll} from './nip27.ts'
|
||||
|
||||
test('matchAll', () => {
|
||||
const result = nip27.matchAll(
|
||||
const result = matchAll(
|
||||
'Hello nostr:npub108pv4cg5ag52nq082kd5leu9ffrn2gdg6g4xdwatn73y36uzplmq9uyev6!\n\nnostr:note1gmtnz6q2m55epmlpe3semjdcq987av3jvx4emmjsa8g3s9x7tg4sclreky'
|
||||
)
|
||||
|
||||
|
@ -33,7 +33,7 @@ test('replaceAll', () => {
|
|||
const content =
|
||||
'Hello nostr:npub108pv4cg5ag52nq082kd5leu9ffrn2gdg6g4xdwatn73y36uzplmq9uyev6!\n\nnostr:note1gmtnz6q2m55epmlpe3semjdcq987av3jvx4emmjsa8g3s9x7tg4sclreky'
|
||||
|
||||
const result = nip27.replaceAll(content, ({decoded, value}) => {
|
||||
const result = replaceAll(content, ({decoded, value}) => {
|
||||
switch (decoded.type) {
|
||||
case 'npub':
|
||||
return '@alex'
|
||||
|
|
14
nip27.ts
14
nip27.ts
|
@ -1,12 +1,12 @@
|
|||
import * as nip19 from './nip19'
|
||||
import * as nip21 from './nip21'
|
||||
import {decode} from './nip19.ts'
|
||||
import {NOSTR_URI_REGEX, type NostrURI} from './nip21.ts'
|
||||
|
||||
/** Regex to find NIP-21 URIs inside event content. */
|
||||
export const regex = () =>
|
||||
new RegExp(`\\b${nip21.NOSTR_URI_REGEX.source}\\b`, 'g')
|
||||
new RegExp(`\\b${NOSTR_URI_REGEX.source}\\b`, 'g')
|
||||
|
||||
/** 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. */
|
||||
start: number
|
||||
/** Index where the URI ends in the event content. */
|
||||
|
@ -23,7 +23,7 @@ export function * matchAll(content: string): Iterable<NostrURIMatch> {
|
|||
yield {
|
||||
uri: uri as `nostr:${string}`,
|
||||
value,
|
||||
decoded: nip19.decode(value),
|
||||
decoded: decode(value),
|
||||
start: match.index!,
|
||||
end: match.index! + uri.length
|
||||
}
|
||||
|
@ -51,13 +51,13 @@ export function * matchAll(content: string): Iterable<NostrURIMatch> {
|
|||
*/
|
||||
export function replaceAll(
|
||||
content: string,
|
||||
replacer: (match: nip21.NostrURI) => string
|
||||
replacer: (match: NostrURI) => string
|
||||
): string {
|
||||
return content.replaceAll(regex(), (uri, value) => {
|
||||
return replacer({
|
||||
uri: uri as `nostr:${string}`,
|
||||
value,
|
||||
decoded: nip19.decode(value)
|
||||
decoded: decode(value)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
import fetch from 'node-fetch'
|
||||
import {nip39} from '.'
|
||||
|
||||
import {useFetchImplementation, validateGithub} from './nip39.ts'
|
||||
|
||||
test('validate github claim', async () => {
|
||||
nip39.useFetchImplementation(fetch)
|
||||
useFetchImplementation(fetch)
|
||||
|
||||
let result = await nip39.validateGithub(
|
||||
let result = await validateGithub(
|
||||
'npub1gcxzte5zlkncx26j68ez60fzkvtkm9e0vrwdcvsjakxf9mu9qewqlfnj5z',
|
||||
'vitorpamplona',
|
||||
'cf19e2d1d7f8dac6348ad37b35ec8421'
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
import 'websocket-polyfill'
|
||||
import {
|
||||
relayInit,
|
||||
generatePrivateKey,
|
||||
finishEvent,
|
||||
nip42
|
||||
} from '.'
|
||||
|
||||
import {finishEvent} from './event.ts'
|
||||
import {generatePrivateKey} from './keys.ts'
|
||||
import {authenticate} from './nip42.ts'
|
||||
import {relayInit} from './relay.ts'
|
||||
|
||||
test('auth flow', () => {
|
||||
const relay = relayInit('wss://nostr.kollider.xyz')
|
||||
|
@ -14,7 +13,7 @@ test('auth flow', () => {
|
|||
return new Promise<void>((resolve) => {
|
||||
relay.on('auth', async challenge => {
|
||||
await expect(
|
||||
nip42.authenticate({
|
||||
authenticate({
|
||||
challenge,
|
||||
relay,
|
||||
sign: (e) => finishEvent(e, sk)
|
||||
|
|
4
nip42.ts
4
nip42.ts
|
@ -1,5 +1,5 @@
|
|||
import {EventTemplate, Event, Kind} from './event'
|
||||
import {Relay} from './relay'
|
||||
import {Kind, type EventTemplate, type Event} from './event.ts'
|
||||
import {Relay} from './relay.ts'
|
||||
|
||||
/**
|
||||
* Authenticate via NIP-42 flow.
|
||||
|
|
|
@ -1,25 +1,28 @@
|
|||
import {finishEvent} from './event.ts'
|
||||
import {getPublicKey, generatePrivateKey} from './keys.ts'
|
||||
import {
|
||||
nip57,
|
||||
generatePrivateKey,
|
||||
getPublicKey,
|
||||
finishEvent
|
||||
} from '.'
|
||||
import { buildEvent } from './test-helpers'
|
||||
getZapEndpoint,
|
||||
makeZapReceipt,
|
||||
makeZapRequest,
|
||||
useFetchImplementation,
|
||||
validateZapRequest,
|
||||
} from './nip57.ts'
|
||||
import {buildEvent} from './test-helpers.ts'
|
||||
|
||||
describe('getZapEndpoint', () => {
|
||||
test('returns null if neither lud06 nor lud16 is present', async () => {
|
||||
const metadata = buildEvent({kind: 0, content: '{}'})
|
||||
const result = await nip57.getZapEndpoint(metadata)
|
||||
const result = await getZapEndpoint(metadata)
|
||||
|
||||
expect(result).toBeNull()
|
||||
})
|
||||
|
||||
test('returns null if fetch fails', async () => {
|
||||
const fetchImplementation = jest.fn(() => Promise.reject(new Error()))
|
||||
nip57.useFetchImplementation(fetchImplementation)
|
||||
useFetchImplementation(fetchImplementation)
|
||||
|
||||
const metadata = buildEvent({kind: 0, content: '{"lud16": "name@domain"}'})
|
||||
const result = await nip57.getZapEndpoint(metadata)
|
||||
const result = await getZapEndpoint(metadata)
|
||||
|
||||
expect(result).toBeNull()
|
||||
expect(fetchImplementation).toHaveBeenCalledWith(
|
||||
|
@ -31,10 +34,10 @@ describe('getZapEndpoint', () => {
|
|||
const fetchImplementation = jest.fn(() =>
|
||||
Promise.resolve({json: () => ({allowsNostr: false})})
|
||||
)
|
||||
nip57.useFetchImplementation(fetchImplementation)
|
||||
useFetchImplementation(fetchImplementation)
|
||||
|
||||
const metadata = buildEvent({kind: 0, content: '{"lud16": "name@domain"}'})
|
||||
const result = await nip57.getZapEndpoint(metadata)
|
||||
const result = await getZapEndpoint(metadata)
|
||||
|
||||
expect(result).toBeNull()
|
||||
expect(fetchImplementation).toHaveBeenCalledWith(
|
||||
|
@ -52,10 +55,10 @@ describe('getZapEndpoint', () => {
|
|||
})
|
||||
})
|
||||
)
|
||||
nip57.useFetchImplementation(fetchImplementation)
|
||||
useFetchImplementation(fetchImplementation)
|
||||
|
||||
const metadata = buildEvent({kind: 0, content: '{"lud16": "name@domain"}'})
|
||||
const result = await nip57.getZapEndpoint(metadata)
|
||||
const result = await getZapEndpoint(metadata)
|
||||
|
||||
expect(result).toBe('callback')
|
||||
expect(fetchImplementation).toHaveBeenCalledWith(
|
||||
|
@ -68,7 +71,7 @@ describe('makeZapRequest', () => {
|
|||
test('throws an error if amount is not given', () => {
|
||||
expect(() =>
|
||||
// @ts-expect-error
|
||||
nip57.makeZapRequest({
|
||||
makeZapRequest({
|
||||
profile: 'profile',
|
||||
event: null,
|
||||
relays: [],
|
||||
|
@ -80,7 +83,7 @@ describe('makeZapRequest', () => {
|
|||
test('throws an error if profile is not given', () => {
|
||||
expect(() =>
|
||||
// @ts-expect-error
|
||||
nip57.makeZapRequest({
|
||||
makeZapRequest({
|
||||
event: null,
|
||||
amount: 100,
|
||||
relays: [],
|
||||
|
@ -90,7 +93,7 @@ describe('makeZapRequest', () => {
|
|||
})
|
||||
|
||||
test('returns a valid Zap request', () => {
|
||||
const result = nip57.makeZapRequest({
|
||||
const result = makeZapRequest({
|
||||
profile: 'profile',
|
||||
event: 'event',
|
||||
amount: 100,
|
||||
|
@ -113,7 +116,7 @@ describe('makeZapRequest', () => {
|
|||
|
||||
describe('validateZapRequest', () => {
|
||||
test('returns an error message for invalid JSON', () => {
|
||||
expect(nip57.validateZapRequest('invalid JSON')).toBe(
|
||||
expect(validateZapRequest('invalid JSON')).toBe(
|
||||
'Invalid zap request JSON.'
|
||||
)
|
||||
})
|
||||
|
@ -130,7 +133,7 @@ describe('validateZapRequest', () => {
|
|||
]
|
||||
}
|
||||
|
||||
expect(nip57.validateZapRequest(JSON.stringify(zapRequest))).toBe(
|
||||
expect(validateZapRequest(JSON.stringify(zapRequest))).toBe(
|
||||
'Zap request is not a valid Nostr event.'
|
||||
)
|
||||
})
|
||||
|
@ -151,7 +154,7 @@ describe('validateZapRequest', () => {
|
|||
]
|
||||
}
|
||||
|
||||
expect(nip57.validateZapRequest(JSON.stringify(zapRequest))).toBe(
|
||||
expect(validateZapRequest(JSON.stringify(zapRequest))).toBe(
|
||||
'Invalid signature on zap request.'
|
||||
)
|
||||
})
|
||||
|
@ -172,7 +175,7 @@ describe('validateZapRequest', () => {
|
|||
privateKey
|
||||
)
|
||||
|
||||
expect(nip57.validateZapRequest(JSON.stringify(zapRequest))).toBe(
|
||||
expect(validateZapRequest(JSON.stringify(zapRequest))).toBe(
|
||||
"Zap request doesn't have a 'p' tag."
|
||||
)
|
||||
})
|
||||
|
@ -194,7 +197,7 @@ describe('validateZapRequest', () => {
|
|||
privateKey
|
||||
)
|
||||
|
||||
expect(nip57.validateZapRequest(JSON.stringify(zapRequest))).toBe(
|
||||
expect(validateZapRequest(JSON.stringify(zapRequest))).toBe(
|
||||
"Zap request 'p' tag is not valid hex."
|
||||
)
|
||||
})
|
||||
|
@ -218,7 +221,7 @@ describe('validateZapRequest', () => {
|
|||
privateKey
|
||||
)
|
||||
|
||||
expect(nip57.validateZapRequest(JSON.stringify(zapRequest))).toBe(
|
||||
expect(validateZapRequest(JSON.stringify(zapRequest))).toBe(
|
||||
"Zap request 'e' tag is not valid hex."
|
||||
)
|
||||
})
|
||||
|
@ -240,7 +243,7 @@ describe('validateZapRequest', () => {
|
|||
privateKey
|
||||
)
|
||||
|
||||
expect(nip57.validateZapRequest(JSON.stringify(zapRequest))).toBe(
|
||||
expect(validateZapRequest(JSON.stringify(zapRequest))).toBe(
|
||||
"Zap request doesn't have a 'relays' tag."
|
||||
)
|
||||
})
|
||||
|
@ -263,7 +266,7 @@ describe('validateZapRequest', () => {
|
|||
privateKey
|
||||
)
|
||||
|
||||
expect(nip57.validateZapRequest(JSON.stringify(zapRequest))).toBeNull()
|
||||
expect(validateZapRequest(JSON.stringify(zapRequest))).toBeNull()
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -291,7 +294,7 @@ describe('makeZapReceipt', () => {
|
|||
const bolt11 = 'bolt11'
|
||||
const paidAt = new Date()
|
||||
|
||||
const result = nip57.makeZapReceipt({zapRequest, preimage, bolt11, paidAt})
|
||||
const result = makeZapReceipt({zapRequest, preimage, bolt11, paidAt})
|
||||
|
||||
expect(result.kind).toBe(9735)
|
||||
expect(result.created_at).toBeCloseTo(paidAt.getTime() / 1000, 0)
|
||||
|
@ -324,7 +327,7 @@ describe('makeZapReceipt', () => {
|
|||
const bolt11 = 'bolt11'
|
||||
const paidAt = new Date()
|
||||
|
||||
const result = nip57.makeZapReceipt({zapRequest, bolt11, paidAt})
|
||||
const result = makeZapReceipt({zapRequest, bolt11, paidAt})
|
||||
|
||||
expect(result.kind).toBe(9735)
|
||||
expect(result.created_at).toBeCloseTo(paidAt.getTime() / 1000, 0)
|
||||
|
|
10
nip57.ts
10
nip57.ts
|
@ -1,13 +1,13 @@
|
|||
import {bech32} from '@scure/base'
|
||||
|
||||
import {
|
||||
Event,
|
||||
EventTemplate,
|
||||
Kind,
|
||||
validateEvent,
|
||||
verifySignature,
|
||||
Kind
|
||||
} from './event'
|
||||
import {utf8Decoder} from './utils'
|
||||
type Event,
|
||||
type EventTemplate,
|
||||
} from './event.ts'
|
||||
import {utf8Decoder} from './utils.ts'
|
||||
|
||||
var _fetch: any
|
||||
|
||||
|
|
11
pool.test.ts
11
pool.test.ts
|
@ -1,11 +1,8 @@
|
|||
import 'websocket-polyfill'
|
||||
import {
|
||||
SimplePool,
|
||||
generatePrivateKey,
|
||||
getPublicKey,
|
||||
finishEvent,
|
||||
type Event,
|
||||
} from '.'
|
||||
|
||||
import {finishEvent, type Event} from './event.ts'
|
||||
import {generatePrivateKey, getPublicKey} from './keys.ts'
|
||||
import {SimplePool} from './pool.ts'
|
||||
|
||||
let pool = new SimplePool()
|
||||
|
||||
|
|
15
pool.ts
15
pool.ts
|
@ -1,9 +1,14 @@
|
|||
import {Relay, relayInit} from './relay'
|
||||
import {normalizeURL} from './utils'
|
||||
import {Filter} from './filter'
|
||||
import {Event} from './event'
|
||||
import {SubscriptionOptions, Sub, Pub} from './relay'
|
||||
import {
|
||||
relayInit,
|
||||
type Pub,
|
||||
type Relay,
|
||||
type Sub,
|
||||
type SubscriptionOptions,
|
||||
} from './relay.ts'
|
||||
import {normalizeURL} from './utils.ts'
|
||||
|
||||
import type {Event} from './event.ts'
|
||||
import type {Filter} from './filter.ts'
|
||||
export class SimplePool {
|
||||
private _conn: {[url: string]: Relay}
|
||||
private _seenOn: {[id: string]: Set<string>} = {} // a map of all events we've seen in each relay
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import {parseReferences} from '.'
|
||||
import { buildEvent } from './test-helpers'
|
||||
import {parseReferences} from './references.ts'
|
||||
import {buildEvent} from './test-helpers.ts'
|
||||
|
||||
test('parse mentions', () => {
|
||||
let evt = buildEvent({
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
import {Event} from './event'
|
||||
import {decode, AddressPointer, ProfilePointer, EventPointer} from './nip19'
|
||||
import {
|
||||
decode,
|
||||
type AddressPointer,
|
||||
type ProfilePointer,
|
||||
type EventPointer,
|
||||
} from './nip19.ts'
|
||||
|
||||
import type {Event} from './event.ts'
|
||||
|
||||
type Reference = {
|
||||
text: string
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
import 'websocket-polyfill'
|
||||
import {
|
||||
relayInit,
|
||||
generatePrivateKey,
|
||||
getPublicKey,
|
||||
finishEvent,
|
||||
} from '.'
|
||||
|
||||
import {finishEvent} from './event.ts'
|
||||
import {generatePrivateKey, getPublicKey} from './keys.ts'
|
||||
import {relayInit} from './relay.ts'
|
||||
|
||||
let relay = relayInit('wss://relay.damus.io/')
|
||||
|
||||
|
|
6
relay.ts
6
relay.ts
|
@ -1,8 +1,8 @@
|
|||
/* global WebSocket */
|
||||
|
||||
import {Event, verifySignature, validateEvent} from './event'
|
||||
import {Filter, matchFilters} from './filter'
|
||||
import {getHex64, getSubscriptionId} from './fakejson'
|
||||
import {verifySignature, validateEvent, type Event} from './event.ts'
|
||||
import {matchFilters, type Filter} from './filter.ts'
|
||||
import {getHex64, getSubscriptionId} from './fakejson.ts'
|
||||
|
||||
type RelayEvent = {
|
||||
connect: () => void | Promise<void>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {type Event} from '.'
|
||||
import type {Event} from './event.ts'
|
||||
|
||||
type EventParams<K extends number> = Partial<Event<K>>
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
"esModuleInterop": true,
|
||||
"emitDeclarationOnly": true,
|
||||
"outDir": "lib",
|
||||
"rootDir": "."
|
||||
"rootDir": ".",
|
||||
"allowImportingTsExtensions": true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
import {utils, type Event} from '.'
|
||||
import {buildEvent} from './test-helpers'
|
||||
import {buildEvent} from './test-helpers.ts'
|
||||
import {
|
||||
insertEventIntoAscendingList,
|
||||
insertEventIntoDescendingList,
|
||||
} from './utils.ts'
|
||||
|
||||
const {insertEventIntoAscendingList, insertEventIntoDescendingList} = utils
|
||||
import type {Event} from './event.ts'
|
||||
|
||||
describe('inserting into a desc sorted list of events', () => {
|
||||
test('insert into an empty list', async () => {
|
||||
|
|
Loading…
Reference in New Issue