<oembed><type>rich</type><version>1.0</version><author_name>npub147edljttlezv8m5dugzg4ka8cg3073j3t2hq4h8ncxaz9sm5swuq4tnsv4</author_name><author_url>https://nostr.ae/npub147edljttlezv8m5dugzg4ka8cg3073j3t2hq4h8ncxaz9sm5swuq4tnsv4</author_url><provider_name>njump</provider_name><provider_url>https://nostr.ae</provider_url><html>📅 Original date posted:2015-02-22&#xA;📝 Original message:Hi everyone,&#xA;&#xA;I am working on a Bitcoin point of sale terminal based on a Raspberry Pi, which&#xA;displays QR codes, but also provides payment requests via NFC. It can optionally&#xA;receive the sender&#39;s transaction via Bluetooth, so if the sender wallet&#xA;supports it, the sender can be completely offline. Only the terminal needs an&#xA;internet connection.&#xA;&#xA;Typical scenario envisioned: Customer taps their smartphone (or maybe smartwatch&#xA;in the future) on the NFC pad, confirms the transaction on their phone&#xA;(or smartwatch) and the transaction completes via Bluetooth and/or the phone&#39;s&#xA;internet connection.&#xA;&#xA;You can see a prototype in action here:&#xA;&#xA;  https://www.youtube.com/watch?v=P7vKHMoapr8&#xA;&#xA;The above demo uses a release version of Schildbach&#39;s Bitcoin Wallet, so it&#xA;works as shown today. However, some parts - especially the Bluetooth stuff - are&#xA;custom extensions of Schildbach&#39;s wallet which are not yet standard.&#xA;&#xA;I&#39;m writing this post to document my experience implementing NFC and offline&#xA;payments and hope to move the discussion forward around standardizing some of&#xA;this stuff. Andy Schroder&#39;s work around his Bitcoin Fluid Dispenser [1,2]&#xA;follows along the same lines, so his proposed TBIP74 [3] and TBIP75 [4] are&#xA;relevant here as well.&#xA;&#xA;&#xA;## NFC vs Bluetooth vs NFC+Bluetooth ##&#xA;&#xA;Before I get into the implementation details, a few words for why I decided to&#xA;go with the combination of NFC and Bluetooth:&#xA;&#xA;Doing everything via NFC is an interesting option to keep things simple, but the&#xA;issue is, that one usually can&#39;t maintain the connection while the user confirms&#xA;the transaction (as they take the device back to press a button or maybe enter a&#xA;PIN). So there are three options:&#xA;&#xA;1. Do a &#34;double tap&#34;: User taps, takes the device back, confirms, then taps&#xA;again to transmit the transaction. (I think Google Wallet does something like&#xA;this.)&#xA;&#xA;2. Confirm beforehand: User confirms, then taps and everything can happen in one&#xA;go. The disadvantage is, that you confirm the transaction before you have seen&#xA;the details. (I believe Google Wallet can also work this way.)&#xA;&#xA;3. Tap the phone, then establish a Bluetooth connection which allows you to do&#xA;all necessary communication even if the user takes the device back.&#xA;&#xA;I feel that option 3 is the nicest UX, so that is what I am focusing on right&#xA;now, but there are pros and cons to all options. One disadvantage of option 3 in&#xA;practice is, that many users - in my experience - have Bluetooth turned off, so&#xA;it can result in additional UI dialogs popping up, asking the user to turn on&#xA;Bluetooth.&#xA;&#xA;Regarding doing everything via Bluetooth or maybe BLE: I have been following the&#xA;work that Airbitz has done around that, but personally I prefer the NFC&#xA;interaction of &#34;I touch what I want to pay&#34; rather than &#34;a payment request comes&#xA;to me through the air and I figure out whether it is meant for me/is legitimate&#34;.&#xA;&#xA;&#xA;## NFC data formats ##&#xA;&#xA;A bit of background for those who are not that familiar with NFC: Most Bitcoin&#xA;wallets with NFC support make use of NDEF (NFC Data Exchange Format) as far as I&#xA;am aware (with CoinBlesk being an exception, which uses host-based card&#xA;emulation, if I understand it correctly). NDEF defines a number of record types,&#xA;among them &#39;URI&#39; and &#39;Mime Type&#39;.&#xA;&#xA;A common way of using NFC with Bitcoin is to create a URI record that contains a&#xA;Bitcoin URI. Beyond that Schildbach&#39;s wallet (and maybe others?) also support&#xA;the mime type record, which is then set to &#39;application/bitcoin-paymentrequest&#39;&#xA;and the rest of the NFC data is a complete BIP70 payment request.&#xA;&#xA;&#xA;## Implementation ##&#xA;&#xA;To structure the discussion a little bit, I have listed a number of scenarios to&#xA;consider below. Not every possible combination is listed, but it should cover a&#xA;bit of everything.&#xA;&#xA;Scenarios:&#xA;&#xA;1) Scan QR code, transmit transaction via Bitcoin network&#xA;   Example QR code: bitcoin:1asdf...?amount=42&#xA;&#xA;2) Touch NFC pad, transmit transaction via Bitcoin network&#xA;   Example NFC URI: bitcoin:1asdf...?amount=42&#xA;&#xA;3) Scan QR code, fetch BIP70 details via HTTP, post transaction via HTTP&#xA;   Example QR code: bitcoin:1asdf...?amount=42&amp;r=https://example.org/bip70paymentrequest&#xA;&#xA;4) Touch NFC pad, fetch BIP70 details via HTTP, post transaction via HTTP&#xA;   Example NFC URI: bitcoin:1asdf...?amount=42&amp;r=https://example.org/bip70paymentrequest&#xA;&#xA;5) Touch NFC pad, receive BIP70 details directly, post transaction via HTTP&#xA;   Example NFC MIME record: application/bitcoin-paymentrequest + BIP70 payment request&#xA;&#xA;6) Scan QR code, fetch BIP70 details via Bluetooth, post transaction via Bluetooth&#xA;   Example QR code: bitcoin:1asdf...?amount=42&amp;bt=1234567890AB&#xA;   Payment request has &#39;payment_url&#39; set to &#39;bt:1234567890AB&#39;&#xA;&#xA;7) Touch NFC pad, fetch BIP70 details via Bluetooth, post transaction via Bluetooth&#xA;   Example NFC URI: bitcoin:1asdf...?amount=42&amp;bt=1234567890AB&#xA;   Payment request has &#39;payment_url&#39; set to &#39;bt:1234567890AB&#39;&#xA;&#xA;Scenarios 1 and 2 are basically the &#39;legacy&#39;/pre-BIP70 approach and I am just&#xA;listing them here for comparison. Scenario 3 is what is often in use now, for&#xA;example when using a checkout screen by BitPay or Coinbase.&#xA;&#xA;I played around with both scenarios 4 and 5, trying to decide whether I should&#xA;use an NFC URI record or already provide the complete BIP70 payment request via&#xA;NFC.&#xA;&#xA;My experience here has been, that the latter was fairly fragile in my setup&#xA;(Raspberry Pi, NFC dongle from a company called Sensor ID, using nfcpy). I tried&#xA;with signed payment requests that were around 4k to 5k and the transfer would&#xA;often not complete if I didn&#39;t hold the phone perfectly in place. So I quickly&#xA;switched to using the NFC URI record instead and have the phone fetch the BIP70&#xA;payment request via Bluetooth afterwards. Using this approach the amount of data&#xA;is small enough that it&#39;s usually &#39;all or nothing&#39; and that seems more robust to&#xA;me.&#xA;&#xA;That said, I continue to have problems with the NFC stack that I&#39;m using, so it&#xA;might just be my NFC setup that is causing these problems. I will probably give&#xA;the NXP NFC library a try next (which I believe is also the stack that is used&#xA;by Android). Maybe I have more luck with that approach and could then switch to&#xA;scenario 5.&#xA;&#xA;Scenarios 6 and 7 is what the terminal is doing right now. The &#39;bt&#39; parameter is&#xA;the non-standard extension of Andreas&#39; wallet that I was mentioning. TBIP75&#xA;proposes to change &#39;bt&#39; into &#39;r1&#39; as part of a more generic approach of&#xA;numbering different sources for the BIP70 payment request. I think that is a&#xA;good idea and would express my vote for this proposal. So the QR code or NFC URI&#xA;would then look something like this:&#xA;&#xA;  bitcoin:1asdf...?amount=42&amp;r=https://example.org/bip70&amp;r1=bt:1234567890AB/resource&#xA;&#xA;In addition the payment request would need to list additional &#39;payment_url&#39;s. My&#xA;proposal would be to do something like this:&#xA;&#xA;    message PaymentDetails {&#xA;        ...&#xA;        optional string payment_url = 6;&#xA;        optional bytes merchant_data = 7;&#xA;        repeated string additional_payment_urls = 8;&#xA;          // ^-- new; to hold things like &#39;bt:1234567890AB&#39;&#xA;    }&#xA;&#xA;TBIP75 proposes to just change &#39;optional string payment_url&#39; into &#39;repeated&#xA;string payment_url&#39;. If this isn&#39;t causing any problems (and hopefully not too&#xA;much confusion?) I guess that would be fine too.&#xA;&#xA;In my opinion a wallet should then actually attempt all or multiple of the&#xA;provided mechanisms in parallel (e.g. try to fetch the BIP70 payment request via&#xA;both HTTP and Bluetooth) and go with whatever completes first. But that is of&#xA;course up to each wallet to decide how to handle.&#xA;&#xA;TBIP75 furthermore proposes to include an additional &#39;h&#39; parameter which would&#xA;be a hash of the BIP70 payment request, preventing a MITM attack on the&#xA;Bluetooth channel even if the BIP70 payment request isn&#39;t signed. This would&#xA;have also been my suggestion, although I know that Mike Hearn has raised&#xA;concerns about this approach. One being, that one needs to finalize the BIP70&#xA;payment request at the time the QR code and NFC URI is generated.&#xA;&#xA;&#xA;## Questions ##&#xA;&#xA;My questions to the list:&#xA;&#xA;1) Do you prefer changing &#39;optional string payment_url&#39; into &#39;repeated string&#xA;payment_url&#39; or would you rather introduce a new field &#39;additional_payment_urls&#39;?&#xA;&#xA;2) @Andreas: Is the r, r1, r2 mechanism already implemented in Bitcoin Wallet?&#xA;&#xA;3) Are there other comments regarding &#39;h&#39; parameter as per TBIP75?&#xA;&#xA;4) General comments, advice, feedback?&#xA;&#xA;I appreciate your input! :-)&#xA;&#xA;Cheers,&#xA;Jan&#xA;&#xA;[1] http://andyschroder.com/BitcoinFluidDispenser/&#xA;[2] https://www.mail-archive.com/bitcoin-development%40lists.sourceforge.net/msg06354.html&#xA;[3] https://github.com/AndySchroder/bips/blob/master/tbip-0074.mediawiki&#xA;[4] https://github.com/AndySchroder/bips/blob/master/tbip-0075.mediawiki</html></oembed>