Running JavaScript code on Android Wallet

Manuel Cabras
4 min readOct 11, 2019

--

Instead of bitching on Twitter, this week I decided to do a little Aparté on a specific part of the Android Wallet codebase: running JavaScript.

I’m writing this article mostly because I̶ ̶h̶a̶v̶e̶ ̶n̶o̶ ̶u̶p̶d̶a̶t̶e̶ ̶f̶o̶r̶ ̶y̶o̶u̶ I simply wanted to share my last difficulties and hopefully teach you something about the development world if you’re not a tech guy!

TLDR: Go to the last paragraph.

What’s a JavaScript engine?

A JavaScript engine is a program that is able to read and execute JavaScript, a programming language mostly used in the web environment (but not only), which conforms to the ECMAScript specifications.

ECMAScript, simply put, is a specification that aims to standardize JavaScript.

There are few known engines out there, that can all run JavaScript:

  • JavaScriptCore: a JS engine released by Apple, will tell later
  • Rhino: A JS engine is written in Java published by Mozilla
  • Spider Monkey: a JS engine also was written by Mozilla, used for their browser i.e.
  • Hermes, an engine created by Facebook, used on Android with React Native
  • V8, a JS engine written in C++ by Google, used on Chrome and core component of the Node.js runtime.

All those engines can execute JavaScript code, but none of them are easily available on Android, which is the main difference with iOS since Swift can access JavaScriptCore easily and flawlessly.

But, why do you need to execute JavaScript?

Since we’re using the Bitcore suite provided by BitPay, we have to use a crypto library called the Stanford JavaScript Crypto Library (SJCL), which is a secure, small and fast library for cryptography in JavaScript.

SJCL will mostly be used to encrypt, decrypt and decode data between the app and Bitcore.

While I’ve been researching a port of this library, I haven’t found any satisfactory results. Besides, once this will be over, I’ll be publishing the result as a standalone library for other people to use.

I’ve also been suggested to host a web server with an exposed REST API, but besides adding a security risk, it’s a bit overkill for the feature set needed.

But, you can use WebView, no?

Yes and, no. WebView’s an object that ideally allows you to display a Web page and yes, can execute JavaScript via the JavaScript Interface.

WebView ideally should be used only when we want to display a web page, and even if it can be used without displaying actual content, it’s an (almost) full-featured browser and it would slow down the app execution too much.

Relying only on a JavaScript engine is enough for the purpose of

So, how are you solving your problem?

Since Android has no “plug-and-play” implementation of any known JS engine besides web view, I’ve started searching for a library that could do this for me.

On a regular Java program, you can use an object called a Script Engine (handled with, guess it, a Script Engine Manager) which allows loading an engine for different languages, JS included, and execute JavaScript code.

But, Android also can be written in Java, right?

Well, yes, but here’s the thing. Java is the language, but a language would be nothing without a Development Kit, which is a “toolbox” that facilitates the development of an application by providing a set of tools for a lot of common applications. Think about Java being bare metal, and a Development kit is tools like a screwdriver, a hammer, etc.

Between classic Java development, and Android development, the development kits differ, and while they share most of the packages (let’s think about pockets in your toolbox), Android doesn’t have the package containing the Engine Script object.

So, first try, I found out about an external library providing the classes needed to use the Script Engine and Rhino (the one provided by Mozilla). It was all fun and games and once figured out how to use it, well, things got nasty.

Turns out I was receiving the result of the JavaScript functions I needed in the wrong format. And there was nothing I could do, like forcing a format I’ve would’ve liked — it could also have involved in altering the data without knowledge of it and I can not allow this since even a byte can completely corrupt the data. So I had to discard this option.

And now, the solution.

J2V8 -Java2V8

I don’t know how I did not find out earlier. J2V8 (available HERE on GitHub) is a set of Java bindings for the V8 engine. It allows us to easily read a script and execute functions from it in a fast and reliable way.

So here I am, right now, implementing J2V8 to read SJCL to be able to implement Bitcore on the Android wallet.

If you made it through that bit wall of text, thank you for the patience on going through my rant and I hope someone can find some use from this article!

Tips

XVG : DNqhnfa2Uf8cvns5udz3uH7EcoUZvysHNg

BTC : 1F5KZc1kzB5VA1eKpbYpFcbrRhXsYNmmo5

BAT : 0xefd4c1e7730f7b00e1Ac8438BbBDC2a1cD1cE93E

References

--

--