Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add GiftWrap and NIP-17 DMs #279

Open
wants to merge 23 commits into
base: master
Choose a base branch
from

Conversation

rodant
Copy link

@rodant rodant commented Nov 3, 2024

This PR is a continuation of the work by @manimejia in #233. Besides fixing test errors support for NIP-46 signers must still be added.

Thanks to @manimejia for the great work so far!

@rodant
Copy link
Author

rodant commented Dec 9, 2024

I'm glad for bringing this PR on the table now. Besides adding support for Nip-46 signers and convenience methods for Nip-17 encryption, some bugs were fixed and several unit tests were added.

I'd still format all the PR files according to the projects configuration, but haven't done it yet to keep the review simpler. I'm looking forward to your thoughts.

@ekzyis
Copy link

ekzyis commented Dec 10, 2024

Hello, thanks for the PR! Will this also support NIP-44 for NWC?

I think not but wanted to make sure if I understand correctly that NIP-44 for NWC will require another PR.

@rodant
Copy link
Author

rodant commented Dec 10, 2024

Hello, thanks for the PR! Will this also support NIP-44 for NWC?

I think not but wanted to make sure if I understand correctly that NIP-44 for NWC will require another PR.

Hi, I'm not sure about NWC, but Nip-44 encryption is generally supported, even before this PR. It comes to the signer used, if it support it, you can use Nip-44 encryption with NDK.

@rodant
Copy link
Author

rodant commented Dec 17, 2024

Hi all of you, just bumping this PR. Any thoughts from the contributors, @pablof7z , @erskingardner ?

@erskingardner
Copy link
Collaborator

@rodant can you fix the merge conflicts? I'll try and review then.

@rodant
Copy link
Author

rodant commented Dec 18, 2024

@rodant can you fix the merge conflicts? I'll try and review then.

Hi, sure. I'll take care of this in the next 2 hours. Thanks for reacting!

ndk/src/events/gift-wrapping.ts Outdated Show resolved Hide resolved
ndk/src/events/index.ts Outdated Show resolved Hide resolved
ndk/src/events/index.ts Outdated Show resolved Hide resolved
ndk/src/events/index.ts Show resolved Hide resolved
ndk/src/events/encryption.ts Outdated Show resolved Hide resolved
ndk/src/events/encryption.ts Outdated Show resolved Hide resolved
@erskingardner
Copy link
Collaborator

@rodant had a quick spin through now and left a few comments - mostly very small.

@rodant rodant requested a review from erskingardner December 18, 2024 16:02
@erskingardner
Copy link
Collaborator

@rodant FYI, i've not been working on NDK for a few months so I've pinged @pablof7z to have a look before merging just to make sure it's not clobbering anything else he's working on

@rodant
Copy link
Author

rodant commented Dec 19, 2024

@rodant FYI, i've not been working on NDK for a few months so I've pinged @pablof7z to have a look before merging just to make sure it's not clobbering anything else he's working on

All right, thanks for your quick and helpful review. It was a pleasure to interact with you.

Copy link
Collaborator

@pablof7z pablof7z left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some changes requested, most importantly there is no signature validation of the inner event!

this: NDKEvent,
recipient?: NDKUser,
signer?: NDKSigner,
nip : EncryptionNip | undefined = defaultEncryption
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nip04 is/should be getting deprecated, so this should just default to nip44, if a developer wants to stick with nip04 encryption they should always pass in that scheme; this approach makes the choice between nip04 and nip44 appear much more subjective.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It sounds good, I'll change it.

@@ -19,6 +19,12 @@ export enum NDKKind {
// NIP-22
GenericRespose = 22,

// Nip 59 : Gift Wrap
GiftWrap = 1059,
GiftWrapSeal = 13,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I try to keep the definitions ordered by number, so 13 and 14 should be way further up.

export type EncryptionMethod = 'encrypt' | 'decrypt'

// some clients may wish to set a default for message encryption...
let defaultEncryption : EncryptionNip | undefined = undefined;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be anchored to the singleton ndk -- some applications might want to have multiple instances of NDK with different default encryptions

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, it makes sense. I'll move this as well as the EncryptionNip type definition to the NDK class. This way there are less circular dependencies.

): Promise<string> {
const promise = new Promise<string>((resolve, reject) => {
if (!this.bunkerPubkey) throw new Error("Bunker pubkey not set");

this.rpc.sendRequest(
this.bunkerPubkey,
method + "_encrypt",
`${nip}_${method}`,
[recipient.pubkey, value],
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should now read peer instead of sender or recipient.

const signer = NDKPrivateKeySigner.generate();
const content = await signer.encrypt(recipient, JSON.stringify(sealed), params?.encryptionNip || 'nip44')
const pubkey = (await signer.user()).pubkey
let wrap : any = {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should just be something like:

const wrap = new NDKEvent();
wrap.kind = NDKKind.GiftWrap,
wrap.created_at = approximateNow(5)
if (params?.wrapTags) wrap.tags = params.wrapTags;
wrap.tag(recipient);
wrap.content = JSON.stringify(sealed.rawEvent())
await wrap.encrypt(recipient, signer);
await wrap.sign(signer);
return wrap;

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, your version is kind of more elegant. I'll take over your proposal.

if (!rumor) throw new Error("Failed to decrypt seal")

if (seal.pubkey === rumor.pubkey) {
return new NDKEvent(this.ndk, rumor as NostrEvent)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important: need to manually perform a signature validation of the rumor otherwise anyone could fake these

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess you mean the seal event, right? The rumor must not be signed according to the nip. That's really important, good point.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants