Author

Topic: Walk-Thru: Handling "bitcoin:" URLs (merchants and clients) (Read 3999 times)

full member
Activity: 198
Merit: 102
Just in case anyone is looking to implement the Bitcoin URI handling Java you'll do well to have a read of this StackExchange question first http://stackoverflow.com/questions/1947209/registering-a-url-protocol-handler-in-a-multiple-platforms.

Not much use for Python, I'm afraid.  Sad
legendary
Activity: 1428
Merit: 1093
Core Armory Developer

OMG then sorry, seems like I did not read your posting thourogh enough :-/!

Don't sweat it.  It's a looooooooong post. Smiley

Edit:  Actually I didn't clarify that point in the post.  I'll add some context to clear that up.
hero member
Activity: 772
Merit: 500
On Windows it's a simple open the file to add entries to registry.
For Win >= Vista the UAC will prompt for an admin-token on WinXP you need have admin-rights, yes.

Of course this assumes you know what you are doing as it replaces / overwrites existing entries for "bitcoin:".
For Windows users it's more handy than what you've written I think (as a Windows user). But yes, perhaps it should be a user setting and don't require admin-rights to add this to the registry.

I guess I'm confused.  What I've written is python code that checks the registry keys every time Armory is open, and either sets the local-user's-registry keys to default to Armory, or ask the user if they want to switch if it's already set to something else.   I'm not sure what "handy" means here, since this is all under the hood -- it behaves exactly like Firefox/IE/Chrome -- "Armory is not currently set as your default Bitcoin application.  Would you like to switch the default to Armory?"

However, for those not using python, the .reg file approach seems reasonable as something to run during application installation, but not each time the app is opened.  Mainly because it overwrites the keys blindly, and requires keeping a .reg file around to keep executing.  And the admin thing, but that goes away if you just switch to the HKEY_CURRENT_USER\Software\Classes\bitcoin\* keys instead.



OMG then sorry, seems like I did not read your posting thourogh enough :-/!

Dia
legendary
Activity: 1428
Merit: 1093
Core Armory Developer
On Windows it's a simple open the file to add entries to registry.
For Win >= Vista the UAC will prompt for an admin-token on WinXP you need have admin-rights, yes.

Of course this assumes you know what you are doing as it replaces / overwrites existing entries for "bitcoin:".
For Windows users it's more handy than what you've written I think (as a Windows user). But yes, perhaps it should be a user setting and don't require admin-rights to add this to the registry.

I guess I'm confused.  What I've written is python code that checks the registry keys every time Armory is open, and either sets the local-user's-registry keys to default to Armory, or ask the user if they want to switch if it's already set to something else.   I'm not sure what "handy" means here, since this is all under the hood -- it behaves exactly like Firefox/IE/Chrome -- "Armory is not currently set as your default Bitcoin application.  Would you like to switch the default to Armory?"

However, for those not using python, the .reg file approach seems reasonable as something to run during application installation, but not each time the app is opened.  Mainly because it overwrites the keys blindly, and requires keeping a .reg file around to keep executing.  And the admin thing, but that goes away if you just switch to the HKEY_CURRENT_USER\Software\Classes\bitcoin\* keys instead.

hero member
Activity: 772
Merit: 500
On Windows it's a simple open the file to add entries to registry.
For Win >= Vista the UAC will prompt for an admin-token on WinXP you need have admin-rights, yes.

Of course this assumes you know what you are doing as it replaces / overwrites existing entries for "bitcoin:".
For Windows users it's more handy than what you've written I think (as a Windows user). But yes, perhaps it should be a user setting and don't require admin-rights to add this to the registry.

Dia
legendary
Activity: 1428
Merit: 1093
Core Armory Developer
For Windows you can use this and save it into a BC_handler.reg:

Code:
Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\bitcoin]
@="URL:bitcoin Protocol"
"FriendlyTypeName"="Bitcoin URI"
"URL Protocol"=""

[HKEY_CLASSES_ROOT\bitcoin\DefaultIcon]
@="E:\\Bitcoin\\Client\\bitcoin-qt.exe,0"

[HKEY_CLASSES_ROOT\bitcoin\shell]

[HKEY_CLASSES_ROOT\bitcoin\shell\open]

[HKEY_CLASSES_ROOT\bitcoin\shell\open\command]
@="\"E:\\Bitcoin\\Client\\bitcoin-qt.exe\" \"%1\""

You have to edit the path ("E:\\Bitcoin\\Client\\bitcoin-qt.exe") to match up your local setup.

Diapolo,

(1) What am I supposed to do with that file?  I saw examples like it everywhere, but nothing told how to ... use it.  Do I open the registry and import it?  Is there a command for executing that file?  And how do I invoke it on installation or on-load of my program.  Also what about checking for existing apps behind those keys before overwriting them?


(2) That modifies the HKEY_CLASSES_ROOT, which requires admin/root and changes it for all users.  I believe it makes more sense to use the HKEY_CURRENT_USER\Software\Classes\ to do it just for the current user and no admin required.

hero member
Activity: 772
Merit: 500
For Windows you can use this and save it into a BC_handler.reg:

Code:
Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\bitcoin]
@="URL:bitcoin Protocol"
"FriendlyTypeName"="Bitcoin URI"
"URL Protocol"=""

[HKEY_CLASSES_ROOT\bitcoin\DefaultIcon]
@="E:\\Bitcoin\\Client\\bitcoin-qt.exe,0"

[HKEY_CLASSES_ROOT\bitcoin\shell]

[HKEY_CLASSES_ROOT\bitcoin\shell\open]

[HKEY_CLASSES_ROOT\bitcoin\shell\open\command]
@="\"E:\\Bitcoin\\Client\\bitcoin-qt.exe\" \"%1\""

You have to edit the path ("E:\\Bitcoin\\Client\\bitcoin-qt.exe") to match up your local setup.
legendary
Activity: 1708
Merit: 1066
Thanks etotheipi for that write up.

For support of non-ASCII labels, MultiBit uses UTF8 encoding (which includes ASCII) before the % encoding is applied and I would recommend doing that. I have tried it out in Russian, Chinese, Thai, Hindi and Arabic and it works fine.

For Mac bitcoin registration it is all specified in the Info.plist file. If you look at the bottom of this file you can see how MultiBit specifies it will deal with 'bitcoin' links:

https://github.com/jim618/multibit/blob/v0.3/src/app-resources/MultiBit.app/Contents/Info.plist

It is the CFBundleURLSchemes key.

You do not have to do any registration - the Mac OS picks these up automatically.
legendary
Activity: 1428
Merit: 1093
Core Armory Developer
I wanted to share all the information I accumulated on the topic of "bitcoin:" URL's so that developers and merchants don't have to be intimidated by them (I was, at first).  I recently figured all this out in the past two weeks while integrating full support into Armory, which is now available in version 0.75.1 (latest).    

But I may not be doing everything efficiently, and I will need to figure it out on Mac/OSX, too.  So I wanted to share what I've learned, and use the discussion to fill in the gaps and make this a one-stop place for handling bitcoin URI strings.  Also, if you know the proper way to do this in Unity and KDE, please let me know!




Creating and parsing "bitcoin:" URI Strings:

This is the easiest part, which is fully-documented in BIP 21: URI Scheme.   Here a simple example of how you would include it (using my donation address, of course!)

Code:

...which looks like:  Donate 1.0 BTC to the Armory Project!

In order to encode URI-reserved characters such as spaces, various punctuation, etc, you need to the percent encoding scheme.   It consists of taking the message you want to put into the URL, and replacing all spaces with "%20", all exclamation points with %21, etc.  It's all on that link.

I believe that the "label" field is to label the address and that the "message" field is for marking the transaction.  i.e. if you click on a link that has label "Eto's Key" and mess "Donation to receive his Encryption Seminar", then the "Eto's Key" would show up in the address book, and the "Donation to receive..." would show up on the transaction ledger.  For addresses that are only ever used once, I don't think it matters, but that's how I interpret the difference between the two.

I think both these fields is where the real value of bitcoin URLs happens.  Merchants are best equipped to create these field entries automatically, and can insert things like Order#, purchase information, etc.  Maybe even contact information.  Then, the user ends up with full purchase history and documentation in their wallet without any effort.

UPDATE: For now it seems like a good idea to only use the "label=" field for any information that should be saved in the wallet.  I believe Bitcoin-Qt will not save the "message=" data, which used to be described as "a message to display after the URI is clicked" (or something like that).  I'll follow up with the devs about it.



Registering your application with the operating system:  Windows:

It was intimidating at first, but after some research I found out it's only a couple of registry key modifications.  And of course, I use python so anything is easy Smiley  ("import _winreg").  My python code for doing it is in ArmoryQt.py around line 500.  The following process is executed every time Armory is opened:

  • Check "HKEY_CLASSES_ROOT\bitcoin\shell\open\command" if it exists and if it's set to anything (should not be modified)
  • If not, check "HKEY_CURRENT_USER\Software\Classes\bitcoin\shell\open\command" if it exists and it's set to anything.
  • If it is set to another application, pop up message box asking if they want to use this program as the default
  • If it's not set or does not exist, or the user confirms they want to make it default, create and set all the following registry keys:
Code:
HKEY_CURRENT_USER\Software\Classes\bitcoin                      Name: ""                Setting: "URL:bitcoin Protocol"
HKEY_CURRENT_USER\Software\Classes\bitcoin                      Name: "URL Protocol"    Setting: ""
HKEY_CURRENT_USER\Software\Classes\bitcoin\shell
HKEY_CURRENT_USER\Software\Classes\bitcoin\shell\open
HKEY_CURRENT_USER\Software\Classes\bitcoin\shell\open\command   Name: ""                Setting: "C:\Path\To\Program.exe %1"
HKEY_CURRENT_USER\Software\Classes\bitcoin\DefaultIcon          Name: ""                Setting: "C:\Path\To\Program\appicon.ico"
    Where I put Name=="" means set the default param for that key (every entry has a default).  Python uses an empty string to reference it

Don't modify the HKEY_CLASSES_ROOT objects -- you can't do so without admin/root, anyway.  But I think this really needs to go under the HKEY_CURRENT_USER which is local settings for this user, and they can be modified by a user-level program on application load.  However, you could add an install option that modifies "HKEY_CLASSES_ROOT" to set it as the default for all users (which the user can then change for their own account using the HKEY_CURRENT_USER registry keys).

Update:  Diapolo mentioned a way to overwrite registry keys using a .reg file.  This could be useful at installation time, though it will overwrite the keys regardless of what's there already.  I'm sure there's an easy way to expand this, though.




Registering your application with the operating system:  Linux:

I got this working in Ubuntu, tested successfully on 9.04 up to 12.04.  However, this solution probably only works for Gnome, and for 10.10+ (or maybe 11.04+) there appears to be a bug in Unity desktop that requires a root-fix.  I didn't find a user-level solution for the Unity-based versions.

Gnome-Based Desktop

Very similar to the Windows registry solution, but using the gconf-editor instead.  I didn't know how to modify it directly through python, so I just collected the correct command-line calls and execute them using subprocess.Popen().  Check for an existing [user-level] handler with the command:

Code:
gconftool-2 --get /desktop/gnome/url-handlers/bitcoin/command
which in my case returns: "python /usr/share/armory/ArmoryQt.py %s".    I simply search for "ArmoryQt.py" in the output and use that to identify whether Armory is currently set as the default.

Then to set it, I use the following calls:

Code:
   gconftool-2 -t string -s /desktop/gnome/url-handlers/bitcoin/command "python /usr/share/armory/ArmoryQt.py "%s"
    gconftool-2 -s /desktop/gnome/url-handlers/bitcoin/needs_terminal false -t bool
    gconftool-2 -t bool -s /desktop/gnome/url-handlers/bitcoin/enabled true

You can see where I do this in ArmoryQt.py around line 465.  If another app is set and this is the first time the user has loaded Armory, I skip the question window... the user has enough to worry about with this new program...


Unity-Based Desktop (and maybe KDE...?)

This works for Ubuntu 11.04+, and also shows one way to get your app into the user's Applications menu.  Note that this solution is a root-level fix: you're not going to be able to do this for on-load unless the user is running your app with root/admin permission.  Because the gconftool-2 stuff is borked in 11.04+.  For installing your own app into the menu, you need to create a desktop file:  My armory.desktop file looks like this:

Quote
[Desktop Entry]
Type=Application
Name=Armory
GenericName=Bitcoin Client
Comment=Full-featured Bitcoin wallet management application
Categories=Qt;Network;
Exec=python /usr/share/armory/ArmoryQt.py %u
Icon=armoryicon
StartupNotify=false
Terminal=false
MimeType=x-scheme-handler/bitcoin

The text that is bolded is left out on Ubuntu 9.04-10.10.  It is included for 11.04+ so that it permanently registers the app with Ubuntu during installation.  I believe root is needed to change this.  Of course, just having the desktop file made isn't enough, it needs to be installed:

Code:
xdg-icon-resource install --novendor --context apps --size 64 /usr/share/armory/img/armory_icon_64x64.png armoryicon
xdg-desktop-menu  install --novendor /usr/share/applications/armory.desktop
(note that the .desktop file uses "Icon=armoryicon", so the first line registers a relationship between the string "armoryicon" and the actual location of the icon to use).

At least this can be done and put in the Makefile, and you don't have to deal with extra startup operations... but it is kind of rude to other client developers.  I'm happy to take recommendations for how this could be improved.  And also support for non-Gnome-based desktop managers.





Registering your application with the operating system:  Mac/OSX:

I got nothing.  I haven't even tried yet.  Maybe someone can fill me in, in preparation of having to support it in Armory one day (I promise, Armory will support Mac...eventually).
Jump to: