Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

Monero C++ Library

A C++ library for creating Monero applications using native bindings to monero v0.18.2.2 'Flourine Fermie'.

  • Supports fully client-side wallets by wrapping wallet2.h.
  • 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-javascript using JNI and WebAssembly bindings.

Table of contents

Sample code

// create a wallet from a mnemonic phrase
monero_wallet_config wallet_config;
wallet_config.m_mnemonic = "hefty value later extra artistic firm radar yodel talent future fungal nutshell because sanity awesome nail unjustly rage unafraid cedar delayed thumbs comb custom sanity";
wallet_config.m_path = "MyWalletRestored";
wallet_config.m_password = "supersecretpassword123";
wallet_config.m_network_type = monero_network_type::STAGENET;
wallet_config.m_server_uri = "http://localhost:38081";
wallet_config.m_server_username = "superuser";
wallet_config.m_server_password = "abctesting123";
wallet_config.m_restore_height = 380104;
wallet_config.m_seed_offset = "";
monero_wallet* wallet_restored = 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;

// start syncing the wallet continuously in the background

// get balance, account, subaddresses
string restored_primary = wallet_restored->get_primary_address();
uint64_t balance = wallet_restored->get_balance(); // can specify account and subaddress indices
monero_account account = wallet_restored->get_account(1, true); // get account with subaddresses
uint64_t unlocked_account_balance = account.m_unlocked_balance.get(); // get boost::optional value

// query a transaction by hash
monero_tx_query tx_query;
tx_query.m_hash = "314a0f1375db31cea4dac4e0a51514a6282b43792269b3660166d4d2b46437ca";
shared_ptr<monero_tx_wallet> tx = wallet_restored->get_txs(tx_query)[0];
for (const shared_ptr<monero_transfer> transfer : tx->get_transfers()) {
  bool is_incoming = transfer->is_incoming().get();
  uint64_t in_amount = transfer->m_amount.get();
  int account_index = transfer->m_account_index.get();

// query incoming transfers to account 1
monero_transfer_query transfer_query;
transfer_query.m_is_incoming = true;
transfer_query.m_account_index = 1;
vector<shared_ptr<monero_transfer>> transfers = wallet_restored->get_transfers(transfer_query);

// query unspent outputs
monero_output_query output_query;
output_query.m_is_spent = false;
vector<shared_ptr<monero_output_wallet>> outputs = wallet_restored->get_outputs(output_query);

// create and sync a new wallet with a random mnemonic phrase
wallet_config = monero_wallet_config();
wallet_config.m_path = "MyWalletRandom";
wallet_config.m_password = "supersecretpassword123";
wallet_config.m_network_type = monero_network_type::STAGENET;
wallet_config.m_server_uri = "http://localhost:38081";
wallet_config.m_server_username = "superuser";
wallet_config.m_server_password = "abctesting123";
wallet_config.m_language = "English";
monero_wallet* wallet_random = monero_wallet_full::create_wallet(wallet_config);

// synchronize in the background every 5 seconds

// get wallet info
string random_mnemonic = wallet_random->get_mnemonic();
string random_primary = wallet_random->get_primary_address();
uint64_t random_height = wallet_random->get_height();
bool random_is_synced = wallet_random->is_synced();

// receive notifications when funds are received, confirmed, and unlocked
struct : monero_wallet_listener {
  void on_output_received(const monero_output_wallet& output) {
    cout << "Wallet received funds!" << endl;
    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();
    int account_index = output.m_account_index.get();
    int subaddress_index = output.m_subaddress_index.get();
    FUNDS_RECEIVED = true;
} my_listener;

// send funds from the restored wallet to the random wallet
monero_tx_config tx_config;
tx_config.m_account_index = 0;
tx_config.m_address = wallet_random->get_address(1, 0);
tx_config.m_amount = 50000;
tx_config.m_relay = true;
shared_ptr<monero_tx_wallet> sent_tx = wallet_restored->create_tx(tx_config);
bool in_pool = sent_tx->m_in_tx_pool.get();  // true

// mine with 7 threads to push the network along
int num_threads = 7;
bool is_background = false;
bool ignore_battery = false;
wallet_restored->start_mining(num_threads, is_background, ignore_battery);

// wait for the next block to be added to the chain
uint64_t next_height = wallet_random->wait_for_next_block();

// stop mining

// create config to send funds to multiple destinations in the random wallet
tx_config = monero_tx_config();
tx_config.m_account_index = 1; // withdraw funds from this account
tx_config.m_subaddress_indices = vector<uint32_t>();
tx_config.m_subaddress_indices.push_back(1); // withdraw funds from these subaddresses within the account
tx_config.m_priority = monero_tx_priority::UNIMPORTANT; // no rush
tx_config.m_relay = false; // create transaction and relay to the network if true
vector<shared_ptr<monero_destination>> destinations; // specify the recipients and their amounts
destinations.push_back(make_shared<monero_destination>(wallet_random->get_address(1, 0), 50000));
destinations.push_back(make_shared<monero_destination>(wallet_random->get_address(2, 0), 50000));
tx_config.m_destinations = destinations;

// create the transaction, confirm with the user, and relay to the network
shared_ptr<monero_tx_wallet> created_tx = wallet_restored->create_tx(tx_config);
uint64_t fee = created_tx->m_fee.get(); // "Are you sure you want to send ...?"
wallet_restored->relay_tx(*created_tx); // recipient receives notification within 5 seconds

// save and close the wallets


Using this library 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-javascript compiles this project to WebAssembly binaries.

Building monero-cpp on Mac & Linux

  1. If building this library standalone instead of as a submodule in another project, clone the project repository and update its submodules:
    1. git clone --recurse-submodules
    2. cd ./monero-cpp && ./bin/
  2. Install monero-project dependencies for your system. For example, on Ubuntu:
    1. sudo apt update && sudo apt install build-essential cmake pkg-config libssl-dev libzmq3-dev libsodium-dev libunwind8-dev liblzma-dev libreadline6-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

    2. Install expat (dependency of unbound):

      cd ~
      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
      sudo make install
      cd ../
    3. Install unbound:

      cd ~
      tar xzf unbound-1.17.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.17.0
      ./configure --with-libexpat=/usr --with-ssl=/usr
      sudo make install
      cd ../
  3. export MONERO_CPP=path/to/monero-cpp
  4. cd $MONERO_CPP/external/monero-project
  5. Build monero-project to create .a libraries, e.g.: make release-static -j8
  6. Link to this library's source files in your application or build as a shared library in ./build/: cd $MONERO_CPP && ./bin/

Building libmonero-cpp.dll on Windows

  1. Download and install MSYS2.

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

  3. Update packages: pacman -Syu and confirm at prompts.

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

    For 64 bit:

    pacman -S mingw-w64-x86_64-toolchain make mingw-w64-x86_64-cmake mingw-w64-x86_64-boost mingw-w64-x86_64-openssl mingw-w64-x86_64-zeromq mingw-w64-x86_64-libsodium mingw-w64-x86_64-hidapi mingw-w64-x86_64-unbound mingw-w64-x86_64-protobuf git mingw-w64-x86_64-libusb gettext base-devel

    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
  5. Clone repo if installing standalone (skip if building as part of another repo like monero-java or monero-javascript): git clone --recursive

  6. Update submodules: cd <path/to/monero-cpp> && ./bin/

  7. cd ./external/monero-project

  8. Build monero-project:

    For 64 bit: make release-static-win64

    For 32 bit: make release-static-win32

  9. Build as a shared library to ./build/: cd ../../ && ./bin/

Related projects


This project is licensed under MIT.


If this library brings you value, please consider donating.