import 'dart:convert'; import 'package:bip340/bip340.dart' as bip340; import 'package:crypto/crypto.dart'; import 'package:swarm/swarm.dart'; import 'package:test/test.dart'; const _privKey = '0000000000000000000000000000000000000000000000000000000000000001'; void main() { late NostrSignerActor signer; setUp(() { signer = NostrSignerActor(_privKey); }); test('GetPublicKey returns correct pubkey', () async { final result = await signer.handle(const GetPublicKey()); expect(result, isA()); expect( (result as PublicKeyResult).publicKey, equals(bip340.getPublicKey(_privKey)), ); }); test('SignEvent returns EventSigned', () async { final result = await signer.handle( const SignEvent(kind: 1, content: 'hello'), ); expect(result, isA()); }); test('signed event has all required fields', () async { final result = await signer.handle( const SignEvent(kind: 1, tags: [], content: 'test content'), ); final event = jsonDecode((result as EventSigned).event) as Map; expect(event.containsKey('id'), isTrue); expect(event.containsKey('pubkey'), isTrue); expect(event.containsKey('created_at'), isTrue); expect(event.containsKey('kind'), isTrue); expect(event.containsKey('tags'), isTrue); expect(event.containsKey('content'), isTrue); expect(event.containsKey('sig'), isTrue); }); test('event id is correct SHA-256', () async { const kind = 1; const content = 'sha256 test'; const tags = >[]; const ts = 1700000000; final result = await signer.handle( const SignEvent(kind: kind, tags: tags, content: content, createdAt: ts), ); final event = jsonDecode((result as EventSigned).event) as Map; final pubkey = bip340.getPublicKey(_privKey); final ser = jsonEncode([0, pubkey, ts, kind, tags, content]); final expectedId = sha256 .convert(utf8.encode(ser)) .bytes .map((b) => b.toRadixString(16).padLeft(2, '0')) .join(); expect(event['id'], equals(expectedId)); }); test('signature verifies', () async { final result = await signer.handle( const SignEvent(kind: 1, content: 'verify me', createdAt: 1700000000), ); final event = jsonDecode((result as EventSigned).event) as Map; final pubkey = event['pubkey'] as String; final id = event['id'] as String; final sig = event['sig'] as String; expect(bip340.verify(pubkey, id, sig), isTrue); }); test('createdAt is used when provided', () async { const ts = 1234567890; final result = await signer.handle( const SignEvent(kind: 1, content: 'timestamp test', createdAt: ts), ); final event = jsonDecode((result as EventSigned).event) as Map; expect(event['created_at'], equals(ts)); }); test('createdAt defaults to now', () async { final before = DateTime.now().millisecondsSinceEpoch ~/ 1000; final result = await signer.handle( const SignEvent(kind: 1, content: 'now test'), ); final after = DateTime.now().millisecondsSinceEpoch ~/ 1000; final event = jsonDecode((result as EventSigned).event) as Map; final ts = event['created_at'] as int; expect(ts, greaterThanOrEqualTo(before)); expect(ts, lessThanOrEqualTo(after + 2)); }); }