mirror of
https://github.com/block/buzz.git
synced 2026-11-01 23:11:58 +00:00
fix(deps): update dependency pointycastle to v4 (#687)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Will Pfleger <wpfleger@block.xyz> Co-authored-by: Will Pfleger <pfleger.will@gmail.com>
This commit is contained in:
@@ -271,7 +271,7 @@ class ObserverRelayNotifier extends Notifier<ObserverRelayState> {
|
||||
|
||||
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<ObserverRelayState> {
|
||||
|
||||
static String _derivePubkey(String privHex) {
|
||||
try {
|
||||
return nostr.Keychain(privHex).public;
|
||||
return nostr.Keys(privHex).public;
|
||||
} catch (_) {
|
||||
throw const FormatException('failed to derive pubkey');
|
||||
}
|
||||
|
||||
@@ -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 = <List<String>>[
|
||||
@@ -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.
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -154,8 +154,8 @@ class PairingNotifier extends Notifier<PairingState> {
|
||||
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<PairingState> {
|
||||
// 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<PairingState> {
|
||||
kind: kind,
|
||||
content: content,
|
||||
tags: tags,
|
||||
privkey: _ephemeralPrivkey!,
|
||||
secretKey: _ephemeralPrivkey!,
|
||||
createdAt: createdAt,
|
||||
);
|
||||
|
||||
_socket?.publishEvent(event.toJson());
|
||||
_socket?.publishEvent(event.toMap());
|
||||
}
|
||||
|
||||
void _handleDisconnected(Object? error) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -25,8 +25,8 @@ class UserStatusNotifier extends AsyncNotifier<UserStatus?> {
|
||||
|
||||
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,19 +74,17 @@ class UserStatusNotifier extends AsyncNotifier<UserStatus?> {
|
||||
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<String, dynamic>.from(event.toJson())),
|
||||
);
|
||||
await session.publish(NostrEvent.fromJson(event.toMap()));
|
||||
|
||||
// Optimistic update: update own state immediately.
|
||||
final newStatus = (trimmed.isNotEmpty || emoji.isNotEmpty)
|
||||
@@ -99,7 +97,7 @@ class UserStatusNotifier extends AsyncNotifier<UserStatus?> {
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -66,9 +66,9 @@ final relayConfigProvider = NotifierProvider<RelayConfigNotifier, RelayConfig>(
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,16 +119,14 @@ 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),
|
||||
),
|
||||
() => _FakeRelayConfigNotifier(nsec: userKeychain.nsec),
|
||||
),
|
||||
],
|
||||
);
|
||||
@@ -154,16 +152,14 @@ 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),
|
||||
),
|
||||
() => _FakeRelayConfigNotifier(nsec: userKeychain.nsec),
|
||||
),
|
||||
],
|
||||
);
|
||||
@@ -181,17 +177,15 @@ 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),
|
||||
),
|
||||
() => _FakeRelayConfigNotifier(nsec: firstUser.nsec),
|
||||
),
|
||||
],
|
||||
);
|
||||
@@ -205,7 +199,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<void>.delayed(Duration.zero);
|
||||
|
||||
@@ -229,9 +223,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 +243,7 @@ void main() {
|
||||
await Future<void>.delayed(Duration.zero);
|
||||
|
||||
final conversationKey = getConversationKey(
|
||||
agentKeychain.private,
|
||||
agentKeychain.secret,
|
||||
ownerKeychain.public,
|
||||
);
|
||||
final encrypted = nip44Encrypt(
|
||||
@@ -273,11 +267,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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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');
|
||||
|
||||
Reference in New Issue
Block a user