gandlafbtc / nutstash-wallet

Cashu Wallet with multi-mint and send-to-nostr-key functionality
https://v2.nutstash.app
GNU General Public License v3.0
44 stars 10 forks source link

show qr code when revealing token as url. #64

Closed dipunm closed 1 week ago

dipunm commented 1 year ago

Description

This change adds a QR code image whenever a token is created to be sent and the "send as link" toggle is turned on.

I found that this would be convenient when face to face for sending people the link without necessarily having their contact details already.

Some whitespace changes are caused by running npm run format. Only the Sending.svelte file has meaningful changes.

Changes

PR Tasks

vercel[bot] commented 1 year ago

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
cashu-wallet ✅ Ready (Inspect) Visit Preview 💬 Add feedback May 20, 2023 8:15am
gandlafbtc commented 1 year ago

I like this, and i have been thinking about adding something like that, the only issue is that when the token get's to big (e.g. it's not a power of two, or consists of multiple proofs) the QR might not pick it up. I don't know the threshhold, i think it depends on the camera quality and screen quality. Maybe we could include a message if the token consits of multiple proofs, that hints to the user that the token might be too big to scan or something like that. What do you think?

Thanks for the PR!

dipunm commented 1 year ago

Interesting, I was testing with a QR with 2 tokens, and it scanned well enough on my phone, but I see where you're coming from.

I guess this needs a little more thought, there is likely going to be an extreme for the QR code component, and then there's gonna be a limit of what typical cameras can scan, so it's worth testing a little more.

If the QR code would have to be split into multiple, IMO that would probably feel clunky, animated QR's are not standard in the real world, and so we should find that limit and then use it to determine if a QR code is relevant and show a message otherwise.

dipunm commented 1 year ago

So to test, let's come up with a plan:

Typical upper amount to send: £20.00? In sats @ rate of 5000 sats per £: 100,000 sats In binary: 11000011010100000 (17 bits) max value: 11111111111111111 = 131,071

Amounts to test: Each amount is incrementally 1 more token than the next.

1 sat = 1 (1 bit) 3 sats = 11 (2 bits) 7 sats = 111 (3 bits) 15 sats = 1111 (4 bits) 31 sats = 11111 (5 bits) 63 sats = 111111 (6 bits) 127 sats = 1111111 (7 bits) 255 sats = 11111111 (8 bits) 511 sats = 111111111 (9 bits) 1,203 sats = 1111111111 (10 bits) 2,047 sats = 11111111111 (11 bits) 4,095 sats = 111111111111 (12 bits) 8,191 sats = 1111111111111 (13 bits) 16,383 sats = 11111111111111 (14 bits) 32,767 sats = 111111111111111 (15 bits) 65,535 sats = 1111111111111111 (16 bits) 131,071 sats = 11111111111111111 (17 bits)

Once we have a limit of how many tokens in a single QR code is too many, we can think about how to implement warnings or messaging.

dipunm commented 1 year ago

The first test is just QR Code creation.

131,071sats is too big to even generate a QR code.

511 sats will generate a QR code, but on a pixel 6 it is too large to fit on screen.

63 sats same as 511

15 fits just about.

This shows that QR Codes are likely to be useful with only upto 4 tokens maximum on a mobile device.

Still need to test scanning with different devices (iphone, old iphone, android etc).

gandlafbtc commented 1 year ago

amazing, thanks for testing this!

dipunm commented 1 year ago

Tested scanning onto an iPhone 6s plus it scanned very easily.

The resolution of the screen however is smaller so trying to claim it back, the qr code is too big for this phone.

PXL_20230319_105841073

I think some logic that checks the screen width/height would be helpful.

dipunm commented 1 year ago

14 (3 tokens) was fine on the iPhone 6s plus.

dipunm commented 1 year ago

Alternatively, a popup window that scales the image might also be an option.

Or just scaling the image.

dipunm commented 1 year ago

Upon reflection, I think scaling down is not a good idea. I would say 3 tokens is about right and now we should focus on the user experience and messaging.

My thoughts are:

Messaging: Talking about the technicals is not going to be great UX, a "read more" can help if necessary. I'm thinking something like: "Sorry, the amount you entered cannot be used to generate a QR code (read more)." [ Send 18,944 sats instead ]

Potentially, we could suggest a higher amount too if the balance is sufficient. It really depends on the intent, if they are looking to pay for something, they would want a higher amount, if looking to tip, they may want a lower amount.

@gandlafbtc what are your thoughts on this?

gandlafbtc commented 1 year ago

I agree, 3 tokens should be max.

We could also start looking into compressing the data, right now it is pure json turned into base64. If we go down that route we should do it as a cashu protocol standard tho. One way of doing that is turning the json objects into an array of arrays. that would remove the need for field descriptors.

A whole other approach, which would allow us also to use any amount we want, would be to post an encrypted note on nostr, and then use the noteID+the decryption key in the QR to retreive and decrypt the note.

I am still thinking about what the right approach for this is, i will strike up a discussion about that in the Cashu Telegram group, just to see what others think.

Thank you again for your research into this!

callebtc commented 1 year ago

Interesting. I do this on cashu.me for max 1 token because I couldn't get most cameras to scan it. It's more than one token, I don't show a QR code.

handsomelatino commented 1 year ago

Not familiar enough with the protocol, but are the tokens concatenated without a checksum? If so, there could be a way to scan multiple tokens (ie: user scans one token, it gets added, then users pressed an (+ add more) etc.)

Might not be the ideal UX but could potentially work for now.

dipunm commented 1 year ago

I'm not a huge fan of that idea, but its in the back pocket. The premise of this PR was to make ecash feel easy fast and native. Each scan turns into a webpage load followed by confirmation dialogs, doing this for multiple notes is not going to be fun.

@gandlafbtc how did the idea around compressing the token/json go? Do you want/need me to start that off?

I was unfortunately not around for a bit hence the lack of reply and progress.

gandlafbtc commented 1 year ago

no worries. Fedimint has an interesting solution for this. They have a qr code that loops through multiple chunks. The scanning device has then to reconstruct the complete data from all chunks. I think we should do it in a similar way.

So the qr code would constantly change every 1/5 sec, and show the next chunk

dipunm commented 1 year ago

Animated qr codes are cool, and maybe necessary, but my goal with this feature was to make sending sats feel native and require no app downloads.

My thoughts around an animated qr code with this goal in mind:

The multiple qr code idea is cool, but I'd say out of scope for this PR.

I want to follow up with a nostr based solution (after looking at how you deal with nostr so far). Any push back on that idea?

gandlafbtc commented 1 year ago

I would definitely prefer qr codes that work offline. the main reason, this does not leave a data trace. Check out the work in progress on the 'send-receive' branch.

It defaults to a single qr when it's only one proof, and to an animated qr when it's too big to fit in a single qr.

I appreciate all the thought you've been putting into this, i think your ideas are good, but maybe we have to consider them as alternatives to sending the tokens offline. I think offline should be the default

dipunm commented 1 year ago

FYI, I just came across this: Looks like an interesting way to implement animated QR codes, thought you might find it useful: https://divan.dev/posts/fountaincodes/