parent
b22e2465cc
commit
2e85f7a5fe
|
@ -244,6 +244,24 @@ describe('NostrTypeGuard', () => {
|
|||
expect(is).toBeFalse()
|
||||
})
|
||||
|
||||
test('isNote', () => {
|
||||
const is = NostrTypeGuard.isNote('note1gmtnz6q2m55epmlpe3semjdcq987av3jvx4emmjsa8g3s9x7tg4sclreky')
|
||||
|
||||
expect(is).toBeTrue()
|
||||
})
|
||||
|
||||
test('isNote with invalid note', () => {
|
||||
const is = NostrTypeGuard.isNote('note1gmtnz6q2m55epmlpe3semjdcq987av3jvx4emmjsa8g3s9x7tg4sçlreky')
|
||||
|
||||
expect(is).toBeFalse()
|
||||
})
|
||||
|
||||
test('isNote with invalid note', () => {
|
||||
const is = NostrTypeGuard.isNote('npub1jz5mdljkmffmqjshpyjgqgrhdkuxd9ztzasv8xeh5q92fv33sjgqy4pats')
|
||||
|
||||
expect(is).toBeFalse()
|
||||
})
|
||||
|
||||
test('isNcryptsec', () => {
|
||||
const is = NostrTypeGuard.isNcryptsec(
|
||||
'ncryptsec1qgg9947rlpvqu76pj5ecreduf9jxhselq2nae2kghhvd5g7dgjtcxfqtd67p9m0w57lspw8gsq6yphnm8623nsl8xn9j4jdzz84zm3frztj3z7s35vpzmqf6ksu8r89qk5z2zxfmu5gv8th8wclt0h4p',
|
||||
|
@ -261,7 +279,7 @@ describe('NostrTypeGuard', () => {
|
|||
})
|
||||
|
||||
test('isNcryptsec with invalid ncrytpsec', () => {
|
||||
const is = NostrTypeGuard.isNcryptsec('npub1jz5mdljkmffmqjshpyjgqgrhdkuxd9ztzãsv8xeh5q92fv33sjgqy4pats')
|
||||
const is = NostrTypeGuard.isNcryptsec('note1gmtnz6q2m55epmlpe3semjdcq987av3jvx4emmjsa8g3s9x7tg4sçlreky')
|
||||
|
||||
expect(is).toBeFalse()
|
||||
})
|
||||
|
|
8
nip19.ts
8
nip19.ts
|
@ -8,6 +8,7 @@ export type NEvent = `nevent1${string}`
|
|||
export type NAddr = `naddr1${string}`
|
||||
export type NSec = `nsec1${string}`
|
||||
export type NPub = `npub1${string}`
|
||||
export type Note = `note1${string}`
|
||||
export type Ncryptsec = `ncryptsec1${string}`
|
||||
|
||||
export const NostrTypeGuard = {
|
||||
|
@ -16,6 +17,7 @@ export const NostrTypeGuard = {
|
|||
isNAddr: (value?: string | null): value is NAddr => /^naddr1[a-z\d]+$/.test(value || ''),
|
||||
isNSec: (value?: string | null): value is NSec => /^nsec1[a-z\d]{58}$/.test(value || ''),
|
||||
isNPub: (value?: string | null): value is NPub => /^npub1[a-z\d]{58}$/.test(value || ''),
|
||||
isNote: (value?: string | null): value is Note => /^note1[a-z\d]+$/.test(value || ''),
|
||||
isNcryptsec: (value?: string | null): value is Ncryptsec => /^ncryptsec1[a-z\d]+$/.test(value || ''),
|
||||
}
|
||||
|
||||
|
@ -65,6 +67,7 @@ type Prefixes = {
|
|||
naddr: AddressPointer
|
||||
nsec: Uint8Array
|
||||
npub: string
|
||||
note: string
|
||||
}
|
||||
|
||||
type DecodeValue<Prefix extends keyof Prefixes> = {
|
||||
|
@ -137,6 +140,7 @@ export function decode(nip19: string): DecodeResult {
|
|||
return { type: prefix, data }
|
||||
|
||||
case 'npub':
|
||||
case 'note':
|
||||
return { type: prefix, data: bytesToHex(data) }
|
||||
|
||||
default:
|
||||
|
@ -169,6 +173,10 @@ export function npubEncode(hex: string): NPub {
|
|||
return encodeBytes('npub', hexToBytes(hex))
|
||||
}
|
||||
|
||||
export function noteEncode(hex: string): Note {
|
||||
return encodeBytes('note', hexToBytes(hex))
|
||||
}
|
||||
|
||||
function encodeBech32<Prefix extends string>(prefix: Prefix, data: Uint8Array): `${Prefix}1${string}` {
|
||||
let words = bech32.toWords(data)
|
||||
return bech32.encode(prefix, words, Bech32MaxSize) as `${Prefix}1${string}`
|
||||
|
|
|
@ -3,6 +3,7 @@ import { test as testRegex, parse } from './nip21.ts'
|
|||
|
||||
test('test()', () => {
|
||||
expect(testRegex('nostr:npub108pv4cg5ag52nq082kd5leu9ffrn2gdg6g4xdwatn73y36uzplmq9uyev6')).toBe(true)
|
||||
expect(testRegex('nostr:note1gmtnz6q2m55epmlpe3semjdcq987av3jvx4emmjsa8g3s9x7tg4sclreky')).toBe(true)
|
||||
expect(testRegex(' nostr:npub108pv4cg5ag52nq082kd5leu9ffrn2gdg6g4xdwatn73y36uzplmq9uyev6')).toBe(false)
|
||||
expect(testRegex('nostr:')).toBe(false)
|
||||
expect(testRegex('nostr:npub108pv4cg5ag52nQq082kd5leu9ffrn2gdg6g4xdwatn73y36uzplmq9uyev6')).toBe(false)
|
||||
|
@ -10,14 +11,14 @@ test('test()', () => {
|
|||
})
|
||||
|
||||
test('parse', () => {
|
||||
const result = parse('nostr:npub108pv4cg5ag52nq082kd5leu9ffrn2gdg6g4xdwatn73y36uzplmq9uyev6')
|
||||
const result = parse('nostr:note1gmtnz6q2m55epmlpe3semjdcq987av3jvx4emmjsa8g3s9x7tg4sclreky')
|
||||
|
||||
expect(result).toEqual({
|
||||
uri: 'nostr:npub108pv4cg5ag52nq082kd5leu9ffrn2gdg6g4xdwatn73y36uzplmq9uyev6',
|
||||
value: 'npub108pv4cg5ag52nq082kd5leu9ffrn2gdg6g4xdwatn73y36uzplmq9uyev6',
|
||||
uri: 'nostr:note1gmtnz6q2m55epmlpe3semjdcq987av3jvx4emmjsa8g3s9x7tg4sclreky',
|
||||
value: 'note1gmtnz6q2m55epmlpe3semjdcq987av3jvx4emmjsa8g3s9x7tg4sclreky',
|
||||
decoded: {
|
||||
type: 'npub',
|
||||
data: '79c2cae114ea28a981e7559b4fe7854a473521a8d22a66bbab9fa248eb820ff6',
|
||||
type: 'note',
|
||||
data: '46d731680add2990efe1cc619dc9b8014feeb23261ab9dee50e9d11814de5a2b',
|
||||
},
|
||||
})
|
||||
})
|
||||
|
|
|
@ -3,7 +3,7 @@ import { matchAll, replaceAll } from './nip27.ts'
|
|||
|
||||
test('matchAll', () => {
|
||||
const result = matchAll(
|
||||
'Hello nostr:npub108pv4cg5ag52nq082kd5leu9ffrn2gdg6g4xdwatn73y36uzplmq9uyev6!\n\nnostr:nevent1qqst8cujky046negxgwwm5ynqwn53t8aqjr6afd8g59nfqwxpdhylpcpzamhxue69uhhyetvv9ujuetcv9khqmr99e3k7mg8arnc9',
|
||||
'Hello nostr:npub108pv4cg5ag52nq082kd5leu9ffrn2gdg6g4xdwatn73y36uzplmq9uyev6!\n\nnostr:note1gmtnz6q2m55epmlpe3semjdcq987av3jvx4emmjsa8g3s9x7tg4sclreky',
|
||||
)
|
||||
|
||||
expect([...result]).toEqual([
|
||||
|
@ -18,52 +18,46 @@ test('matchAll', () => {
|
|||
end: 75,
|
||||
},
|
||||
{
|
||||
uri: 'nostr:nevent1qqst8cujky046negxgwwm5ynqwn53t8aqjr6afd8g59nfqwxpdhylpcpzamhxue69uhhyetvv9ujuetcv9khqmr99e3k7mg8arnc9',
|
||||
value: 'nevent1qqst8cujky046negxgwwm5ynqwn53t8aqjr6afd8g59nfqwxpdhylpcpzamhxue69uhhyetvv9ujuetcv9khqmr99e3k7mg8arnc9',
|
||||
uri: 'nostr:note1gmtnz6q2m55epmlpe3semjdcq987av3jvx4emmjsa8g3s9x7tg4sclreky',
|
||||
value: 'note1gmtnz6q2m55epmlpe3semjdcq987av3jvx4emmjsa8g3s9x7tg4sclreky',
|
||||
decoded: {
|
||||
type: 'nevent',
|
||||
data: {
|
||||
id: 'b3e392b11f5d4f28321cedd09303a748acfd0487aea5a7450b3481c60b6e4f87',
|
||||
relays: ['wss://relay.example.com'],
|
||||
},
|
||||
type: 'note',
|
||||
data: '46d731680add2990efe1cc619dc9b8014feeb23261ab9dee50e9d11814de5a2b',
|
||||
},
|
||||
start: 78,
|
||||
end: 192,
|
||||
end: 147,
|
||||
},
|
||||
])
|
||||
})
|
||||
|
||||
test('matchAll with an invalid nip19', () => {
|
||||
const result = matchAll(
|
||||
'Hello nostr:npub129tvj896hqqkljerxkccpj9flshwnw999v9uwn9lfmwlj8vnzwgq9y5llnpub1rujdpkd8mwezrvpqd2rx2zphfaztqrtsfg6w3vdnlj!\n\nnostr:nevent1qqst8cujky046negxgwwm5ynqwn53t8aqjr6afd8g59nfqwxpdhylpcpzamhxue69uhhyetvv9ujuetcv9khqmr99e3k7mg8arnc9',
|
||||
'Hello nostr:npub129tvj896hqqkljerxkccpj9flshwnw999v9uwn9lfmwlj8vnzwgq9y5llnpub1rujdpkd8mwezrvpqd2rx2zphfaztqrtsfg6w3vdnlj!\n\nnostr:note1gmtnz6q2m55epmlpe3semjdcq987av3jvx4emmjsa8g3s9x7tg4sclreky',
|
||||
)
|
||||
|
||||
expect([...result]).toEqual([
|
||||
{
|
||||
decoded: {
|
||||
data: {
|
||||
id: 'b3e392b11f5d4f28321cedd09303a748acfd0487aea5a7450b3481c60b6e4f87',
|
||||
relays: ['wss://relay.example.com'],
|
||||
data: '46d731680add2990efe1cc619dc9b8014feeb23261ab9dee50e9d11814de5a2b',
|
||||
type: 'note',
|
||||
},
|
||||
type: 'nevent',
|
||||
},
|
||||
end: 238,
|
||||
end: 193,
|
||||
start: 124,
|
||||
uri: 'nostr:nevent1qqst8cujky046negxgwwm5ynqwn53t8aqjr6afd8g59nfqwxpdhylpcpzamhxue69uhhyetvv9ujuetcv9khqmr99e3k7mg8arnc9',
|
||||
value: 'nevent1qqst8cujky046negxgwwm5ynqwn53t8aqjr6afd8g59nfqwxpdhylpcpzamhxue69uhhyetvv9ujuetcv9khqmr99e3k7mg8arnc9',
|
||||
uri: 'nostr:note1gmtnz6q2m55epmlpe3semjdcq987av3jvx4emmjsa8g3s9x7tg4sclreky',
|
||||
value: 'note1gmtnz6q2m55epmlpe3semjdcq987av3jvx4emmjsa8g3s9x7tg4sclreky',
|
||||
},
|
||||
])
|
||||
})
|
||||
|
||||
test('replaceAll', () => {
|
||||
const content =
|
||||
'Hello nostr:npub108pv4cg5ag52nq082kd5leu9ffrn2gdg6g4xdwatn73y36uzplmq9uyev6!\n\nnostr:nevent1qqst8cujky046negxgwwm5ynqwn53t8aqjr6afd8g59nfqwxpdhylpcpzamhxue69uhhyetvv9ujuetcv9khqmr99e3k7mg8arnc9'
|
||||
'Hello nostr:npub108pv4cg5ag52nq082kd5leu9ffrn2gdg6g4xdwatn73y36uzplmq9uyev6!\n\nnostr:note1gmtnz6q2m55epmlpe3semjdcq987av3jvx4emmjsa8g3s9x7tg4sclreky'
|
||||
|
||||
const result = replaceAll(content, ({ decoded, value }) => {
|
||||
switch (decoded.type) {
|
||||
case 'npub':
|
||||
return '@alex'
|
||||
case 'nevent':
|
||||
case 'note':
|
||||
return '!1234'
|
||||
default:
|
||||
return value
|
||||
|
|
4
nip27.ts
4
nip27.ts
|
@ -44,8 +44,8 @@ export function* matchAll(content: string): Iterable<NostrURIMatch> {
|
|||
* switch(decoded.type) {
|
||||
* case 'npub':
|
||||
* return renderMention(decoded)
|
||||
* case 'nevent':
|
||||
* return renderEvent(decoded)
|
||||
* case 'note':
|
||||
* return renderNote(decoded)
|
||||
* default:
|
||||
* return value
|
||||
* }
|
||||
|
|
|
@ -9,7 +9,7 @@ type Reference = {
|
|||
address?: AddressPointer
|
||||
}
|
||||
|
||||
const mentionRegex = /\bnostr:((npub|naddr|nevent|nprofile)1\w+)\b|#\[(\d+)\]/g
|
||||
const mentionRegex = /\bnostr:((note|npub|naddr|nevent|nprofile)1\w+)\b|#\[(\d+)\]/g
|
||||
|
||||
export function parseReferences(evt: Event): Reference[] {
|
||||
let references: Reference[] = []
|
||||
|
@ -33,6 +33,13 @@ export function parseReferences(evt: Event): Reference[] {
|
|||
})
|
||||
break
|
||||
}
|
||||
case 'note': {
|
||||
references.push({
|
||||
text: ref[0],
|
||||
event: { id: data as string, relays: [] },
|
||||
})
|
||||
break
|
||||
}
|
||||
case 'nevent': {
|
||||
references.push({
|
||||
text: ref[0],
|
||||
|
|
Loading…
Reference in New Issue