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