Skip to content

Commit

Permalink
feat: NIP17
Browse files Browse the repository at this point in the history
  • Loading branch information
ethicnology committed Feb 3, 2025
1 parent a9c671a commit 3d18224
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ flutter pub add nostr
- [x] [NIP 10 Conventions for clients' use of e and p tags in text events](https://github.com/nostr-protocol/nips/blob/master/10.md)
- [x] [NIP 13 Proof of Work](https://github.com/nostr-protocol/nips/blob/master/13.md)
- [x] [NIP 15 End of Stored Events Notice](https://github.com/nostr-protocol/nips/blob/master/15.md)
- [x] [NIP 17 Private Direct Messages (Partial)](https://github.com/nostr-protocol/nips/blob/master/17.md)
- [x] [NIP 19 bech32-encoded entities](https://github.com/nostr-protocol/nips/blob/master/19.md)
- [x] [NIP 20 Command Results](https://github.com/nostr-protocol/nips/blob/master/20.md)
- [x] [NIP 21 nostr: URI scheme](https://github.com/nostr-protocol/nips/blob/master/21.md)
Expand Down
43 changes: 43 additions & 0 deletions lib/src/nips/nip_017.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import 'package:nostr/nostr.dart';

class Nip17 {
static Future<Event> encode({
required String message,
required String authorPrivkey,
required String receiverPubkey,
}) async {
final authorPubkey = Keychain(authorPrivkey).public;

final rumor = Event.partial(
pubkey: authorPubkey,
kind: 14,
content: message,
);
rumor.id = rumor.getEventId();
// Kind 14s MUST never be signed.
// If it is signed, the message might leak to relays and become fully public.
rumor.sig = '';

return await Nip59.wrap(
rumor: rumor,
authorPrivkey: authorPrivkey,
recipientPubkey: receiverPubkey,
);
}

static Future<Event> decode({
required Event giftWrap,
required String receiverPrivkey,
}) async {
final dm = await Nip59.unwrap(
giftWrap: giftWrap,
recipientPrivkey: receiverPrivkey,
);

if (dm.kind != 14) {
throw Exception('NIP-17 define private direct messages with kind=14');
}

return dm;
}
}
46 changes: 46 additions & 0 deletions test/nips/nip_017_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import 'package:nostr/src/nips/nip_017.dart';
import 'package:test/test.dart';
import 'package:nostr/nostr.dart';

void main() async {
final authorNsec =
'nsec1w8udu59ydjvedgs3yv5qccshcj8k05fh3l60k9x57asjrqdpa00qkmr89m';
final authorPrivkey = Nip19.decodePrivkey(authorNsec);
final author = Keychain(authorPrivkey);

final recipientNsec =
'nsec12ywtkplvyq5t6twdqwwygavp5lm4fhuang89c943nf2z92eez43szvn4dt';
final recipientPrivkey = Nip19.decodePrivkey(recipientNsec);
final recipient = Keychain(recipientPrivkey);

final message = 'Hola, que tal?';

final dm = await Nip17.encode(
authorPrivkey: author.private,
receiverPubkey: recipient.public,
message: message,
);

group('NIP-17 Direct Message', () {
test('encode a direct message', () async {
expect(dm.kind, 1059);
expect(dm.tags, [
[
"p",
"918e2da906df4ccd12c8ac672d8335add131a4cf9d27ce42b3bb3625755f0788"
]
]);
});

test('decode a direct message', () async {
final x = await Nip17.decode(
giftWrap: dm,
receiverPrivkey: recipient.private,
);

expect(x.kind, 14);
expect(x.pubkey, author.public);
expect(x.sig, isEmpty);
});
});
}

0 comments on commit 3d18224

Please sign in to comment.