Nip44Encrypt test and error return

This commit is contained in:
randogoth 2026-07-11 17:37:24 +03:00
parent 1fee9e5d34
commit 6e0c1e0f0b
2 changed files with 45 additions and 3 deletions

View file

@ -83,6 +83,11 @@ class Nip46SignerActor with Handler<SignerMessage, SignerResult> {
GetPublicKey() => _getPublicKey(), GetPublicKey() => _getPublicKey(),
SignEvent(:final kind, :final tags, :final content, :final createdAt) => SignEvent(:final kind, :final tags, :final content, :final createdAt) =>
_remoteSignEvent(kind, tags, content, 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<SignerMessage, SignerResult> {
} }
])); ]));
await _request('connect', [_appPubkey, _secret ?? '', 'sign_event,get_public_key']); await _request(
'connect', [_appPubkey, _secret ?? '', 'sign_event,get_public_key']);
_connected = true; _connected = true;
} }
@ -134,7 +140,12 @@ class Nip46SignerActor with Handler<SignerMessage, SignerResult> {
int? createdAt, int? createdAt,
) async { ) async {
final ts = createdAt ?? DateTime.now().millisecondsSinceEpoch ~/ 1000; 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)]); final result = await _request('sign_event', [jsonEncode(unsigned)]);
return EventSigned(result); return EventSigned(result);
} }
@ -143,7 +154,12 @@ class Nip46SignerActor with Handler<SignerMessage, SignerResult> {
final id = _randomId(); final id = _randomId();
final body = jsonEncode({'id': id, 'method': method, 'params': params}); final body = jsonEncode({'id': id, 'method': method, 'params': params});
final encrypted = nip44Encrypt(body, _appPrivkey, _signerPubkey); 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<String>(); final completer = Completer<String>();
_pending[id] = completer; _pending[id] = completer;

View file

@ -104,4 +104,30 @@ void main() {
expect(ts, greaterThanOrEqualTo(before)); expect(ts, greaterThanOrEqualTo(before));
expect(ts, lessThanOrEqualTo(after + 2)); 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),
);
});
} }