nostr-crypto-utils 0.2.0 → 0.4.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/README.md +365 -39
- package/dist/__tests__/setup.d.ts +4 -0
- package/dist/__tests__/setup.js +13 -0
- package/dist/constants.d.ts +26 -76
- package/dist/constants.js +26 -70
- package/dist/crypto/encryption.d.ts +13 -0
- package/dist/crypto/encryption.js +71 -0
- package/dist/crypto/events.d.ts +25 -0
- package/dist/crypto/events.js +113 -0
- package/dist/crypto/index.d.ts +85 -0
- package/dist/crypto/index.js +269 -0
- package/dist/crypto/keys.d.ts +34 -0
- package/dist/crypto/keys.js +150 -0
- package/dist/event/creation.d.ts +29 -0
- package/dist/event/creation.js +53 -0
- package/dist/event/signing.d.ts +18 -0
- package/dist/event/signing.js +43 -0
- package/dist/functions.d.ts +19 -0
- package/dist/functions.js +127 -0
- package/dist/index.d.ts +5 -179
- package/dist/index.js +8 -394
- package/dist/integration/index.d.ts +12 -0
- package/dist/integration/index.js +27 -0
- package/dist/nips/index.d.ts +6 -0
- package/dist/nips/index.js +6 -0
- package/dist/nips/nip-01.d.ts +55 -0
- package/dist/nips/nip-01.js +139 -0
- package/dist/nips/nip-04.d.ts +52 -0
- package/dist/nips/nip-04.js +77 -0
- package/dist/protocol/constants.d.ts +99 -0
- package/dist/protocol/constants.js +93 -0
- package/dist/{integration.d.ts → protocol/index.d.ts} +29 -114
- package/dist/protocol/index.js +259 -0
- package/dist/protocol/transport.d.ts +14 -0
- package/dist/protocol/transport.js +30 -0
- package/dist/transport/index.d.ts +30 -0
- package/dist/transport/index.js +56 -0
- package/dist/types/base.d.ts +139 -39
- package/dist/types/base.js +39 -2
- package/dist/types/guards.d.ts +11 -8
- package/dist/types/guards.js +120 -66
- package/dist/types/index.d.ts +5 -15
- package/dist/types/index.js +4 -3
- package/dist/types/messages.d.ts +7 -0
- package/dist/types/protocol.d.ts +37 -102
- package/dist/types/protocol.js +3 -58
- package/dist/types.d.ts +82 -0
- package/dist/types.js +33 -0
- package/dist/utils/encoding.d.ts +15 -0
- package/dist/utils/encoding.js +25 -0
- package/dist/utils/events.d.ts +35 -0
- package/dist/utils/events.js +62 -0
- package/dist/utils/functions.d.ts +39 -0
- package/dist/utils/functions.js +105 -0
- package/dist/utils/index.d.ts +8 -0
- package/dist/utils/index.js +12 -0
- package/dist/utils/integration.d.ts +77 -0
- package/dist/utils/integration.js +248 -0
- package/dist/utils/logger.d.ts +23 -0
- package/dist/utils/logger.js +52 -0
- package/dist/{validation.d.ts → utils/validation.d.ts} +10 -26
- package/dist/{validation.js → utils/validation.js} +47 -80
- package/dist/validation/index.d.ts +97 -0
- package/dist/validation/index.js +322 -0
- package/package.json +22 -11
- package/dist/__tests__/crypto.test.js +0 -186
- package/dist/__tests__/guards.test.d.ts +0 -1
- package/dist/__tests__/guards.test.js +0 -81
- package/dist/__tests__/integration.test.d.ts +0 -1
- package/dist/__tests__/integration.test.js +0 -160
- package/dist/__tests__/nip_compliance.test.d.ts +0 -1
- package/dist/__tests__/nip_compliance.test.js +0 -124
- package/dist/__tests__/transport.test.d.ts +0 -1
- package/dist/__tests__/transport.test.js +0 -165
- package/dist/__tests__/types.test.d.ts +0 -1
- package/dist/__tests__/types.test.js +0 -243
- package/dist/__tests__/validation.test.d.ts +0 -1
- package/dist/__tests__/validation.test.js +0 -142
- package/dist/integration.js +0 -324
- /package/dist/{__tests__/crypto.test.d.ts → types/messages.js} +0 -0
package/README.md
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
# nostr-crypto-utils
|
|
2
2
|
|
|
3
|
-
A
|
|
3
|
+
A lightweight, type-safe TypeScript library for Nostr cryptography, designed to complement [@humanjavaenterprises/nostr-nsec-seedphrase](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase). Together, they provide a robust, security-focused alternative to larger Nostr client libraries.
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/@humanjavaenterprises/nostr-crypto-utils)
|
|
6
6
|
[](http://www.typescriptlang.org/)
|
|
7
7
|
[](https://github.com/HumanjavaEnterprises/nostr-crypto-utils/blob/main/LICENSE)
|
|
8
8
|
[](https://humanjavaenterprises.github.io/nostr-crypto-utils/)
|
|
9
|
+
[](https://github.com/HumanjavaEnterprises/nostr-crypto-utils/actions)
|
|
10
|
+
[](https://coveralls.io/github/HumanjavaEnterprises/nostr-crypto-utils?branch=main)
|
|
11
|
+
[](https://snyk.io/test/github/HumanjavaEnterprises/nostr-crypto-utils)
|
|
9
12
|
|
|
10
13
|
## Security Notice
|
|
11
14
|
|
|
@@ -13,6 +16,15 @@ A comprehensive TypeScript library providing cryptographic utilities and protoco
|
|
|
13
16
|
|
|
14
17
|
If you discover a security vulnerability, please follow our [Security Policy](SECURITY.md) and report it through [GitHub's Security Advisory feature](https://github.com/humanjavaenterprises/nostr-crypto-utils/security/advisories/new).
|
|
15
18
|
|
|
19
|
+
## Why Choose nostr-crypto-utils?
|
|
20
|
+
|
|
21
|
+
- **Lightweight**: Only 208.7KB unpacked, focusing on essential cryptographic operations
|
|
22
|
+
- **Type-First**: Built from the ground up with TypeScript for maximum type safety
|
|
23
|
+
- **Minimal Dependencies**: Reduced attack surface and easier auditing
|
|
24
|
+
- **Modular Design**: Perfect for projects that need cryptographic operations without full client functionality
|
|
25
|
+
- **Complementary**: Works seamlessly with nostr-nsec-seedphrase for complete key management
|
|
26
|
+
- **Security Focused**: Strict validation and comprehensive test coverage
|
|
27
|
+
|
|
16
28
|
## Features
|
|
17
29
|
|
|
18
30
|
- **Complete NIP Compliance**: Implements all required cryptographic operations according to Nostr Implementation Possibilities (NIPs)
|
|
@@ -21,6 +33,8 @@ If you discover a security vulnerability, please follow our [Security Policy](SE
|
|
|
21
33
|
- **Message Formatting**: Protocol-compliant message formatting for relay communication
|
|
22
34
|
- **Encryption**: Secure encryption and decryption for direct messages (NIP-04)
|
|
23
35
|
- **Validation**: Comprehensive validation for events, filters, and subscriptions
|
|
36
|
+
- **Cross-Platform**: Works in both Node.js and browser environments
|
|
37
|
+
- **Zero Dependencies**: Minimal external dependencies for better security
|
|
24
38
|
|
|
25
39
|
## Features and Capabilities
|
|
26
40
|
|
|
@@ -30,71 +44,383 @@ If you discover a security vulnerability, please follow our [Security Policy](SE
|
|
|
30
44
|
| Event Creation | ✅ | Create and validate Nostr events |
|
|
31
45
|
| Event Signing | ✅ | Sign events with schnorr signatures |
|
|
32
46
|
| Event Verification | ✅ | Verify event signatures and validate event structure |
|
|
33
|
-
|
|
|
34
|
-
| Message
|
|
35
|
-
|
|
|
36
|
-
|
|
|
47
|
+
| Direct Messages (NIP-04) | ✅ | Encrypt and decrypt direct messages |
|
|
48
|
+
| Message Formatting | ✅ | Format messages for relay communication |
|
|
49
|
+
| Type Safety | ✅ | Full TypeScript support with strict typing |
|
|
50
|
+
| Browser Support | ✅ | Works in modern browsers with Web Crypto API |
|
|
51
|
+
| Node.js Support | ✅ | Full support for Node.js environments |
|
|
52
|
+
|
|
53
|
+
## Integration with nostr-nsec-seedphrase
|
|
54
|
+
|
|
55
|
+
This library is designed to work seamlessly with [@humanjavaenterprises/nostr-nsec-seedphrase](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase) to provide a complete solution for Nostr key management and cryptographic operations:
|
|
56
|
+
|
|
57
|
+
```typescript
|
|
58
|
+
import { generateSeedPhrase } from '@humanjavaenterprises/nostr-nsec-seedphrase';
|
|
59
|
+
import { createTextNoteEvent, signEvent } from '@humanjavaenterprises/nostr-crypto-utils';
|
|
60
|
+
|
|
61
|
+
// Generate keys using nostr-nsec-seedphrase
|
|
62
|
+
const seedPhrase = generateSeedPhrase();
|
|
63
|
+
const keyPair = seedPhraseToKeyPair(seedPhrase);
|
|
64
|
+
|
|
65
|
+
// Use nostr-crypto-utils for event creation and signing
|
|
66
|
+
const event = createTextNoteEvent({
|
|
67
|
+
content: 'Hello Nostr!',
|
|
68
|
+
pubkey: keyPair.publicKey,
|
|
69
|
+
created_at: Math.floor(Date.now() / 1000)
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
const signedEvent = signEvent(event, keyPair.privateKey);
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Together, these libraries provide:
|
|
76
|
+
- Secure key generation and recovery through seed phrases
|
|
77
|
+
- Type-safe cryptographic operations
|
|
78
|
+
- Comprehensive event handling
|
|
79
|
+
- Minimal bundle size and dependencies
|
|
80
|
+
|
|
81
|
+
## Delegate Token Creation (NIP-26)
|
|
82
|
+
|
|
83
|
+
You can use this library to create delegate tokens for use on web servers or other applications. This implements [NIP-26](https://github.com/nostr-protocol/nips/blob/master/26.md) for delegation of signing authority.
|
|
84
|
+
|
|
85
|
+
### Basic Delegation Example
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
import { createDelegation, validateDelegation } from '@humanjavaenterprises/nostr-crypto-utils';
|
|
89
|
+
|
|
90
|
+
// Create a delegation token (delegator's perspective)
|
|
91
|
+
const delegatorKeyPair = await generateKeyPair();
|
|
92
|
+
const delegateePubkey = 'npub1...'; // The public key you're delegating to
|
|
93
|
+
|
|
94
|
+
const delegation = await createDelegation({
|
|
95
|
+
delegatorPrivkey: delegatorKeyPair.privateKey,
|
|
96
|
+
delegateePubkey,
|
|
97
|
+
conditions: {
|
|
98
|
+
kind: 1, // Only allow text notes
|
|
99
|
+
until: Math.floor(Date.now() / 1000) + 30 * 24 * 60 * 60 // 30 days
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
// Validate a delegation token (delegatee's perspective)
|
|
104
|
+
const isValid = await validateDelegation({
|
|
105
|
+
token: delegation.token,
|
|
106
|
+
delegatorPubkey: delegatorKeyPair.publicKey,
|
|
107
|
+
delegateePubkey,
|
|
108
|
+
kind: 1
|
|
109
|
+
});
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Web Server Example
|
|
113
|
+
|
|
114
|
+
Here's how to use delegation tokens in a web server context:
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
import { createEvent, signEventWithDelegation } from '@humanjavaenterprises/nostr-crypto-utils';
|
|
118
|
+
|
|
119
|
+
// On your server, store these securely
|
|
120
|
+
const DELEGATE_PRIVKEY = 'nsec1...'; // Your server's private key
|
|
121
|
+
const DELEGATION_TOKEN = 'nostr:delegation:...'; // Token from the delegator
|
|
122
|
+
const DELEGATOR_PUBKEY = 'npub1...'; // Delegator's public key
|
|
123
|
+
|
|
124
|
+
// Create and sign an event on behalf of the delegator
|
|
125
|
+
const event = await createEvent({
|
|
126
|
+
kind: 1,
|
|
127
|
+
content: 'Posted via delegation!',
|
|
128
|
+
pubkey: DELEGATOR_PUBKEY, // Original delegator's pubkey
|
|
129
|
+
created_at: Math.floor(Date.now() / 1000)
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
const signedEvent = await signEventWithDelegation({
|
|
133
|
+
event,
|
|
134
|
+
delegatePrivkey: DELEGATE_PRIVKEY,
|
|
135
|
+
delegation: {
|
|
136
|
+
token: DELEGATION_TOKEN,
|
|
137
|
+
conditions: {
|
|
138
|
+
kind: 1,
|
|
139
|
+
until: Math.floor(Date.now() / 1000) + 30 * 24 * 60 * 60
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Conditional Delegation
|
|
146
|
+
|
|
147
|
+
You can create more specific delegations with conditions:
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
// Create a delegation with multiple conditions
|
|
151
|
+
const delegation = await createDelegation({
|
|
152
|
+
delegatorPrivkey: delegatorKeyPair.privateKey,
|
|
153
|
+
delegateePubkey,
|
|
154
|
+
conditions: {
|
|
155
|
+
kinds: [1, 6], // Allow only text notes and reposts
|
|
156
|
+
until: Math.floor(Date.now() / 1000) + 7 * 24 * 60 * 60, // 1 week
|
|
157
|
+
since: Math.floor(Date.now() / 1000), // Starting from now
|
|
158
|
+
tags: [
|
|
159
|
+
['t', 'nostr'], // Only allow posts with tag 't' = 'nostr'
|
|
160
|
+
['p', delegateePubkey] // Only allow mentions of the delegatee
|
|
161
|
+
]
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Security Considerations
|
|
167
|
+
|
|
168
|
+
When working with delegated tokens:
|
|
169
|
+
|
|
170
|
+
1. **Store Securely**: Always store delegation tokens and private keys securely
|
|
171
|
+
2. **Check Expiration**: Validate the delegation's time constraints before using
|
|
172
|
+
3. **Validate Conditions**: Check all conditions before signing or accepting delegated events
|
|
173
|
+
4. **Limit Scope**: Only delegate the minimum required permissions
|
|
174
|
+
5. **Monitor Usage**: Keep track of how delegated tokens are being used
|
|
175
|
+
|
|
176
|
+
For more details on delegation, see the [NIP-26 specification](https://github.com/nostr-protocol/nips/blob/master/26.md).
|
|
177
|
+
|
|
178
|
+
## Type System Improvements
|
|
179
|
+
|
|
180
|
+
### Enhanced Type System
|
|
181
|
+
|
|
182
|
+
- **Consolidated Type Definitions**: Improved consistency and safety through unified type definitions
|
|
183
|
+
- **Better Type Inference**: Enhanced type inference for easier development and better code completion
|
|
184
|
+
- **Stricter Type Checks**: Improved type safety with stricter checks for better error prevention
|
|
185
|
+
|
|
186
|
+
### Improved Type Documentation
|
|
187
|
+
|
|
188
|
+
- **Better JSDoc Comments**: Improved documentation with clear and concise JSDoc comments
|
|
189
|
+
- **NIP References**: Added references to relevant NIPs for better understanding of the underlying protocol
|
|
190
|
+
|
|
191
|
+
## Troubleshooting
|
|
192
|
+
|
|
193
|
+
### Common Issues and Solutions
|
|
194
|
+
|
|
195
|
+
#### 1. Invalid Delegation Token
|
|
196
|
+
|
|
197
|
+
```typescript
|
|
198
|
+
// ❌ Common mistake: Using expired delegation
|
|
199
|
+
const delegation = await createDelegation({
|
|
200
|
+
delegatorPrivkey,
|
|
201
|
+
delegateePubkey,
|
|
202
|
+
conditions: {
|
|
203
|
+
until: Math.floor(Date.now() / 1000) - 3600 // Already expired!
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
// ✅ Correct: Ensure future expiration
|
|
208
|
+
const delegation = await createDelegation({
|
|
209
|
+
delegatorPrivkey,
|
|
210
|
+
delegateePubkey,
|
|
211
|
+
conditions: {
|
|
212
|
+
until: Math.floor(Date.now() / 1000) + (24 * 60 * 60) // 24 hours from now
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
#### 2. Signature Verification Failures
|
|
218
|
+
|
|
219
|
+
```typescript
|
|
220
|
+
// ❌ Common mistake: Using wrong key format
|
|
221
|
+
const wrongPubkey = 'npub1...'; // Using bech32 format directly
|
|
222
|
+
const event = await signEventWithDelegation({ pubkey: wrongPubkey, ... });
|
|
223
|
+
|
|
224
|
+
// ✅ Correct: Convert from bech32 to hex format first
|
|
225
|
+
import { nip19 } from 'nostr-tools';
|
|
226
|
+
const { data: pubkeyHex } = nip19.decode(pubkey);
|
|
227
|
+
const event = await signEventWithDelegation({ pubkey: pubkeyHex, ... });
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
#### 3. Permission Issues
|
|
231
|
+
|
|
232
|
+
```typescript
|
|
233
|
+
// ❌ Common mistake: Mismatched event kinds
|
|
234
|
+
const delegation = await createDelegation({
|
|
235
|
+
conditions: { kind: 1 } // Only allows kind 1
|
|
236
|
+
});
|
|
237
|
+
const event = createEvent({ kind: 4 }); // Trying to create kind 4
|
|
238
|
+
// This will fail!
|
|
239
|
+
|
|
240
|
+
// ✅ Correct: Match delegation conditions
|
|
241
|
+
const delegation = await createDelegation({
|
|
242
|
+
conditions: { kinds: [1, 4] } // Allow both kinds
|
|
243
|
+
});
|
|
244
|
+
const event = createEvent({ kind: 4 }); // Now works!
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
#### 4. Token Format Issues
|
|
248
|
+
|
|
249
|
+
```typescript
|
|
250
|
+
// ❌ Common mistake: Invalid token parsing
|
|
251
|
+
const token = 'nostr:delegation:...';
|
|
252
|
+
const parts = token.split(':'); // Naive splitting
|
|
253
|
+
|
|
254
|
+
// ✅ Correct: Use proper token parsing
|
|
255
|
+
import { parseDelegationToken } from '@humanjavaenterprises/nostr-crypto-utils';
|
|
256
|
+
const { delegator, conditions } = parseDelegationToken(token);
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### Debug Mode
|
|
260
|
+
|
|
261
|
+
Enable debug mode to get detailed logging:
|
|
262
|
+
|
|
263
|
+
```typescript
|
|
264
|
+
import { setDebugLevel } from '@humanjavaenterprises/nostr-crypto-utils';
|
|
265
|
+
|
|
266
|
+
// Enable debug logging
|
|
267
|
+
setDebugLevel('debug');
|
|
268
|
+
|
|
269
|
+
// Or for even more detail
|
|
270
|
+
setDebugLevel('trace');
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
### Common Error Messages
|
|
274
|
+
|
|
275
|
+
| Error Message | Likely Cause | Solution |
|
|
276
|
+
|--------------|--------------|----------|
|
|
277
|
+
| "Invalid delegation token" | Token expired or malformed | Check token expiration and format |
|
|
278
|
+
| "Signature verification failed" | Wrong key format or corrupted signature | Verify key formats and conversion |
|
|
279
|
+
| "Condition check failed" | Event doesn't match delegation conditions | Check event kind and other conditions |
|
|
280
|
+
| "Invalid pubkey format" | Using bech32 instead of hex | Convert pubkey to correct format |
|
|
281
|
+
| "Token expired" | Delegation token past expiration | Create new delegation with future expiration |
|
|
282
|
+
|
|
283
|
+
### Validation Checks
|
|
284
|
+
|
|
285
|
+
When troubleshooting, verify these common points:
|
|
286
|
+
|
|
287
|
+
1. **Key Formats**
|
|
288
|
+
- Private keys should be in hex format
|
|
289
|
+
- Public keys should be in hex format (not bech32)
|
|
290
|
+
- Signatures should be 64 bytes in hex format
|
|
291
|
+
|
|
292
|
+
2. **Time Constraints**
|
|
293
|
+
- Token expiration should be in the future
|
|
294
|
+
- Check system clock synchronization
|
|
295
|
+
- Use UTC timestamps consistently
|
|
296
|
+
|
|
297
|
+
3. **Permission Scope**
|
|
298
|
+
- Verify event kinds match delegation conditions
|
|
299
|
+
- Check any tag restrictions
|
|
300
|
+
- Confirm time window restrictions
|
|
301
|
+
|
|
302
|
+
4. **Network Issues**
|
|
303
|
+
- Verify relay connections
|
|
304
|
+
- Check for rate limiting
|
|
305
|
+
- Confirm proper websocket handling
|
|
306
|
+
|
|
307
|
+
### Testing Tools
|
|
308
|
+
|
|
309
|
+
```typescript
|
|
310
|
+
// Test delegation validity
|
|
311
|
+
const testDelegation = async (delegation) => {
|
|
312
|
+
const result = await validateDelegation({
|
|
313
|
+
token: delegation.token,
|
|
314
|
+
delegatorPubkey: delegation.delegator,
|
|
315
|
+
delegateePubkey: delegation.delegatee,
|
|
316
|
+
kind: 1
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
console.log('Delegation valid:', result.isValid);
|
|
320
|
+
if (!result.isValid) {
|
|
321
|
+
console.error('Validation error:', result.error);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
return result;
|
|
325
|
+
};
|
|
326
|
+
|
|
327
|
+
// Test event signing
|
|
328
|
+
const testEventSigning = async (event, delegation) => {
|
|
329
|
+
try {
|
|
330
|
+
const signed = await signEventWithDelegation({
|
|
331
|
+
event,
|
|
332
|
+
delegatePrivkey: delegation.privateKey,
|
|
333
|
+
delegation: delegation.token
|
|
334
|
+
});
|
|
335
|
+
console.log('Event signed successfully:', signed.id);
|
|
336
|
+
return true;
|
|
337
|
+
} catch (error) {
|
|
338
|
+
console.error('Signing failed:', error);
|
|
339
|
+
return false;
|
|
340
|
+
}
|
|
341
|
+
};
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
For more help, join our [Discord community](https://discord.gg/nostr) or [open an issue](https://github.com/humanjavaenterprises/nostr-crypto-utils/issues).
|
|
37
345
|
|
|
38
346
|
## Installation
|
|
39
347
|
|
|
40
348
|
```bash
|
|
41
|
-
npm install nostr-crypto-utils
|
|
349
|
+
npm install @humanjavaenterprises/nostr-crypto-utils
|
|
42
350
|
```
|
|
43
351
|
|
|
44
352
|
## Quick Start
|
|
45
353
|
|
|
46
354
|
```typescript
|
|
47
|
-
import {
|
|
355
|
+
import { createKeyPair, createTextNoteEvent, signEvent } from '@humanjavaenterprises/nostr-crypto-utils';
|
|
48
356
|
|
|
49
|
-
// Generate a new
|
|
50
|
-
const keyPair =
|
|
51
|
-
console.log('Public Key:', keyPair.publicKey);
|
|
52
|
-
console.log('Private Key:', keyPair.privateKey);
|
|
357
|
+
// Generate a new key pair
|
|
358
|
+
const keyPair = createKeyPair();
|
|
53
359
|
|
|
54
|
-
// Create
|
|
55
|
-
const event =
|
|
56
|
-
kind: 1,
|
|
360
|
+
// Create a text note event
|
|
361
|
+
const event = createTextNoteEvent({
|
|
57
362
|
content: 'Hello Nostr!',
|
|
58
|
-
|
|
59
|
-
|
|
363
|
+
pubkey: keyPair.publicKey,
|
|
364
|
+
created_at: Math.floor(Date.now() / 1000)
|
|
365
|
+
});
|
|
60
366
|
|
|
61
|
-
//
|
|
62
|
-
const
|
|
367
|
+
// Sign the event
|
|
368
|
+
const signedEvent = signEvent(event, keyPair.privateKey);
|
|
63
369
|
```
|
|
64
370
|
|
|
65
371
|
## Documentation
|
|
66
372
|
|
|
67
|
-
|
|
373
|
+
Comprehensive documentation is available at [https://humanjavaenterprises.github.io/nostr-crypto-utils/](https://humanjavaenterprises.github.io/nostr-crypto-utils/)
|
|
68
374
|
|
|
69
|
-
##
|
|
375
|
+
## Type Safety
|
|
70
376
|
|
|
71
|
-
|
|
377
|
+
This library is written in TypeScript and provides comprehensive type definitions for all functions and data structures. Type checking is enforced at compile time to catch potential errors early.
|
|
72
378
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
- 💬 [Start a discussion](https://github.com/humanjavaenterprises/nostr-crypto-utils/discussions)
|
|
76
|
-
- 📖 [Read documentation](https://humanjavaenterprises.github.io/nostr-crypto-utils/)
|
|
77
|
-
- 🔒 [Report security issues](https://github.com/humanjavaenterprises/nostr-crypto-utils/security/advisories/new)
|
|
379
|
+
```typescript
|
|
380
|
+
import { NostrEvent, NostrFilter, ValidationResult } from '@humanjavaenterprises/nostr-crypto-utils';
|
|
78
381
|
|
|
79
|
-
|
|
382
|
+
// All types are properly defined
|
|
383
|
+
const filter: NostrFilter = {
|
|
384
|
+
kinds: [1],
|
|
385
|
+
authors: ['pubkey1', 'pubkey2'],
|
|
386
|
+
limit: 10
|
|
387
|
+
};
|
|
80
388
|
|
|
81
|
-
|
|
389
|
+
// Validation results include type information
|
|
390
|
+
const result: ValidationResult = validateEvent(event);
|
|
391
|
+
```
|
|
82
392
|
|
|
83
|
-
|
|
84
|
-
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
|
|
85
|
-
3. Commit your changes (`git commit -m 'feat: add amazing feature'`)
|
|
86
|
-
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
87
|
-
5. Open a Pull Request
|
|
393
|
+
## Contributing
|
|
88
394
|
|
|
89
|
-
|
|
90
|
-
- Read our [Code of Conduct](CODE_OF_CONDUCT.md)
|
|
91
|
-
- Check our [Contributing Guidelines](.github/CONTRIBUTING.md)
|
|
92
|
-
- Review our [Security Policy](SECURITY.md)
|
|
93
|
-
- Search [existing issues](https://github.com/humanjavaenterprises/nostr-crypto-utils/issues) before creating a new one
|
|
395
|
+
We welcome contributions! Please see our [Contributing Guidelines](CONTRIBUTING.md) for details.
|
|
94
396
|
|
|
95
397
|
## License
|
|
96
398
|
|
|
97
|
-
[
|
|
399
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
400
|
+
|
|
401
|
+
## Changelog
|
|
402
|
+
|
|
403
|
+
### v0.3.0 (2024-12-28)
|
|
404
|
+
- 🔒 Improved type safety with stricter TypeScript checks
|
|
405
|
+
- 🐛 Fixed crypto implementation for cross-platform compatibility
|
|
406
|
+
- ✨ Added comprehensive validation for all message types
|
|
407
|
+
- 📝 Updated documentation with more examples
|
|
408
|
+
|
|
409
|
+
### v0.2.0 (2024-12-26)
|
|
410
|
+
- 🎉 Initial public release
|
|
411
|
+
- ✨ Added support for NIP-01 and NIP-04
|
|
412
|
+
- 🔑 Implemented key pair generation and management
|
|
413
|
+
- 📝 Added comprehensive documentation
|
|
414
|
+
|
|
415
|
+
## Support
|
|
416
|
+
|
|
417
|
+
- 📖 [Documentation](https://humanjavaenterprises.github.io/nostr-crypto-utils/)
|
|
418
|
+
- 🐛 [Issue Tracker](https://github.com/humanjavaenterprises/nostr-crypto-utils/issues)
|
|
419
|
+
- 💬 [Discussions](https://github.com/humanjavaenterprises/nostr-crypto-utils/discussions)
|
|
420
|
+
|
|
421
|
+
## Related Projects
|
|
422
|
+
|
|
423
|
+
- [@humanjavaenterprises/nostr-nsec-seedphrase](https://github.com/HumanjavaEnterprises/nostr-nsec-seedphrase) - Generate and manage Nostr private keys using BIP-39 seed phrases
|
|
98
424
|
|
|
99
425
|
---
|
|
100
426
|
<div align="center">
|
package/dist/__tests__/setup.js
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module test/setup
|
|
3
|
+
* @description Test setup and configuration
|
|
4
|
+
*/
|
|
5
|
+
import { afterEach, beforeEach } from 'vitest';
|
|
1
6
|
import { webcrypto } from 'node:crypto';
|
|
2
7
|
// Configure crypto for test environment
|
|
3
8
|
if (typeof globalThis.crypto === 'undefined') {
|
|
4
9
|
globalThis.crypto = webcrypto;
|
|
5
10
|
}
|
|
11
|
+
// Set up global test environment
|
|
12
|
+
beforeEach(() => {
|
|
13
|
+
// Add any global setup here
|
|
14
|
+
});
|
|
15
|
+
afterEach(() => {
|
|
16
|
+
// Add any cleanup here
|
|
17
|
+
});
|
|
18
|
+
// Add any custom matchers or global test utilities here
|
package/dist/constants.d.ts
CHANGED
|
@@ -1,99 +1,49 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Constants used
|
|
3
|
-
* @module constants
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* Nostr protocol message types as defined in NIP-01
|
|
7
|
-
* @constant
|
|
8
|
-
* @type {const}
|
|
2
|
+
* Constants used throughout the library
|
|
9
3
|
*/
|
|
10
4
|
export declare const NOSTR_MESSAGE_TYPE: {
|
|
11
|
-
/** Client sending an event to a relay */
|
|
12
5
|
readonly EVENT: "EVENT";
|
|
13
|
-
/** Client requesting events from a relay */
|
|
14
6
|
readonly REQ: "REQ";
|
|
15
|
-
/** Client closing a subscription */
|
|
16
7
|
readonly CLOSE: "CLOSE";
|
|
17
|
-
/** Relay sending a notice/message to a client */
|
|
18
8
|
readonly NOTICE: "NOTICE";
|
|
19
|
-
|
|
9
|
+
readonly EOSE: "EOSE";
|
|
20
10
|
readonly OK: "OK";
|
|
21
|
-
/** Relay requesting client authentication */
|
|
22
11
|
readonly AUTH: "AUTH";
|
|
23
|
-
|
|
24
|
-
readonly EOSE: "EOSE";
|
|
12
|
+
readonly ERROR: "ERROR";
|
|
25
13
|
};
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
* @constant
|
|
29
|
-
* @type {const}
|
|
30
|
-
*/
|
|
31
|
-
export declare const NOSTR_KIND: {
|
|
32
|
-
/** User metadata (NIP-01) */
|
|
33
|
-
readonly METADATA: 0;
|
|
34
|
-
/** Text note (NIP-01) */
|
|
14
|
+
export declare const NOSTR_EVENT_KIND: {
|
|
15
|
+
readonly SET_METADATA: 0;
|
|
35
16
|
readonly TEXT_NOTE: 1;
|
|
36
|
-
/** Relay recommendation (NIP-01) */
|
|
37
17
|
readonly RECOMMEND_SERVER: 2;
|
|
38
|
-
|
|
39
|
-
readonly CONTACTS: 3;
|
|
40
|
-
/** Encrypted direct message (NIP-04) */
|
|
18
|
+
readonly CONTACT_LIST: 3;
|
|
41
19
|
readonly ENCRYPTED_DIRECT_MESSAGE: 4;
|
|
42
|
-
/** Event deletion (NIP-09) */
|
|
43
20
|
readonly DELETE: 5;
|
|
44
|
-
/** Event repost (NIP-18) */
|
|
45
21
|
readonly REPOST: 6;
|
|
46
|
-
/** Reaction (NIP-25) */
|
|
47
22
|
readonly REACTION: 7;
|
|
48
|
-
/** Badge award (NIP-58) */
|
|
49
23
|
readonly BADGE_AWARD: 8;
|
|
50
|
-
/** Channel creation (NIP-28) */
|
|
51
24
|
readonly CHANNEL_CREATE: 40;
|
|
52
|
-
/** Channel metadata (NIP-28) */
|
|
53
25
|
readonly CHANNEL_METADATA: 41;
|
|
54
|
-
/** Channel message (NIP-28) */
|
|
55
26
|
readonly CHANNEL_MESSAGE: 42;
|
|
56
|
-
/** Channel hide message (NIP-28) */
|
|
57
27
|
readonly CHANNEL_HIDE_MESSAGE: 43;
|
|
58
|
-
/** Channel mute user (NIP-28) */
|
|
59
28
|
readonly CHANNEL_MUTE_USER: 44;
|
|
60
|
-
|
|
61
|
-
readonly
|
|
62
|
-
|
|
63
|
-
readonly
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
readonly
|
|
73
|
-
|
|
74
|
-
readonly
|
|
75
|
-
|
|
76
|
-
readonly
|
|
77
|
-
|
|
78
|
-
readonly
|
|
79
|
-
|
|
80
|
-
readonly DEDUPLICATION: "d";
|
|
81
|
-
/** Event expiration timestamp */
|
|
82
|
-
readonly EXPIRATION: "expiration";
|
|
83
|
-
/** Event kind being referenced */
|
|
84
|
-
readonly KIND: "k";
|
|
85
|
-
/** Relay URL */
|
|
86
|
-
readonly RELAY: "r";
|
|
87
|
-
/** Subject or title */
|
|
88
|
-
readonly SUBJECT: "subject";
|
|
89
|
-
/** Content warning */
|
|
90
|
-
readonly CONTENT_WARNING: "content-warning";
|
|
91
|
-
/** Proof of work nonce */
|
|
92
|
-
readonly NONCE: "nonce";
|
|
29
|
+
readonly CHANNEL_RESERVED_FIRST: 40;
|
|
30
|
+
readonly CHANNEL_RESERVED_LAST: 49;
|
|
31
|
+
readonly REPORTING: 1984;
|
|
32
|
+
readonly ZAP_REQUEST: 9734;
|
|
33
|
+
readonly ZAP: 9735;
|
|
34
|
+
readonly MUTE_LIST: 10000;
|
|
35
|
+
readonly PIN_LIST: 10001;
|
|
36
|
+
readonly RELAY_LIST_METADATA: 10002;
|
|
37
|
+
readonly CLIENT_AUTH: 22242;
|
|
38
|
+
readonly CLIENT_ERROR: 23;
|
|
39
|
+
readonly PARAMETERIZED_REPLACEABLE_FIRST: 30000;
|
|
40
|
+
readonly PARAMETERIZED_REPLACEABLE_LAST: 39999;
|
|
41
|
+
readonly REPLACEABLE_FIRST: 10000;
|
|
42
|
+
readonly REPLACEABLE_LAST: 19999;
|
|
43
|
+
readonly EPHEMERAL_FIRST: 20000;
|
|
44
|
+
readonly EPHEMERAL_LAST: 29999;
|
|
45
|
+
readonly REGULAR_FIRST: 1000;
|
|
46
|
+
readonly REGULAR_LAST: 9999;
|
|
47
|
+
readonly CUSTOM_FIRST: 40000;
|
|
48
|
+
readonly CUSTOM_LAST: 49999;
|
|
93
49
|
};
|
|
94
|
-
/** Type for message types extracted from NOSTR_MESSAGE_TYPE constant */
|
|
95
|
-
export type NostrMessageType = typeof NOSTR_MESSAGE_TYPE[keyof typeof NOSTR_MESSAGE_TYPE];
|
|
96
|
-
/** Type for event kinds extracted from NOSTR_KIND constant */
|
|
97
|
-
export type NostrKind = typeof NOSTR_KIND[keyof typeof NOSTR_KIND];
|
|
98
|
-
/** Type for tags extracted from NOSTR_TAG constant */
|
|
99
|
-
export type NostrTag = typeof NOSTR_TAG[keyof typeof NOSTR_TAG];
|