From 73987c7360882f6fe57f8fecb066ce8cf0727695 Mon Sep 17 00:00:00 2001 From: Asai Toshiya Date: Thu, 21 Nov 2024 23:51:38 +0900 Subject: [PATCH] Revert "nip19: remove note1." This reverts commit a8a805fb712a19f59da5dc752cde21bc72af0209. --- nip19.test.ts | 20 +++++++++++++++++++- nip19.ts | 8 ++++++++ nip21.test.ts | 11 ++++++----- nip27.test.ts | 34 ++++++++++++++-------------------- nip27.ts | 4 ++-- references.ts | 9 ++++++++- 6 files changed, 57 insertions(+), 29 deletions(-) diff --git a/nip19.test.ts b/nip19.test.ts index 3cf2ffa5..7654c68f 100644 --- a/nip19.test.ts +++ b/nip19.test.ts @@ -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() }) diff --git a/nip19.ts b/nip19.ts index 216abc98..cf04c5d6 100644 --- a/nip19.ts +++ b/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 = { @@ -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: Prefix, data: Uint8Array): `${Prefix}1${string}` { let words = bech32.toWords(data) return bech32.encode(prefix, words, Bech32MaxSize) as `${Prefix}1${string}` diff --git a/nip21.test.ts b/nip21.test.ts index a14be3c3..d1ac4fb3 100644 --- a/nip21.test.ts +++ b/nip21.test.ts @@ -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', }, }) }) diff --git a/nip27.test.ts b/nip27.test.ts index 732452b4..02de0c0a 100644 --- a/nip27.test.ts +++ b/nip27.test.ts @@ -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'], - }, - type: 'nevent', + data: '46d731680add2990efe1cc619dc9b8014feeb23261ab9dee50e9d11814de5a2b', + type: 'note', }, - 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 diff --git a/nip27.ts b/nip27.ts index 2ae6489e..d45224cc 100644 --- a/nip27.ts +++ b/nip27.ts @@ -44,8 +44,8 @@ export function* matchAll(content: string): Iterable { * switch(decoded.type) { * case 'npub': * return renderMention(decoded) - * case 'nevent': - * return renderEvent(decoded) + * case 'note': + * return renderNote(decoded) * default: * return value * } diff --git a/references.ts b/references.ts index 1a273529..5c6acb9f 100644 --- a/references.ts +++ b/references.ts @@ -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],