nostr-core 0.4.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +93 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +99 -3
- package/dist/index.js.map +1 -1
- package/dist/lnurl.d.ts +161 -0
- package/dist/lnurl.d.ts.map +1 -0
- package/dist/lnurl.js +343 -0
- package/dist/lnurl.js.map +1 -0
- package/dist/nip02.d.ts +27 -0
- package/dist/nip02.d.ts.map +1 -0
- package/dist/nip02.js +55 -0
- package/dist/nip02.js.map +1 -0
- package/dist/nip05.d.ts +24 -0
- package/dist/nip05.d.ts.map +1 -0
- package/dist/nip05.js +57 -0
- package/dist/nip05.js.map +1 -0
- package/dist/nip06.d.ts +26 -0
- package/dist/nip06.d.ts.map +1 -0
- package/dist/nip06.js +49 -0
- package/dist/nip06.js.map +1 -0
- package/dist/nip09.d.ts +34 -0
- package/dist/nip09.d.ts.map +1 -0
- package/dist/nip09.js +66 -0
- package/dist/nip09.js.map +1 -0
- package/dist/nip10.d.ts +40 -0
- package/dist/nip10.d.ts.map +1 -0
- package/dist/nip10.js +69 -0
- package/dist/nip10.js.map +1 -0
- package/dist/nip11.d.ts +41 -0
- package/dist/nip11.d.ts.map +1 -0
- package/dist/nip11.js +38 -0
- package/dist/nip11.js.map +1 -0
- package/dist/nip13.d.ts +26 -0
- package/dist/nip13.d.ts.map +1 -0
- package/dist/nip13.js +75 -0
- package/dist/nip13.js.map +1 -0
- package/dist/nip18.d.ts +28 -0
- package/dist/nip18.d.ts.map +1 -0
- package/dist/nip18.js +66 -0
- package/dist/nip18.js.map +1 -0
- package/dist/nip21.d.ts +14 -0
- package/dist/nip21.d.ts.map +1 -0
- package/dist/nip21.js +24 -0
- package/dist/nip21.js.map +1 -0
- package/dist/nip22.d.ts +26 -0
- package/dist/nip22.d.ts.map +1 -0
- package/dist/nip22.js +109 -0
- package/dist/nip22.js.map +1 -0
- package/dist/nip23.d.ts +24 -0
- package/dist/nip23.d.ts.map +1 -0
- package/dist/nip23.js +70 -0
- package/dist/nip23.js.map +1 -0
- package/dist/nip24.d.ts +31 -0
- package/dist/nip24.d.ts.map +1 -0
- package/dist/nip24.js +75 -0
- package/dist/nip24.js.map +1 -0
- package/dist/nip25.d.ts +32 -0
- package/dist/nip25.d.ts.map +1 -0
- package/dist/nip25.js +54 -0
- package/dist/nip25.js.map +1 -0
- package/dist/nip27.d.ts +16 -0
- package/dist/nip27.d.ts.map +1 -0
- package/dist/nip27.js +44 -0
- package/dist/nip27.js.map +1 -0
- package/dist/nip28.d.ts +52 -0
- package/dist/nip28.d.ts.map +1 -0
- package/dist/nip28.js +118 -0
- package/dist/nip28.js.map +1 -0
- package/dist/nip29.d.ts +60 -0
- package/dist/nip29.d.ts.map +1 -0
- package/dist/nip29.js +122 -0
- package/dist/nip29.js.map +1 -0
- package/dist/nip30.d.ts +18 -0
- package/dist/nip30.d.ts.map +1 -0
- package/dist/nip30.js +24 -0
- package/dist/nip30.js.map +1 -0
- package/dist/nip31.d.ts +11 -0
- package/dist/nip31.d.ts.map +1 -0
- package/dist/nip31.js +15 -0
- package/dist/nip31.js.map +1 -0
- package/dist/nip36.d.ts +14 -0
- package/dist/nip36.d.ts.map +1 -0
- package/dist/nip36.js +24 -0
- package/dist/nip36.js.map +1 -0
- package/dist/nip40.d.ts +14 -0
- package/dist/nip40.d.ts.map +1 -0
- package/dist/nip40.js +26 -0
- package/dist/nip40.js.map +1 -0
- package/dist/nip42.d.ts +20 -0
- package/dist/nip42.d.ts.map +1 -0
- package/dist/nip42.js +38 -0
- package/dist/nip42.js.map +1 -0
- package/dist/nip48.d.ts +23 -0
- package/dist/nip48.d.ts.map +1 -0
- package/dist/nip48.js +30 -0
- package/dist/nip48.js.map +1 -0
- package/dist/nip50.d.ts +23 -0
- package/dist/nip50.d.ts.map +1 -0
- package/dist/nip50.js +47 -0
- package/dist/nip50.js.map +1 -0
- package/dist/nip51.d.ts +57 -0
- package/dist/nip51.d.ts.map +1 -0
- package/dist/nip51.js +118 -0
- package/dist/nip51.js.map +1 -0
- package/dist/nip52.d.ts +112 -0
- package/dist/nip52.d.ts.map +1 -0
- package/dist/nip52.js +405 -0
- package/dist/nip52.js.map +1 -0
- package/dist/nip56.d.ts +28 -0
- package/dist/nip56.d.ts.map +1 -0
- package/dist/nip56.js +60 -0
- package/dist/nip56.js.map +1 -0
- package/dist/nip57.d.ts +48 -0
- package/dist/nip57.d.ts.map +1 -0
- package/dist/nip57.js +140 -0
- package/dist/nip57.js.map +1 -0
- package/dist/nip58.d.ts +133 -0
- package/dist/nip58.d.ts.map +1 -0
- package/dist/nip58.js +275 -0
- package/dist/nip58.js.map +1 -0
- package/dist/nip59.js +1 -1
- package/dist/nip65.d.ts +28 -0
- package/dist/nip65.d.ts.map +1 -0
- package/dist/nip65.js +83 -0
- package/dist/nip65.js.map +1 -0
- package/dist/nip75.d.ts +43 -0
- package/dist/nip75.d.ts.map +1 -0
- package/dist/nip75.js +144 -0
- package/dist/nip75.js.map +1 -0
- package/dist/nip98.d.ts +24 -0
- package/dist/nip98.d.ts.map +1 -0
- package/dist/nip98.js +68 -0
- package/dist/nip98.js.map +1 -0
- package/dist/relay.d.ts +2 -0
- package/dist/relay.d.ts.map +1 -1
- package/dist/relay.js +20 -0
- package/dist/relay.js.map +1 -1
- package/package.json +35 -4
package/dist/lnurl.js
ADDED
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
import { bech32 } from '@scure/base';
|
|
2
|
+
import { utf8Encoder, utf8Decoder } from './utils.js';
|
|
3
|
+
// ── Error ──────────────────────────────────────────────────────────────
|
|
4
|
+
export class LnurlError extends Error {
|
|
5
|
+
code;
|
|
6
|
+
constructor(message, code = 'LNURL_ERROR') {
|
|
7
|
+
super(message);
|
|
8
|
+
this.name = 'LnurlError';
|
|
9
|
+
this.code = code;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
// ── LUD-01: Bech32 encode/decode ───────────────────────────────────────
|
|
13
|
+
/**
|
|
14
|
+
* Encode a URL as an LNURL bech32 string.
|
|
15
|
+
*/
|
|
16
|
+
export function encodeLnurl(url) {
|
|
17
|
+
const data = utf8Encoder.encode(url);
|
|
18
|
+
const words = bech32.toWords(data);
|
|
19
|
+
return bech32.encode('lnurl', words, 1023);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Decode an LNURL bech32 string back to a URL.
|
|
23
|
+
*/
|
|
24
|
+
export function decodeLnurl(encoded) {
|
|
25
|
+
const { prefix, words } = bech32.decode(encoded.toLowerCase(), 1023);
|
|
26
|
+
if (prefix !== 'lnurl') {
|
|
27
|
+
throw new LnurlError(`Invalid LNURL prefix: expected "lnurl", got "${prefix}"`);
|
|
28
|
+
}
|
|
29
|
+
const data = new Uint8Array(bech32.fromWords(words));
|
|
30
|
+
return utf8Decoder.decode(data);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Check if a string is a valid bech32-encoded LNURL.
|
|
34
|
+
*/
|
|
35
|
+
export function isLnurl(str) {
|
|
36
|
+
try {
|
|
37
|
+
decodeLnurl(str);
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
// ── LUD-17: Scheme prefixes ────────────────────────────────────────────
|
|
45
|
+
const SCHEME_MAP = {
|
|
46
|
+
'lnurlp://': 'payRequest',
|
|
47
|
+
'lnurlw://': 'withdrawRequest',
|
|
48
|
+
'lnurlc://': 'channelRequest',
|
|
49
|
+
'keyauth://': 'login',
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Resolve an LNURL string to a plain URL.
|
|
53
|
+
* Accepts bech32-encoded LNURL, scheme-prefixed URLs (LUD-17),
|
|
54
|
+
* or plain https:// URLs (passthrough).
|
|
55
|
+
*/
|
|
56
|
+
export function resolveUrl(input) {
|
|
57
|
+
// LUD-17: scheme prefixes
|
|
58
|
+
for (const [scheme, tag] of Object.entries(SCHEME_MAP)) {
|
|
59
|
+
if (input.startsWith(scheme)) {
|
|
60
|
+
const rest = input.slice(scheme.length);
|
|
61
|
+
const isOnion = rest.includes('.onion');
|
|
62
|
+
const protocol = isOnion ? 'http://' : 'https://';
|
|
63
|
+
return { url: `${protocol}${rest}`, tag };
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// Plain URL passthrough
|
|
67
|
+
if (input.startsWith('https://') || input.startsWith('http://')) {
|
|
68
|
+
return { url: input };
|
|
69
|
+
}
|
|
70
|
+
// LUD-01: bech32
|
|
71
|
+
const url = decodeLnurl(input);
|
|
72
|
+
return { url };
|
|
73
|
+
}
|
|
74
|
+
// ── LUD-20: Metadata parsing ───────────────────────────────────────────
|
|
75
|
+
/**
|
|
76
|
+
* Parse the LNURL metadata JSON string into structured data.
|
|
77
|
+
* Metadata is a JSON-encoded array of [mime-type, content] tuples.
|
|
78
|
+
*/
|
|
79
|
+
export function parseLnurlMetadata(metadata) {
|
|
80
|
+
let entries;
|
|
81
|
+
try {
|
|
82
|
+
entries = JSON.parse(metadata);
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
throw new LnurlError('Invalid LNURL metadata: not valid JSON');
|
|
86
|
+
}
|
|
87
|
+
if (!Array.isArray(entries)) {
|
|
88
|
+
throw new LnurlError('Invalid LNURL metadata: expected array');
|
|
89
|
+
}
|
|
90
|
+
let plainText = '';
|
|
91
|
+
let longDesc;
|
|
92
|
+
let image;
|
|
93
|
+
for (const entry of entries) {
|
|
94
|
+
if (!Array.isArray(entry) || entry.length < 2)
|
|
95
|
+
continue;
|
|
96
|
+
const [mime, content] = entry;
|
|
97
|
+
if (mime === 'text/plain') {
|
|
98
|
+
plainText = content;
|
|
99
|
+
}
|
|
100
|
+
else if (mime === 'text/long-desc') {
|
|
101
|
+
longDesc = content;
|
|
102
|
+
}
|
|
103
|
+
else if (mime.startsWith('image/') && !image) {
|
|
104
|
+
image = { type: mime, data: content };
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return { plainText, longDesc, image, entries };
|
|
108
|
+
}
|
|
109
|
+
// ── LUD-06: payRequest ─────────────────────────────────────────────────
|
|
110
|
+
/**
|
|
111
|
+
* Fetch a pay request from an LNURL (bech32, scheme-prefixed, or plain URL).
|
|
112
|
+
*/
|
|
113
|
+
export async function fetchPayRequest(input) {
|
|
114
|
+
const { url } = resolveUrl(input);
|
|
115
|
+
let data;
|
|
116
|
+
try {
|
|
117
|
+
const res = await fetch(url);
|
|
118
|
+
if (!res.ok)
|
|
119
|
+
throw new LnurlError(`HTTP ${res.status} from ${url}`);
|
|
120
|
+
data = (await res.json());
|
|
121
|
+
}
|
|
122
|
+
catch (err) {
|
|
123
|
+
if (err instanceof LnurlError)
|
|
124
|
+
throw err;
|
|
125
|
+
throw new LnurlError(`Failed to fetch pay request: ${err.message}`);
|
|
126
|
+
}
|
|
127
|
+
if (data.status === 'ERROR') {
|
|
128
|
+
throw new LnurlError(`LNURL error: ${data.reason || 'Unknown'}`);
|
|
129
|
+
}
|
|
130
|
+
if (data.tag !== 'payRequest') {
|
|
131
|
+
throw new LnurlError(`Expected tag "payRequest", got "${data.tag}"`);
|
|
132
|
+
}
|
|
133
|
+
return {
|
|
134
|
+
tag: 'payRequest',
|
|
135
|
+
callback: data.callback,
|
|
136
|
+
minSendable: data.minSendable,
|
|
137
|
+
maxSendable: data.maxSendable,
|
|
138
|
+
metadata: data.metadata,
|
|
139
|
+
commentAllowed: data.commentAllowed,
|
|
140
|
+
payerData: data.payerData,
|
|
141
|
+
allowsNostr: data.allowsNostr,
|
|
142
|
+
nostrPubkey: data.nostrPubkey,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Request an invoice from a pay request callback (LUD-06/12/18).
|
|
147
|
+
*/
|
|
148
|
+
export async function requestInvoice(payRequest, amountMsats, opts) {
|
|
149
|
+
if (amountMsats < payRequest.minSendable || amountMsats > payRequest.maxSendable) {
|
|
150
|
+
throw new LnurlError(`Amount ${amountMsats} msats outside allowed range [${payRequest.minSendable}, ${payRequest.maxSendable}]`);
|
|
151
|
+
}
|
|
152
|
+
const sep = payRequest.callback.includes('?') ? '&' : '?';
|
|
153
|
+
let url = `${payRequest.callback}${sep}amount=${amountMsats}`;
|
|
154
|
+
// LUD-12: comment
|
|
155
|
+
if (opts?.comment) {
|
|
156
|
+
if (payRequest.commentAllowed && opts.comment.length > payRequest.commentAllowed) {
|
|
157
|
+
throw new LnurlError(`Comment exceeds max length of ${payRequest.commentAllowed} chars`);
|
|
158
|
+
}
|
|
159
|
+
url += `&comment=${encodeURIComponent(opts.comment)}`;
|
|
160
|
+
}
|
|
161
|
+
// LUD-18: payer data
|
|
162
|
+
if (opts?.payerData) {
|
|
163
|
+
url += `&payerdata=${encodeURIComponent(JSON.stringify(opts.payerData))}`;
|
|
164
|
+
}
|
|
165
|
+
// Nostr zap request
|
|
166
|
+
if (opts?.nostr) {
|
|
167
|
+
url += `&nostr=${encodeURIComponent(opts.nostr)}`;
|
|
168
|
+
}
|
|
169
|
+
let data;
|
|
170
|
+
try {
|
|
171
|
+
const res = await fetch(url);
|
|
172
|
+
if (!res.ok)
|
|
173
|
+
throw new LnurlError(`Callback HTTP ${res.status}`);
|
|
174
|
+
data = (await res.json());
|
|
175
|
+
}
|
|
176
|
+
catch (err) {
|
|
177
|
+
if (err instanceof LnurlError)
|
|
178
|
+
throw err;
|
|
179
|
+
throw new LnurlError(`Failed to request invoice: ${err.message}`);
|
|
180
|
+
}
|
|
181
|
+
if (data.status === 'ERROR') {
|
|
182
|
+
throw new LnurlError(`Callback error: ${data.reason || 'Unknown'}`);
|
|
183
|
+
}
|
|
184
|
+
if (!data.pr) {
|
|
185
|
+
throw new LnurlError('Invalid callback response: missing invoice (pr field)');
|
|
186
|
+
}
|
|
187
|
+
return {
|
|
188
|
+
pr: data.pr,
|
|
189
|
+
routes: data.routes || [],
|
|
190
|
+
successAction: data.successAction,
|
|
191
|
+
verify: data.verify,
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
// ── LUD-03: withdrawRequest ────────────────────────────────────────────
|
|
195
|
+
/**
|
|
196
|
+
* Fetch a withdraw request from an LNURL.
|
|
197
|
+
*/
|
|
198
|
+
export async function fetchWithdrawRequest(input) {
|
|
199
|
+
const { url } = resolveUrl(input);
|
|
200
|
+
let data;
|
|
201
|
+
try {
|
|
202
|
+
const res = await fetch(url);
|
|
203
|
+
if (!res.ok)
|
|
204
|
+
throw new LnurlError(`HTTP ${res.status} from ${url}`);
|
|
205
|
+
data = (await res.json());
|
|
206
|
+
}
|
|
207
|
+
catch (err) {
|
|
208
|
+
if (err instanceof LnurlError)
|
|
209
|
+
throw err;
|
|
210
|
+
throw new LnurlError(`Failed to fetch withdraw request: ${err.message}`);
|
|
211
|
+
}
|
|
212
|
+
if (data.status === 'ERROR') {
|
|
213
|
+
throw new LnurlError(`LNURL error: ${data.reason || 'Unknown'}`);
|
|
214
|
+
}
|
|
215
|
+
if (data.tag !== 'withdrawRequest') {
|
|
216
|
+
throw new LnurlError(`Expected tag "withdrawRequest", got "${data.tag}"`);
|
|
217
|
+
}
|
|
218
|
+
return {
|
|
219
|
+
tag: 'withdrawRequest',
|
|
220
|
+
callback: data.callback,
|
|
221
|
+
k1: data.k1,
|
|
222
|
+
defaultDescription: data.defaultDescription,
|
|
223
|
+
minWithdrawable: data.minWithdrawable,
|
|
224
|
+
maxWithdrawable: data.maxWithdrawable,
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Submit a withdraw request with a BOLT-11 invoice.
|
|
229
|
+
*/
|
|
230
|
+
export async function submitWithdrawRequest(withdrawRequest, invoice) {
|
|
231
|
+
const sep = withdrawRequest.callback.includes('?') ? '&' : '?';
|
|
232
|
+
const url = `${withdrawRequest.callback}${sep}k1=${withdrawRequest.k1}&pr=${invoice}`;
|
|
233
|
+
let data;
|
|
234
|
+
try {
|
|
235
|
+
const res = await fetch(url);
|
|
236
|
+
if (!res.ok)
|
|
237
|
+
throw new LnurlError(`Withdraw callback HTTP ${res.status}`);
|
|
238
|
+
data = (await res.json());
|
|
239
|
+
}
|
|
240
|
+
catch (err) {
|
|
241
|
+
if (err instanceof LnurlError)
|
|
242
|
+
throw err;
|
|
243
|
+
throw new LnurlError(`Failed to submit withdraw request: ${err.message}`);
|
|
244
|
+
}
|
|
245
|
+
if (data.status === 'ERROR') {
|
|
246
|
+
throw new LnurlError(`Withdraw error: ${data.reason || 'Unknown'}`);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
// ── LUD-09/10: Success action handling ─────────────────────────────────
|
|
250
|
+
/**
|
|
251
|
+
* Parse and validate a success action object.
|
|
252
|
+
*/
|
|
253
|
+
export function parseSuccessAction(raw) {
|
|
254
|
+
const action = raw;
|
|
255
|
+
if (!action || typeof action !== 'object' || !action.tag) {
|
|
256
|
+
throw new LnurlError('Invalid success action: missing tag');
|
|
257
|
+
}
|
|
258
|
+
switch (action.tag) {
|
|
259
|
+
case 'message':
|
|
260
|
+
return { tag: 'message', message: action.message || '' };
|
|
261
|
+
case 'url':
|
|
262
|
+
return {
|
|
263
|
+
tag: 'url',
|
|
264
|
+
description: action.description || '',
|
|
265
|
+
url: action.url || '',
|
|
266
|
+
};
|
|
267
|
+
case 'aes':
|
|
268
|
+
return {
|
|
269
|
+
tag: 'aes',
|
|
270
|
+
description: action.description || '',
|
|
271
|
+
ciphertext: action.ciphertext || '',
|
|
272
|
+
iv: action.iv || '',
|
|
273
|
+
};
|
|
274
|
+
default:
|
|
275
|
+
throw new LnurlError(`Unknown success action tag: ${action.tag}`);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Decrypt an AES success action using the payment preimage (LUD-10).
|
|
280
|
+
* Uses AES-256-CBC with PKCS5 padding.
|
|
281
|
+
*
|
|
282
|
+
* @param action - The AES success action from the callback response
|
|
283
|
+
* @param preimageHex - The payment preimage as a hex string (32 bytes)
|
|
284
|
+
* @returns The decrypted plaintext string
|
|
285
|
+
*/
|
|
286
|
+
export async function decryptAesSuccessAction(action, preimageHex) {
|
|
287
|
+
// Convert hex preimage to bytes (32 bytes = 256-bit key)
|
|
288
|
+
const key = hexToBytes(preimageHex);
|
|
289
|
+
if (key.length !== 32) {
|
|
290
|
+
throw new LnurlError('Preimage must be 32 bytes (64 hex chars)');
|
|
291
|
+
}
|
|
292
|
+
const iv = base64ToBytes(action.iv);
|
|
293
|
+
const ciphertext = base64ToBytes(action.ciphertext);
|
|
294
|
+
// Use Web Crypto API for AES-256-CBC
|
|
295
|
+
const cryptoKey = await crypto.subtle.importKey('raw', key.buffer, { name: 'AES-CBC' }, false, [
|
|
296
|
+
'decrypt',
|
|
297
|
+
]);
|
|
298
|
+
const decrypted = await crypto.subtle.decrypt({ name: 'AES-CBC', iv: iv.buffer }, cryptoKey, ciphertext.buffer);
|
|
299
|
+
return utf8Decoder.decode(new Uint8Array(decrypted));
|
|
300
|
+
}
|
|
301
|
+
// ── LUD-21: Verify payments ────────────────────────────────────────────
|
|
302
|
+
/**
|
|
303
|
+
* Poll a verify URL to check if a payment has been settled.
|
|
304
|
+
*/
|
|
305
|
+
export async function verifyPayment(verifyUrl) {
|
|
306
|
+
let data;
|
|
307
|
+
try {
|
|
308
|
+
const res = await fetch(verifyUrl);
|
|
309
|
+
if (!res.ok)
|
|
310
|
+
throw new LnurlError(`Verify HTTP ${res.status}`);
|
|
311
|
+
data = (await res.json());
|
|
312
|
+
}
|
|
313
|
+
catch (err) {
|
|
314
|
+
if (err instanceof LnurlError)
|
|
315
|
+
throw err;
|
|
316
|
+
throw new LnurlError(`Failed to verify payment: ${err.message}`);
|
|
317
|
+
}
|
|
318
|
+
if (data.status === 'ERROR') {
|
|
319
|
+
throw new LnurlError(`Verify error: ${data.reason || 'Unknown'}`);
|
|
320
|
+
}
|
|
321
|
+
return {
|
|
322
|
+
settled: data.settled,
|
|
323
|
+
preimage: data.preimage || null,
|
|
324
|
+
pr: data.pr,
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
// ── Helpers ────────────────────────────────────────────────────────────
|
|
328
|
+
function hexToBytes(hex) {
|
|
329
|
+
const bytes = new Uint8Array(hex.length / 2);
|
|
330
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
331
|
+
bytes[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
|
|
332
|
+
}
|
|
333
|
+
return bytes;
|
|
334
|
+
}
|
|
335
|
+
function base64ToBytes(b64) {
|
|
336
|
+
const binary = atob(b64);
|
|
337
|
+
const bytes = new Uint8Array(binary.length);
|
|
338
|
+
for (let i = 0; i < binary.length; i++) {
|
|
339
|
+
bytes[i] = binary.charCodeAt(i);
|
|
340
|
+
}
|
|
341
|
+
return bytes;
|
|
342
|
+
}
|
|
343
|
+
//# sourceMappingURL=lnurl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lnurl.js","sourceRoot":"","sources":["../src/lnurl.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAErD,0EAA0E;AAE1E,MAAM,OAAO,UAAW,SAAQ,KAAK;IACnC,IAAI,CAAQ;IACZ,YAAY,OAAe,EAAE,IAAI,GAAG,aAAa;QAC/C,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,YAAY,CAAA;QACxB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;IAClB,CAAC;CACF;AAiFD,0EAA0E;AAE1E;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,MAAM,IAAI,GAAG,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;IACpC,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;IAClC,OAAO,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,CAAA;AAC5C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,OAAe;IACzC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,EAA2B,EAAE,IAAI,CAAC,CAAA;IAC7F,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;QACvB,MAAM,IAAI,UAAU,CAAC,gDAAgD,MAAM,GAAG,CAAC,CAAA;IACjF,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAA;IACpD,OAAO,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;AACjC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,OAAO,CAAC,GAAW;IACjC,IAAI,CAAC;QACH,WAAW,CAAC,GAAG,CAAC,CAAA;QAChB,OAAO,IAAI,CAAA;IACb,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC;AAED,0EAA0E;AAE1E,MAAM,UAAU,GAA2B;IACzC,WAAW,EAAE,YAAY;IACzB,WAAW,EAAE,iBAAiB;IAC9B,WAAW,EAAE,gBAAgB;IAC7B,YAAY,EAAE,OAAO;CACtB,CAAA;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,KAAa;IACtC,0BAA0B;IAC1B,KAAK,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;QACvD,IAAI,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YAC7B,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;YACvC,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAA;YACvC,MAAM,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAA;YACjD,OAAO,EAAE,GAAG,EAAE,GAAG,QAAQ,GAAG,IAAI,EAAE,EAAE,GAAG,EAAE,CAAA;QAC3C,CAAC;IACH,CAAC;IAED,wBAAwB;IACxB,IAAI,KAAK,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAChE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,CAAA;IACvB,CAAC;IAED,iBAAiB;IACjB,MAAM,GAAG,GAAG,WAAW,CAAC,KAAK,CAAC,CAAA;IAC9B,OAAO,EAAE,GAAG,EAAE,CAAA;AAChB,CAAC;AAED,0EAA0E;AAE1E;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,QAAgB;IACjD,IAAI,OAA2B,CAAA;IAC/B,IAAI,CAAC;QACH,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAuB,CAAA;IACtD,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,UAAU,CAAC,wCAAwC,CAAC,CAAA;IAChE,CAAC;IAED,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,UAAU,CAAC,wCAAwC,CAAC,CAAA;IAChE,CAAC;IAED,IAAI,SAAS,GAAG,EAAE,CAAA;IAClB,IAAI,QAA4B,CAAA;IAChC,IAAI,KAAiD,CAAA;IAErD,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;YAAE,SAAQ;QACvD,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,KAAK,CAAA;QAC7B,IAAI,IAAI,KAAK,YAAY,EAAE,CAAC;YAC1B,SAAS,GAAG,OAAO,CAAA;QACrB,CAAC;aAAM,IAAI,IAAI,KAAK,gBAAgB,EAAE,CAAC;YACrC,QAAQ,GAAG,OAAO,CAAA;QACpB,CAAC;aAAM,IAAI,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;YAC/C,KAAK,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,CAAA;QACvC,CAAC;IACH,CAAC;IAED,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,CAAA;AAChD,CAAC;AAED,0EAA0E;AAE1E;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,KAAa;IACjD,MAAM,EAAE,GAAG,EAAE,GAAG,UAAU,CAAC,KAAK,CAAC,CAAA;IAEjC,IAAI,IAA6B,CAAA;IACjC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAA;QAC5B,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,MAAM,IAAI,UAAU,CAAC,QAAQ,GAAG,CAAC,MAAM,SAAS,GAAG,EAAE,CAAC,CAAA;QACnE,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAA4B,CAAA;IACtD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,UAAU;YAAE,MAAM,GAAG,CAAA;QACxC,MAAM,IAAI,UAAU,CAAC,gCAAiC,GAAa,CAAC,OAAO,EAAE,CAAC,CAAA;IAChF,CAAC;IAED,IAAI,IAAI,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;QAC5B,MAAM,IAAI,UAAU,CAAC,gBAAiB,IAAI,CAAC,MAAiB,IAAI,SAAS,EAAE,CAAC,CAAA;IAC9E,CAAC;IAED,IAAI,IAAI,CAAC,GAAG,KAAK,YAAY,EAAE,CAAC;QAC9B,MAAM,IAAI,UAAU,CAAC,mCAAmC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAA;IACtE,CAAC;IAED,OAAO;QACL,GAAG,EAAE,YAAY;QACjB,QAAQ,EAAE,IAAI,CAAC,QAAkB;QACjC,WAAW,EAAE,IAAI,CAAC,WAAqB;QACvC,WAAW,EAAE,IAAI,CAAC,WAAqB;QACvC,QAAQ,EAAE,IAAI,CAAC,QAAkB;QACjC,cAAc,EAAE,IAAI,CAAC,cAAoC;QACzD,SAAS,EAAE,IAAI,CAAC,SAAsC;QACtD,WAAW,EAAE,IAAI,CAAC,WAAkC;QACpD,WAAW,EAAE,IAAI,CAAC,WAAiC;KACpD,CAAA;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,UAA8B,EAC9B,WAAmB,EACnB,IAA4B;IAE5B,IAAI,WAAW,GAAG,UAAU,CAAC,WAAW,IAAI,WAAW,GAAG,UAAU,CAAC,WAAW,EAAE,CAAC;QACjF,MAAM,IAAI,UAAU,CAClB,UAAU,WAAW,iCAAiC,UAAU,CAAC,WAAW,KAAK,UAAU,CAAC,WAAW,GAAG,CAC3G,CAAA;IACH,CAAC;IAED,MAAM,GAAG,GAAG,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAA;IACzD,IAAI,GAAG,GAAG,GAAG,UAAU,CAAC,QAAQ,GAAG,GAAG,UAAU,WAAW,EAAE,CAAA;IAE7D,kBAAkB;IAClB,IAAI,IAAI,EAAE,OAAO,EAAE,CAAC;QAClB,IAAI,UAAU,CAAC,cAAc,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,UAAU,CAAC,cAAc,EAAE,CAAC;YACjF,MAAM,IAAI,UAAU,CAAC,iCAAiC,UAAU,CAAC,cAAc,QAAQ,CAAC,CAAA;QAC1F,CAAC;QACD,GAAG,IAAI,YAAY,kBAAkB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAA;IACvD,CAAC;IAED,qBAAqB;IACrB,IAAI,IAAI,EAAE,SAAS,EAAE,CAAC;QACpB,GAAG,IAAI,cAAc,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,CAAA;IAC3E,CAAC;IAED,oBAAoB;IACpB,IAAI,IAAI,EAAE,KAAK,EAAE,CAAC;QAChB,GAAG,IAAI,UAAU,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAA;IACnD,CAAC;IAED,IAAI,IAA6B,CAAA;IACjC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAA;QAC5B,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,MAAM,IAAI,UAAU,CAAC,iBAAiB,GAAG,CAAC,MAAM,EAAE,CAAC,CAAA;QAChE,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAA4B,CAAA;IACtD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,UAAU;YAAE,MAAM,GAAG,CAAA;QACxC,MAAM,IAAI,UAAU,CAAC,8BAA+B,GAAa,CAAC,OAAO,EAAE,CAAC,CAAA;IAC9E,CAAC;IAED,IAAI,IAAI,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;QAC5B,MAAM,IAAI,UAAU,CAAC,mBAAoB,IAAI,CAAC,MAAiB,IAAI,SAAS,EAAE,CAAC,CAAA;IACjF,CAAC;IAED,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;QACb,MAAM,IAAI,UAAU,CAAC,uDAAuD,CAAC,CAAA;IAC/E,CAAC;IAED,OAAO;QACL,EAAE,EAAE,IAAI,CAAC,EAAY;QACrB,MAAM,EAAG,IAAI,CAAC,MAAoB,IAAI,EAAE;QACxC,aAAa,EAAE,IAAI,CAAC,aAA0C;QAC9D,MAAM,EAAE,IAAI,CAAC,MAA4B;KAC1C,CAAA;AACH,CAAC;AAED,0EAA0E;AAE1E;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,KAAa;IACtD,MAAM,EAAE,GAAG,EAAE,GAAG,UAAU,CAAC,KAAK,CAAC,CAAA;IAEjC,IAAI,IAA6B,CAAA;IACjC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAA;QAC5B,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,MAAM,IAAI,UAAU,CAAC,QAAQ,GAAG,CAAC,MAAM,SAAS,GAAG,EAAE,CAAC,CAAA;QACnE,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAA4B,CAAA;IACtD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,UAAU;YAAE,MAAM,GAAG,CAAA;QACxC,MAAM,IAAI,UAAU,CAAC,qCAAsC,GAAa,CAAC,OAAO,EAAE,CAAC,CAAA;IACrF,CAAC;IAED,IAAI,IAAI,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;QAC5B,MAAM,IAAI,UAAU,CAAC,gBAAiB,IAAI,CAAC,MAAiB,IAAI,SAAS,EAAE,CAAC,CAAA;IAC9E,CAAC;IAED,IAAI,IAAI,CAAC,GAAG,KAAK,iBAAiB,EAAE,CAAC;QACnC,MAAM,IAAI,UAAU,CAAC,wCAAwC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAA;IAC3E,CAAC;IAED,OAAO;QACL,GAAG,EAAE,iBAAiB;QACtB,QAAQ,EAAE,IAAI,CAAC,QAAkB;QACjC,EAAE,EAAE,IAAI,CAAC,EAAY;QACrB,kBAAkB,EAAE,IAAI,CAAC,kBAA4B;QACrD,eAAe,EAAE,IAAI,CAAC,eAAyB;QAC/C,eAAe,EAAE,IAAI,CAAC,eAAyB;KAChD,CAAA;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,eAAwC,EACxC,OAAe;IAEf,MAAM,GAAG,GAAG,eAAe,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAA;IAC9D,MAAM,GAAG,GAAG,GAAG,eAAe,CAAC,QAAQ,GAAG,GAAG,MAAM,eAAe,CAAC,EAAE,OAAO,OAAO,EAAE,CAAA;IAErF,IAAI,IAA6B,CAAA;IACjC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAA;QAC5B,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,MAAM,IAAI,UAAU,CAAC,0BAA0B,GAAG,CAAC,MAAM,EAAE,CAAC,CAAA;QACzE,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAA4B,CAAA;IACtD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,UAAU;YAAE,MAAM,GAAG,CAAA;QACxC,MAAM,IAAI,UAAU,CAAC,sCAAuC,GAAa,CAAC,OAAO,EAAE,CAAC,CAAA;IACtF,CAAC;IAED,IAAI,IAAI,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;QAC5B,MAAM,IAAI,UAAU,CAAC,mBAAoB,IAAI,CAAC,MAAiB,IAAI,SAAS,EAAE,CAAC,CAAA;IACjF,CAAC;AACH,CAAC;AAED,0EAA0E;AAE1E;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAY;IAC7C,MAAM,MAAM,GAAG,GAA8B,CAAA;IAC7C,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;QACzD,MAAM,IAAI,UAAU,CAAC,qCAAqC,CAAC,CAAA;IAC7D,CAAC;IAED,QAAQ,MAAM,CAAC,GAAG,EAAE,CAAC;QACnB,KAAK,SAAS;YACZ,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,OAAO,EAAG,MAAM,CAAC,OAAkB,IAAI,EAAE,EAAE,CAAA;QACtE,KAAK,KAAK;YACR,OAAO;gBACL,GAAG,EAAE,KAAK;gBACV,WAAW,EAAG,MAAM,CAAC,WAAsB,IAAI,EAAE;gBACjD,GAAG,EAAG,MAAM,CAAC,GAAc,IAAI,EAAE;aAClC,CAAA;QACH,KAAK,KAAK;YACR,OAAO;gBACL,GAAG,EAAE,KAAK;gBACV,WAAW,EAAG,MAAM,CAAC,WAAsB,IAAI,EAAE;gBACjD,UAAU,EAAG,MAAM,CAAC,UAAqB,IAAI,EAAE;gBAC/C,EAAE,EAAG,MAAM,CAAC,EAAa,IAAI,EAAE;aAChC,CAAA;QACH;YACE,MAAM,IAAI,UAAU,CAAC,+BAA+B,MAAM,CAAC,GAAG,EAAE,CAAC,CAAA;IACrE,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,MAA8C,EAC9C,WAAmB;IAEnB,yDAAyD;IACzD,MAAM,GAAG,GAAG,UAAU,CAAC,WAAW,CAAC,CAAA;IACnC,IAAI,GAAG,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;QACtB,MAAM,IAAI,UAAU,CAAC,0CAA0C,CAAC,CAAA;IAClE,CAAC;IAED,MAAM,EAAE,GAAG,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;IACnC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;IAEnD,qCAAqC;IACrC,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,GAAG,CAAC,MAAqB,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE;QAC5G,SAAS;KACV,CAAC,CAAA;IAEF,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,EAAE,CAAC,MAAqB,EAAE,EAAE,SAAS,EAAE,UAAU,CAAC,MAAqB,CAAC,CAAA;IAE7I,OAAO,WAAW,CAAC,MAAM,CAAC,IAAI,UAAU,CAAC,SAAS,CAAC,CAAC,CAAA;AACtD,CAAC;AAED,0EAA0E;AAE1E;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,SAAiB;IACnD,IAAI,IAA6B,CAAA;IACjC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,SAAS,CAAC,CAAA;QAClC,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,MAAM,IAAI,UAAU,CAAC,eAAe,GAAG,CAAC,MAAM,EAAE,CAAC,CAAA;QAC9D,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAA4B,CAAA;IACtD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,UAAU;YAAE,MAAM,GAAG,CAAA;QACxC,MAAM,IAAI,UAAU,CAAC,6BAA8B,GAAa,CAAC,OAAO,EAAE,CAAC,CAAA;IAC7E,CAAC;IAED,IAAI,IAAI,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;QAC5B,MAAM,IAAI,UAAU,CAAC,iBAAkB,IAAI,CAAC,MAAiB,IAAI,SAAS,EAAE,CAAC,CAAA;IAC/E,CAAC;IAED,OAAO;QACL,OAAO,EAAE,IAAI,CAAC,OAAkB;QAChC,QAAQ,EAAG,IAAI,CAAC,QAAmB,IAAI,IAAI;QAC3C,EAAE,EAAE,IAAI,CAAC,EAAY;KACtB,CAAA;AACH,CAAC;AAED,0EAA0E;AAE1E,SAAS,UAAU,CAAC,GAAW;IAC7B,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;IAC5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,KAAK,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;IACtD,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAED,SAAS,aAAa,CAAC,GAAW;IAChC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAA;IACxB,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;IAC3C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACvC,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAA;IACjC,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC"}
|
package/dist/nip02.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type NostrEvent, type EventTemplate } from './event.js';
|
|
2
|
+
export type ContactEntry = {
|
|
3
|
+
pubkey: string;
|
|
4
|
+
relay?: string;
|
|
5
|
+
petname?: string;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Create a kind 3 follow list (contact list) event template (unsigned).
|
|
9
|
+
*/
|
|
10
|
+
export declare function createFollowListEventTemplate(contacts: ContactEntry[]): EventTemplate;
|
|
11
|
+
/**
|
|
12
|
+
* Create and sign a kind 3 follow list event.
|
|
13
|
+
*/
|
|
14
|
+
export declare function createFollowListEvent(contacts: ContactEntry[], secretKey: Uint8Array): NostrEvent;
|
|
15
|
+
/**
|
|
16
|
+
* Parse a kind 3 follow list event into contact entries.
|
|
17
|
+
*/
|
|
18
|
+
export declare function parseFollowList(event: NostrEvent): ContactEntry[];
|
|
19
|
+
/**
|
|
20
|
+
* Check if a pubkey is in a follow list event.
|
|
21
|
+
*/
|
|
22
|
+
export declare function isFollowing(event: NostrEvent, pubkey: string): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Get all followed pubkeys from a follow list event.
|
|
25
|
+
*/
|
|
26
|
+
export declare function getFollowedPubkeys(event: NostrEvent): string[];
|
|
27
|
+
//# sourceMappingURL=nip02.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nip02.d.ts","sourceRoot":"","sources":["../src/nip02.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,UAAU,EAAE,KAAK,aAAa,EAAE,MAAM,YAAY,CAAA;AAE/E,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB,CAAA;AAED;;GAEG;AACH,wBAAgB,6BAA6B,CAAC,QAAQ,EAAE,YAAY,EAAE,GAAG,aAAa,CAgBrF;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,YAAY,EAAE,EAAE,SAAS,EAAE,UAAU,GAAG,UAAU,CAEjG;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,UAAU,GAAG,YAAY,EAAE,CASjE;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAEtE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,EAAE,CAE9D"}
|
package/dist/nip02.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { finalizeEvent } from './event.js';
|
|
2
|
+
/**
|
|
3
|
+
* Create a kind 3 follow list (contact list) event template (unsigned).
|
|
4
|
+
*/
|
|
5
|
+
export function createFollowListEventTemplate(contacts) {
|
|
6
|
+
const tags = contacts.map(c => {
|
|
7
|
+
const tag = ['p', c.pubkey];
|
|
8
|
+
tag.push(c.relay ?? '');
|
|
9
|
+
tag.push(c.petname ?? '');
|
|
10
|
+
// Trim trailing empty strings
|
|
11
|
+
while (tag.length > 1 && tag[tag.length - 1] === '')
|
|
12
|
+
tag.pop();
|
|
13
|
+
return tag;
|
|
14
|
+
});
|
|
15
|
+
return {
|
|
16
|
+
kind: 3,
|
|
17
|
+
tags,
|
|
18
|
+
content: '',
|
|
19
|
+
created_at: Math.floor(Date.now() / 1000),
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Create and sign a kind 3 follow list event.
|
|
24
|
+
*/
|
|
25
|
+
export function createFollowListEvent(contacts, secretKey) {
|
|
26
|
+
return finalizeEvent(createFollowListEventTemplate(contacts), secretKey);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Parse a kind 3 follow list event into contact entries.
|
|
30
|
+
*/
|
|
31
|
+
export function parseFollowList(event) {
|
|
32
|
+
return event.tags
|
|
33
|
+
.filter(t => t[0] === 'p' && t[1])
|
|
34
|
+
.map(t => {
|
|
35
|
+
const entry = { pubkey: t[1] };
|
|
36
|
+
if (t[2])
|
|
37
|
+
entry.relay = t[2];
|
|
38
|
+
if (t[3])
|
|
39
|
+
entry.petname = t[3];
|
|
40
|
+
return entry;
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Check if a pubkey is in a follow list event.
|
|
45
|
+
*/
|
|
46
|
+
export function isFollowing(event, pubkey) {
|
|
47
|
+
return event.tags.some(t => t[0] === 'p' && t[1] === pubkey);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Get all followed pubkeys from a follow list event.
|
|
51
|
+
*/
|
|
52
|
+
export function getFollowedPubkeys(event) {
|
|
53
|
+
return event.tags.filter(t => t[0] === 'p' && t[1]).map(t => t[1]);
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=nip02.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nip02.js","sourceRoot":"","sources":["../src/nip02.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAuC,MAAM,YAAY,CAAA;AAQ/E;;GAEG;AACH,MAAM,UAAU,6BAA6B,CAAC,QAAwB;IACpE,MAAM,IAAI,GAAe,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;QACxC,MAAM,GAAG,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,CAAA;QAC3B,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAA;QACvB,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC,CAAA;QACzB,8BAA8B;QAC9B,OAAO,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,EAAE;YAAE,GAAG,CAAC,GAAG,EAAE,CAAA;QAC9D,OAAO,GAAG,CAAA;IACZ,CAAC,CAAC,CAAA;IAEF,OAAO;QACL,IAAI,EAAE,CAAC;QACP,IAAI;QACJ,OAAO,EAAE,EAAE;QACX,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;KAC1C,CAAA;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB,CAAC,QAAwB,EAAE,SAAqB;IACnF,OAAO,aAAa,CAAC,6BAA6B,CAAC,QAAQ,CAAC,EAAE,SAAS,CAAC,CAAA;AAC1E,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,KAAiB;IAC/C,OAAO,KAAK,CAAC,IAAI;SACd,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;SACjC,GAAG,CAAC,CAAC,CAAC,EAAE;QACP,MAAM,KAAK,GAAiB,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;QAC5C,IAAI,CAAC,CAAC,CAAC,CAAC;YAAE,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;QAC5B,IAAI,CAAC,CAAC,CAAC,CAAC;YAAE,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;QAC9B,OAAO,KAAK,CAAA;IACd,CAAC,CAAC,CAAA;AACN,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,KAAiB,EAAE,MAAc;IAC3D,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,CAAA;AAC9D,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAiB;IAClD,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AACpE,CAAC"}
|
package/dist/nip05.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export type Nip05Result = {
|
|
2
|
+
pubkey: string;
|
|
3
|
+
relays?: string[];
|
|
4
|
+
};
|
|
5
|
+
export declare class Nip05Error extends Error {
|
|
6
|
+
code: string;
|
|
7
|
+
constructor(message: string, code?: string);
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Parse a NIP-05 address into name and domain parts.
|
|
11
|
+
*/
|
|
12
|
+
export declare function parseNip05Address(address: string): {
|
|
13
|
+
name: string;
|
|
14
|
+
domain: string;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Query a NIP-05 address and return the associated pubkey and relays.
|
|
18
|
+
*/
|
|
19
|
+
export declare function queryNip05(address: string): Promise<Nip05Result>;
|
|
20
|
+
/**
|
|
21
|
+
* Verify that a NIP-05 address resolves to the expected pubkey.
|
|
22
|
+
*/
|
|
23
|
+
export declare function verifyNip05(address: string, expectedPubkey: string): Promise<boolean>;
|
|
24
|
+
//# sourceMappingURL=nip05.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nip05.d.ts","sourceRoot":"","sources":["../src/nip05.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GAAG;IACxB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;CAClB,CAAA;AAED,qBAAa,UAAW,SAAQ,KAAK;IACnC,IAAI,EAAE,MAAM,CAAA;gBACA,OAAO,EAAE,MAAM,EAAE,IAAI,SAAgB;CAKlD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAInF;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAyBtE;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAO3F"}
|
package/dist/nip05.js
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
export class Nip05Error extends Error {
|
|
2
|
+
code;
|
|
3
|
+
constructor(message, code = 'NIP05_ERROR') {
|
|
4
|
+
super(message);
|
|
5
|
+
this.name = 'Nip05Error';
|
|
6
|
+
this.code = code;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Parse a NIP-05 address into name and domain parts.
|
|
11
|
+
*/
|
|
12
|
+
export function parseNip05Address(address) {
|
|
13
|
+
const match = address.match(/^([^@]+)@([^@]+)$/);
|
|
14
|
+
if (!match)
|
|
15
|
+
throw new Nip05Error(`Invalid NIP-05 address: ${address}`, 'INVALID_ADDRESS');
|
|
16
|
+
return { name: match[1], domain: match[2] };
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Query a NIP-05 address and return the associated pubkey and relays.
|
|
20
|
+
*/
|
|
21
|
+
export async function queryNip05(address) {
|
|
22
|
+
const { name, domain } = parseNip05Address(address);
|
|
23
|
+
const url = `https://${domain}/.well-known/nostr.json?name=${encodeURIComponent(name)}`;
|
|
24
|
+
let json;
|
|
25
|
+
try {
|
|
26
|
+
const res = await fetch(url);
|
|
27
|
+
if (!res.ok)
|
|
28
|
+
throw new Nip05Error(`HTTP ${res.status} from ${domain}`, 'FETCH_ERROR');
|
|
29
|
+
json = (await res.json());
|
|
30
|
+
}
|
|
31
|
+
catch (err) {
|
|
32
|
+
if (err instanceof Nip05Error)
|
|
33
|
+
throw err;
|
|
34
|
+
throw new Nip05Error(`Failed to query ${domain}: ${err.message}`, 'FETCH_ERROR');
|
|
35
|
+
}
|
|
36
|
+
const names = json.names;
|
|
37
|
+
if (!names || !names[name]) {
|
|
38
|
+
throw new Nip05Error(`Name "${name}" not found on ${domain}`, 'NOT_FOUND');
|
|
39
|
+
}
|
|
40
|
+
const pubkey = names[name];
|
|
41
|
+
const relaysMap = json.relays;
|
|
42
|
+
const relays = relaysMap?.[pubkey];
|
|
43
|
+
return { pubkey, relays };
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Verify that a NIP-05 address resolves to the expected pubkey.
|
|
47
|
+
*/
|
|
48
|
+
export async function verifyNip05(address, expectedPubkey) {
|
|
49
|
+
try {
|
|
50
|
+
const result = await queryNip05(address);
|
|
51
|
+
return result.pubkey === expectedPubkey;
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=nip05.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nip05.js","sourceRoot":"","sources":["../src/nip05.ts"],"names":[],"mappings":"AAKA,MAAM,OAAO,UAAW,SAAQ,KAAK;IACnC,IAAI,CAAQ;IACZ,YAAY,OAAe,EAAE,IAAI,GAAG,aAAa;QAC/C,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,YAAY,CAAA;QACxB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;IAClB,CAAC;CACF;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAe;IAC/C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAA;IAChD,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,UAAU,CAAC,2BAA2B,OAAO,EAAE,EAAE,iBAAiB,CAAC,CAAA;IACzF,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAA;AAC7C,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,OAAe;IAC9C,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAA;IAEnD,MAAM,GAAG,GAAG,WAAW,MAAM,gCAAgC,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAA;IACvF,IAAI,IAA6B,CAAA;IAEjC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAA;QAC5B,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,MAAM,IAAI,UAAU,CAAC,QAAQ,GAAG,CAAC,MAAM,SAAS,MAAM,EAAE,EAAE,aAAa,CAAC,CAAA;QACrF,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAA4B,CAAA;IACtD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,UAAU;YAAE,MAAM,GAAG,CAAA;QACxC,MAAM,IAAI,UAAU,CAAC,mBAAmB,MAAM,KAAM,GAAa,CAAC,OAAO,EAAE,EAAE,aAAa,CAAC,CAAA;IAC7F,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,CAAC,KAA2C,CAAA;IAC9D,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,UAAU,CAAC,SAAS,IAAI,kBAAkB,MAAM,EAAE,EAAE,WAAW,CAAC,CAAA;IAC5E,CAAC;IAED,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,CAAA;IAC1B,MAAM,SAAS,GAAG,IAAI,CAAC,MAA8C,CAAA;IACrE,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC,MAAM,CAAC,CAAA;IAElC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAA;AAC3B,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAAe,EAAE,cAAsB;IACvE,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,CAAA;QACxC,OAAO,MAAM,CAAC,MAAM,KAAK,cAAc,CAAA;IACzC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC"}
|
package/dist/nip06.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export type DerivedKey = {
|
|
2
|
+
secretKey: Uint8Array;
|
|
3
|
+
publicKey: string;
|
|
4
|
+
};
|
|
5
|
+
/**
|
|
6
|
+
* Get the BIP-44 derivation path for Nostr keys.
|
|
7
|
+
* Path: m/44'/1237'/<account>'/0/0
|
|
8
|
+
*/
|
|
9
|
+
export declare function getDerivationPath(accountIndex: number): string;
|
|
10
|
+
/**
|
|
11
|
+
* Generate a BIP-39 mnemonic phrase.
|
|
12
|
+
*/
|
|
13
|
+
export declare function generateMnemonic(wordCount?: 12 | 24): string;
|
|
14
|
+
/**
|
|
15
|
+
* Validate a BIP-39 mnemonic phrase.
|
|
16
|
+
*/
|
|
17
|
+
export declare function validateMnemonic(mnemonic: string): boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Derive a Nostr key pair from a BIP-39 mnemonic phrase.
|
|
20
|
+
*/
|
|
21
|
+
export declare function mnemonicToKey(mnemonic: string, accountIndex?: number, passphrase?: string): DerivedKey;
|
|
22
|
+
/**
|
|
23
|
+
* Derive a Nostr key pair from a BIP-32 seed.
|
|
24
|
+
*/
|
|
25
|
+
export declare function deriveKey(seed: Uint8Array, accountIndex?: number): DerivedKey;
|
|
26
|
+
//# sourceMappingURL=nip06.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nip06.d.ts","sourceRoot":"","sources":["../src/nip06.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,UAAU,GAAG;IACvB,SAAS,EAAE,UAAU,CAAA;IACrB,SAAS,EAAE,MAAM,CAAA;CAClB,CAAA;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAE9D;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,GAAE,EAAE,GAAG,EAAO,GAAG,MAAM,CAGhE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAE1D;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,SAAI,EAAE,UAAU,SAAK,GAAG,UAAU,CAM7F;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,UAAU,EAAE,YAAY,SAAI,GAAG,UAAU,CAWxE"}
|
package/dist/nip06.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { HDKey } from '@scure/bip32';
|
|
2
|
+
import { generateMnemonic as genMnemonic, mnemonicToSeedSync, validateMnemonic as valMnemonic } from '@scure/bip39';
|
|
3
|
+
import { wordlist as english } from '@scure/bip39/wordlists/english.js';
|
|
4
|
+
import { bytesToHex } from '@noble/hashes/utils';
|
|
5
|
+
import { schnorr } from '@noble/curves/secp256k1';
|
|
6
|
+
/**
|
|
7
|
+
* Get the BIP-44 derivation path for Nostr keys.
|
|
8
|
+
* Path: m/44'/1237'/<account>'/0/0
|
|
9
|
+
*/
|
|
10
|
+
export function getDerivationPath(accountIndex) {
|
|
11
|
+
return `m/44'/1237'/${accountIndex}'/0/0`;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Generate a BIP-39 mnemonic phrase.
|
|
15
|
+
*/
|
|
16
|
+
export function generateMnemonic(wordCount = 12) {
|
|
17
|
+
const strength = wordCount === 24 ? 256 : 128;
|
|
18
|
+
return genMnemonic(english, strength);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Validate a BIP-39 mnemonic phrase.
|
|
22
|
+
*/
|
|
23
|
+
export function validateMnemonic(mnemonic) {
|
|
24
|
+
return valMnemonic(mnemonic, english);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Derive a Nostr key pair from a BIP-39 mnemonic phrase.
|
|
28
|
+
*/
|
|
29
|
+
export function mnemonicToKey(mnemonic, accountIndex = 0, passphrase = '') {
|
|
30
|
+
if (!validateMnemonic(mnemonic)) {
|
|
31
|
+
throw new Error('Invalid mnemonic');
|
|
32
|
+
}
|
|
33
|
+
const seed = mnemonicToSeedSync(mnemonic, passphrase);
|
|
34
|
+
return deriveKey(seed, accountIndex);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Derive a Nostr key pair from a BIP-32 seed.
|
|
38
|
+
*/
|
|
39
|
+
export function deriveKey(seed, accountIndex = 0) {
|
|
40
|
+
const path = getDerivationPath(accountIndex);
|
|
41
|
+
const root = HDKey.fromMasterSeed(seed);
|
|
42
|
+
const child = root.derive(path);
|
|
43
|
+
if (!child.privateKey)
|
|
44
|
+
throw new Error('Failed to derive private key');
|
|
45
|
+
const secretKey = child.privateKey;
|
|
46
|
+
const publicKey = bytesToHex(schnorr.getPublicKey(secretKey));
|
|
47
|
+
return { secretKey, publicKey };
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=nip06.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nip06.js","sourceRoot":"","sources":["../src/nip06.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAA;AACpC,OAAO,EAAE,gBAAgB,IAAI,WAAW,EAAE,kBAAkB,EAAE,gBAAgB,IAAI,WAAW,EAAE,MAAM,cAAc,CAAA;AACnH,OAAO,EAAE,QAAQ,IAAI,OAAO,EAAE,MAAM,mCAAmC,CAAA;AACvE,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAA;AAOjD;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,YAAoB;IACpD,OAAO,eAAe,YAAY,OAAO,CAAA;AAC3C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,YAAqB,EAAE;IACtD,MAAM,QAAQ,GAAG,SAAS,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAA;IAC7C,OAAO,WAAW,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;AACvC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAgB;IAC/C,OAAO,WAAW,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;AACvC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,QAAgB,EAAE,YAAY,GAAG,CAAC,EAAE,UAAU,GAAG,EAAE;IAC/E,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAA;IACrC,CAAC;IACD,MAAM,IAAI,GAAG,kBAAkB,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;IACrD,OAAO,SAAS,CAAC,IAAI,EAAE,YAAY,CAAC,CAAA;AACtC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,SAAS,CAAC,IAAgB,EAAE,YAAY,GAAG,CAAC;IAC1D,MAAM,IAAI,GAAG,iBAAiB,CAAC,YAAY,CAAC,CAAA;IAC5C,MAAM,IAAI,GAAG,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,CAAA;IACvC,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IAE/B,IAAI,CAAC,KAAK,CAAC,UAAU;QAAE,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAA;IAEtE,MAAM,SAAS,GAAG,KAAK,CAAC,UAAU,CAAA;IAClC,MAAM,SAAS,GAAG,UAAU,CAAC,OAAO,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,CAAA;IAE7D,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,CAAA;AACjC,CAAC"}
|
package/dist/nip09.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { type NostrEvent, type EventTemplate } from './event.js';
|
|
2
|
+
export type DeletionTarget = {
|
|
3
|
+
type: 'event';
|
|
4
|
+
id: string;
|
|
5
|
+
} | {
|
|
6
|
+
type: 'address';
|
|
7
|
+
address: string;
|
|
8
|
+
};
|
|
9
|
+
export type DeletionRequest = {
|
|
10
|
+
targets: DeletionTarget[];
|
|
11
|
+
reason?: string;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Create a kind 5 deletion event template (unsigned).
|
|
15
|
+
*/
|
|
16
|
+
export declare function createDeletionEventTemplate(request: DeletionRequest): EventTemplate;
|
|
17
|
+
/**
|
|
18
|
+
* Create and sign a kind 5 deletion event.
|
|
19
|
+
*/
|
|
20
|
+
export declare function createDeletionEvent(request: DeletionRequest, secretKey: Uint8Array): NostrEvent;
|
|
21
|
+
/**
|
|
22
|
+
* Parse a kind 5 deletion event.
|
|
23
|
+
*/
|
|
24
|
+
export declare function parseDeletion(event: NostrEvent): {
|
|
25
|
+
eventIds: string[];
|
|
26
|
+
addresses: string[];
|
|
27
|
+
kinds: number[];
|
|
28
|
+
reason: string;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Check if a deletion event targets a specific event.
|
|
32
|
+
*/
|
|
33
|
+
export declare function isDeletionOf(deletion: NostrEvent, target: NostrEvent): boolean;
|
|
34
|
+
//# sourceMappingURL=nip09.d.ts.map
|