Skip to content

Commit a2da3c5

Browse files
committed
fix: migrate to nostr ^2.0.0 for pointycastle v4 compatibility
The nostr v2.0.0 package widens its pointycastle constraint to >=3.7.3 <5.0.0, unblocking pointycastle v4. Beyond the documented Keychain→Keys and privkey:→secretKey: renames, v2 also changed Keys.private→Keys.secret, dropped the Nip19.encodePrivkey/decodePrivkey helpers (replaced by Nip19.encode/decode and the Keys.nsec getter), and changed Event.toJson() to return String while adding Event.toMap() for callers that need Map<String,dynamic>.
1 parent 8eb511b commit a2da3c5

17 files changed

Lines changed: 123 additions & 123 deletions

mobile/lib/features/channels/agent_activity/observer_subscription.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ class ObserverRelayNotifier extends Notifier<ObserverRelayState> {
271271

272272
static String _decodePrivkey(String nsec) {
273273
try {
274-
final privHex = nostr.Nip19.decodePrivkey(nsec);
274+
final privHex = nostr.Nip19.decode(payload: nsec).data;
275275
if (privHex.isEmpty) {
276276
throw const FormatException('empty private key');
277277
}
@@ -283,7 +283,7 @@ class ObserverRelayNotifier extends Notifier<ObserverRelayState> {
283283

284284
static String _derivePubkey(String privHex) {
285285
try {
286-
return nostr.Keychain(privHex).public;
286+
return nostr.Keys(privHex).public;
287287
} catch (_) {
288288
throw const FormatException('failed to derive pubkey');
289289
}

mobile/lib/features/channels/compose_bar.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -593,7 +593,7 @@ void _sendTypingIndicator(
593593
final nsec = config.nsec;
594594
if (nsec == null || nsec.isEmpty) return;
595595

596-
final privkeyHex = nostr.Nip19.decodePrivkey(nsec);
596+
final privkeyHex = nostr.Nip19.decode(payload: nsec).data;
597597
if (privkeyHex.isEmpty) return;
598598

599599
final tags = <List<String>>[
@@ -609,13 +609,13 @@ void _sendTypingIndicator(
609609
kind: EventKind.typingIndicator,
610610
content: '',
611611
tags: tags,
612-
privkey: privkeyHex,
612+
secretKey: privkeyHex,
613613
verify: false,
614614
);
615615

616616
// Send directly over WebSocket — fire-and-forget, matching desktop.
617617
final session = ref.read(relaySessionProvider.notifier);
618-
session.sendRaw(['EVENT', event.toJson()]);
618+
session.sendRaw(['EVENT', event.toMap()]);
619619
} catch (_) {
620620
// Fire-and-forget — typing indicator failure is non-fatal.
621621
}

mobile/lib/features/channels/read_state/read_state_manager.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class ReadStateCrypto {
2222
required String pubkey,
2323
}) {
2424
try {
25-
final privkeyHex = nostr.Nip19.decodePrivkey(nsec);
25+
final privkeyHex = nostr.Nip19.decode(payload: nsec).data;
2626
if (privkeyHex.isEmpty || pubkey.isEmpty) {
2727
return null;
2828
}

mobile/lib/features/pairing/pairing_provider.dart

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,8 @@ class PairingNotifier extends Notifier<PairingState> {
154154
final relayWsUrl = qr.relays.first;
155155

156156
// 2. Generate ephemeral keypair.
157-
final keychain = nostr.Keychain.generate();
158-
_ephemeralPrivkey = keychain.private;
157+
final keychain = nostr.Keys.generate();
158+
_ephemeralPrivkey = keychain.secret;
159159
_ephemeralPubkey = keychain.public;
160160

161161
// 3. Derive session ID and SAS immediately (we know source pubkey from QR).
@@ -302,7 +302,7 @@ class PairingNotifier extends Notifier<PairingState> {
302302
// NIP-AB §Event Validation: verify event signature (NIP-01).
303303
// The nostr package's Event.fromJson verifies id + sig on construction.
304304
try {
305-
final event = nostr.Event.fromJson(eventJson);
305+
final event = nostr.Event.fromJson(jsonEncode(eventJson));
306306
if (event.id != eventId) return; // id mismatch
307307
} catch (_) {
308308
return; // invalid signature or malformed event
@@ -507,11 +507,11 @@ class PairingNotifier extends Notifier<PairingState> {
507507
kind: kind,
508508
content: content,
509509
tags: tags,
510-
privkey: _ephemeralPrivkey!,
510+
secretKey: _ephemeralPrivkey!,
511511
createdAt: createdAt,
512512
);
513513

514-
_socket?.publishEvent(event.toJson());
514+
_socket?.publishEvent(event.toMap());
515515
}
516516

517517
void _handleDisconnected(Object? error) {

mobile/lib/features/pairing/pairing_socket.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,12 +166,12 @@ class PairingSocket {
166166
kind: EventKind.auth,
167167
content: '',
168168
tags: tags,
169-
privkey: _ephemeralPrivkey,
169+
secretKey: _ephemeralPrivkey,
170170
createdAt: DateTime.now().millisecondsSinceEpoch ~/ 1000,
171171
);
172172

173173
_pendingAuthEventId = event.id;
174-
send(['AUTH', event.toJson()]);
174+
send(['AUTH', event.toMap()]);
175175
} catch (e) {
176176
_failAuth(e);
177177
}

mobile/lib/features/profile/user_status_provider.dart

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ class UserStatusNotifier extends AsyncNotifier<UserStatus?> {
2525

2626
String pubkey;
2727
try {
28-
final privkeyHex = nostr.Nip19.decodePrivkey(nsec);
29-
final keyPair = nostr.Keychain(privkeyHex);
28+
final privkeyHex = nostr.Nip19.decode(payload: nsec).data;
29+
final keyPair = nostr.Keys(privkeyHex);
3030
pubkey = keyPair.public.toLowerCase();
3131
} catch (_) {
3232
return null;
@@ -74,18 +74,18 @@ class UserStatusNotifier extends AsyncNotifier<UserStatus?> {
7474
tags.add(['emoji', emoji]);
7575
}
7676

77-
final privkeyHex = nostr.Nip19.decodePrivkey(nsec);
77+
final privkeyHex = nostr.Nip19.decode(payload: nsec).data;
7878
final event = nostr.Event.from(
7979
kind: EventKind.userStatus,
8080
content: trimmed,
8181
tags: tags,
82-
privkey: privkeyHex,
82+
secretKey: privkeyHex,
8383
verify: false,
8484
);
8585

8686
final session = ref.read(relaySessionProvider.notifier);
8787
await session.publish(
88-
NostrEvent.fromJson(Map<String, dynamic>.from(event.toJson())),
88+
NostrEvent.fromJson(event.toMap()),
8989
);
9090

9191
// Optimistic update: update own state immediately.
@@ -99,7 +99,7 @@ class UserStatusNotifier extends AsyncNotifier<UserStatus?> {
9999
state = AsyncValue.data(newStatus);
100100

101101
// Also update the shared cache so other UI reads stay consistent.
102-
final keyPair = nostr.Keychain(privkeyHex);
102+
final keyPair = nostr.Keys(privkeyHex);
103103
final pubkey = keyPair.public.toLowerCase();
104104
ref.read(userStatusCacheProvider.notifier).updateStatus(pubkey, newStatus);
105105
}

mobile/lib/features/settings/settings_page.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,9 @@ class SettingsPage extends HookConsumerWidget {
5757
const SizedBox(height: Grid.xxs),
5858
Builder(
5959
builder: (context) {
60-
final privHex = nostr.Nip19.decodePrivkey(config.nsec!);
60+
final privHex = nostr.Nip19.decode(payload: config.nsec!).data;
6161
final pubkey = privHex.isNotEmpty
62-
? nostr.Keychain(privHex).public
62+
? nostr.Keys(privHex).public
6363
: 'unknown';
6464
return ListTile(
6565
leading: const Icon(LucideIcons.key),

mobile/lib/shared/relay/media_upload.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ class MediaUploadService {
270270

271271
String _buildUploadAuthHeader(String sha256) {
272272
final authEvent = _buildUploadAuthEvent(sha256);
273-
final authJson = jsonEncode(authEvent.toJson());
273+
final authJson = authEvent.toJson();
274274
final encoded = base64Url.encode(utf8.encode(authJson)).replaceAll('=', '');
275275
return 'Nostr $encoded';
276276
}
@@ -281,7 +281,7 @@ class MediaUploadService {
281281
throw Exception('Cannot upload media: no signing key available');
282282
}
283283

284-
final privkeyHex = nostr.Nip19.decodePrivkey(nsec);
284+
final privkeyHex = nostr.Nip19.decode(payload: nsec).data;
285285
if (privkeyHex.isEmpty) {
286286
throw Exception('Invalid nsec');
287287
}
@@ -300,7 +300,7 @@ class MediaUploadService {
300300
kind: _uploadAuthKind,
301301
content: 'Upload sprout-media',
302302
tags: tags,
303-
privkey: privkeyHex,
303+
secretKey: privkeyHex,
304304
verify: false,
305305
);
306306
}

mobile/lib/shared/relay/relay_provider.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,9 @@ final relayConfigProvider = NotifierProvider<RelayConfigNotifier, RelayConfig>(
6666
String? pubkeyFromNsec(String? nsec) {
6767
if (nsec == null || nsec.isEmpty) return null;
6868
try {
69-
final privkeyHex = nostr.Nip19.decodePrivkey(nsec);
69+
final privkeyHex = nostr.Nip19.decode(payload: nsec).data;
7070
if (privkeyHex.isEmpty) return null;
71-
return nostr.Keychain(privkeyHex).public;
71+
return nostr.Keys(privkeyHex).public;
7272
} catch (_) {
7373
return null;
7474
}

mobile/lib/shared/relay/relay_socket.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ class RelaySocket {
178178

179179
try {
180180
// Decode bech32 nsec to hex private key.
181-
final privkeyHex = nostr.Nip19.decodePrivkey(_nsec);
181+
final privkeyHex = nostr.Nip19.decode(payload: _nsec).data;
182182
if (privkeyHex.isEmpty) {
183183
_failAuth(Exception('Invalid nsec'));
184184
return;
@@ -195,11 +195,11 @@ class RelaySocket {
195195
kind: EventKind.auth,
196196
content: '',
197197
tags: tags,
198-
privkey: privkeyHex,
198+
secretKey: privkeyHex,
199199
);
200200

201201
_pendingAuthEventId = event.id;
202-
send(['AUTH', event.toJson()]);
202+
send(['AUTH', event.toMap()]);
203203
} catch (e) {
204204
_failAuth(e);
205205
}

0 commit comments

Comments
 (0)