Skip to content

Conversation

@keshav0479
Copy link
Contributor

What does this PR do?

Fixes #1206

Hi @KoalaSat ,
This PR implements the encrypted image upload feature for the trade chat. As we discussed, I've implemented the full flow using XChaCha20-Poly1305 for encryption and BUD-01/02 for Blossom authentication.

What's Implemented

  • Encryption: Images are encrypted client-side using XChaCha20-Poly1305 (via @noble/ciphers).
  • Authorization: Uploads to the Blossom server are authenticated using BUD-01/02 (Kind 24242) events signed with the robot's nsec.
  • Protocol:
    • The encrypted blob is uploaded to the coordinator's Blossom server.
    • Decryption keys & metadata are sent to the peer via NIP-17 Kind 15 file messages.
    • Everything is wrapped in NIP-59 (Gift Wrap) to ensure privacy and metadata protection.

Testing Status

I've verified the core logic extensively:

  • Encryption/Decryption: Verified using a standalone test harness (XChaCha20-Poly1305 works perfectly).
  • Blossom Auth: Verified that the server challenges requests (returns 401) and accepted my auth event structure during dev testing.
  • Code review confirms compliance with NIP-17 and BUD-01 specs.

Note: I wasn't able to complete a full "click-to-upload" test in the live chat UI locally because setting up a fully funded Lightning node for the trade flow was a bit of a blocker. The logic is good, but I'd love it if we could verify the final UI integration on a testnet coordinator!

Looking forward to your feedback!

Checklist before merging

  • Install pre-commit and initialize it: pip install pre-commit, then pre-commit install. Pre-commit installs git hooks that automatically check the codebase. If pre-commit fails when you commit your changes, please fix the problems it points out.

Copy link
Member

@KoalaSat KoalaSat left a comment

Choose a reason for hiding this comment

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

Looking great so far! I;m not sure if I missed it but are we checking the file is an image? I would try to avoid people somehow sending malicious files

@keshav0479
Copy link
Contributor Author

Looking great so far! I;m not sure if I missed it but are we checking the file is an image? I would try to avoid people somehow sending malicious files

Good catch! added a strict check to block anything that isn't an image (like .exe or .sh etc) to be safe.

Comment on lines 154 to 155
});
}, [federation.roboPool, garage, handleNostrEvent]);
Copy link
Member

Choose a reason for hiding this comment

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

There is no need for this subscription, look for these events in https://github.com/RoboSats/robosats/blob/main/frontend/src/contexts/FederationContext.tsx#L53

Probably you can also simplify handleNostrEvent with it

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done! Refactored to use notifs from FederationContext instead of creating a duplicate subscription. Much cleaner now!

@KoalaSat
Copy link
Member

Good news @keshav0479 , our friend @TempleOfSats already have it up and running, in case you want to test it further with a real coordinator: http://ngdk7ocdzmz5kzsysa3om6du7ycj2evxp2f2olfkyq37htx3gllwp2yd.onion/blossom/

@keshav0479
Copy link
Contributor Author

Good news @keshav0479 , our friend @TempleOfSats already have it up and running, in case you want to test it further with a real coordinator: http://ngdk7ocdzmz5kzsysa3om6du7ycj2evxp2f2olfkyq37htx3gllwp2yd.onion/blossom/

This is awesome, thanks @KoalaSat and @TempleOfSats! i'll give it a spin via Tor and report back.

@keshav0479
Copy link
Contributor Author

Gave it a spin on TempleOfSats, works great!
Verified the full encryption--> upload-->download-->decrypt flow directly against the onion endpoint using a test script. Server accepted the auth and returned the blob correctly.

Screenshot From 2026-01-23 10-34-38

One thing though: i couldn't reach the chat UI locally since opening a trade needs a funded LND node. Is there any way to mock the trade state or jump straight into the chat view for testing? Would love to click the actual button if there's a workaround.

@KoalaSat
Copy link
Member

One thing though: i couldn't reach the chat UI locally since opening a trade needs a funded LND node. Is there any way to mock the trade state or jump straight into the chat view for testing? Would love to click the actual button if there's a workaround.

You can use testnet if you have it, if not, then your only option is to actually create a real trade with yourself. But a node is not necessary, just some funds to move forward.

@keshav0479
Copy link
Contributor Author

Very happy to share that i just finished a full end-to-end trade test on TheBigLake - and the image feature is working beautifully! 🎉

Screenshot From 2026-01-23 16-53-48 Screenshot From 2026-01-23 17-12-31 Screenshot From 2026-01-23 17-18-02

Tested & verified:

  • PNG, SVG, and 1MB JPEG uploads
  • XChaCha20 encryption/decryption
  • Non-image file blocking
    One small thing: There's a minor UI glitch where messages can duplicate sometimes (looks like a React state vs Nostr event key conflict). The protocol is solid, just needs a quick dedup fix, which i'll update in the next commit!

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.

[feat] Ability to Upload Images in Chat

2 participants