All Nostr files have been successfully refactored to use nostr-tools v2.17.2 API.
- Changed:
privateKeyfromstringtoUint8Array - Storage: Still stored as hex string in SecureStore
- Conversion: Uses
bytesToHex()for storage,hexToBytes()for loading
// Before (v1.x)
private privateKey: string | null = null;
this.privateKey = generatePrivateKey(); // returned hex string
// After (v2.x)
private privateKey: Uint8Array | null = null;
this.privateKey = generateSecretKey(); // returns Uint8Array
await SecureStore.setItemAsync(KEY, bytesToHex(this.privateKey));- Changed: Replaced manual
getEventHash+getSignaturewithfinalizeEvent - One-step signing:
finalizeEventautomatically adds id, pubkey, and signature
// Before (v1.x)
const eventWithId = { ...event, id: getEventHash(event) };
const sig = getSignature(eventWithId, this.privateKey);
return { ...eventWithId, sig };
// After (v2.x)
const eventTemplate = {
kind: event.kind,
created_at: event.created_at,
tags: event.tags,
content: event.content,
};
return finalizeEvent(eventTemplate, this.privateKey);- Changed:
pool.sub()→pool.subscribe() - New API: Uses callback object with
oneventandoneose
// Before (v1.x)
const sub = this.pool.sub(relays, filters);
sub.on('event', callback);
sub.on('eose', onEOSE);
// After (v2.x)
const sub = this.pool.subscribe(relays, filters, {
onevent: (event) => { callback(event); },
oneose: () => { onEOSE(); },
});- Changed:
getPublicKey()now acceptsUint8Arrayparameter
// Before (v1.x)
this.publicKey = getPublicKey(this.privateKey); // privateKey was hex string
// After (v2.x)
this.publicKey = getPublicKey(this.privateKey); // privateKey is Uint8Array- Changed: Direct lib paths for React Native/Metro compatibility
- Added:
@noble/hashes/utilsforbytesToHexandhexToBytes
import { bytesToHex, hexToBytes } from '@noble/hashes/utils';
import type { Event as NostrToolsEvent, EventTemplate } from 'nostr-tools/lib/types/core';
import { SimplePool } from 'nostr-tools/lib/types/pool';
import { generateSecretKey, getPublicKey, finalizeEvent } from 'nostr-tools/lib/types/pure';
import * as nip04 from 'nostr-tools/lib/types/nip04';
import * as nip19 from 'nostr-tools/lib/types/nip19';No changes required - NIP-04 functions automatically handle both Uint8Array and hex string secret keys internally.
// Still works!
const encrypted = await nip04.encrypt(this.privateKey, recipientPubkey, content);
const decrypted = await nip04.decrypt(this.privateKey, senderPubkey, ciphertext);- ✅ INostrAdapter.ts - Interface unchanged, compatible with v2.x
- ✅ NostrRelayManager.ts - No changes needed, works with v2.x
- ✅ SendMessageWithNostrFallbackUseCase.ts - No changes needed
- ✅ NostrQuickStart.ts - Already updated with inline CSV data
All TypeScript errors have been resolved:
- ✅
nostr-toolsmodule found - ✅ Private key type mismatch fixed
- ✅
getEventHash/getSignatureremoved (usingfinalizeEvent) - ✅
SimplePool.sub()replaced with.subscribe() - ✅ All imports working with direct lib paths
- Initialize NostrAdapter
- Generate and store private key
- Load existing private key from SecureStore
- Derive public key correctly
- Encode public key to npub format
- Sign text event (kind 1)
- Sign encrypted DM (kind 4)
- Verify event id is correct
- Verify signature is valid
- Connect to multiple relays
- Publish event to relays
- Subscribe to events
- Receive events via callback
- Unsubscribe from events
- Handle EOSE (end of stored events)
- Encrypt content for recipient
- Decrypt content from sender
- Send encrypted DM
- Receive encrypted DM
- BLE → Nostr fallback works
- Message delivery tracking
- Relay selection (geo-based)
- Error handling
import { NostrAdapter } from '@/src/infrastructure/nostr/NostrAdapter';
import { NostrRelayManager } from '@/src/infrastructure/nostr/NostrRelayManager';
// Initialize
const adapter = new NostrAdapter();
await adapter.initialize(); // Generates key if not exists
// Get public key
const pubkey = adapter.getPublicKey();
console.log('My npub:', nip19.npubEncode(pubkey));
// Connect to relays
const relayManager = new NostrRelayManager();
await relayManager.loadRelaysFromCSV(csvData);
const relays = relayManager.getRecommendedRelays(37.7749, -122.4194, 5);
await adapter.connectToRelays(relays.map(r => r.url));
// Publish a note
const results = await adapter.publishEvent({
kind: 1,
pubkey,
created_at: Math.floor(Date.now() / 1000),
tags: [],
content: 'Hello from anon0mesh! 🚀',
});
console.log('Published to', results.filter(r => r.success).length, 'relays');
// Subscribe to messages
adapter.subscribe(
[
{ kinds: [4], '#p': [pubkey] }, // Encrypted DMs to me
{ kinds: [1], authors: [friendPubkey] }, // Friend's notes
],
(event) => {
console.log('Received:', event);
}
);
// Send encrypted DM
await adapter.publishEncryptedMessage(
friendPubkey,
'Secret message! 🤫',
[]
);| Feature | v1.x | v2.x |
|---|---|---|
| Private Key Type | string (hex) |
Uint8Array |
| Storage | Direct hex | Convert to/from hex |
| Event Signing | Manual 2-step | finalizeEvent() one-step |
| Subscriptions | .sub() + .on() |
.subscribe() with callbacks |
| Public Key | From hex string | From Uint8Array |
| Imports | Package exports | Direct lib paths (RN) |
- Better Performance - Binary operations faster than hex string manipulation
- Type Safety - Clear distinction between binary keys and encoded keys
- Simpler API -
finalizeEventcombines multiple operations - Modern Standards - Aligns with other Nostr libraries
- Better Docs - Official documentation at jsr.io/@nostr/tools
- Official Docs
- GitHub README
- NOSTR_INTEGRATION.md - Full integration guide
- NOSTR_V2_MIGRATION.md - Migration reference
- ✅ Refactoring complete - All code updated for v2.x
- ⏳ Test integration - Run through testing checklist
- ⏳ Update RelayMessageUseCase - Add Nostr relay support
- ⏳ Build and test on device - Verify React Native compatibility
Refactored by: GitHub Copilot
Date: November 9, 2025
Version: nostr-tools@2.17.2
Status: ✅ Ready for testing