I became a bounty coder!

A few weeks ago, I saw a $400 bounty appear for MetaMask internationalization (separating out text to make the app translatable). I had used MetaMask before and felt good about my ability to complete the project, so I registered my interest and got to work.
What is MetaMask?
MetaMask is a multi-browser plugin which I’d describe as an Ethereum caddy — it holds an Ether cryptocurrency wallet, makes that wallet available on web pages, and helps you sign and interact with other ‘smart contracts’ and tokens online using the web3 library.
I first downloaded MetaMask to create an account and interact with CryptoKitties, but it’s used many places around the web.
How is a bounty created?
Owocki created the bounty with 0.4 Ether (then worth $393, now closer to $320) on GitCoin. This automatically added a notification to the relevant GitHub Issue, which had been open since July 2016. Maintainer Kumavis quickly made a comment which warned bounty hunters to focus on the newest UI branch.
How did I start working on the bounty?
I found out about the bounty when I saw this Tweet:
The first step was to claim this task, so we don’t have multiple people creating duplicate solutions or potentially copying each other’s work. A claim lasts for two weeks.
On the GitCoin website, I needed to associate myself with an Ethereum address, which is best accomplished with MetaMask (!!). I used the plugin to create an address and receive a small amount of Ether. Then I was able to sign the contract and pay a fee (typical in Ethereum transactions). According to this transaction record in the blockchain, I spent about 12 cents on the transaction and ‘gas’ fees.
I asked Kumavis for some clarification to make sure that I would be working on the right branch.
Is it difficult to add internationalization to a browser extension?
I was concerned at first, then I found the guide for Chrome apps, then I discovered that this is now a web standard which works in all the MetaMask browsers.
I was pleased to see the views use React / Hyperscript syntax, so all of the view code had a consistent appearance and was all in one ui directory.
Unraveling the project, there were four main tasks:
- make a translation function which calls browser.i18n.getMessage or a fallback function
- replace all UI text, such as <button>Confirm</button>, with the translation function <button>t(‘confirm’)</button>
- enter shortcut codes in the manifest.json file so that the name and description in the App Store can be translated
- build an organized list of all translations for the default language locale (en for English) which can be copied for other languages
Some internationalization issues were:
- inconsistent UI text (e.g. buttons on different forms reading ‘Confirm’ and ‘CONFIRM’). I decided to replace the latter with ‘Confirm’ and a text-transform: uppercase; — this is also better for accessibility reasons.
- a shorthand for longer phrases (‘Confirm this Transaction’ with ‘confirmThisTransaction’ or ‘confirmButton’ or ‘transactionConfirmButton’?)
- organizing the English translations (I decided on alphabetical order, so that similar phrases might be bundled together)
- a few menus looked at the text of your choice and not a unique ID.
Building and Testing
I found it difficult to consistently build the new UI branch on my machine. Maybe I have an old version of gulp? I got a full build working one day, tested it out, and forgot how to do it by the next day.
Tests on my machine and CircleCI were partially successful then returned with different errors, which I don’t fully understand. I think it may be related to old UI vs. new UI.
I suspect that these problems are common for bounty developers who move from project to project. If I were a full-time ‘bounty hunter’, I would either create a new development environment for each project, or I would insist on projects facilitating that. I’m sure there’s a good Dockerfile out there for Chrome and Firefox testing.
I wasn’t sure how to write new tests around internationalization. JavaScript tests don’t have a browser.i18n API, so they always run my fallback function. I created a Japanese locale, but to make it appear, it wasn’t enough to add Japanese to my browser preferences… I needed to change my OS language. This was a little scary (what if I couldn’t figure out how to go back?) and I’m not sure how to implement that in a testing environment.
Circling back
Once I had seen the project working on my machine, I posted a Work-In-Progress pull request on the MetaMask repo. I explained some of my design decisions and asked for feedback (particularly on how to name and organize the almost 190 translatable phrases).
Five days later, still having no major response, I finished up coding and posted another comment, ending with “Welcoming your feedback on this”.
Unfortunately, I didn’t hear any feedback in the past 10 days, and my hold on the project expired. Around the same time I started a new job, where I’m not allowed to do bounty work on the side :-P
Updated March 12th, 2018
It took a month and a half, but after another user asked about translations, two developers at Consensys started on the final work to merge and approve my code for addition to MetaMask! That means the project was a success!
I couldn’t contribute much to this final step, so I asked the bounty-poster and the other contributors about splitting the reward. The other guys said it was their full-time work, so I’ve now claimed and received the full amount (about $280 at today’s prices). Another big plus is that I’ll be seeing translations soon (I know people have already volunteered for Chinese and Russian).
Conclusions
I would love to do more bounty work in the future. With cryptocurrency payments, it would be possible for someone to work on this anywhere in the world, without worrying about bank accounts or revealing their identity.
Before this type of coding goes mainstream, project builds and tests need to be designed carefully for a coder to drop into a project and help, without first learning the ongoing development branches or personalities on the project.
Also, if a bounty is offered by a project user, and the code is not a priority for the maintainers, then how will the bounty be claimed? It’s not unusual for a freelancer to wait a long time to get paid, but having a 3rd party makes it more complex. If I were relying on this bounty for my livelihood, I might check for more buy-in from the maintainers before and after starting work.
