Skip to content

About

A C++ library for using Monero

Resources

Stars

0 stars

Watchers

2 watching

Forks

 
 

Repository files navigation

Monero C++ Library

A C++ library for creating Monero applications using RPC or native bindings to monero v0.18.5.4 'Fluorine Fermi'.

  • Supports fully client-side wallets by wrapping wallet2.h.
  • Supports wallet and daemon RPC clients.
  • Supports multisig, view-only, and offline wallets.
  • Uses a clearly defined data model and API specification intended to be intuitive and robust.
  • Query wallet transactions, transfers, and outputs by their properties.
  • Receive notifications when wallets sync, send, or receive.
  • Tested by over 100 tests in monero-java and monero-ts using JNI and WebAssembly bindings.

Architecture


Build C++ applications using RPC or native bindings to monero-project/monero. Wallet implementations are interchangeable by conforming to a common interface, monero_wallet.h.

Sample code

// connect to daemon
monero_daemon* daemon = new monero_daemon_rpc("http://localhost:38081", "superuser", "abctesting123");
uint64_t height = daemon->get_height();                            // 1523651
vector<shared_ptr<monero_tx>> txs_in_pool = daemon->get_tx_pool(); // get transactions in the pool
for (const shared_ptr<monero_tx>& tx : txs_in_pool) monero_utils::free(tx);

// create wallet from mnemonic phrase using native bindings to monero-project
monero_wallet_config wallet_config;
wallet_config.m_path = "sample_wallet_full";
wallet_config.m_password = "supersecretpassword123";
wallet_config.m_network_type = monero_network_type::STAGENET;
wallet_config.m_server = make_shared<monero_rpc_connection>("http://localhost:38081", "superuser", "abctesting123");
wallet_config.m_seed = "hefty value scenic...";
wallet_config.m_restore_height = 573936;
monero_wallet* wallet_full = monero_wallet_full::create_wallet(wallet_config);

// synchronize the wallet and receive progress notifications
struct : monero_wallet_listener {
  void on_sync_progress(uint64_t height, uint64_t start_height, uint64_t end_height, double percent_done, const string& message) {
    // feed a progress bar?
  }
} my_sync_listener;
wallet_full->sync(my_sync_listener);

// synchronize in the background every 5 seconds
wallet_full->start_syncing(5000);

// receive notifications when funds are received, confirmed, and unlocked
struct : monero_wallet_listener {
  void on_output_received(const monero_output_wallet& output) {
    uint64_t amount = output.m_amount.get();
    string tx_hash = output.m_tx->m_hash.get();
    bool is_confirmed = output.m_tx->m_is_confirmed.get();
    bool is_locked = dynamic_pointer_cast<monero_tx_wallet>(output.m_tx)->m_is_locked.get();
    FUNDS_RECEIVED = true;
  }
} my_listener;
wallet_full->add_listener(my_listener);

// connect to wallet RPC and open wallet
monero_wallet_rpc* wallet_rpc = new monero_wallet_rpc("http://localhost:38083", "rpc_user", "abc123");
wallet_rpc->open_wallet("sample_wallet_rpc", "supersecretpassword123");
string primary_address = wallet_rpc->get_primary_address();       // 555zgduFhmKd2o8rPUz...
uint64_t balance = wallet_rpc->get_balance();                     // 533648366742
vector<shared_ptr<monero_tx_wallet>> txs = wallet_rpc->get_txs(); // get transactions containing transfers to/from the wallet
monero_utils::free(txs);

// send funds from RPC wallet to full wallet
monero_tx_config tx_config;
tx_config.m_account_index = 0;
tx_config.m_address = wallet_full->get_address(1, 0);
tx_config.m_amount = 250000000000; // send 0.25 XMR (denominated in atomic units)
tx_config.m_relay = false; // create transaction and relay to the network if true
shared_ptr<monero_tx_wallet> created_tx = wallet_rpc->create_tx(tx_config);
uint64_t fee = created_tx->m_fee.get(); // "Are you sure you want to send... ?"
wallet_rpc->relay_tx(*created_tx); // relay the transaction
monero_utils::free(created_tx);

// recipient receives unconfirmed funds within 5 seconds
this_thread::sleep_for(chrono::seconds(5));
assert(FUNDS_RECEIVED);

// save and close wallet
wallet_full->close(true);
delete wallet_full;
delete wallet_rpc;
delete daemon;

Documentation

Using monero-cpp in your project

This project may be compiled as part of another application or built as a shared or static library.

For example, monero-java compiles this project to a shared library to support Java JNI bindings, while monero-ts compiles this project to WebAssembly binaries.

Linux

  1. Clone the project repository if applicable: git clone --recurse-submodules https://github.com/woodser/monero-cpp.git

  2. Update dependencies: sudo apt update && sudo apt install build-essential cmake pkg-config libssl-dev libzmq3-dev libunbound-dev libsodium-dev libunwind8-dev liblzma-dev libreadline6-dev libexpat1-dev libpgm-dev qttools5-dev-tools libhidapi-dev libusb-1.0-0-dev libprotobuf-dev protobuf-compiler libudev-dev libboost-chrono-dev libboost-date-time-dev libboost-filesystem-dev libboost-locale-dev libboost-program-options-dev libboost-regex-dev libboost-serialization-dev libboost-system-dev libboost-thread-dev python3 ccache doxygen graphviz nettle-dev libevent-dev

  3. Follow instructions to install unbound for Linux to your home directory (e.g. ~/unbound-1.22.0).

    For example, install expat:

    cd ~
    wget https://github.com/libexpat/libexpat/releases/download/R_2_4_8/expat-2.4.8.tar.bz2
    tar -xf expat-2.4.8.tar.bz2
    sudo rm expat-2.4.8.tar.bz2
    cd expat-2.4.8
    ./configure --enable-static --disable-shared
    make
    sudo make install
    cd ../
    

    For example, install unbound:

    cd ~
    wget https://www.nlnetlabs.nl/downloads/unbound/unbound-1.22.0.tar.gz
    tar xzf unbound-1.22.0.tar.gz
    sudo apt update
    sudo apt install -y build-essential
    sudo apt install -y libssl-dev
    sudo apt install -y libexpat1-dev
    sudo apt-get install -y bison
    sudo apt-get install -y flex
    cd unbound-1.22.0
    ./configure --with-libexpat=/usr --with-ssl=/usr --enable-static-exe
    make
    sudo make install
    cd ../
    
  4. Build monero-project, located as a submodule at ./external/monero-project. Install dependencies as needed for your system, then build with: make release-static -j8

  5. Link to this library's source files in your application, or build monero-cpp to a shared library in ./build: ./bin/build_libmonero_cpp.sh

macOS

  1. Clone the project repository if applicable: git clone --recurse-submodules https://github.com/woodser/monero-cpp.git

  2. Build unbound against OpenSSL 3. Boost 1.85 is incompatible with OpenSSL 4, and Homebrew's current unbound requires OpenSSL 4. If Homebrew's unbound is installed, run brew unlink unbound before installing the source build below.

    For example:

    brew install openssl@3 expat
    cd ~
    wget https://nlnetlabs.nl/downloads/unbound/unbound-1.22.0.tar.gz
    tar xzf unbound-1.22.0.tar.gz
    cd ~/unbound-1.22.0
    ./configure --with-ssl="$(brew --prefix openssl@3)" --with-libexpat="$(brew --prefix expat)" --with-libunbound-only --with-libevent=no --enable-static --disable-shared --with-pic
    make
    sudo make install
    
  3. Install any remaining dependencies, using openssl@3 for OpenSSL. When switching OpenSSL installations, remove the old build and external/monero-project/build/release directories first so CMake does not reuse cached headers and libraries.

  4. From the monero-cpp directory, build both monero-project and monero-cpp: ./bin/build_libmonero_cpp.sh. On macOS this selects Homebrew's openssl@3 for both builds. To use another compatible OpenSSL installation, set the OPENSSL_ROOT_DIR environment variable when running the script; extra CMake arguments apply only to monero-cpp.

    To build monero-project separately before linking this library's source files into your application:

    cmake -S external/monero-project -B external/monero-project/build/release \
      -DSTATIC=ON -DBUILD_64=ON -DCMAKE_BUILD_TYPE=Release -DUSE_DEVICE_TREZOR=OFF \
      -DOPENSSL_ROOT_DIR="$(brew --prefix openssl@3)"
    cmake --build external/monero-project/build/release -j6
    

Windows

  1. Download and install MSYS2.

    Note: If the latest version cannot be installed, use a historical version: https://github.com/msys2/msys2-installer/releases/download/2024-12-08/msys2-x86_64-20241208.exe

  2. Press the Windows button and launch MSYS2 MINGW64 for 64-bit systems or MSYS2 MINGW32 for 32-bit.

  3. Update packages: pacman -Syu, confirming at the prompts.

  4. Relaunch MSYS2 (if necessary) and install dependencies:

    For 64-bit:

    pacman -S mingw-w64-x86_64-toolchain mingw-w64-x86_64-cmake mingw-w64-x86_64-openssl mingw-w64-x86_64-zeromq mingw-w64-x86_64-libsodium mingw-w64-x86_64-unbound mingw-w64-x86_64-protobuf mingw-w64-x86_64-expat mingw-w64-x86_64-icu mingw-w64-x86_64-ntldd git make gettext base-devel wget
    # removed from the msys2 mingw64 repo; install the archived packages
    wget https://repo.msys2.org/mingw/mingw64/mingw-w64-x86_64-hidapi-0.15.0-2-any.pkg.tar.zst https://repo.msys2.org/mingw/mingw64/mingw-w64-x86_64-libusb-1.0.30-1-any.pkg.tar.zst
    echo "89fb61549a437d65076a092a367fcb264fc7045ee9ebef48cd81f5a76a5588f8  mingw-w64-x86_64-hidapi-0.15.0-2-any.pkg.tar.zst" | sha256sum -c
    echo "124edc26b009678a4c5e759481a364abf63ed7f2f49a53092e8bd0a47c0c0740  mingw-w64-x86_64-libusb-1.0.30-1-any.pkg.tar.zst" | sha256sum -c
    pacman -U mingw-w64-x86_64-hidapi-0.15.0-2-any.pkg.tar.zst mingw-w64-x86_64-libusb-1.0.30-1-any.pkg.tar.zst
    wget https://repo.msys2.org/mingw/mingw64/mingw-w64-x86_64-boost-1.87.0-3-any.pkg.tar.zst
    echo "241919a5885a9270d0e0937e71cf5e146c2a8cabecc2714f09248350181cb1b6  mingw-w64-x86_64-boost-1.87.0-3-any.pkg.tar.zst" | sha256sum -c
    pacman -U mingw-w64-x86_64-boost-1.87.0-3-any.pkg.tar.zst
    

    For 32-bit:

    pacman -S  mingw-w64-i686-toolchain make mingw-w64-i686-cmake mingw-w64-i686-boost mingw-w64-i686-openssl mingw-w64-i686-zeromq mingw-w64-i686-libsodium mingw-w64-i686-hidapi mingw-w64-i686-unbound mingw-w64-i686-protobuf git mingw-w64-i686-libusb gettext base-devel mingw-w64-i686-icu
    
  5. Clone repo if installing standalone (skip if building as part of another repo like monero-java or monero-ts): git clone --recurse-submodules https://github.com/woodser/monero-cpp.git

  6. In ./external/monero-project/Makefile, add -D USE_DEVICE_TREZOR=OFF to the release-static-win64 target (or release-static-win32 for 32-bit).

  7. Build monero-project, located as a submodule at ./external/monero-project. Install dependencies as needed for your system, then build with:

    For 64-bit: make release-static-win64

    For 32-bit: make release-static-win32

  8. Link to this library's source files in your application, or build monero-cpp to a shared library (libmonero-cpp.dll) in ./build: ./bin/build_libmonero_cpp.sh

Android

The build workflow produces shared and static libraries for arm64-v8a and x86_64 (Android 9/API 28 or later), without hardware wallet support.

For HTTPS daemon connections, set SSL_CERT_FILE to the absolute path of a trusted PEM CA bundle in app-private storage before creating wallet or RPC clients. Bundled OpenSSL does not use Android's Java trust store.

Running sample code and tests

  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 ./

  4. Build with the sample code, scratchpad, and tests enabled: ./bin/build_libmonero_cpp.sh -D BUILD_SAMPLE=ON -D BUILD_SCRATCHPAD=ON -D BUILD_TESTS=ON

    Flags are cached in ./build/CMakeCache.txt, so pass them on every build to change them. Editing the defaults in CMakeLists.txt has no effect once ./build exists.

  5. Run the app, for example: ./build/sample_code

Related projects

License

This project is licensed under MIT.

Donations

If this library has been valuable to you, please consider donating to support its continued development.


46FR1GKVqFNQnDiFkH7AuzbUBrGQwz2VdaXTDD4jcjRE8YkkoTYTmZ2Vohsz9gLSqkj5EM6ai9Q7sBoX4FPPYJdGKQQXPVz

About

A C++ library for using Monero

Resources

Stars

0 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

Languages