/monero-java

Java library for using Monero

Primary LanguageJavaMIT LicenseMIT

Monero Java Library

A Java library for creating Monero applications using RPC and JNI bindings to monero v0.18.3.1 'Fluorine Fermi'.

  • Supports wallet and daemon RPC clients.
  • Supports client-side wallets using JNI bindings.
  • Supports multisig, view-only, and offline wallets.
  • Wallet types are interchangeable by conforming to a common interface.
  • Uses a clearly defined data model and API specification intended to be intuitive and robust.
  • Query wallet transactions, transfers, and outputs by their properties.
  • Fetch and process binary data from the daemon (e.g. raw blocks).
  • Receive notifications when blocks are added to the chain or when wallets sync, send, or receive.
  • Over 300 passing JUnit tests.

Table of contents

Architecture


Build Java applications using RPC or JNI bindings to monero-project/monero. Wallet implementations are interchangeable by conforming to a common interface, MoneroWallet.java.

Sample code

// connect to daemon
MoneroDaemon daemon = new MoneroDaemonRpc("http://localhost:38081", "superuser", "abctesting123");
long height = daemon.getHeight();                       // 1523651
List<MoneroTx> txsInPool = daemon.getTxPool();          // get transactions in the pool

// open wallet on monero-wallet-rpc
MoneroWalletRpc walletRpc = new MoneroWalletRpc("http://localhost:38083", "rpc_user", "abc123");
walletRpc.openWallet("sample_wallet_rpc", "supersecretpassword123");
String primaryAddress = walletRpc.getPrimaryAddress();  // 555zgduFhmKd2o8rPUz...
BigInteger balance = walletRpc.getBalance();            // 533648366742
List<MoneroTxWallet> txs = walletRpc.getTxs();          // get transactions containing transfers to/from the wallet

// create wallet from mnemonic phrase using JNI bindings to monero-project
MoneroWalletFull walletFull = MoneroWalletFull.createWallet(new MoneroWalletConfig()
        .setPath("sample_wallet_full")
        .setPassword("supersecretpassword123")
        .setNetworkType(MoneroNetworkType.STAGENET)
        .setServerUri("http://localhost:38081")
        .setServerUsername("superuser")
        .setServerPassword("abctesting123")
        .setSeed("hefty value scenic...")
        .setRestoreHeight(573936l));

// synchronize the wallet and receive progress notifications
walletFull.sync(new MoneroWalletListener() {
  @Override
  public void onSyncProgress(long height, long startHeight, long endHeight, double percentDone, String message) {
    // feed a progress bar?
  }
});

// synchronize in the background every 5 seconds
walletFull.startSyncing(5000l);

// receive notifications when funds are received, confirmed, and unlocked
walletFull.addListener(new MoneroWalletListener() {
  @Override
  public void onOutputReceived(MoneroOutputWallet output) {
    BigInteger amount = output.getAmount();
    String txHash = output.getTx().getHash();
    Boolean isConfirmed = output.getTx().isConfirmed();
    Boolean isLocked = output.getTx().isLocked();
    FUNDS_RECEIVED = true;
  }
});

// send funds from RPC wallet to full wallet
MoneroTxWallet createdTx = walletRpc.createTx(new MoneroTxConfig()
        .setAccountIndex(0)
        .setAddress(walletFull.getAddress(1, 0))
        .setAmount("250000000000") // send 0.25 XMR (denominated in atomic units)
        .setRelay(false)); // create transaction and relay to the network if true
BigInteger fee = createdTx.getFee(); // "Are you sure you want to send... ?"
walletRpc.relayTx(createdTx); // relay the transaction

// recipient receives unconfirmed funds within 5 seconds
TimeUnit.SECONDS.sleep(5);
assertTrue(FUNDS_RECEIVED);

// save and close wallet
walletFull.close(true);

Documentation

Using monero-java in your project

For Maven, add to pom.xml:

<dependency>
  <groupId>io.github.monero-ecosystem</groupId>
  <artifactId>monero-java</artifactId>
  <version>0.8.8</version>
</dependency>

For Gradle, add to build.gradle:

compile 'io.github.monero-ecosystem:monero-java:0.8.8'

You are now ready to use this library with monerod and monero-wallet-rpc endpoints.

If you want to use client-side wallets, first build the JNI shared libraries.

If using RPC servers:

  1. Download and install Monero CLI.
  2. Start monerod, e.g.: ./monerod --stagenet (or use a remote daemon).
  3. Start monero-wallet-rpc, e.g.: ./monero-wallet-rpc --daemon-address http://localhost:38081 --stagenet --rpc-bind-port 38083 --rpc-login rpc_user:abc123 --wallet-dir ./

Building JNI shared libraries from source

If you want to process binary data or use a client-side wallet instead of RPC, shared libraries must be built for your specific platform for this Java library to use. This project uses a C++ counterpart library, monero-cpp, to support JNI, which is included as a submodule in ./external/monero-cpp.

Mac & Linux

  1. Install maven and Java JDK for your system
    Ubuntu: sudo apt-get install maven default-jdk
    Mac: brew install maven openjdk
  2. export JAVA_HOME=/path/to/jdk, for example:
    Ubuntu: export JAVA_HOME=/usr/lib/jvm/default-java
    Mac: export JAVA_HOME=/Library/Java/JavaVirtualMachines/adoptopenjdk-11.jdk/Contents/Home
  3. Clone the project repository: git clone https://github.com/monero-ecosystem/monero-java.git
  4. cd ./monero-java
  5. Install Maven dependencies: mvn install
  6. Update submodules: ./bin/update_submodules.sh
  7. Build ./external/monero-cpp as a shared library.
  8. Build shared libraries to ./build/: ./bin/build_libmonero_java.sh
  9. Run TestMoneroUtils.java JUnit tests to verify the shared libraries are working with Java JNI.
  10. Add the shared libraries within ./build/ to your application's classpath.

Windows

  1. Download and install Java JDK. During installation, enable the option to set the $JAVA_HOME environment variable if possible.

  2. Install MSYS2.

  3. Install Maven:

    a. Download binary zip archive from https://maven.apache.org/download.cgi
    b. Unpack to C:\msys64\usr\local

  4. Start MSYS2 MINGW64 or MSYS MINGW32 depending on your system.

  5. Update packages: pacman -Syu and confirm at the prompts.

  6. Install dependencies. During installation, use default=all by leaving the input blank and pressing enter.

    64-bit: pacman -S mingw-w64-x86_64-toolchain make mingw-w64-x86_64-cmake git

    32-bit: pacman -S mingw-w64-i686-toolchain make mingw-w64-i686-cmake git

  7. Set environment variables:

    export JAVA_HOME=/path/to/jdk/ (if not set during installation)
    export MAVEN_HOME=/usr/local/apache-maven-3.x.x/
    export PATH=$PATH:$JAVA_HOME/bin/:$MAVEN_HOME/bin/

  8. Clone the project repository: git clone https://github.com/monero-ecosystem/monero-java.git

  9. cd ./monero-java

  10. Install Maven dependencies: mvn install

  11. Update submodules: ./bin/update_submodules.sh

  12. Build ./external/monero-cpp as a shared library. Follow instructions for Windows.

  13. Build shared libraries to ./build/: ./bin/build_libmonero_java.sh

  14. Run TestMoneroUtils.java JUnit tests to verify the shared libraries are working with Java JNI.

  15. Add the shared libraries within ./build/ to your application's classpath.

Memory Growth

If you see unrestricted memory growth using native bindings, consider applying jemalloc to improve memory management with malloc. In many cases, this can completely resolve the memory growth.

For example: export LD_PRELOAD=/path/to/libjemalloc.a then run your app.

Running JUnit tests

  1. Clone the project repository: git clone https://github.com/monero-ecosystem/monero-java.git
  2. cd monero-java
  3. If using JNI, build JNI shared libraries from source.
  4. Start RPC servers:
    1. Download and install Monero CLI.
    2. Start monerod, e.g.: ./monerod --stagenet (or use a remote daemon).
    3. Start monero-wallet-rpc, e.g.: ./monero-wallet-rpc --daemon-address http://localhost:38081 --stagenet --rpc-bind-port 38083 --rpc-login rpc_user:abc123 --wallet-dir ./
  5. Configure the appropriate RPC endpoints, authentication, and other settings in TestUtils.java.
  6. Run all *.java files in src/main/test as JUnits.

Related projects

License

This project is licensed under MIT.

Donations

If this library brings you value, please consider donating.


46FR1GKVqFNQnDiFkH7AuzbUBrGQwz2VdaXTDD4jcjRE8YkkoTYTmZ2Vohsz9gLSqkj5EM6ai9Q7sBoX4FPPYJdGKQQXPVz