Skip to content

Repository files navigation

Monero Python Library

Codacy Badge Codacy Badge Tests

Build Debian Packages Build Windows Package Build MacOS

Pybind Python Docs Matrix

A Python library for creating Monero applications using RPC and Python bindings to monero v0.18.5.3 'Fluorine Fermi'.

  • Supports wallet and daemon RPC clients.
  • Supports client-side wallets using Python 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.

Architecture


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

Sample code

from monero import *

# custom wallet listener implementation
class MyWalletListener(MoneroWalletListener):
    def on_sync_progress(self, height: int, start_height: int, end_height: int, percent_done: float, message: str) -> None:
        pass # feed a progress bar?

    def on_output_received(self, output: MoneroOutputWallet) -> None:
        amount: int = output.amount
        tx_hash: str = output.tx.hash
        is_confirmed: bool = output.tx.is_confirmed
        is_locked: bool = output.tx.is_locked

# connect to daemon
daemon: MoneroDaemon = MoneroDaemonRpc("http://localhost:38081", "superuser", "abctesting123")
height: int = daemon.get_height() # 1523651
txs_in_pool: list[MoneroTx] = daemon.get_tx_pool() # get transactions in the pool

# create wallet from mnemonic phrase using Python bindings to monero-project

wallet_config = MoneroWalletConfig()
wallet_config.path = "sample_wallet_full"
wallet_config.password = "supersecretpassword123"
wallet_config.network_type = MoneroNetworkType.STAGENET
wallet_config.server = MoneroRpcConnection()
wallet_config.server.username = "superuser"
wallet_config.server.password = "abctesting123"
wallet_config.seed = "hefty value scenic..."
wallet_config.restore_height = 573936
wallet_full: MoneroWallet = MoneroWalletFull.create_wallet(wallet_config)

listener: MoneroWalletListener = MyWalletListener()

# synchronize the wallet and receive progress notifications
wallet_full.sync(listener)

# synchronize in the background every 5 seconds
wallet_full.start_syncing(5000)

# receive notifications when funds are received, confirmed, and unlocked
wallet_full.add_listener(listener)

# connect to wallet RPC and open wallet
wallet_rpc: MoneroWallet = MoneroWalletRpc("http://localhost:38083", "rpc_user", "abc123")
wallet_rpc.open_wallet("sample_wallet_rpc", "supersecretpassword123")
primary_address: str = wallet_rpc.get_primary_address() # 555zgduFhmKd2o8rPUz...
balance: int = wallet_rpc.get_balance() # 533648366742
txs: list[MoneroTxWallet] = wallet_rpc.get_txs() # get transactions containing transfers to/from the wallet

# send funds from RPC wallet to full wallet
tx_config = MoneroTxConfig()
tx_config.account_index = 0
tx_config.address = wallet_full.get_address(1, 0)
tx_config.amount = 250000000000 # send 0.25 XMR (denominated in atomic units)
tx_config.relay = False # create transaction and relay to the network if true

created_tx: MoneroTxWallet = wallet_rpc.create_tx(tx_config)
fee: int = created_tx.fee # "Are you sure you want to send... ?"
wallet_rpc.relay_tx(created_tx) # relay the transaction

# save and close wallet
wallet_full.close(True)

Installation

Every release has prebuilt packages attached:

  • Debian and Ubuntu: python3-monero_<version>-1<distro>1_<arch>.deb for bookworm, trixie, jammy and noble on amd64, arm64 and armhf, installed for the system Python 3:
    sudo apt install ./python3-monero_0.9.10-1noble1_amd64.deb
  • macOS and Windows: one wheel per Python version, monero-<version>-<python>-<platform>.whl:
    pip3 install monero-0.9.10-cp313-cp313-win_amd64.whl

On anything else, build it from source.

Building monero-python from source

Linux and macOS

  1. Install build dependencies:

    # Ubuntu/Debian
    
    sudo apt install -y python3-all python3-pip python3-pybind11
  2. Clone the project repository:

    git clone --recurse-submodules https://github.com/libmonero/monero-python.git
  3. Build the monero-cpp submodule (located at ./external/monero-cpp) as a native library by following instructions for your system.

  4. Build monero-python to ./build/:

    cd monero-python
    mkdir -p build
    cd build
    cmake ..
    make
  5. Or build and install monero-python with pip:

    pip3 install . --break-system-packages
  6. Or run build script: ./bin/build_libmonero_python.sh

Faster rebuilds: if ccache is installed it is used automatically for monero and monero-python (pass -DUSE_CCACHE=OFF to cmake to disable it). To use it for monero-cpp as well, build that with -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache.

Debian package

The package is built from debian/ with dpkg-buildpackage, the way CI does it. It installs the build dependencies and some static libraries system wide, so build it in a container of the release you want it for (ubuntu:24.04, ubuntu:22.04, debian:trixie or debian:bookworm).

  1. Install Docker

  2. Clone the repository

    git clone --recursive https://github.com/libmonero/monero-python.git
  3. Build, replacing ubuntu:24.04 with the release you want

    docker run --rm -it -v <MONERO_PYTHON_DIR_FULL_PATH>:/monero-python -w /monero-python ubuntu:24.04 bash -c '
      apt-get update && apt-get install -y dpkg-dev &&
      apt-get build-dep -y ./ &&
      debian/set-version.sh &&
      dpkg-buildpackage --build=binary --no-sign &&
      mkdir -p debian/artifacts && mv ../python3-monero_* debian/artifacts/'
    • MONERO_PYTHON_DIR_FULL_PATH - full path to monero-python directory
    • debian/set-version.sh adds an entry for the version of pyproject.toml to debian/changelog, there is no need to commit it
    • add --jobs=4 to dpkg-buildpackage to build faster, each compiler needs 1 to 2 GB of memory
  4. The package is placed in monero-python/debian/artifacts

Windows

  1. Download and install MSYS2.

  2. Press the Windows button and launch MSYS2 MINGW64.

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

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

    pacman -S mingw-w64-x86_64-toolchain make 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 git gettext base-devel wget
    wget https://repo.msys2.org/mingw/mingw64/mingw-w64-x86_64-icu-78.3-4-any.pkg.tar.zst
    echo "8486a018aca2e56d1fcd2eed2069011f2e1da02e03af72b38916ee06cbe7203f  mingw-w64-x86_64-icu-78.3-4-any.pkg.tar.zst" | sha256sum -c
    pacman -U mingw-w64-x86_64-icu-78.3-4-any.pkg.tar.zst
    # hidapi and libusb were 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.92.0-3-any.pkg.tar.zst
    echo "8d5a7621778e955a52755940fe16ead78c0e57a2ff443418b43c25388df1ba2a  mingw-w64-x86_64-boost-1.92.0-3-any.pkg.tar.zst" | sha256sum -c
    pacman -U mingw-w64-x86_64-boost-1.92.0-3-any.pkg.tar.zst
    wget https://repo.msys2.org/mingw/mingw64/mingw-w64-x86_64-pybind11-2.13.6-2-any.pkg.tar.zst
    echo "5b56ad87bc544336b2d51edb8bb0614f46542571362daf4d7e53bf23120175a1  mingw-w64-x86_64-pybind11-2.13.6-2-any.pkg.tar.zst" | sha256sum -c
    pacman -U mingw-w64-x86_64-pybind11-2.13.6-2-any.pkg.tar.zst
    

    These are the versions CI uses. CI also pins the MinGW toolchain, see build-windows.yml.

  5. Clone repo: git clone --recurse-submodules https://github.com/libmonero/monero-python.git

  6. Build monero-cpp, located as a submodule at ./external/monero-cpp:

    cd external/monero-cpp
    ./bin/build_libmonero_cpp.sh
    cd ../..
    
  7. Build monero-python:

    mkdir -p build &&
    cd build &&
    cmake ..
    cmake --build .
    
  8. Or run build script: ./bin/build_libmonero_python.sh

Use RPC servers in your project:

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

Note

On Windows, first install MSYS2:

  1. Install MSYS2.
  2. Environment variables > System variables > Path > Edit > New > C:\msys64\mingw64\bin

Memory Growth

If you see unrestricted memory growth using monero-python, 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.so.2 then run your app. It has to be the shared library, on Debian and Ubuntu it comes with the libjemalloc2 package. A static .a archive is ignored.

Running Python tests

  1. Install pytest:

    # With PIP
    
    pip3 install pytest pytest-rerunfailures pytest-timeout pytest-cov --break-system-packages
    # System-wide installation Ubuntu/Debian
    
    sudo apt install -y python3-pytest python3-pytest-rerunfailures python3-pytest-timeout python3-pytest-cov
  2. Clone the project repository:

    git clone --recurse-submodules https://github.com/libmonero/monero-python.git
    
    cd monero-python
  3. Setup docker test environment

    docker compose -f tests/docker-compose.yml up -d node_1 node_2 xmr_wallet_1 xmr_wallet_2 xmr_wallet_3
  4. Or start RPC servers locally:

    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 config.ini.

  6. Run all python tests with:

    pytest

    The tests assume the RPC servers of the docker environment. If you started them locally, set IN_CONTAINER=false.

    To run only the unit tests, which need no daemon or wallet RPC server:

    pytest -m unit
  7. Cleanup docker test environment

    docker compose -f tests/docker-compose.yml down -v

Related projects

License

This project is licensed under MIT.

Sponsors

We would like to thank our sponsors for their financial contributions that keep this project up and running!

Monero Community
Monero Community
The maintenance of this project for a first stable release has been generously funded by the Monero Community Crowdfunding System (see proposal).

Donations

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

XMR

84rXAu3QhsfbQ2vbxyoEptbRLZ2gtyL8k2qCeJwM5AU4FcxVDEbLRuxMZD5pXD1TR295Nodn7y9mkjoMemHrnMqa9ZnJTza

Releases

Used by

Contributors

Languages