diff --git a/mobile/lib/features/channels/agent_activity/observer_subscription.dart b/mobile/lib/features/channels/agent_activity/observer_subscription.dart index aa8c25cc8..c15686c58 100644 --- a/mobile/lib/features/channels/agent_activity/observer_subscription.dart +++ b/mobile/lib/features/channels/agent_activity/observer_subscription.dart @@ -271,7 +271,7 @@ class ObserverRelayNotifier extends Notifier { static String _decodePrivkey(String nsec) { try { - final privHex = nostr.Nip19.decodePrivkey(nsec); + final privHex = nostr.Nip19.decode(payload: nsec).data; if (privHex.isEmpty) { throw const FormatException('empty private key'); } @@ -283,7 +283,7 @@ class ObserverRelayNotifier extends Notifier { static String _derivePubkey(String privHex) { try { - return nostr.Keychain(privHex).public; + return nostr.Keys(privHex).public; } catch (_) { throw const FormatException('failed to derive pubkey'); } diff --git a/mobile/lib/features/channels/compose_bar.dart b/mobile/lib/features/channels/compose_bar.dart index 3b5d6c1d8..185ea2180 100644 --- a/mobile/lib/features/channels/compose_bar.dart +++ b/mobile/lib/features/channels/compose_bar.dart @@ -593,7 +593,7 @@ void _sendTypingIndicator( final nsec = config.nsec; if (nsec == null || nsec.isEmpty) return; - final privkeyHex = nostr.Nip19.decodePrivkey(nsec); + final privkeyHex = nostr.Nip19.decode(payload: nsec).data; if (privkeyHex.isEmpty) return; final tags = >[ @@ -609,13 +609,13 @@ void _sendTypingIndicator( kind: EventKind.typingIndicator, content: '', tags: tags, - privkey: privkeyHex, + secretKey: privkeyHex, verify: false, ); // Send directly over WebSocket — fire-and-forget, matching desktop. final session = ref.read(relaySessionProvider.notifier); - session.sendRaw(['EVENT', event.toJson()]); + session.sendRaw(['EVENT', event.toMap()]); } catch (_) { // Fire-and-forget — typing indicator failure is non-fatal. } diff --git a/mobile/lib/features/channels/read_state/read_state_manager.dart b/mobile/lib/features/channels/read_state/read_state_manager.dart index 0db7ed188..eb7548b29 100644 --- a/mobile/lib/features/channels/read_state/read_state_manager.dart +++ b/mobile/lib/features/channels/read_state/read_state_manager.dart @@ -22,7 +22,7 @@ class ReadStateCrypto { required String pubkey, }) { try { - final privkeyHex = nostr.Nip19.decodePrivkey(nsec); + final privkeyHex = nostr.Nip19.decode(payload: nsec).data; if (privkeyHex.isEmpty || pubkey.isEmpty) { return null; } diff --git a/mobile/lib/features/pairing/pairing_provider.dart b/mobile/lib/features/pairing/pairing_provider.dart index bedf618fd..ffc2cb274 100644 --- a/mobile/lib/features/pairing/pairing_provider.dart +++ b/mobile/lib/features/pairing/pairing_provider.dart @@ -154,8 +154,8 @@ class PairingNotifier extends Notifier { final relayWsUrl = qr.relays.first; // 2. Generate ephemeral keypair. - final keychain = nostr.Keychain.generate(); - _ephemeralPrivkey = keychain.private; + final keychain = nostr.Keys.generate(); + _ephemeralPrivkey = keychain.secret; _ephemeralPubkey = keychain.public; // 3. Derive session ID and SAS immediately (we know source pubkey from QR). @@ -302,7 +302,7 @@ class PairingNotifier extends Notifier { // NIP-AB §Event Validation: verify event signature (NIP-01). // The nostr package's Event.fromJson verifies id + sig on construction. try { - final event = nostr.Event.fromJson(eventJson); + final event = nostr.Event.fromJson(jsonEncode(eventJson)); if (event.id != eventId) return; // id mismatch } catch (_) { return; // invalid signature or malformed event @@ -507,11 +507,11 @@ class PairingNotifier extends Notifier { kind: kind, content: content, tags: tags, - privkey: _ephemeralPrivkey!, + secretKey: _ephemeralPrivkey!, createdAt: createdAt, ); - _socket?.publishEvent(event.toJson()); + _socket?.publishEvent(event.toMap()); } void _handleDisconnected(Object? error) { diff --git a/mobile/lib/features/pairing/pairing_socket.dart b/mobile/lib/features/pairing/pairing_socket.dart index 3c0a0cafb..1b8eb2932 100644 --- a/mobile/lib/features/pairing/pairing_socket.dart +++ b/mobile/lib/features/pairing/pairing_socket.dart @@ -166,12 +166,12 @@ class PairingSocket { kind: EventKind.auth, content: '', tags: tags, - privkey: _ephemeralPrivkey, + secretKey: _ephemeralPrivkey, createdAt: DateTime.now().millisecondsSinceEpoch ~/ 1000, ); _pendingAuthEventId = event.id; - send(['AUTH', event.toJson()]); + send(['AUTH', event.toMap()]); } catch (e) { _failAuth(e); } diff --git a/mobile/lib/features/profile/user_status_provider.dart b/mobile/lib/features/profile/user_status_provider.dart index 668a72de8..58a4e36fc 100644 --- a/mobile/lib/features/profile/user_status_provider.dart +++ b/mobile/lib/features/profile/user_status_provider.dart @@ -25,8 +25,8 @@ class UserStatusNotifier extends AsyncNotifier { String pubkey; try { - final privkeyHex = nostr.Nip19.decodePrivkey(nsec); - final keyPair = nostr.Keychain(privkeyHex); + final privkeyHex = nostr.Nip19.decode(payload: nsec).data; + final keyPair = nostr.Keys(privkeyHex); pubkey = keyPair.public.toLowerCase(); } catch (_) { return null; @@ -74,18 +74,18 @@ class UserStatusNotifier extends AsyncNotifier { tags.add(['emoji', emoji]); } - final privkeyHex = nostr.Nip19.decodePrivkey(nsec); + final privkeyHex = nostr.Nip19.decode(payload: nsec).data; final event = nostr.Event.from( kind: EventKind.userStatus, content: trimmed, tags: tags, - privkey: privkeyHex, + secretKey: privkeyHex, verify: false, ); final session = ref.read(relaySessionProvider.notifier); await session.publish( - NostrEvent.fromJson(Map.from(event.toJson())), + NostrEvent.fromJson(event.toMap()), ); // Optimistic update: update own state immediately. @@ -99,7 +99,7 @@ class UserStatusNotifier extends AsyncNotifier { state = AsyncValue.data(newStatus); // Also update the shared cache so other UI reads stay consistent. - final keyPair = nostr.Keychain(privkeyHex); + final keyPair = nostr.Keys(privkeyHex); final pubkey = keyPair.public.toLowerCase(); ref.read(userStatusCacheProvider.notifier).updateStatus(pubkey, newStatus); } diff --git a/mobile/lib/features/settings/settings_page.dart b/mobile/lib/features/settings/settings_page.dart index 9b8132ac8..6d50dd336 100644 --- a/mobile/lib/features/settings/settings_page.dart +++ b/mobile/lib/features/settings/settings_page.dart @@ -57,9 +57,9 @@ class SettingsPage extends HookConsumerWidget { const SizedBox(height: Grid.xxs), Builder( builder: (context) { - final privHex = nostr.Nip19.decodePrivkey(config.nsec!); + final privHex = nostr.Nip19.decode(payload: config.nsec!).data; final pubkey = privHex.isNotEmpty - ? nostr.Keychain(privHex).public + ? nostr.Keys(privHex).public : 'unknown'; return ListTile( leading: const Icon(LucideIcons.key), diff --git a/mobile/lib/shared/relay/media_upload.dart b/mobile/lib/shared/relay/media_upload.dart index c0c562b0d..ab2ed58d0 100644 --- a/mobile/lib/shared/relay/media_upload.dart +++ b/mobile/lib/shared/relay/media_upload.dart @@ -270,7 +270,7 @@ class MediaUploadService { String _buildUploadAuthHeader(String sha256) { final authEvent = _buildUploadAuthEvent(sha256); - final authJson = jsonEncode(authEvent.toJson()); + final authJson = authEvent.toJson(); final encoded = base64Url.encode(utf8.encode(authJson)).replaceAll('=', ''); return 'Nostr $encoded'; } @@ -281,7 +281,7 @@ class MediaUploadService { throw Exception('Cannot upload media: no signing key available'); } - final privkeyHex = nostr.Nip19.decodePrivkey(nsec); + final privkeyHex = nostr.Nip19.decode(payload: nsec).data; if (privkeyHex.isEmpty) { throw Exception('Invalid nsec'); } @@ -300,7 +300,7 @@ class MediaUploadService { kind: _uploadAuthKind, content: 'Upload sprout-media', tags: tags, - privkey: privkeyHex, + secretKey: privkeyHex, verify: false, ); } diff --git a/mobile/lib/shared/relay/relay_provider.dart b/mobile/lib/shared/relay/relay_provider.dart index b517df05b..828e8bede 100644 --- a/mobile/lib/shared/relay/relay_provider.dart +++ b/mobile/lib/shared/relay/relay_provider.dart @@ -66,9 +66,9 @@ final relayConfigProvider = NotifierProvider( String? pubkeyFromNsec(String? nsec) { if (nsec == null || nsec.isEmpty) return null; try { - final privkeyHex = nostr.Nip19.decodePrivkey(nsec); + final privkeyHex = nostr.Nip19.decode(payload: nsec).data; if (privkeyHex.isEmpty) return null; - return nostr.Keychain(privkeyHex).public; + return nostr.Keys(privkeyHex).public; } catch (_) { return null; } diff --git a/mobile/lib/shared/relay/relay_socket.dart b/mobile/lib/shared/relay/relay_socket.dart index 3ed4d27a0..9054ddff2 100644 --- a/mobile/lib/shared/relay/relay_socket.dart +++ b/mobile/lib/shared/relay/relay_socket.dart @@ -178,7 +178,7 @@ class RelaySocket { try { // Decode bech32 nsec to hex private key. - final privkeyHex = nostr.Nip19.decodePrivkey(_nsec); + final privkeyHex = nostr.Nip19.decode(payload: _nsec).data; if (privkeyHex.isEmpty) { _failAuth(Exception('Invalid nsec')); return; @@ -195,11 +195,11 @@ class RelaySocket { kind: EventKind.auth, content: '', tags: tags, - privkey: privkeyHex, + secretKey: privkeyHex, ); _pendingAuthEventId = event.id; - send(['AUTH', event.toJson()]); + send(['AUTH', event.toMap()]); } catch (e) { _failAuth(e); } diff --git a/mobile/lib/shared/relay/signed_event_relay.dart b/mobile/lib/shared/relay/signed_event_relay.dart index c98f20c59..730009522 100644 --- a/mobile/lib/shared/relay/signed_event_relay.dart +++ b/mobile/lib/shared/relay/signed_event_relay.dart @@ -18,9 +18,9 @@ class SignedEventRelay { String? get pubkey { final nsec = _nsec; if (nsec == null || nsec.isEmpty) return null; - final privkeyHex = nostr.Nip19.decodePrivkey(nsec); + final privkeyHex = nostr.Nip19.decode(payload: nsec).data; if (privkeyHex.isEmpty) return null; - return nostr.Keychain(privkeyHex).public; + return nostr.Keys(privkeyHex).public; } /// Sign and submit an event. Returns the relay's OK response as a [NostrEvent] @@ -37,7 +37,7 @@ class SignedEventRelay { throw Exception('Cannot submit event: no signing key available'); } - final privkeyHex = nostr.Nip19.decodePrivkey(nsec); + final privkeyHex = nostr.Nip19.decode(payload: nsec).data; if (privkeyHex.isEmpty) { throw Exception('Invalid nsec'); } @@ -46,12 +46,12 @@ class SignedEventRelay { kind: kind, content: content, tags: tags, - privkey: privkeyHex, + secretKey: privkeyHex, createdAt: createdAt, verify: false, ); - final nostrEvent = NostrEvent.fromJson(event.toJson()); + final nostrEvent = NostrEvent.fromJson(event.toMap()); return _session.publish(nostrEvent); } } diff --git a/mobile/pubspec.lock b/mobile/pubspec.lock index 433dd79f9..8569de00e 100644 --- a/mobile/pubspec.lock +++ b/mobile/pubspec.lock @@ -69,10 +69,10 @@ packages: dependency: transitive description: name: bip340 - sha256: "2a92f6ed68959f75d67c9a304c17928b9c9449587d4f75ee68f34152f7f69e87" + sha256: "4c2df9fa2409d26f1d9334b2801015ebe4dc3978191f186743e60e89a90230c4" url: "https://pub.dev" source: hosted - version: "0.2.0" + version: "0.3.1" boolean_selector: dependency: transitive description: @@ -249,6 +249,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.7.12" + elliptic: + dependency: transitive + description: + name: elliptic + sha256: "67931d408faa353bdebac9f7a1df0c3f6f828f4e8439cdf084573cd1601a2f4b" + url: "https://pub.dev" + source: hosted + version: "0.3.12" fake_async: dependency: transitive description: @@ -608,14 +616,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.1" - js: - dependency: transitive - description: - name: js - sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 - url: "https://pub.dev" - source: hosted - version: "0.6.7" json_annotation: dependency: transitive description: @@ -692,10 +692,10 @@ packages: dependency: transitive description: name: meta - sha256: "1741988757a65eb6b36abe716829688cf01910bbf91c34354ff7ec1c3de2b349" + sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394" url: "https://pub.dev" source: hosted - version: "1.18.0" + version: "1.17.0" mime: dependency: transitive description: @@ -756,10 +756,10 @@ packages: dependency: "direct main" description: name: nostr - sha256: a99942e4eedd5823d16f42e6df96240488028666a329ee1047552f79db564123 + sha256: "44d602199d032e40a469b8e00e3c58e1b0c206673e0edf4a4a468499f75f6298" url: "https://pub.dev" source: hosted - version: "1.5.0" + version: "2.0.0" objective_c: dependency: transitive description: @@ -884,10 +884,10 @@ packages: dependency: "direct main" description: name: pointycastle - sha256: "4be0097fcf3fd3e8449e53730c631200ebc7b88016acecab2b0da2f0149222fe" + sha256: "92aa3841d083cc4b0f4709b5c74fd6409a3e6ba833ffc7dc6a8fee096366acf5" url: "https://pub.dev" source: hosted - version: "3.9.1" + version: "4.0.0" pool: dependency: transitive description: @@ -1121,26 +1121,26 @@ packages: dependency: transitive description: name: test - sha256: "8d9ceddbab833f180fbefed08afa76d7c03513dfdba87ffcec2718b02bbcbf20" + sha256: "280d6d890011ca966ad08df7e8a4ddfab0fb3aa49f96ed6de56e3521347a9ae7" url: "https://pub.dev" source: hosted - version: "1.31.0" + version: "1.30.0" test_api: dependency: transitive description: name: test_api - sha256: "949a932224383300f01be9221c39180316445ecb8e7547f70a41a35bf421fb9e" + sha256: "8161c84903fd860b26bfdefb7963b3f0b68fee7adea0f59ef805ecca346f0c7a" url: "https://pub.dev" source: hosted - version: "0.7.11" + version: "0.7.10" test_core: dependency: transitive description: name: test_core - sha256: "1991d4cfe85d5043241acac92962c3977c8d2f2add1ee73130c7b286417d1d34" + sha256: "0381bd1585d1a924763c308100f2138205252fb90c9d4eeaf28489ee65ccde51" url: "https://pub.dev" source: hosted - version: "0.6.17" + version: "0.6.16" tuple: dependency: transitive description: diff --git a/mobile/pubspec.yaml b/mobile/pubspec.yaml index e5d8471a0..452a9e5af 100644 --- a/mobile/pubspec.yaml +++ b/mobile/pubspec.yaml @@ -18,8 +18,8 @@ dependencies: shared_preferences: ^2.5.5 web_socket_channel: ^3.0.1 connectivity_plus: ^7.0.0 - nostr: ^1.5.0 - pointycastle: ^3.7.3 + nostr: ^2.0.0 + pointycastle: ^4.0.0 url_launcher: ^6.3.2 gpt_markdown: ^1.1.6 intl: ^0.20.2 diff --git a/mobile/test/features/channels/agent_activity/observer_subscription_test.dart b/mobile/test/features/channels/agent_activity/observer_subscription_test.dart index 90adcd3a1..247f15a12 100644 --- a/mobile/test/features/channels/agent_activity/observer_subscription_test.dart +++ b/mobile/test/features/channels/agent_activity/observer_subscription_test.dart @@ -78,11 +78,11 @@ void main() { test( 'subscribes with correct filter shape and transitions to open', () async { - final userKeychain = nostr.Keychain.generate(); - final nsec = nostr.Nip19.encodePrivkey(userKeychain.private); + final userKeychain = nostr.Keys.generate(); + final nsec = userKeychain.nsec; final myPubkey = userKeychain.public; // Agent needs a valid 64-char hex pubkey for getConversationKey. - final agentKeychain = nostr.Keychain.generate(); + final agentKeychain = nostr.Keys.generate(); final agentPubkey = agentKeychain.public; final relaySession = _RecordingRelaySession(); @@ -119,15 +119,15 @@ void main() { test( 'uses one shared relay subscription for channel-scoped readers', () async { - final userKeychain = nostr.Keychain.generate(); - final agentKeychain = nostr.Keychain.generate(); + final userKeychain = nostr.Keys.generate(); + final agentKeychain = nostr.Keys.generate(); final relaySession = _RecordingRelaySession(); final container = ProviderContainer( overrides: [ relaySessionProvider.overrideWith(() => relaySession), relayConfigProvider.overrideWith( () => _FakeRelayConfigNotifier( - nsec: nostr.Nip19.encodePrivkey(userKeychain.private), + nsec: userKeychain.nsec, ), ), ], @@ -154,15 +154,15 @@ void main() { ); test('surfaces relay CLOSED messages through observer state', () async { - final userKeychain = nostr.Keychain.generate(); - final agentKeychain = nostr.Keychain.generate(); + final userKeychain = nostr.Keys.generate(); + final agentKeychain = nostr.Keys.generate(); final relaySession = _RecordingRelaySession(); final container = ProviderContainer( overrides: [ relaySessionProvider.overrideWith(() => relaySession), relayConfigProvider.overrideWith( () => _FakeRelayConfigNotifier( - nsec: nostr.Nip19.encodePrivkey(userKeychain.private), + nsec: userKeychain.nsec, ), ), ], @@ -181,16 +181,16 @@ void main() { }); test('ignores stale subscribe completion after identity changes', () async { - final firstUser = nostr.Keychain.generate(); - final secondUser = nostr.Keychain.generate(); - final agentKeychain = nostr.Keychain.generate(); + final firstUser = nostr.Keys.generate(); + final secondUser = nostr.Keys.generate(); + final agentKeychain = nostr.Keys.generate(); final relaySession = _RecordingRelaySession()..delaySubscribes = true; final container = ProviderContainer( overrides: [ relaySessionProvider.overrideWith(() => relaySession), relayConfigProvider.overrideWith( () => _FakeRelayConfigNotifier( - nsec: nostr.Nip19.encodePrivkey(firstUser.private), + nsec: firstUser.nsec, ), ), ], @@ -205,7 +205,7 @@ void main() { expect(relaySession.filters.single.tags['#p'], [firstUser.public]); (container.read(relayConfigProvider.notifier) as _FakeRelayConfigNotifier) - .setNsec(nostr.Nip19.encodePrivkey(secondUser.private)); + .setNsec(secondUser.nsec); container.read(observerSubscriptionProvider(key)); await Future.delayed(Duration.zero); @@ -229,9 +229,9 @@ void main() { test( 'decrypts observer frames and exposes channel-scoped transcript', () async { - final ownerKeychain = nostr.Keychain.generate(); - final agentKeychain = nostr.Keychain.generate(); - final nsec = nostr.Nip19.encodePrivkey(ownerKeychain.private); + final ownerKeychain = nostr.Keys.generate(); + final agentKeychain = nostr.Keys.generate(); + final nsec = ownerKeychain.nsec; final relaySession = _RecordingRelaySession(); final container = ProviderContainer( overrides: [ @@ -249,7 +249,7 @@ void main() { await Future.delayed(Duration.zero); final conversationKey = getConversationKey( - agentKeychain.private, + agentKeychain.secret, ownerKeychain.public, ); final encrypted = nip44Encrypt( @@ -273,11 +273,11 @@ void main() { ['agent', agentKeychain.public], ['frame', 'telemetry'], ], - privkey: agentKeychain.private, + secretKey: agentKeychain.secret, verify: false, ); - relaySession.emit(NostrEvent.fromJson(event.toJson())); + relaySession.emit(NostrEvent.fromJson(event.toMap())); final state = container.read(observerSubscriptionProvider(key)); expect(state.connection, ObserverConnectionState.open); diff --git a/mobile/test/features/channels/compose_bar_test.dart b/mobile/test/features/channels/compose_bar_test.dart index 7f782378b..a3f6681a8 100644 --- a/mobile/test/features/channels/compose_bar_test.dart +++ b/mobile/test/features/channels/compose_bar_test.dart @@ -156,8 +156,8 @@ void main() { testWidgets('uploads an image and sends markdown plus imeta tags', ( tester, ) async { - final keychain = nostr.Keychain.generate(); - final nsec = nostr.Nip19.encodePrivkey(keychain.private); + final keychain = nostr.Keys.generate(); + final nsec = keychain.nsec; final uploadService = MediaUploadService( baseUrl: 'https://relay.example', apiToken: null, @@ -222,8 +222,8 @@ void main() { testWidgets('keeps the remove button pinned to the attachment corner', ( tester, ) async { - final keychain = nostr.Keychain.generate(); - final nsec = nostr.Nip19.encodePrivkey(keychain.private); + final keychain = nostr.Keys.generate(); + final nsec = keychain.nsec; final uploadService = MediaUploadService( baseUrl: 'https://relay.example', apiToken: null, @@ -290,8 +290,8 @@ void main() { testWidgets('shows an upload error when gallery upload fails', ( tester, ) async { - final keychain = nostr.Keychain.generate(); - final nsec = nostr.Nip19.encodePrivkey(keychain.private); + final keychain = nostr.Keys.generate(); + final nsec = keychain.nsec; final uploadService = MediaUploadService( baseUrl: 'https://relay.example', apiToken: null, @@ -325,8 +325,8 @@ void main() { }); testWidgets('shows a clean error when a GIF is picked', (tester) async { - final keychain = nostr.Keychain.generate(); - final nsec = nostr.Nip19.encodePrivkey(keychain.private); + final keychain = nostr.Keys.generate(); + final nsec = keychain.nsec; final uploadService = MediaUploadService( baseUrl: 'https://relay.example', apiToken: null, @@ -362,8 +362,8 @@ void main() { testWidgets('shows a clean error when an animated PNG is picked', ( tester, ) async { - final keychain = nostr.Keychain.generate(); - final nsec = nostr.Nip19.encodePrivkey(keychain.private); + final keychain = nostr.Keys.generate(); + final nsec = keychain.nsec; final uploadService = MediaUploadService( baseUrl: 'https://relay.example', apiToken: null, @@ -401,8 +401,8 @@ void main() { testWidgets('taps Video in chooser sheet and uploads video', skip: true, ( tester, ) async { - final keychain = nostr.Keychain.generate(); - final nsec = nostr.Nip19.encodePrivkey(keychain.private); + final keychain = nostr.Keys.generate(); + final nsec = keychain.nsec; // Build a temp file with a valid MP4 ftyp header (isom brand). final mp4Bytes = Uint8List(32); diff --git a/mobile/test/features/channels/read_state/read_state_manager_test.dart b/mobile/test/features/channels/read_state/read_state_manager_test.dart index 9c1b85cf5..bdbb2ffee 100644 --- a/mobile/test/features/channels/read_state/read_state_manager_test.dart +++ b/mobile/test/features/channels/read_state/read_state_manager_test.dart @@ -10,8 +10,8 @@ void main() { test('dispose flushes a pending publish after marking disposed', () async { SharedPreferences.setMockInitialValues({}); final prefs = await SharedPreferences.getInstance(); - final keychain = nostr.Keychain.generate(); - final nsec = nostr.Nip19.encodePrivkey(keychain.private); + final keychain = nostr.Keys.generate(); + final nsec = keychain.nsec; final crypto = ReadStateCrypto.tryCreate( nsec: nsec, pubkey: keychain.public, @@ -45,8 +45,8 @@ void main() { test('disables remote sync after relay rejects read-state kind', () async { SharedPreferences.setMockInitialValues({}); final prefs = await SharedPreferences.getInstance(); - final keychain = nostr.Keychain.generate(); - final nsec = nostr.Nip19.encodePrivkey(keychain.private); + final keychain = nostr.Keys.generate(); + final nsec = keychain.nsec; final crypto = ReadStateCrypto.tryCreate( nsec: nsec, pubkey: keychain.public, @@ -77,8 +77,8 @@ void main() { () async { SharedPreferences.setMockInitialValues({}); final prefs = await SharedPreferences.getInstance(); - final keychain = nostr.Keychain.generate(); - final nsec = nostr.Nip19.encodePrivkey(keychain.private); + final keychain = nostr.Keys.generate(); + final nsec = keychain.nsec; final crypto = ReadStateCrypto.tryCreate( nsec: nsec, pubkey: keychain.public, diff --git a/mobile/test/shared/relay/media_upload_test.dart b/mobile/test/shared/relay/media_upload_test.dart index 9c78277c8..4b2e7ad6d 100644 --- a/mobile/test/shared/relay/media_upload_test.dart +++ b/mobile/test/shared/relay/media_upload_test.dart @@ -236,8 +236,8 @@ void main() { group('MediaUploadService', () { test('signs Blossom auth and uploads gallery image bytes', () async { - final keychain = nostr.Keychain.generate(); - final nsec = nostr.Nip19.encodePrivkey(keychain.private); + final keychain = nostr.Keys.generate(); + final nsec = keychain.nsec; http.Request? capturedRequest; final client = http_testing.MockClient((request) async { @@ -322,8 +322,8 @@ void main() { }); test('uses a bracketed IPv6 server tag in Blossom auth', () async { - final keychain = nostr.Keychain.generate(); - final nsec = nostr.Nip19.encodePrivkey(keychain.private); + final keychain = nostr.Keys.generate(); + final nsec = keychain.nsec; http.Request? capturedRequest; final client = http_testing.MockClient((request) async { @@ -369,8 +369,8 @@ void main() { }); test('transcodes HEIC gallery files on iOS before upload', () async { - final keychain = nostr.Keychain.generate(); - final nsec = nostr.Nip19.encodePrivkey(keychain.private); + final keychain = nostr.Keys.generate(); + final nsec = keychain.nsec; final previousPlatform = debugDefaultTargetPlatformOverride; debugDefaultTargetPlatformOverride = TargetPlatform.iOS; addTearDown(() { @@ -419,8 +419,8 @@ void main() { }); test('sanitizes iOS JPEG gallery files before upload', () async { - final keychain = nostr.Keychain.generate(); - final nsec = nostr.Nip19.encodePrivkey(keychain.private); + final keychain = nostr.Keys.generate(); + final nsec = keychain.nsec; final previousPlatform = debugDefaultTargetPlatformOverride; debugDefaultTargetPlatformOverride = TargetPlatform.iOS; addTearDown(() { @@ -472,8 +472,8 @@ void main() { }); test('transcodes HEIC gallery files on Android before upload', () async { - final keychain = nostr.Keychain.generate(); - final nsec = nostr.Nip19.encodePrivkey(keychain.private); + final keychain = nostr.Keys.generate(); + final nsec = keychain.nsec; final previousPlatform = debugDefaultTargetPlatformOverride; debugDefaultTargetPlatformOverride = TargetPlatform.android; addTearDown(() { @@ -522,8 +522,8 @@ void main() { }); test('sanitizes Android JPEG gallery files before upload', () async { - final keychain = nostr.Keychain.generate(); - final nsec = nostr.Nip19.encodePrivkey(keychain.private); + final keychain = nostr.Keys.generate(); + final nsec = keychain.nsec; final previousPlatform = debugDefaultTargetPlatformOverride; debugDefaultTargetPlatformOverride = TargetPlatform.android; addTearDown(() { @@ -575,8 +575,8 @@ void main() { }); test('sanitizes Android PNG gallery files before upload', () async { - final keychain = nostr.Keychain.generate(); - final nsec = nostr.Nip19.encodePrivkey(keychain.private); + final keychain = nostr.Keys.generate(); + final nsec = keychain.nsec; final previousPlatform = debugDefaultTargetPlatformOverride; debugDefaultTargetPlatformOverride = TargetPlatform.android; addTearDown(() { @@ -628,8 +628,8 @@ void main() { }); test('rejects GIF gallery files before upload', () async { - final keychain = nostr.Keychain.generate(); - final nsec = nostr.Nip19.encodePrivkey(keychain.private); + final keychain = nostr.Keys.generate(); + final nsec = keychain.nsec; final service = MediaUploadService( baseUrl: 'https://relay.example', @@ -653,8 +653,8 @@ void main() { }); test('rejects animated PNG gallery files before upload', () async { - final keychain = nostr.Keychain.generate(); - final nsec = nostr.Nip19.encodePrivkey(keychain.private); + final keychain = nostr.Keys.generate(); + final nsec = keychain.nsec; final service = MediaUploadService( baseUrl: 'https://relay.example', @@ -681,8 +681,8 @@ void main() { }); test('uploads static PNG when acTL appears only in chunk payload', () async { - final keychain = nostr.Keychain.generate(); - final nsec = nostr.Nip19.encodePrivkey(keychain.private); + final keychain = nostr.Keys.generate(); + final nsec = keychain.nsec; http.Request? capturedRequest; final client = http_testing.MockClient((request) async { @@ -720,8 +720,8 @@ void main() { }); test('rejects animated WebP gallery files before upload', () async { - final keychain = nostr.Keychain.generate(); - final nsec = nostr.Nip19.encodePrivkey(keychain.private); + final keychain = nostr.Keys.generate(); + final nsec = keychain.nsec; final service = MediaUploadService( baseUrl: 'https://relay.example', @@ -748,8 +748,8 @@ void main() { }); test('rejects unsupported gallery files before upload', () async { - final keychain = nostr.Keychain.generate(); - final nsec = nostr.Nip19.encodePrivkey(keychain.private); + final keychain = nostr.Keys.generate(); + final nsec = keychain.nsec; final service = MediaUploadService( baseUrl: 'https://relay.example', @@ -852,8 +852,8 @@ void main() { } test('uploads MP4 container directly without transcoding', () async { - final keychain = nostr.Keychain.generate(); - final nsec = nostr.Nip19.encodePrivkey(keychain.private); + final keychain = nostr.Keys.generate(); + final nsec = keychain.nsec; var transcodeCalled = false; final client = http_testing.MockClient((request) async { return http.Response( @@ -896,8 +896,8 @@ void main() { }); test('transcodes non-MP4 container before uploading', () async { - final keychain = nostr.Keychain.generate(); - final nsec = nostr.Nip19.encodePrivkey(keychain.private); + final keychain = nostr.Keys.generate(); + final nsec = keychain.nsec; var transcodeCalled = false; final client = http_testing.MockClient((request) async { expect(request.headers['Content-Type'], 'video/mp4');