@Tags(['integration']) library; import 'dart:convert'; import 'package:bip340/bip340.dart' as bip340; import 'package:swarm/swarm.dart'; import 'package:test/test.dart'; const _privKey = '0000000000000000000000000000000000000000000000000000000000000001'; const _relayUrl = 'wss://relay.otherwhere.app/'; void main() { late NostrFetchActor fetcher; late String pubkey; setUp(() { fetcher = NostrFetchActor(relayUrls: [_relayUrl]); pubkey = bip340.getPublicKey(_privKey); }); String filter(Map f) => jsonEncode(f); group('relay.otherwhere.app fetch', () { test('fetches kind 0 (metadata) by author', () async { final result = await fetcher.handle(FetchEvents( filter({'kinds': [0], 'authors': [pubkey], 'limit': 1}), )); final events = (result as EventsFetched).events; expect(events, isNotEmpty); final event = jsonDecode(events.first) as Map; expect(event['kind'], equals(0)); expect(event['pubkey'], equals(pubkey)); }, timeout: const Timeout(Duration(seconds: 15))); test('fetches kind 37515 (place) by d tag', () async { final result = await fetcher.handle(FetchEvents( filter({ 'kinds': [37515], '#d': ['place:swarmtest0'], 'authors': [pubkey], 'limit': 1, }), )); final events = (result as EventsFetched).events; expect(events, isNotEmpty); final event = jsonDecode(events.first) as Map; expect(event['kind'], equals(37515)); final tags = event['tags'] as List; final dTag = tags.firstWhere((t) => (t as List).first == 'd') as List; expect(dTag[1], equals('place:swarmtest0')); }, timeout: const Timeout(Duration(seconds: 15))); test('fetches kind 37518 (check-in) by d tag', () async { final result = await fetcher.handle(FetchEvents( filter({ 'kinds': [37518], '#d': ['checkin:swarmtest0'], 'authors': [pubkey], 'limit': 1, }), )); final events = (result as EventsFetched).events; expect(events, isNotEmpty); final event = jsonDecode(events.first) as Map; expect(event['kind'], equals(37518)); }, timeout: const Timeout(Duration(seconds: 15))); test('fetched events have valid BIP-340 signatures', () async { final result = await fetcher.handle(FetchEvents( filter({'authors': [pubkey], 'limit': 10}), )); final events = (result as EventsFetched).events; expect(events, isNotEmpty); for (final raw in events) { final e = jsonDecode(raw) as Map; expect( bip340.verify( e['pubkey'] as String, e['id'] as String, e['sig'] as String, ), isTrue, reason: 'event ${e['id']} has invalid signature', ); } }, timeout: const Timeout(Duration(seconds: 15))); test('returns empty list for unknown author', () async { const unknown = 'deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef'; final result = await fetcher.handle(FetchEvents( filter({'authors': [unknown], 'limit': 5}), )); expect((result as EventsFetched).events, isEmpty); }, timeout: const Timeout(Duration(seconds: 15))); }); }