@unicitylabs/nostr-js-sdk 0.1.1 → 0.2.1

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 (84) hide show
  1. package/README.md +115 -12
  2. package/dist/browser/index.js +1685 -80
  3. package/dist/browser/index.js.map +1 -1
  4. package/dist/browser/index.min.js +7 -6
  5. package/dist/browser/index.min.js.map +1 -1
  6. package/dist/browser/index.umd.js +1694 -85
  7. package/dist/browser/index.umd.js.map +1 -1
  8. package/dist/browser/index.umd.min.js +7 -6
  9. package/dist/browser/index.umd.min.js.map +1 -1
  10. package/dist/cjs/NostrKeyManager.js +57 -0
  11. package/dist/cjs/NostrKeyManager.js.map +1 -1
  12. package/dist/cjs/client/NostrClient.js +46 -0
  13. package/dist/cjs/client/NostrClient.js.map +1 -1
  14. package/dist/cjs/crypto/index.js +4 -2
  15. package/dist/cjs/crypto/index.js.map +1 -1
  16. package/dist/cjs/crypto/nip04.js +14 -3
  17. package/dist/cjs/crypto/nip04.js.map +1 -1
  18. package/dist/cjs/crypto/nip44.js +297 -0
  19. package/dist/cjs/crypto/nip44.js.map +1 -0
  20. package/dist/cjs/index.js +27 -1
  21. package/dist/cjs/index.js.map +1 -1
  22. package/dist/cjs/messaging/index.js +24 -0
  23. package/dist/cjs/messaging/index.js.map +1 -0
  24. package/dist/cjs/messaging/nip17.js +267 -0
  25. package/dist/cjs/messaging/nip17.js.map +1 -0
  26. package/dist/cjs/messaging/types.js +20 -0
  27. package/dist/cjs/messaging/types.js.map +1 -0
  28. package/dist/cjs/nametag/NametagUtils.js +1 -1
  29. package/dist/cjs/nametag/NametagUtils.js.map +1 -1
  30. package/dist/cjs/payment/PaymentRequestProtocol.js +2 -0
  31. package/dist/cjs/payment/PaymentRequestProtocol.js.map +1 -1
  32. package/dist/cjs/protocol/EventKinds.js +13 -1
  33. package/dist/cjs/protocol/EventKinds.js.map +1 -1
  34. package/dist/cjs/token/TokenTransferProtocol.js +35 -5
  35. package/dist/cjs/token/TokenTransferProtocol.js.map +1 -1
  36. package/dist/esm/NostrKeyManager.js +57 -0
  37. package/dist/esm/NostrKeyManager.js.map +1 -1
  38. package/dist/esm/client/NostrClient.js +46 -0
  39. package/dist/esm/client/NostrClient.js.map +1 -1
  40. package/dist/esm/crypto/index.js +3 -1
  41. package/dist/esm/crypto/index.js.map +1 -1
  42. package/dist/esm/crypto/nip04.js +14 -3
  43. package/dist/esm/crypto/nip04.js.map +1 -1
  44. package/dist/esm/crypto/nip44.js +283 -0
  45. package/dist/esm/crypto/nip44.js.map +1 -0
  46. package/dist/esm/index.js +4 -1
  47. package/dist/esm/index.js.map +1 -1
  48. package/dist/esm/messaging/index.js +8 -0
  49. package/dist/esm/messaging/index.js.map +1 -0
  50. package/dist/esm/messaging/nip17.js +229 -0
  51. package/dist/esm/messaging/nip17.js.map +1 -0
  52. package/dist/esm/messaging/types.js +16 -0
  53. package/dist/esm/messaging/types.js.map +1 -0
  54. package/dist/esm/nametag/NametagUtils.js +1 -1
  55. package/dist/esm/nametag/NametagUtils.js.map +1 -1
  56. package/dist/esm/payment/PaymentRequestProtocol.js +2 -0
  57. package/dist/esm/payment/PaymentRequestProtocol.js.map +1 -1
  58. package/dist/esm/protocol/EventKinds.js +12 -0
  59. package/dist/esm/protocol/EventKinds.js.map +1 -1
  60. package/dist/esm/token/TokenTransferProtocol.js +34 -5
  61. package/dist/esm/token/TokenTransferProtocol.js.map +1 -1
  62. package/dist/types/NostrKeyManager.d.ts +36 -0
  63. package/dist/types/NostrKeyManager.d.ts.map +1 -1
  64. package/dist/types/client/NostrClient.d.ts +31 -0
  65. package/dist/types/client/NostrClient.d.ts.map +1 -1
  66. package/dist/types/crypto/index.d.ts +1 -1
  67. package/dist/types/crypto/index.d.ts.map +1 -1
  68. package/dist/types/crypto/nip04.d.ts.map +1 -1
  69. package/dist/types/crypto/nip44.d.ts +78 -0
  70. package/dist/types/crypto/nip44.d.ts.map +1 -0
  71. package/dist/types/index.d.ts +4 -1
  72. package/dist/types/index.d.ts.map +1 -1
  73. package/dist/types/messaging/index.d.ts +8 -0
  74. package/dist/types/messaging/index.d.ts.map +1 -0
  75. package/dist/types/messaging/nip17.d.ts +42 -0
  76. package/dist/types/messaging/nip17.d.ts.map +1 -0
  77. package/dist/types/messaging/types.d.ts +59 -0
  78. package/dist/types/messaging/types.d.ts.map +1 -0
  79. package/dist/types/payment/PaymentRequestProtocol.d.ts.map +1 -1
  80. package/dist/types/protocol/EventKinds.d.ts +6 -0
  81. package/dist/types/protocol/EventKinds.d.ts.map +1 -1
  82. package/dist/types/token/TokenTransferProtocol.d.ts +22 -3
  83. package/dist/types/token/TokenTransferProtocol.d.ts.map +1 -1
  84. package/package.json +2 -1
package/README.md CHANGED
@@ -4,8 +4,10 @@ A TypeScript SDK for Nostr protocol with Unicity extensions. Works in both Node.
4
4
 
5
5
  ## Features
6
6
 
7
+ - **NIP-17 Private Messages** - Gift-wrapped private direct messages with sender anonymity
8
+ - **NIP-44 Encryption** - Modern ChaCha20-Poly1305 AEAD encryption with HKDF
7
9
  - **BIP-340 Schnorr Signatures** - Full support for secp256k1 Schnorr signatures
8
- - **NIP-04 Encryption** - AES-256-CBC encryption with ECDH key agreement
10
+ - **NIP-04 Encryption** - Legacy AES-256-CBC encryption with ECDH key agreement
9
11
  - **GZIP Compression** - Automatic compression for large messages (>1KB)
10
12
  - **Multi-Relay Support** - Connect to multiple relays with automatic reconnection
11
13
  - **Token Transfers** - Encrypted Unicity token transfers over Nostr
@@ -73,7 +75,7 @@ const event = Event.create(keyManager, {
73
75
  const eventId = await client.publishEvent(event);
74
76
  ```
75
77
 
76
- ### Encrypted Direct Messages
78
+ ### Encrypted Direct Messages (NIP-04 Legacy)
77
79
 
78
80
  ```typescript
79
81
  // Send encrypted DM
@@ -85,6 +87,67 @@ const encrypted = await keyManager.encryptHex('Hello!', recipientPubkey);
85
87
  const decrypted = await keyManager.decryptHex(encrypted, senderPubkey);
86
88
  ```
87
89
 
90
+ ### NIP-17 Private Messages (Recommended)
91
+
92
+ NIP-17 provides enhanced privacy using gift-wrapping with ephemeral keys:
93
+
94
+ ```typescript
95
+ // Send private message by nametag (auto-resolves to pubkey)
96
+ const eventId = await client.sendPrivateMessageToNametag(
97
+ 'alice', // recipient nametag
98
+ 'Hello, this is a private message!'
99
+ );
100
+
101
+ // Or send by pubkey directly
102
+ const recipientPubkey = '...';
103
+ const eventId = await client.sendPrivateMessage(
104
+ recipientPubkey,
105
+ 'Hello, this is a private message!'
106
+ );
107
+
108
+ // Send reply to a previous message
109
+ const eventId = await client.sendPrivateMessage(
110
+ recipientPubkey,
111
+ 'This is a reply!',
112
+ { replyToEventId: originalEventId }
113
+ );
114
+
115
+ // Send read receipt
116
+ await client.sendReadReceipt(senderPubkey, messageEventId);
117
+ ```
118
+
119
+ Receive and unwrap private messages:
120
+
121
+ ```typescript
122
+ import { Filter, EventKinds } from '@unicitylabs/nostr-sdk';
123
+
124
+ // Subscribe to gift-wrapped messages
125
+ const filter = Filter.builder()
126
+ .kinds(EventKinds.GIFT_WRAP)
127
+ .pTags(keyManager.getPublicKeyHex())
128
+ .build();
129
+
130
+ client.subscribe(filter, {
131
+ onEvent: (event) => {
132
+ try {
133
+ const message = client.unwrapPrivateMessage(event);
134
+
135
+ if (message.kind === EventKinds.CHAT_MESSAGE) {
136
+ console.log('From:', message.senderPubkey);
137
+ console.log('Content:', message.content);
138
+
139
+ // Send read receipt
140
+ client.sendReadReceipt(message.senderPubkey, message.eventId);
141
+ } else if (message.kind === EventKinds.READ_RECEIPT) {
142
+ console.log('Read receipt for:', message.replyToEventId);
143
+ }
144
+ } catch (e) {
145
+ // Message not for us or decryption failed
146
+ }
147
+ },
148
+ });
149
+ ```
150
+
88
151
  ### Subscriptions
89
152
 
90
153
  ```typescript
@@ -127,8 +190,28 @@ const event = await TokenTransferProtocol.createTokenTransferEvent(
127
190
 
128
191
  await client.publishEvent(event);
129
192
 
193
+ // Create token transfer in response to a payment request
194
+ const paymentRequestEventId = '...'; // Event ID of the original payment request
195
+ const event = await TokenTransferProtocol.createTokenTransferEvent(
196
+ keyManager,
197
+ recipientPubkey,
198
+ tokenJson,
199
+ {
200
+ amount: 100n,
201
+ symbol: 'UNIT',
202
+ replyToEventId: paymentRequestEventId // Links transfer to the payment request
203
+ }
204
+ );
205
+
130
206
  // Parse received token transfer
131
207
  const tokenJson = await TokenTransferProtocol.parseTokenTransfer(event, keyManager);
208
+
209
+ // Get reply-to event ID (for payment request correlation)
210
+ const replyToId = TokenTransferProtocol.getReplyToEventId(event);
211
+ if (replyToId) {
212
+ // This transfer is in response to a payment request
213
+ const originalRequest = pendingRequests.get(replyToId);
214
+ }
132
215
  ```
133
216
 
134
217
  ### Payment Requests
@@ -223,6 +306,7 @@ Token transfers use Nostr event kind 31113 with NIP-04 encryption.
223
306
  | `type` | Yes | Always `"token_transfer"` |
224
307
  | `amount` | No | Transfer amount (metadata for filtering) |
225
308
  | `symbol` | No | Token symbol (metadata for filtering) |
309
+ | `e` | No | Reply-to event ID (for payment request correlation) |
226
310
 
227
311
  ### Encrypted Content
228
312
 
@@ -247,10 +331,11 @@ gz:<base64_ciphertext>?iv=<base64_iv>
247
331
  TokenTransferProtocol.isTokenTransfer(event); // boolean
248
332
 
249
333
  // Get metadata from tags
250
- TokenTransferProtocol.getAmount(event); // bigint | undefined
251
- TokenTransferProtocol.getSymbol(event); // string | undefined
252
- TokenTransferProtocol.getRecipient(event); // string | undefined
253
- TokenTransferProtocol.getSender(event); // string
334
+ TokenTransferProtocol.getAmount(event); // bigint | undefined
335
+ TokenTransferProtocol.getSymbol(event); // string | undefined
336
+ TokenTransferProtocol.getRecipient(event); // string | undefined
337
+ TokenTransferProtocol.getSender(event); // string
338
+ TokenTransferProtocol.getReplyToEventId(event); // string | undefined (payment request correlation)
254
339
  ```
255
340
 
256
341
  ## Payment Request Format
@@ -350,7 +435,9 @@ const parsed = await PaymentRequestProtocol.parsePaymentRequest(event, keyManage
350
435
 
351
436
  - **Bech32** - Bech32 encoding/decoding (npub, nsec)
352
437
  - **SchnorrSigner** - BIP-340 Schnorr signatures
353
- - **NIP04** - NIP-04 encryption/decryption
438
+ - **NIP04** - NIP-04 encryption/decryption (legacy)
439
+ - **NIP44** - NIP-44 encryption/decryption (ChaCha20-Poly1305)
440
+ - **NIP17** - NIP-17 private direct messages with gift-wrapping
354
441
  - **EventKinds** - Event kind constants
355
442
  - **NametagUtils** - Nametag normalization and hashing
356
443
  - **NametagBinding** - Nametag binding event creation
@@ -363,7 +450,11 @@ const parsed = await PaymentRequestProtocol.parsePaymentRequest(event, keyManage
363
450
  |------|------|-------------|
364
451
  | 0 | PROFILE | User profile metadata |
365
452
  | 1 | TEXT_NOTE | Short text note |
366
- | 4 | ENCRYPTED_DM | Encrypted direct message |
453
+ | 4 | ENCRYPTED_DM | Encrypted direct message (NIP-04) |
454
+ | 13 | SEAL | Encrypted seal for gift-wrapping (NIP-17) |
455
+ | 14 | CHAT_MESSAGE | Private direct message rumor (NIP-17) |
456
+ | 15 | READ_RECEIPT | Read receipt rumor (NIP-17) |
457
+ | 1059 | GIFT_WRAP | Gift-wrapped message (NIP-17) |
367
458
  | 30078 | APP_DATA | Application-specific data (nametag bindings) |
368
459
  | 31111 | AGENT_PROFILE | Agent profile information |
369
460
  | 31112 | AGENT_LOCATION | Agent GPS location |
@@ -392,22 +483,34 @@ npm run lint
392
483
 
393
484
  ## E2E Testing with Relay
394
485
 
486
+ ### NIP-17 Private Messages
487
+
488
+ ```bash
489
+ # Run NIP-17 E2E tests against real relay
490
+ npm test tests/integration/nip17-relay.test.ts
491
+
492
+ # Use a custom relay
493
+ NOSTR_TEST_RELAY=wss://your-relay.com npm test tests/integration/nip17-relay.test.ts
494
+ ```
495
+
496
+ ### Payment Requests (Manual)
497
+
395
498
  To test payment requests against a real wallet:
396
499
 
397
500
  ```bash
398
501
  # Send a single payment request
399
- TARGET_NAMETAG=mp-6 npm test -- --testNamePattern="send single payment request"
502
+ TARGET_NAMETAG=mp-9 npm test -- --testNamePattern="send single payment request"
400
503
 
401
504
  # Send multiple payment requests (for UI testing)
402
- TARGET_NAMETAG=mp-6 npm test -- --testNamePattern="send multiple payment requests"
505
+ TARGET_NAMETAG=mp-9 npm test -- --testNamePattern="send multiple payment requests"
403
506
 
404
507
  # Full flow with token transfer verification (requires wallet interaction)
405
- TARGET_NAMETAG=mp-6 npm test -- --testNamePattern="full payment request flow"
508
+ TARGET_NAMETAG=mp-9 npm test -- --testNamePattern="full payment request flow"
406
509
  ```
407
510
 
408
511
  Environment variables:
409
512
  - `TARGET_NAMETAG` - Nametag of the wallet to send requests to (required)
410
- - `NOSTR_RELAY` - Relay URL (default: `wss://nostr-relay.testnet.unicity.network`)
513
+ - `NOSTR_TEST_RELAY` - Relay URL (default: `wss://nostr-relay.testnet.unicity.network`)
411
514
  - `AMOUNT` - Amount in smallest units (default: `1000000`)
412
515
  - `TIMEOUT` - Timeout in seconds for full flow test (default: `120`)
413
516