TLDR: Using a java wrapper around bitcoind and LND with gomobile you can run a fully validating bitcoin node on your android device
The purpose of this article is to demonstrate how it is possible for a user to run their own Bitcoin and Lightning full node on their consumer Android OS device such as their smart phone or smart TV. This has been realised recently by the Japanese lightning company Nayuta, and the wallet implementing this is available for public beta test now by clicking here https://nayuta.co/wallet
The three main components used are stated below however recognition should be awarded to the developers of these components allowing us to “put the pieces together” to create the final application.
The foundational app used in this setup is ABCore developed by the Green Address team at Blockstream, ABCore is an Android wrapper for bitcoind allowing bitcoind to be run on Android OS. We did make changes to the Java wrapper around ABCore in order for it to work with LND and the latest Android OS features (such as Job Scheduler), however a lot of the code base is still based on ABCore.
The lightning implementation I chose to use along side ABCore is LND, the reason being that LND is written in golang and golang has a very useful module called gomobile which lets you compile a golang app into an iOS or Android library.
The LND api communicates using gRPC which is an RPC framework allowing a native Android Java app to communicate with the LND lncli.
Putting it all together
We created a Java library for bitcoind using Android Studio, this library is based on ABCore and can be found here
Creating bitcoind library
This library is made up of several classes but the most important classes are
This class checks if bitcoind has been downloaded and if not it downloads the latest build for Android devices from the following repo https://github.com/greenaddress/bitcoin_ndk/releases
note: In the future it is planned to include the bitcoind binary in the app bundle itself rather than downloading it on app launch.
This class runs the downloaded bitcoind binary using the Android ProcessBuilder. It also has the ability to run the app as a service which allows bitcoind to run in the background even when the parent app is closed.
This is an RPC service which allows the app to connect to bitcoind and create RPC calls such as GetBlockchainInfo. Currently this is needed as bitcoind runs in a separate process to the main app. bitcoind is running on local host behind a password, the RPCIntetentService connects to bitcoind over local host using the password specified in bitcoin.conf. For the purposes of our app the bitcoin.conf is generated by the parent app.
This class allows us to make use of Android Oreo’s JobScheduler. The JobScheduler is a useful feature that allow us to schedule code to run under certain conditions when the OS decides. For example we can add restrictions that bitcoind only runs when charging and connected to wifi, this would have the effect of letting the OS try to sync the blockchain whenever it seems possible assuming the user is connected to wifi and is charging.
For the purpose of Nayuta app we exported this module as an .aar library.
Creating LND library
LND can easily be built as an android library using the make android command. This produces an lndmobile.jar file. This file is not enough in its self to run LND we also need to use android gRPC in order to pass RPC commands to LND. We created a couple of libraries to do this.
This first is a library that allows us to create and parse gRPC requests and responses, found here
The second is a simple wrapper allowing us to send and receive the generated gRPC requests and response to the lndmobile library, found here
It should be possible to combine these libraries into one library that both creates/parses and sends/receives gRPC requests, (however there seemed to be issues when doing this initially hence splitting these two features into separate libraries allowed us to continue development).
Importing into our app
Now we have the following android libraries
Our app is developed using a cross platform framework called Appcelerator which is similar to React Native. Appcelerator allows the usage of native code as well as importing native modules.
We imported our generated libraries into our Appcelerator app, however to allow lnd to use bitcoind as backend we need to setup our configuration files for LND and bitcoind respectively.
It is fairly simply to do this and all that is required is to make sure both the lnd.conf and the bitcoin.conf have the same RPC uri and credentials as well as setting up ZMQs for bitcoind over local host.
Example config files can be seen below
note that in the bitcoin.conf there are a few params which are designed to optimize the performance for mobile.
- prune: this is set to 550 to run the app in pruned node so we don’t store the whole blockchain as it is not needed for LND to function.
- blocksonly: this disables the mempool so the mobile only needs to have the bandwidth to download blocks and not rely transactions.
- disablewallet: we do not need the wallet as LND has its own internal wallet.
With the configuration files saved in the correct app directory for lndmobile and bitcoind it is now possible to first run bitcoind, let it synchronise and then run LND which should connect to bitcoind over rpc and zmqs and use it as its backend.
By creating android libraries and wrappers around LND and bitcoind as well as correctly generating the necessary .conf files we can import these libraries into a cross platform or native android app project and run LND with a bitcoind backend. This is implemented in the Nayuta wallet which will be made open source soon so you will be able to look at the implementation in more detail.