nostr-core 0.1.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.
Files changed (58) hide show
  1. package/README.md +229 -0
  2. package/dist/crypto.d.ts +3 -0
  3. package/dist/crypto.d.ts.map +1 -0
  4. package/dist/crypto.js +9 -0
  5. package/dist/crypto.js.map +1 -0
  6. package/dist/event.d.ts +22 -0
  7. package/dist/event.d.ts.map +1 -0
  8. package/dist/event.js +68 -0
  9. package/dist/event.js.map +1 -0
  10. package/dist/fiat.d.ts +9 -0
  11. package/dist/fiat.d.ts.map +1 -0
  12. package/dist/fiat.js +48 -0
  13. package/dist/fiat.js.map +1 -0
  14. package/dist/filter.d.ts +14 -0
  15. package/dist/filter.d.ts.map +1 -0
  16. package/dist/filter.js +29 -0
  17. package/dist/filter.js.map +1 -0
  18. package/dist/index.d.ts +19 -0
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +24 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/lightning-address.d.ts +26 -0
  23. package/dist/lightning-address.d.ts.map +1 -0
  24. package/dist/lightning-address.js +110 -0
  25. package/dist/lightning-address.js.map +1 -0
  26. package/dist/nip04.d.ts +3 -0
  27. package/dist/nip04.d.ts.map +1 -0
  28. package/dist/nip04.js +27 -0
  29. package/dist/nip04.js.map +1 -0
  30. package/dist/nip19.d.ts +43 -0
  31. package/dist/nip19.d.ts.map +1 -0
  32. package/dist/nip19.js +152 -0
  33. package/dist/nip19.js.map +1 -0
  34. package/dist/nip44.d.ts +4 -0
  35. package/dist/nip44.d.ts.map +1 -0
  36. package/dist/nip44.js +106 -0
  37. package/dist/nip44.js.map +1 -0
  38. package/dist/nwc.d.ts +49 -0
  39. package/dist/nwc.d.ts.map +1 -0
  40. package/dist/nwc.js +395 -0
  41. package/dist/nwc.js.map +1 -0
  42. package/dist/pool.d.ts +31 -0
  43. package/dist/pool.d.ts.map +1 -0
  44. package/dist/pool.js +113 -0
  45. package/dist/pool.js.map +1 -0
  46. package/dist/relay.d.ts +51 -0
  47. package/dist/relay.d.ts.map +1 -0
  48. package/dist/relay.js +204 -0
  49. package/dist/relay.js.map +1 -0
  50. package/dist/types.d.ts +137 -0
  51. package/dist/types.d.ts.map +1 -0
  52. package/dist/types.js +64 -0
  53. package/dist/types.js.map +1 -0
  54. package/dist/utils.d.ts +5 -0
  55. package/dist/utils.d.ts.map +1 -0
  56. package/dist/utils.js +26 -0
  57. package/dist/utils.js.map +1 -0
  58. package/package.json +49 -0
package/README.md ADDED
@@ -0,0 +1,229 @@
1
+ # nostr-core
2
+
3
+ Dead-simple, vendor-neutral [Nostr Wallet Connect (NWC)](https://github.com/nostr-protocol/nips/blob/master/47.md) client for JavaScript and TypeScript.
4
+
5
+ ```ts
6
+ import { NWC } from 'nostr-core'
7
+
8
+ const nwc = new NWC('nostr+walletconnect://...')
9
+ await nwc.connect()
10
+
11
+ const { balance } = await nwc.getBalance()
12
+ console.log(`Balance: ${balance} msats`)
13
+
14
+ const { preimage } = await nwc.payInvoice('lnbc...')
15
+ console.log('Paid! Preimage:', preimage)
16
+
17
+ nwc.close()
18
+ ```
19
+
20
+ ## Features
21
+
22
+ - **Single connection string** - pass a `nostr+walletconnect://` URI and start making calls
23
+ - **Full NIP-47 coverage** - `pay_invoice`, `get_balance`, `make_invoice`, `list_transactions`, `pay_keysend`, `sign_message`, and more
24
+ - **Auto-encryption** - detects NIP-04 or NIP-44 support and handles it transparently
25
+ - **Typed errors** - specific error classes for timeouts, connection failures, wallet rejections, and decryption issues
26
+ - **Zero framework deps** - built on audited [noble](https://paulmillr.com/noble/) cryptography libraries only
27
+ - **ESM-only** - tree-shakeable, modern JavaScript
28
+
29
+ ## Install
30
+
31
+ ```sh
32
+ npm install nostr-core
33
+ ```
34
+
35
+ Requires Node.js 18+ or any runtime with Web Crypto and WebSocket support (Deno, Bun, Cloudflare Workers).
36
+
37
+ ## Quick Start
38
+
39
+ ### Connect to a Wallet
40
+
41
+ ```ts
42
+ import { NWC } from 'nostr-core'
43
+
44
+ const nwc = new NWC('nostr+walletconnect://...')
45
+ await nwc.connect()
46
+
47
+ const info = await nwc.getInfo()
48
+ console.log('Connected to:', info.alias)
49
+ console.log('Methods:', info.methods)
50
+ ```
51
+
52
+ ### Pay an Invoice
53
+
54
+ ```ts
55
+ try {
56
+ const { preimage, fees_paid } = await nwc.payInvoice('lnbc...')
57
+ console.log('Preimage:', preimage)
58
+ } catch (err) {
59
+ console.error('Payment failed:', err.message)
60
+ }
61
+ ```
62
+
63
+ ### Pay a Lightning Address
64
+
65
+ ```ts
66
+ try {
67
+ const { preimage, invoice } = await nwc.payLightningAddress('hello@getalby.com', 100)
68
+ console.log('Paid 100 sats! Preimage:', preimage)
69
+ } catch (err) {
70
+ console.error('Payment failed:', err.message)
71
+ }
72
+ ```
73
+
74
+ ### Pay a Lightning Address in Fiat
75
+
76
+ ```ts
77
+ // Pay $5 USD to a Lightning Address - automatically converts to sats
78
+ const { preimage, sats, rate } = await nwc.payLightningAddressFiat('hello@getalby.com', 5, 'usd')
79
+ console.log(`Paid ${sats} sats ($5 at $${rate}/BTC)`)
80
+ ```
81
+
82
+ ### Create an Invoice
83
+
84
+ ```ts
85
+ const tx = await nwc.makeInvoice({
86
+ amount: 10000, // msats
87
+ description: 'Coffee',
88
+ })
89
+ console.log('Invoice:', tx.invoice)
90
+ ```
91
+
92
+ ### Listen for Payments
93
+
94
+ ```ts
95
+ nwc.on('payment_received', (notification) => {
96
+ console.log('Received:', notification.notification.amount, 'msats')
97
+ })
98
+ ```
99
+
100
+ ### Close
101
+
102
+ ```ts
103
+ nwc.close()
104
+ ```
105
+
106
+ ## API
107
+
108
+ ### NWC Methods
109
+
110
+ | Method | Description |
111
+ |--------|-------------|
112
+ | `connect()` | Connect to relay, auto-detect encryption |
113
+ | `getInfo()` | Wallet metadata (alias, network, supported methods) |
114
+ | `getBalance()` | Wallet balance in msats |
115
+ | `getBudget()` | NWC spending budget info |
116
+ | `payInvoice(invoice, amount?)` | Pay a BOLT-11 invoice |
117
+ | `payKeysend(params)` | Keysend payment to a node pubkey |
118
+ | `makeInvoice(params)` | Create a Lightning invoice |
119
+ | `lookupInvoice(params)` | Look up an invoice by hash or string |
120
+ | `listTransactions(params?)` | List past transactions |
121
+ | `signMessage(message)` | Sign a message with the wallet's key |
122
+ | `payLightningAddress(address, amountSats)` | Resolve a Lightning Address and pay the invoice |
123
+ | `payLightningAddressFiat(address, fiatAmount, currency)` | Convert fiat to sats and pay a Lightning Address |
124
+ | `on(event, handler)` | Listen for `payment_received` / `payment_sent` |
125
+ | `off(event, handler)` | Remove an event handler |
126
+ | `close()` | Disconnect and clean up |
127
+
128
+ ### Configuration
129
+
130
+ ```ts
131
+ const nwc = new NWC(connectionString)
132
+ nwc.replyTimeout = 30000 // Wallet reply timeout (default: 60s)
133
+ nwc.publishTimeout = 10000 // Relay publish timeout (default: 5s)
134
+ ```
135
+
136
+ ### Error Handling
137
+
138
+ ```ts
139
+ import { NWCWalletError, NWCTimeoutError, NWCConnectionError } from 'nostr-core'
140
+
141
+ try {
142
+ await nwc.payInvoice('lnbc...')
143
+ } catch (err) {
144
+ if (err instanceof NWCWalletError) {
145
+ console.error(`Wallet rejected [${err.code}]: ${err.message}`)
146
+ } else if (err instanceof NWCTimeoutError) {
147
+ console.error('Timed out:', err.code) // 'PUBLISH_TIMEOUT' or 'REPLY_TIMEOUT'
148
+ } else if (err instanceof NWCConnectionError) {
149
+ console.error('Connection lost')
150
+ }
151
+ }
152
+ ```
153
+
154
+ Error hierarchy:
155
+
156
+ ```
157
+ NWCError (code: string)
158
+ ├── NWCWalletError - wallet rejected the request
159
+ ├── NWCTimeoutError - generic timeout
160
+ │ ├── NWCPublishTimeoutError - relay didn't acknowledge
161
+ │ └── NWCReplyTimeoutError - wallet didn't respond
162
+ ├── NWCPublishError - relay rejected the event
163
+ ├── NWCConnectionError - couldn't connect to relay
164
+ ├── NWCDecryptionError - couldn't decrypt response
165
+ ├── LightningAddressError - Lightning Address resolution failed
166
+ └── FiatConversionError - fiat-to-sats conversion failed
167
+ ```
168
+
169
+ ## Low-Level Exports
170
+
171
+ nostr-core also exports the building blocks used internally:
172
+
173
+ ```ts
174
+ import {
175
+ // Key management
176
+ generateSecretKey, getPublicKey,
177
+
178
+ // Events
179
+ finalizeEvent, verifyEvent, getEventHash, serializeEvent, validateEvent,
180
+
181
+ // Relay connections
182
+ Relay, RelayPool,
183
+
184
+ // Encryption
185
+ nip04, nip44,
186
+
187
+ // Bech32 encoding
188
+ nip19,
189
+
190
+ // Filters
191
+ matchFilter, matchFilters,
192
+
193
+ // Utilities
194
+ normalizeURL, bytesToHex, hexToBytes, randomBytes,
195
+ } from 'nostr-core'
196
+ ```
197
+
198
+ ## Why nostr-core over @getalby/sdk?
199
+
200
+ If you've used `@getalby/sdk` before, here's why `nostr-core` is a better fit for most NWC use cases:
201
+
202
+ | | **nostr-core** | **@getalby/sdk** | |
203
+ |---|---|---|---|
204
+ | **Install size** | 118 MB | 159 MB | **26% smaller** |
205
+ | **Packages installed** | 79 | 436 | **82% fewer** |
206
+ | **Dependency tree** | 132 total | 698 total | **81% fewer** |
207
+ | **Vendor lock-in** | None - pure NIP-47 protocol | Coupled to Alby (OAuth, webhooks, branding) | |
208
+ | **Error handling** | Typed hierarchy (8 specific classes) | Generic errors | |
209
+ | **Encryption** | Auto-detects NIP-04 / NIP-44 | Manual configuration | |
210
+ | **Fiat conversion** | Built-in (zero extra deps) | Via `@getalby/lightning-tools` | |
211
+ | **Runtime support** | Node 18+, Deno, Bun, Cloudflare Workers | Primarily Node.js | |
212
+ | **API surface** | One class (`NWC`) | Multiple overlapping abstractions | |
213
+
214
+ **Use `@getalby/sdk`** if you need Alby OAuth or WebLN compatibility. **Use `nostr-core`** for everything else - including Lightning Address payments and fiat currency conversion, which are now supported natively.
215
+
216
+ See the full [comparison guide](./docs/guide/comparison.md) for details.
217
+
218
+ ## Dependencies
219
+
220
+ | Package | Purpose |
221
+ |---------|---------|
222
+ | [@noble/curves](https://github.com/paulmillr/noble-curves) | secp256k1 / schnorr signatures |
223
+ | [@noble/hashes](https://github.com/paulmillr/noble-hashes) | SHA-256, HMAC, HKDF |
224
+ | [@noble/ciphers](https://github.com/paulmillr/noble-ciphers) | AES-CBC, ChaCha20 |
225
+ | [@scure/base](https://github.com/paulmillr/scure-base) | Base64, bech32 encoding |
226
+
227
+ ## License
228
+
229
+ MIT
@@ -0,0 +1,3 @@
1
+ export declare function generateSecretKey(): Uint8Array;
2
+ export declare function getPublicKey(secretKey: Uint8Array): string;
3
+ //# sourceMappingURL=crypto.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"AAGA,wBAAgB,iBAAiB,IAAI,UAAU,CAE9C;AAED,wBAAgB,YAAY,CAAC,SAAS,EAAE,UAAU,GAAG,MAAM,CAE1D"}
package/dist/crypto.js ADDED
@@ -0,0 +1,9 @@
1
+ import { schnorr } from '@noble/curves/secp256k1';
2
+ import { bytesToHex } from '@noble/hashes/utils';
3
+ export function generateSecretKey() {
4
+ return schnorr.utils.randomSecretKey();
5
+ }
6
+ export function getPublicKey(secretKey) {
7
+ return bytesToHex(schnorr.getPublicKey(secretKey));
8
+ }
9
+ //# sourceMappingURL=crypto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crypto.js","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAA;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAEhD,MAAM,UAAU,iBAAiB;IAC/B,OAAO,OAAO,CAAC,KAAK,CAAC,eAAe,EAAE,CAAA;AACxC,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,SAAqB;IAChD,OAAO,UAAU,CAAC,OAAO,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,CAAA;AACpD,CAAC"}
@@ -0,0 +1,22 @@
1
+ export declare const verifiedSymbol: unique symbol;
2
+ export type NostrEvent = {
3
+ kind: number;
4
+ tags: string[][];
5
+ content: string;
6
+ created_at: number;
7
+ pubkey: string;
8
+ id: string;
9
+ sig: string;
10
+ [verifiedSymbol]?: boolean;
11
+ };
12
+ export type EventTemplate = Pick<NostrEvent, 'kind' | 'tags' | 'content' | 'created_at'>;
13
+ export type UnsignedEvent = Pick<NostrEvent, 'kind' | 'tags' | 'content' | 'created_at' | 'pubkey'>;
14
+ export interface VerifiedEvent extends NostrEvent {
15
+ [verifiedSymbol]: true;
16
+ }
17
+ export declare function validateEvent<T>(event: T): event is T & UnsignedEvent;
18
+ export declare function serializeEvent(evt: UnsignedEvent): string;
19
+ export declare function getEventHash(event: UnsignedEvent): string;
20
+ export declare function finalizeEvent(t: EventTemplate, secretKey: Uint8Array): VerifiedEvent;
21
+ export declare function verifyEvent(event: NostrEvent): event is VerifiedEvent;
22
+ //# sourceMappingURL=event.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event.d.ts","sourceRoot":"","sources":["../src/event.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,cAAc,eAAqB,CAAA;AAEhD,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,EAAE,EAAE,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,MAAM,CAAA;IACd,EAAE,EAAE,MAAM,CAAA;IACV,GAAG,EAAE,MAAM,CAAA;IACX,CAAC,cAAc,CAAC,CAAC,EAAE,OAAO,CAAA;CAC3B,CAAA;AAED,MAAM,MAAM,aAAa,GAAG,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,YAAY,CAAC,CAAA;AACxF,MAAM,MAAM,aAAa,GAAG,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,YAAY,GAAG,QAAQ,CAAC,CAAA;AAEnG,MAAM,WAAW,aAAc,SAAQ,UAAU;IAC/C,CAAC,cAAc,CAAC,EAAE,IAAI,CAAA;CACvB;AAID,wBAAgB,aAAa,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,KAAK,IAAI,CAAC,GAAG,aAAa,CAkBrE;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAGzD;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CAGzD;AAED,wBAAgB,aAAa,CAAC,CAAC,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,GAAG,aAAa,CAOpF;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,KAAK,IAAI,aAAa,CAiBrE"}
package/dist/event.js ADDED
@@ -0,0 +1,68 @@
1
+ import { schnorr } from '@noble/curves/secp256k1';
2
+ import { sha256 } from '@noble/hashes/sha2';
3
+ import { bytesToHex, hexToBytes } from '@noble/hashes/utils';
4
+ import { utf8Encoder } from './utils.js';
5
+ export const verifiedSymbol = Symbol('verified');
6
+ const isRecord = (obj) => obj instanceof Object;
7
+ export function validateEvent(event) {
8
+ if (!isRecord(event))
9
+ return false;
10
+ if (typeof event.kind !== 'number')
11
+ return false;
12
+ if (typeof event.content !== 'string')
13
+ return false;
14
+ if (typeof event.created_at !== 'number')
15
+ return false;
16
+ if (typeof event.pubkey !== 'string')
17
+ return false;
18
+ if (!event.pubkey.match(/^[a-f0-9]{64}$/))
19
+ return false;
20
+ if (!Array.isArray(event.tags))
21
+ return false;
22
+ for (let i = 0; i < event.tags.length; i++) {
23
+ const tag = event.tags[i];
24
+ if (!Array.isArray(tag))
25
+ return false;
26
+ for (let j = 0; j < tag.length; j++) {
27
+ if (typeof tag[j] !== 'string')
28
+ return false;
29
+ }
30
+ }
31
+ return true;
32
+ }
33
+ export function serializeEvent(evt) {
34
+ if (!validateEvent(evt))
35
+ throw new Error("can't serialize event with wrong or missing properties");
36
+ return JSON.stringify([0, evt.pubkey, evt.created_at, evt.kind, evt.tags, evt.content]);
37
+ }
38
+ export function getEventHash(event) {
39
+ const eventHash = sha256(utf8Encoder.encode(serializeEvent(event)));
40
+ return bytesToHex(eventHash);
41
+ }
42
+ export function finalizeEvent(t, secretKey) {
43
+ const event = t;
44
+ event.pubkey = bytesToHex(schnorr.getPublicKey(secretKey));
45
+ event.id = getEventHash(event);
46
+ event.sig = bytesToHex(schnorr.sign(hexToBytes(event.id), secretKey));
47
+ event[verifiedSymbol] = true;
48
+ return event;
49
+ }
50
+ export function verifyEvent(event) {
51
+ if (typeof event[verifiedSymbol] === 'boolean')
52
+ return event[verifiedSymbol];
53
+ const hash = getEventHash(event);
54
+ if (hash !== event.id) {
55
+ event[verifiedSymbol] = false;
56
+ return false;
57
+ }
58
+ try {
59
+ const valid = schnorr.verify(hexToBytes(event.sig), hexToBytes(hash), hexToBytes(event.pubkey));
60
+ event[verifiedSymbol] = valid;
61
+ return valid;
62
+ }
63
+ catch {
64
+ event[verifiedSymbol] = false;
65
+ return false;
66
+ }
67
+ }
68
+ //# sourceMappingURL=event.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event.js","sourceRoot":"","sources":["../src/event.ts"],"names":[],"mappings":"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"}
package/dist/fiat.d.ts ADDED
@@ -0,0 +1,9 @@
1
+ import type { FiatRate, FiatConversion } from './types.js';
2
+ export declare function getExchangeRate(currency: string): Promise<FiatRate>;
3
+ export declare function fiatToSats(amount: number, currency: string): Promise<FiatConversion>;
4
+ export declare function satsToFiat(sats: number, currency: string): Promise<{
5
+ amount: number;
6
+ rate: number;
7
+ currency: string;
8
+ }>;
9
+ //# sourceMappingURL=fiat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fiat.d.ts","sourceRoot":"","sources":["../src/fiat.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAM1D,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAiCzE;AAED,wBAAsB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAS1F;AAED,wBAAsB,UAAU,CAC9B,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAS7D"}
package/dist/fiat.js ADDED
@@ -0,0 +1,48 @@
1
+ import { FiatConversionError } from './types.js';
2
+ // Cache exchange rates for 60 seconds
3
+ const rateCache = new Map();
4
+ const CACHE_TTL_MS = 60_000;
5
+ export async function getExchangeRate(currency) {
6
+ const key = currency.toLowerCase();
7
+ const cached = rateCache.get(key);
8
+ const now = Date.now();
9
+ if (cached && now - cached.timestamp < CACHE_TTL_MS) {
10
+ return { rate: cached.rate, currency: key, timestamp: cached.timestamp };
11
+ }
12
+ const url = `https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=${key}`;
13
+ let response;
14
+ try {
15
+ response = await fetch(url);
16
+ }
17
+ catch (err) {
18
+ throw new FiatConversionError(`Failed to fetch exchange rate: ${err.message}`);
19
+ }
20
+ if (!response.ok) {
21
+ throw new FiatConversionError(`Exchange rate API returned ${response.status}`);
22
+ }
23
+ const data = await response.json();
24
+ const rate = data?.bitcoin?.[key];
25
+ if (typeof rate !== 'number' || rate <= 0) {
26
+ throw new FiatConversionError(`Unsupported or invalid currency: ${currency}`);
27
+ }
28
+ const timestamp = now;
29
+ rateCache.set(key, { rate, timestamp });
30
+ return { rate, currency: key, timestamp };
31
+ }
32
+ export async function fiatToSats(amount, currency) {
33
+ if (amount <= 0) {
34
+ throw new FiatConversionError('Amount must be positive');
35
+ }
36
+ const { rate, currency: cur } = await getExchangeRate(currency);
37
+ const sats = Math.round((amount / rate) * 1e8);
38
+ return { sats, rate, currency: cur };
39
+ }
40
+ export async function satsToFiat(sats, currency) {
41
+ if (sats <= 0) {
42
+ throw new FiatConversionError('Sats must be positive');
43
+ }
44
+ const { rate, currency: cur } = await getExchangeRate(currency);
45
+ const amount = (sats / 1e8) * rate;
46
+ return { amount, rate, currency: cur };
47
+ }
48
+ //# sourceMappingURL=fiat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fiat.js","sourceRoot":"","sources":["../src/fiat.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAGhD,sCAAsC;AACtC,MAAM,SAAS,GAAG,IAAI,GAAG,EAA+C,CAAA;AACxE,MAAM,YAAY,GAAG,MAAM,CAAA;AAE3B,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,QAAgB;IACpD,MAAM,GAAG,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAA;IAClC,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IACjC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;IAEtB,IAAI,MAAM,IAAI,GAAG,GAAG,MAAM,CAAC,SAAS,GAAG,YAAY,EAAE,CAAC;QACpD,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,CAAA;IAC1E,CAAC;IAED,MAAM,GAAG,GAAG,2EAA2E,GAAG,EAAE,CAAA;IAE5F,IAAI,QAAkB,CAAA;IACtB,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAA;IAC7B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,mBAAmB,CAAC,kCAAmC,GAAa,CAAC,OAAO,EAAE,CAAC,CAAA;IAC3F,CAAC;IAED,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,mBAAmB,CAAC,8BAA8B,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAA;IAChF,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;IAClC,MAAM,IAAI,GAAG,IAAI,EAAE,OAAO,EAAE,CAAC,GAAG,CAAC,CAAA;IAEjC,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,IAAI,CAAC,EAAE,CAAC;QAC1C,MAAM,IAAI,mBAAmB,CAAC,oCAAoC,QAAQ,EAAE,CAAC,CAAA;IAC/E,CAAC;IAED,MAAM,SAAS,GAAG,GAAG,CAAA;IACrB,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAA;IAEvC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,SAAS,EAAE,CAAA;AAC3C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,MAAc,EAAE,QAAgB;IAC/D,IAAI,MAAM,IAAI,CAAC,EAAE,CAAC;QAChB,MAAM,IAAI,mBAAmB,CAAC,yBAAyB,CAAC,CAAA;IAC1D,CAAC;IAED,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,MAAM,eAAe,CAAC,QAAQ,CAAC,CAAA;IAC/D,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,GAAG,CAAC,CAAA;IAE9C,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAA;AACtC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,IAAY,EACZ,QAAgB;IAEhB,IAAI,IAAI,IAAI,CAAC,EAAE,CAAC;QACd,MAAM,IAAI,mBAAmB,CAAC,uBAAuB,CAAC,CAAA;IACxD,CAAC;IAED,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,MAAM,eAAe,CAAC,QAAQ,CAAC,CAAA;IAC/D,MAAM,MAAM,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,GAAG,IAAI,CAAA;IAElC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAA;AACxC,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { NostrEvent } from './event.js';
2
+ export type Filter = {
3
+ ids?: string[];
4
+ kinds?: number[];
5
+ authors?: string[];
6
+ since?: number;
7
+ until?: number;
8
+ limit?: number;
9
+ search?: string;
10
+ [key: `#${string}`]: string[] | undefined;
11
+ };
12
+ export declare function matchFilter(filter: Filter, event: NostrEvent): boolean;
13
+ export declare function matchFilters(filters: Filter[], event: NostrEvent): boolean;
14
+ //# sourceMappingURL=filter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filter.d.ts","sourceRoot":"","sources":["../src/filter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAE5C,MAAM,MAAM,MAAM,GAAG;IACnB,GAAG,CAAC,EAAE,MAAM,EAAE,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,CAAC,GAAG,EAAE,IAAI,MAAM,EAAE,GAAG,MAAM,EAAE,GAAG,SAAS,CAAA;CAC1C,CAAA;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAiBtE;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAK1E"}
package/dist/filter.js ADDED
@@ -0,0 +1,29 @@
1
+ export function matchFilter(filter, event) {
2
+ if (filter.ids && filter.ids.indexOf(event.id) === -1)
3
+ return false;
4
+ if (filter.kinds && filter.kinds.indexOf(event.kind) === -1)
5
+ return false;
6
+ if (filter.authors && filter.authors.indexOf(event.pubkey) === -1)
7
+ return false;
8
+ for (const f in filter) {
9
+ if (f[0] === '#') {
10
+ const tagName = f.slice(1);
11
+ const values = filter[`#${tagName}`];
12
+ if (values && !event.tags.find(([t, v]) => t === tagName && values.indexOf(v) !== -1))
13
+ return false;
14
+ }
15
+ }
16
+ if (filter.since && event.created_at < filter.since)
17
+ return false;
18
+ if (filter.until && event.created_at > filter.until)
19
+ return false;
20
+ return true;
21
+ }
22
+ export function matchFilters(filters, event) {
23
+ for (let i = 0; i < filters.length; i++) {
24
+ if (matchFilter(filters[i], event))
25
+ return true;
26
+ }
27
+ return false;
28
+ }
29
+ //# sourceMappingURL=filter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filter.js","sourceRoot":"","sources":["../src/filter.ts"],"names":[],"mappings":"AAaA,MAAM,UAAU,WAAW,CAAC,MAAc,EAAE,KAAiB;IAC3D,IAAI,MAAM,CAAC,GAAG,IAAI,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;QAAE,OAAO,KAAK,CAAA;IACnE,IAAI,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAAE,OAAO,KAAK,CAAA;IACzE,IAAI,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAAE,OAAO,KAAK,CAAA;IAE/E,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;YACjB,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;YAC1B,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC,CAAA;YACpC,IAAI,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,OAAO,IAAI,MAAO,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;gBAAE,OAAO,KAAK,CAAA;QACtG,CAAC;IACH,CAAC;IAED,IAAI,MAAM,CAAC,KAAK,IAAI,KAAK,CAAC,UAAU,GAAG,MAAM,CAAC,KAAK;QAAE,OAAO,KAAK,CAAA;IACjE,IAAI,MAAM,CAAC,KAAK,IAAI,KAAK,CAAC,UAAU,GAAG,MAAM,CAAC,KAAK;QAAE,OAAO,KAAK,CAAA;IAEjE,OAAO,IAAI,CAAA;AACb,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,OAAiB,EAAE,KAAiB;IAC/D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACxC,IAAI,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC;YAAE,OAAO,IAAI,CAAA;IACjD,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC"}
@@ -0,0 +1,19 @@
1
+ export { NWC } from './nwc.js';
2
+ export type { EncryptionType, Nip47Method, Nip47NotificationType, GetInfoResponse, GetBalanceResponse, GetBudgetResponse, PayResponse, Transaction, MakeInvoiceRequest, PayInvoiceRequest, PayKeysendRequest, LookupInvoiceRequest, ListTransactionsRequest, ListTransactionsResponse, SignMessageRequest, SignMessageResponse, Nip47Notification, NWCConnectionOptions, LightningAddressResponse, FiatRate, FiatConversion, } from './types.js';
3
+ export { NWCError, NWCWalletError, NWCTimeoutError, NWCPublishTimeoutError, NWCReplyTimeoutError, NWCPublishError, NWCConnectionError, NWCDecryptionError, LightningAddressError, FiatConversionError, } from './types.js';
4
+ export { fetchInvoice, validateLightningAddress, parseLightningAddress } from './lightning-address.js';
5
+ export { getExchangeRate, fiatToSats, satsToFiat } from './fiat.js';
6
+ export { generateSecretKey, getPublicKey } from './crypto.js';
7
+ export { finalizeEvent, verifyEvent, getEventHash, serializeEvent, validateEvent, verifiedSymbol } from './event.js';
8
+ export type { NostrEvent, EventTemplate, UnsignedEvent, VerifiedEvent } from './event.js';
9
+ export { matchFilter, matchFilters } from './filter.js';
10
+ export type { Filter } from './filter.js';
11
+ export * as nip04 from './nip04.js';
12
+ export * as nip44 from './nip44.js';
13
+ export * as nip19 from './nip19.js';
14
+ export { Relay, Subscription } from './relay.js';
15
+ export type { SubscriptionParams } from './relay.js';
16
+ export { RelayPool } from './pool.js';
17
+ export type { SubCloser, PoolSubscribeParams } from './pool.js';
18
+ export { normalizeURL, utf8Encoder, utf8Decoder, bytesToHex, hexToBytes, randomBytes } from './utils.js';
19
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAG9B,YAAY,EACV,cAAc,EACd,WAAW,EACX,qBAAqB,EACrB,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,WAAW,EACX,WAAW,EACX,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,oBAAoB,EACpB,uBAAuB,EACvB,wBAAwB,EACxB,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,EACjB,oBAAoB,EACpB,wBAAwB,EACxB,QAAQ,EACR,cAAc,GACf,MAAM,YAAY,CAAA;AAGnB,OAAO,EACL,QAAQ,EACR,cAAc,EACd,eAAe,EACf,sBAAsB,EACtB,oBAAoB,EACpB,eAAe,EACf,kBAAkB,EAClB,kBAAkB,EAClB,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,YAAY,CAAA;AAGnB,OAAO,EAAE,YAAY,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAA;AAGtG,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AAGnE,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAG7D,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AACpH,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAGzF,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AACvD,YAAY,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAGzC,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AACnC,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AACnC,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AAGnC,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAChD,YAAY,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AACrC,YAAY,EAAE,SAAS,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAA;AAG/D,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,24 @@
1
+ // Main API
2
+ export { NWC } from './nwc.js';
3
+ // Error classes
4
+ export { NWCError, NWCWalletError, NWCTimeoutError, NWCPublishTimeoutError, NWCReplyTimeoutError, NWCPublishError, NWCConnectionError, NWCDecryptionError, LightningAddressError, FiatConversionError, } from './types.js';
5
+ // Lightning Address
6
+ export { fetchInvoice, validateLightningAddress, parseLightningAddress } from './lightning-address.js';
7
+ // Fiat Conversion
8
+ export { getExchangeRate, fiatToSats, satsToFiat } from './fiat.js';
9
+ // Crypto
10
+ export { generateSecretKey, getPublicKey } from './crypto.js';
11
+ // Event system
12
+ export { finalizeEvent, verifyEvent, getEventHash, serializeEvent, validateEvent, verifiedSymbol } from './event.js';
13
+ // Filters
14
+ export { matchFilter, matchFilters } from './filter.js';
15
+ // NIPs
16
+ export * as nip04 from './nip04.js';
17
+ export * as nip44 from './nip44.js';
18
+ export * as nip19 from './nip19.js';
19
+ // Networking
20
+ export { Relay, Subscription } from './relay.js';
21
+ export { RelayPool } from './pool.js';
22
+ // Utils
23
+ export { normalizeURL, utf8Encoder, utf8Decoder, bytesToHex, hexToBytes, randomBytes } from './utils.js';
24
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,WAAW;AACX,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AA2B9B,gBAAgB;AAChB,OAAO,EACL,QAAQ,EACR,cAAc,EACd,eAAe,EACf,sBAAsB,EACtB,oBAAoB,EACpB,eAAe,EACf,kBAAkB,EAClB,kBAAkB,EAClB,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,YAAY,CAAA;AAEnB,oBAAoB;AACpB,OAAO,EAAE,YAAY,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAA;AAEtG,kBAAkB;AAClB,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AAEnE,SAAS;AACT,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE7D,eAAe;AACf,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAGpH,UAAU;AACV,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAGvD,OAAO;AACP,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AACnC,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AACnC,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AAEnC,aAAa;AACb,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAEhD,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAGrC,QAAQ;AACR,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA"}
@@ -0,0 +1,26 @@
1
+ import type { LightningAddressResponse } from './types.js';
2
+ /**
3
+ * Validate whether a string is a valid Lightning Address format (name@domain).
4
+ */
5
+ export declare function validateLightningAddress(address: string): boolean;
6
+ /**
7
+ * Parse a Lightning Address into its name and domain parts.
8
+ * Throws LightningAddressError if the format is invalid.
9
+ */
10
+ export declare function parseLightningAddress(address: string): {
11
+ name: string;
12
+ domain: string;
13
+ };
14
+ /**
15
+ * Resolve a Lightning Address to a BOLT-11 invoice via LNURL-pay.
16
+ *
17
+ * 1. Fetches the LNURL-pay metadata from `https://{domain}/.well-known/lnurlp/{name}`
18
+ * 2. Validates the response (callback URL, min/max sendable)
19
+ * 3. Calls the callback with `?amount={msats}` to obtain an invoice
20
+ *
21
+ * @param address - Lightning Address (e.g. `hello@getalby.com`)
22
+ * @param amountSats - Amount in satoshis to request
23
+ * @returns The BOLT-11 invoice string and any LNURL metadata
24
+ */
25
+ export declare function fetchInvoice(address: string, amountSats: number): Promise<LightningAddressResponse>;
26
+ //# sourceMappingURL=lightning-address.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lightning-address.d.ts","sourceRoot":"","sources":["../src/lightning-address.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAA;AAI1D;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAEjE;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAMvF;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAiGzG"}