diff --git a/lib/src/nip46_signer_actor.dart b/lib/src/nip46_signer_actor.dart index 79b2266..56c19a4 100644 --- a/lib/src/nip46_signer_actor.dart +++ b/lib/src/nip46_signer_actor.dart @@ -83,6 +83,11 @@ class Nip46SignerActor with Handler { GetPublicKey() => _getPublicKey(), SignEvent(:final kind, :final tags, :final content, :final createdAt) => _remoteSignEvent(kind, tags, content, createdAt), + // NIP-44 encrypt/decrypt is not proxied to the remote signer yet; only + // get_public_key and sign_event are requested at connect time. + Nip44Encrypt() || Nip44Decrypt() => throw UnsupportedError( + 'NIP-44 encrypt/decrypt is not supported by Nip46SignerActor', + ), }; } @@ -118,7 +123,8 @@ class Nip46SignerActor with Handler { } ])); - await _request('connect', [_appPubkey, _secret ?? '', 'sign_event,get_public_key']); + await _request( + 'connect', [_appPubkey, _secret ?? '', 'sign_event,get_public_key']); _connected = true; } @@ -134,7 +140,12 @@ class Nip46SignerActor with Handler { int? createdAt, ) async { final ts = createdAt ?? DateTime.now().millisecondsSinceEpoch ~/ 1000; - final unsigned = {'kind': kind, 'content': content, 'tags': tags, 'created_at': ts}; + final unsigned = { + 'kind': kind, + 'content': content, + 'tags': tags, + 'created_at': ts + }; final result = await _request('sign_event', [jsonEncode(unsigned)]); return EventSigned(result); } @@ -143,7 +154,12 @@ class Nip46SignerActor with Handler { final id = _randomId(); final body = jsonEncode({'id': id, 'method': method, 'params': params}); final encrypted = nip44Encrypt(body, _appPrivkey, _signerPubkey); - final eventJson = _signAppEvent(kind: 24133, tags: [['p', _signerPubkey]], content: encrypted); + final eventJson = _signAppEvent( + kind: 24133, + tags: [ + ['p', _signerPubkey] + ], + content: encrypted); final completer = Completer(); _pending[id] = completer; diff --git a/test/nostr_signer_actor_test.dart b/test/nostr_signer_actor_test.dart index 7a9072b..22833d4 100644 --- a/test/nostr_signer_actor_test.dart +++ b/test/nostr_signer_actor_test.dart @@ -104,4 +104,30 @@ void main() { expect(ts, greaterThanOrEqualTo(before)); expect(ts, lessThanOrEqualTo(after + 2)); }); + + test('Nip44Encrypt round-trips to self', () async { + final plaintext = jsonEncode({'blur_content_warnings': 'false', 'x': '1'}); + final encrypted = await signer.handle(Nip44Encrypt(plaintext)) as Nip44Text; + expect(encrypted.value, isNot(equals(plaintext))); + + // Payload is base64 with the NIP-44 v2 version byte (0x02) first. + final bytes = base64.decode(encrypted.value); + expect(bytes.first, equals(0x02)); + + final decrypted = + await signer.handle(Nip44Decrypt(encrypted.value)) as Nip44Text; + expect(decrypted.value, equals(plaintext)); + }); + + test('Nip44Decrypt with a foreign key fails', () async { + final encrypted = + await signer.handle(const Nip44Encrypt('secret')) as Nip44Text; + final other = NostrSignerActor( + '0000000000000000000000000000000000000000000000000000000000000002', + ); + expect( + () => other.handle(Nip44Decrypt(encrypted.value)), + throwsA(anything), + ); + }); }