mirror of
https://github.com/nbd-wtf/nostr-tools.git
synced 2025-12-08 16:28:49 +00:00
add parseReferences() for NIP-10 and NIP-27.
This commit is contained in:
20
README.md
20
README.md
@@ -170,6 +170,26 @@ let relaysForEvent = pool.seenOn(
|
||||
// relaysForEvent will be an array of URLs from relays a given event was seen on
|
||||
```
|
||||
|
||||
### Parsing references (mentions) from a content using NIP-10 and NIP-27
|
||||
|
||||
```js
|
||||
import {parseReferences} from 'nostr-tools'
|
||||
|
||||
let references = parseReferences(event)
|
||||
let simpleAugmentedContent = event.content
|
||||
for (let i = 0; i < references.length; i++) {
|
||||
let {text, profile, event, address} = references[i]
|
||||
let augmentedReference = profile
|
||||
? `<strong>@${profilesCache[profile.pubkey].name}</strong>`
|
||||
: event
|
||||
? `<em>${eventsCache[event.id].content.slice(0, 5)}</em>`
|
||||
: address
|
||||
? `<a href="${text}">[link]</a>`
|
||||
: text
|
||||
simpleAugmentedContent.replaceAll(text, augmentedReference)
|
||||
}
|
||||
```
|
||||
|
||||
### Querying profile data from a NIP-05 address
|
||||
|
||||
```js
|
||||
|
||||
1
index.ts
1
index.ts
@@ -3,6 +3,7 @@ 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'
|
||||
|
||||
62
references.test.js
Normal file
62
references.test.js
Normal file
@@ -0,0 +1,62 @@
|
||||
/* eslint-env jest */
|
||||
|
||||
const {parseReferences} = require('./lib/nostr.cjs')
|
||||
|
||||
test('parse mentions', () => {
|
||||
let evt = {
|
||||
tags: [
|
||||
[
|
||||
'p',
|
||||
'c9d556c6d3978d112d30616d0d20aaa81410e3653911dd67787b5aaf9b36ade8',
|
||||
'wss://nostr.com'
|
||||
],
|
||||
[
|
||||
'e',
|
||||
'a84c5de86efc2ec2cff7bad077c4171e09146b633b7ad117fffe088d9579ac33',
|
||||
'wss://other.com',
|
||||
'reply'
|
||||
],
|
||||
[
|
||||
'e',
|
||||
'31d7c2875b5fc8e6f9c8f9dc1f84de1b6b91d1947ea4c59225e55c325d330fa8',
|
||||
''
|
||||
]
|
||||
],
|
||||
content:
|
||||
'hello #[0], have you seen #[2]? it was made by nostr:nprofile1qqsvc6ulagpn7kwrcwdqgp797xl7usumqa6s3kgcelwq6m75x8fe8yc5usxdg on nostr:nevent1qqsvc6ulagpn7kwrcwdqgp797xl7usumqa6s3kgcelwq6m75x8fe8ychxp5v4! broken #[3]'
|
||||
}
|
||||
|
||||
expect(parseReferences(evt)).toEqual([
|
||||
{
|
||||
text: '#[0]',
|
||||
profile: {
|
||||
pubkey:
|
||||
'c9d556c6d3978d112d30616d0d20aaa81410e3653911dd67787b5aaf9b36ade8',
|
||||
relays: ['wss://nostr.com']
|
||||
}
|
||||
},
|
||||
{
|
||||
text: '#[2]',
|
||||
event: {
|
||||
id: '31d7c2875b5fc8e6f9c8f9dc1f84de1b6b91d1947ea4c59225e55c325d330fa8',
|
||||
relays: []
|
||||
}
|
||||
},
|
||||
{
|
||||
text: 'nostr:nprofile1qqsvc6ulagpn7kwrcwdqgp797xl7usumqa6s3kgcelwq6m75x8fe8yc5usxdg',
|
||||
profile: {
|
||||
pubkey:
|
||||
'cc6b9fea033f59c3c39a0407c5f1bfee439b077508d918cfdc0d6fd431d39393',
|
||||
relays: []
|
||||
}
|
||||
},
|
||||
{
|
||||
text: 'nostr:nevent1qqsvc6ulagpn7kwrcwdqgp797xl7usumqa6s3kgcelwq6m75x8fe8ychxp5v4',
|
||||
event: {
|
||||
id: 'cc6b9fea033f59c3c39a0407c5f1bfee439b077508d918cfdc0d6fd431d39393',
|
||||
relays: [],
|
||||
author: undefined
|
||||
}
|
||||
}
|
||||
])
|
||||
})
|
||||
104
references.ts
Normal file
104
references.ts
Normal file
@@ -0,0 +1,104 @@
|
||||
import {Event} from './event'
|
||||
import {decode, AddressPointer, ProfilePointer, EventPointer} from './nip19'
|
||||
|
||||
type Reference = {
|
||||
text: string
|
||||
profile?: ProfilePointer
|
||||
event?: EventPointer
|
||||
address?: AddressPointer
|
||||
}
|
||||
|
||||
const mentionRegex =
|
||||
/\bnostr:((note|npub|naddr|nevent|nprofile)1\w+)\b|#\[(\d+)\]/g
|
||||
|
||||
export function parseReferences(evt: Event): Reference[] {
|
||||
let references: Reference[] = []
|
||||
for (let ref of evt.content.matchAll(mentionRegex)) {
|
||||
if (ref[2]) {
|
||||
// it's a NIP-27 mention
|
||||
try {
|
||||
let {type, data} = decode(ref[1])
|
||||
switch (type) {
|
||||
case 'npub': {
|
||||
references.push({
|
||||
text: ref[0],
|
||||
profile: {pubkey: data as string, relays: []}
|
||||
})
|
||||
break
|
||||
}
|
||||
case 'nprofile': {
|
||||
references.push({
|
||||
text: ref[0],
|
||||
profile: data as ProfilePointer
|
||||
})
|
||||
break
|
||||
}
|
||||
case 'note': {
|
||||
references.push({
|
||||
text: ref[0],
|
||||
event: {id: data as string, relays: []}
|
||||
})
|
||||
break
|
||||
}
|
||||
case 'nevent': {
|
||||
references.push({
|
||||
text: ref[0],
|
||||
event: data as EventPointer
|
||||
})
|
||||
break
|
||||
}
|
||||
case 'naddr': {
|
||||
references.push({
|
||||
text: ref[0],
|
||||
address: data as AddressPointer
|
||||
})
|
||||
break
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
/***/
|
||||
}
|
||||
} else if (ref[3]) {
|
||||
// it's a NIP-10 mention
|
||||
let idx = parseInt(ref[3], 10)
|
||||
let tag = evt.tags[idx]
|
||||
if (!tag) continue
|
||||
|
||||
switch (tag[0]) {
|
||||
case 'p': {
|
||||
references.push({
|
||||
text: ref[0],
|
||||
profile: {pubkey: tag[1], relays: tag[2] ? [tag[2]] : []}
|
||||
})
|
||||
break
|
||||
}
|
||||
case 'e': {
|
||||
references.push({
|
||||
text: ref[0],
|
||||
event: {id: tag[1], relays: tag[2] ? [tag[2]] : []}
|
||||
})
|
||||
break
|
||||
}
|
||||
case 'a': {
|
||||
try {
|
||||
let [kind, pubkey, identifier] = ref[1].split(':')
|
||||
references.push({
|
||||
text: ref[0],
|
||||
address: {
|
||||
identifier,
|
||||
pubkey,
|
||||
kind: parseInt(kind, 10),
|
||||
relays: tag[2] ? [tag[2]] : []
|
||||
}
|
||||
})
|
||||
} catch (err) {
|
||||
/***/
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return references
|
||||
}
|
||||
Reference in New Issue
Block a user