From 8e8920222abb57923d268b28548a4880621d2378 Mon Sep 17 00:00:00 2001 From: everoddandeven Date: Tue, 28 Jul 2026 14:11:58 +0200 Subject: [PATCH 1/6] Update docs --- README.md | 25 ++++++++--- docs/mkdocs/docs/en/index.md | 2 +- docs/mkdocs/public/api/connection/index.html | 2 +- docs/mkdocs/public/api/daemon/index.html | 2 +- .../public/api/data_model/daemon/index.html | 2 +- .../public/api/data_model/wallet/index.html | 2 +- docs/mkdocs/public/api/utils/index.html | 2 +- docs/mkdocs/public/api/wallet/index.html | 2 +- docs/mkdocs/public/api/wallet_full/index.html | 2 +- docs/mkdocs/public/index.html | 2 +- docs/mkdocs/public/objects.inv | Bin 13684 -> 13929 bytes docs/mkdocs/public/search/search_index.json | 2 +- docs/mkdocs/public/sitemap.xml | 42 +++++++++--------- docs/mkdocs/public/sitemap.xml.gz | Bin 560 -> 560 bytes docs/monero-spec.drawio | 10 ++--- docs/monero-spec.pdf | Bin 128539 -> 300272 bytes src/python/monero_daemon.pyi | 12 ++--- src/python/monero_rpc_connection.pyi | 4 +- src/python/monero_wallet.pyi | 6 +-- src/python/monero_wallet_rpc.pyi | 6 +-- 20 files changed, 70 insertions(+), 55 deletions(-) diff --git a/README.md b/README.md index c5a23a1..d7c53c4 100644 --- a/README.md +++ b/README.md @@ -8,13 +8,14 @@ [![Build Windows Package](https://github.com/everoddandeven/monero-python/actions/workflows/build-windows.yml/badge.svg?branch=main)](https://github.com/everoddandeven/monero-python/actions/workflows/build-windows.yml) [![Build MacOS](https://github.com/everoddandeven/monero-python/actions/workflows/build-macos.yml/badge.svg)](https://github.com/everoddandeven/monero-python/actions/workflows/build-macos.yml) +[![Pybind](https://img.shields.io/badge/pybind-v2-blue?logo=python&logoColor=white +)](https://github.com/pybind/pybind11) +[![Python](https://img.shields.io/badge/python-3.10_%7C_3.11_%7C_3.12_%7C_3.13_%7C_3.14-blue?logo=python&logoColor=white +)](https://github.com/everoddandeven/monero-python#monero-python-library) +[![Docs](https://img.shields.io/badge/docs-stable-blue?logo=readthedocs) +](https://everoddandeven.github.io/monero-python/mkdocs/public/) [![Matrix](https://img.shields.io/badge/matrix-monero--python-blue?logo=matrix)](https://matrix.to/#/#monero-python:monero.social) -> [!WARNING] -> -> monero-python is currently under maintenance, expect bugs and breaking changes. -> The maintenance of this project has been generously funded by the [Monero CCS](https://ccs.getmonero.org/proposals/everoddandeven-monero-python-maintenance.html). - A Python library for creating Monero applications using RPC and Python bindings to [monero v0.18.5.1 'Fluorine Fermi'](https://github.com/monero-project/monero/tree/v0.18.5.1). * Supports wallet and daemon RPC clients. @@ -249,6 +250,20 @@ For example: `export LD_PRELOAD=/path/to/libjemalloc.a` then run your app. 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 + + 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. 🙏 diff --git a/docs/mkdocs/docs/en/index.md b/docs/mkdocs/docs/en/index.md index 3ecdb70..02f9088 100644 --- a/docs/mkdocs/docs/en/index.md +++ b/docs/mkdocs/docs/en/index.md @@ -9,7 +9,7 @@ Welcome to the Monero Python documentation. The aim of this project is to provide an intuitive and robust way to interact with the Monero cryptocurrency in Python using a clearly defined data model. It provides high level classes representing objects from the Monero environment, like wallets, accounts, addresses and transactions. -Developers can create Monero applications using JSON-RPC or Python bindings to monero v0.18.4.4 'Flourine Fermi'. +Developers can create Monero applications using JSON-RPC or Python bindings to monero v0.18.5.1 'Flourine Fermi'. Contributions can be made via issues and pull requests on GitHub, or communicated via the #monero-python workgroup on Matrix. diff --git a/docs/mkdocs/public/api/connection/index.html b/docs/mkdocs/public/api/connection/index.html index 7c6ac59..95fef21 100644 --- a/docs/mkdocs/public/api/connection/index.html +++ b/docs/mkdocs/public/api/connection/index.html @@ -1 +1 @@ - RPC Connection - Monero Python
Skip to content

RPC Connection

MoneroRpcConnection

Bases: SerializableStruct

Models a connection to a daemon.

password: str | None property

Connection authentication password.

priority: int instance-attribute

Connection priority.

proxy_uri: str | None instance-attribute

Connection proxy address.

response_time: int | None property

Connection response time in milliseconds.

timeout: int instance-attribute

Connection timeout (milliseconds).

uri: str | None instance-attribute

Connection uri.

username: str | None property

Connection authentication username.

zmq_uri: str | None instance-attribute

ZMQ connection uri.

before(c1, c2, current_connection) staticmethod

Compare RPC connections.

Parameters:

Name Type Description Default
c1 MoneroRpcConnection

connection.

required
c2 MoneroRpcConnection

other connection.

required
current_connection MoneroRpcConnection

current connection.

required

Returns:

Type Description
bool

True if c1 comes before c2, False otherwise.

check_connection(timeout_ms=20000)

Check the connection and update online, authentication, and response time status.

Parameters:

Name Type Description Default
timeout_ms int

the maximum response time before considered offline.

20000

Returns:

Type Description
bool

True if there is a change in status, False otherwise.

compare(p1, p2) staticmethod

Compare connection priorities.

Parameters:

Name Type Description Default
p1 int

first priority to check.

required
p2 int

second priority to check.

required

Returns:

Type Description
bool

True if p1 comes before p2, False otherwise.

get_attribute(key)

Returns RPC connection attribute.

Parameters:

Name Type Description Default
key str

attribute key.

required

Returns:

Type Description
str

attribute value.

is_authenticated()

Indicates if the connection is authenticated according to the last call to check_connection().

Note: must call check_connection() manually.

Returns:

Type Description
bool | None

True if authenticated or no authentication required, False if not authenticated, or None if check_connection() has not been called.

is_connected()

Indicates if the connection is connected according to the last call to check_connection().

Note: must call check_connection() manually.

Returns:

Type Description
bool | None

True or False to indicate if connected, or None if check_connection() has not been called.

is_i2p()

Indicates if the connection is a I2P connection.

Returns:

Type Description
bool

True if connection is a I2P connection, False otherwise.

is_onion()

Indicates if the connection is a TOR connection.

Returns:

Type Description
bool

True if connection is a TOR connection, False otherwise.

is_online()

Indicates if the connection is online according to the last call to check_connection().

Note: must call check_connection() manually.

Returns:

Type Description
bool | None

True or False to indicate if online, or None if check_connection() has not been called.

send_binary_request(method, parameters=None)

Send a binary RPC request.

Parameters:

Name Type Description Default
method str

is the path of the binary RPC method to invoke.

required
parameters Optional[object]

are the request parameters (default None).

None

Returns:

Type Description
bytes | None

the request's deserialized binary response.

send_json_request(method, parameters=None)

Send a request to the JSON-RPC API.

Parameters:

Name Type Description Default
method str

is the method to request.

required
parameters Optional[object]

are the request's input parameters (default None).

None

Returns:

Type Description
object | None

the RPC API response as a map.

send_path_request(method, parameters=None)

Send a RPC request to the given path and with the given paramters.

E.g. /get_transactions with params.

Parameters:

Name Type Description Default
method str

is the url path of the request to invoke.

required
parameters Optional[object]

are request parameters sent in the body.

None

Returns:

Type Description
object | None

the request's deserialized response.

set_attribute(key, value)

Set RPC connection attribute.

Parameters:

Name Type Description Default
key str

key attribute.

required
value str

value attribute.

required

set_credentials(username, password)

Set RPC connection credentials.

Parameters:

Name Type Description Default
username str

username used for RPC authentication.

required
password str

passowrd user for RPC authentication.

required
\ No newline at end of file + RPC Connection - Monero Python
Skip to content

RPC Connection

MoneroRpcConnection

Bases: SerializableStruct

Models a connection to a daemon.

password: str | None property

Connection authentication password.

priority: int instance-attribute

Connection priority.

proxy_uri: str | None instance-attribute

Connection proxy address.

response_time: int | None property

Connection response time in milliseconds.

timeout_ms: int instance-attribute

Connection timeout (milliseconds).

uri: str | None instance-attribute

Connection uri.

username: str | None property

Connection authentication username.

zmq_uri: str | None instance-attribute

ZMQ connection uri.

check_connection(timeout_ms=None)

Check the connection and update online, authentication, and response time status.

Parameters:

Name Type Description Default
timeout_ms int|None

the maximum response time before considered offline.

None

Returns:

Type Description
bool

True if there is a change in status, False otherwise.

compare(p1, p2) staticmethod

Compare connection priorities.

Parameters:

Name Type Description Default
p1 int

first priority to check.

required
p2 int

second priority to check.

required

Returns:

Type Description
bool

True if p1 comes before p2, False otherwise.

get_attribute(key)

Returns RPC connection attribute.

Parameters:

Name Type Description Default
key str

attribute key.

required

Returns:

Type Description
str

attribute value.

is_authenticated()

Indicates if the connection is authenticated according to the last call to check_connection().

Note: must call check_connection() manually.

Returns:

Type Description
bool | None

True if authenticated or no authentication required, False if not authenticated, or None if check_connection() has not been called.

is_connected()

Indicates if the connection is connected according to the last call to check_connection().

Note: must call check_connection() manually.

Returns:

Type Description
bool | None

True or False to indicate if connected, or None if check_connection() has not been called.

is_i2p()

Indicates if the connection is a I2P connection.

Returns:

Type Description
bool

True if connection is a I2P connection, False otherwise.

is_onion()

Indicates if the connection is a TOR connection.

Returns:

Type Description
bool

True if connection is a TOR connection, False otherwise.

is_online()

Indicates if the connection is online according to the last call to check_connection().

Note: must call check_connection() manually.

Returns:

Type Description
bool | None

True or False to indicate if online, or None if check_connection() has not been called.

send_binary_request(method, parameters=None, timeout_ms=None)

Send a binary RPC request.

Parameters:

Name Type Description Default
method str

is the path of the binary RPC method to invoke.

required
parameters Optional[object]

are the request parameters (default None).

None
timeout_ms Optional[int]

request timeout in milliseconds.

None

Returns:

Type Description
bytes | None

the request's deserialized binary response.

send_json_request(method, parameters=None, timeout_ms=None)

Send a request to the JSON-RPC API.

Parameters:

Name Type Description Default
method str

is the method to request.

required
parameters Optional[object]

are the request's input parameters (default None).

None
timeout_ms Optional[int]

request timeout in milliseconds.

None

Returns:

Type Description
object | None

the RPC API response as a map.

send_path_request(method, parameters=None, timeout_ms=None)

Send a RPC request to the given path and with the given paramters.

E.g. /get_transactions with params.

Parameters:

Name Type Description Default
method str

is the url path of the request to invoke.

required
parameters Optional[object]

are request parameters sent in the body.

None
timeout_ms Optional[int]

request timeout in milliseconds.

None

Returns:

Type Description
object | None

the request's deserialized response.

set_attribute(key, value)

Set RPC connection attribute.

Parameters:

Name Type Description Default
key str

key attribute.

required
value str

value attribute.

required

set_credentials(username, password)

Set RPC connection credentials.

Parameters:

Name Type Description Default
username str

username used for RPC authentication.

required
password str

passowrd user for RPC authentication.

required
\ No newline at end of file diff --git a/docs/mkdocs/public/api/daemon/index.html b/docs/mkdocs/public/api/daemon/index.html index 6ed0dab..d7451a6 100644 --- a/docs/mkdocs/public/api/daemon/index.html +++ b/docs/mkdocs/public/api/daemon/index.html @@ -1 +1 @@ - Daemon Interface - Monero Python
Skip to content

Daemon Interface

MoneroDaemon

Monero daemon interface.

__init__()

Initialize a Monero daemon.

add_listener(listener)

Register a listener to receive daemon notifications.

Parameters:

Name Type Description Default
listener MoneroDaemonListener

the listener to register.

required

check_for_update()

Check for update.

Returns:

Type Description
MoneroDaemonUpdateCheckResult

the result of the update check.

download_update(path='')

Download an update.

Parameters:

Name Type Description Default
path str

download path.

''

Returns:

Type Description
MoneroDaemonUpdateDownloadResult

the result of the update download.

get_alt_block_hashes()

Get known block hashes which are not on the main chain.

Returns:

Type Description
list[str]

known block hashes which are not on the main chain.

get_alt_chains()

Get alternative chains seen by the node.

Returns:

Type Description
list[MoneroAltChain]

alternative chains seen by the node.

get_block_by_hash(hash)

Get a block by hash.

Parameters:

Name Type Description Default
hash str

is the hash of the block to get.

required

Returns:

Type Description
MoneroBlock

the block with the given hash.

get_block_by_height(height)

Get a block by height.

Parameters:

Name Type Description Default
height int

is the height of the block to get.

required

Returns:

Type Description
MoneroBlock

the block at the given height.

get_block_hash(height)

Get a block's hash by its height.

Parameters:

Name Type Description Default
height int

is the height of the block hash to get.

required

Returns:

Type Description
str

the block's hash at the given height.

get_block_hashes(block_hashes, start_height)

Get block hashes as a binary request to the daemon.

Parameters:

Name Type Description Default
block_hashes list[str]

specify block hashes to fetch; first 10 blocks hash goes sequential, next goes in pow(2,n) offset, like 2, 4, 8, 16, 32, 64 and so on, and the last one is always genesis block.

required
start_height int

is the starting height of block hashes to return.

required

Returns:

Type Description
list[str]

the requested block hashes.

get_block_header_by_hash(hash)

Get a block header by its hash.

Parameters:

Name Type Description Default
hash str

is the hash of the block to get the header of.

required

Returns:

Type Description
MoneroBlockHeader

the block's header.

get_block_header_by_height(height)

Get a block header by its height.

Parameters:

Name Type Description Default
height int

is the height of the block to get the header of.

required

Returns:

Type Description
MoneroBlockHeader

the block's header.

get_block_headers_by_range(start_height, end_height)

Get block headers for the given range.

Parameters:

Name Type Description Default
start_height int

is the start height lower bound inclusive (optional).

required
end_height int

is the end height upper bound inclusive (optional).

required

Returns:

Type Description
list[MoneroBlockHeader]

block headers in the given range.

get_block_template(wallet_address, reserve_size=None)

Get a block template for mining a new block.

Parameters:

Name Type Description Default
wallet_address str

is the address of the wallet to receive miner transactions if block is successfully mined.

required

Returns:

Type Description
MoneroBlockTemplate

a block template for mining a new block.

get_blocks_by_hash(block_hashes, start_height, prune)

Get a block by hash.

Parameters:

Name Type Description Default
block_hashes list[str]

is the hash of the block to get.

required
start_height int

filter blocks by block height.

required
prune bool

prune hash.

required

Returns:

Type Description
list[MoneroBlock]

the block with the given hash.

get_blocks_by_height(heights)

Get blocks at the given heights.

Parameters:

Name Type Description Default
heights list[int]

are the heights of the blocks to get.

required

Returns:

Type Description
list[MoneroBlock]

blocks at the given heights.

get_blocks_by_range(start_height, end_height)

Get blocks in the given height range.

Parameters:

Name Type Description Default
start_height int

is the start height lower bound inclusive (optional).

required
end_height int

is the end height upper bound inclusive (optional).

required

Returns:

Type Description
list[MoneroBlock]

blocks in the given height range.

get_blocks_by_range_chunked(start_height, end_height, max_chunk_size=None)

Get blocks in the given height range as chunked requests so that each request is not too big.

Parameters:

Name Type Description Default
start_height int

is the start height lower bound inclusive (optional).

required
end_height int

is the end height upper bound inclusive (optional).

required
max_chunk_size int

is the maximum chunk size in any one request (default 3,000,000 bytes).

None

Returns:

Type Description
list[MoneroBlock]

blocks in the given height range.

get_download_limit()

Get the download bandwidth limit.

Returns:

Type Description
int

is the download bandwidth limit.

get_fee_estimate(grace_blocks=0)

Get mining fee estimates per kB.

Parameters:

Name Type Description Default
grace_blocks int

number of blocks we want the fee estimate to be valid for.

0

Returns:

Type Description
MoneroFeeEstimate

mining fee estimates per kB.

get_hard_fork_info()

Look up information regarding hard fork voting and readiness.

Returns:

Type Description
MoneroHardForkInfo

hard fork information.

get_height()

Get the number of blocks in the longest chain known to the node.

Returns:

Type Description
int

the number of blocks.

get_info()

Get general information about the state of the node and the network.

Returns:

Type Description
MoneroDaemonInfo

general information about the node and network.

get_key_image_spent_status(key_image)

Get the spent status of the given key image.

Parameters:

Name Type Description Default
key_image str

is key image hex to get the status of.

required

Returns:

Type Description
MoneroKeyImageSpentStatus

the status of the key image.

get_key_image_spent_statuses(key_images)

Get the spent status of each given key image.

Parameters:

Name Type Description Default
key_images list[str]

are hex key images to get the statuses of.

required

Returns:

Type Description
list[MoneroKeyImageSpentStatus]

the spent status for each key image.

get_known_peers()

Get all known peers including their last known online status.

Returns:

Type Description
list[MoneroPeer]

the daemon's known peers.

get_last_block_header()

Get the last block's header.

Returns:

Type Description
MoneroBlockHeader

the last block's header.

get_listeners()

Get the listeners registered with the daemon.

Returns:

Type Description
list[MoneroDaemonListener]

the registered listeners.

get_miner_tx_sum(height, num_blocks)

Gets the total emissions and fees from the genesis block to the current height.

Parameters:

Name Type Description Default
height int

is the height to start computing the miner sum.

required
num_blocks int

are the number of blocks to include in the sum.

required

Returns:

Type Description
MoneroMinerTxSum

the sum emission and fees since the geneis block.

get_mining_status()

Get the daemon's mining status.

Returns:

Type Description
MoneroMiningStatus

the daemon's mining status.

get_output_distribution(amounts, is_cumulative=None, start_height=None, end_height=None)

Creates an output distribution.

Parameters:

Name Type Description Default
amounts list[int]

are amounts of outputs to make the distribution with.

required

Returns:

Type Description
list[MoneroOutputDistributionEntry]

output distribution entries meeting the parameters.

get_output_histogram(amounts, min_count, max_count, is_unlocked, recent_cutoff)

Get a histogram of output amounts. For all amounts (possibly filtered by parameters), gives the number of outputs on the chain for that amount. RingCT outputs counts as 0 amount.

Parameters:

Name Type Description Default
amounts list[int]

are amounts of outputs to make the histogram with (atomic-units).

required
min_count Optional[int]

filter amounts with at least this number of outputs.

required
max_count Optional[int]

filter amounts with at most this number of outputs.

required
is_unlocked Optional[bool]

makes a histogram with outputs with the specified lock state.

required
recent_cutoff Optional[int]

exclude outputs from older than this timestamp.

required

Returns:

Type Description
list[MoneroOutputHistogramEntry]

output histogram entries meeting the parameters.

get_outputs(outputs)

Get outputs identified by a list of output amounts and indices as a binary request.

Parameters:

Name Type Description Default
outputs list[MoneroOutput]

identify each output by amount and index.

required

Returns:

Type Description
list[MoneroOutput]

the identified outputs.

get_peer_bans()

Get peer bans.

Returns:

Type Description
list[MoneroBan]

entries about banned peers.

get_peers()

Get peers with active incoming or outgoing connections to the node.

Returns:

Type Description
list[MoneroPeer]

the daemon's peers.

get_sync_info()

Get synchronization information.

Returns:

Type Description
MoneroDaemonSyncInfo

contains sync information.

get_tx(tx_hash, prune=False)

Get a transaction by hash.

Parameters:

Name Type Description Default
tx_hash str

is the hash of the transaction to get.

required
prune bool

specifies if the returned tx should be pruned (defaults to False).

False

Returns:

Type Description
MoneroTx | None

the transaction with the given hash or null if not found.

get_tx_hex(tx_hash, prune=False)

Get a transaction hex by hash.

Parameters:

Name Type Description Default
tx_hash str

is the hash of the transaction to get hex from.

required
prune bool

specifies if the returned tx hex should be pruned (defaults to False).

False

Returns:

Type Description
str | None

the tx hex with the given hash.

get_tx_hexes(tx_hashes, prune=False)

Get transaction hexes by hashes.

Parameters:

Name Type Description Default
tx_hashes list[str]

are hashes of transactions to get hexes from

required
prune bool

Prune transaction hashes.

False

Returns:

Type Description
list[str]

are the tx hexes.

get_tx_pool()

Get valid transactions seen by the node but not yet mined into a block, as well as spent key image information for the tx pool.

Returns:

Type Description
list[MoneroTx]

transactions in the transaction pool.

get_tx_pool_backlog()

Get all transaction pool backlog.

Returns:

Type Description
list[MoneroTxBacklogEntry]

transaction pool backlog entries.

get_tx_pool_hashes()

Get hashes of transactions in the transaction pool.

Returns:

Type Description
list[str]

hashes of transactions in the transaction pool.

get_tx_pool_stats()

Get transaction pool statistics.

Returns:

Type Description
MoneroTxPoolStats

statistics about the transaction pool.

get_txs(tx_hashes, prune=False)

Get transactions by hashes.

Parameters:

Name Type Description Default
tx_hashes list[str]

are hashes of transactions to get.

required
prune bool

Prune transactions.

False

Returns:

Type Description
list[MoneroTx]

found transactions with the given hashes.

get_upload_limit()

Get the upload bandwidth limit.

Returns:

Type Description
int

is the upload bandwidth limit.

get_version()

Gets the version of the daemon.

Returns:

Type Description
MoneroVersion

the version of the daemon.

is_trusted()

Indicates if the daemon is trusted or untrusted.

Returns:

Type Description
bool

True if the daemon is trusted, False otherwise.

prune_blockchain(check)

Prune the blockchain.

Parameters:

Name Type Description Default
check bool

specifies to check the pruning (default False).

required

Returns:

Type Description
MoneroPruneResult

the prune result.

relay_tx_by_hash(tx_hash)

Relays a transaction by hash.

Parameters:

Name Type Description Default
tx_hash str

identifies the transaction to relay.

required

relay_txs_by_hash(tx_hashes)

Relays transactions by hash.

Parameters:

Name Type Description Default
tx_hashes list[str]

identify the transactions to relay.

required

remove_listener(listener)

Unregister a listener to receive daemon notifications.

Parameters:

Name Type Description Default
listener MoneroDaemonListener

a previously registered listener to be unregistered.

required

reset_download_limit()

Reset the download bandwidth limit.

Returns:

Type Description
int

the download bandwidth limit after resetting.

reset_upload_limit()

Reset the upload bandwidth limit.

Returns:

Type Description
int

the upload bandwidth limit after resetting.

set_download_limit(limit)

Set the download bandwidth limit.

Parameters:

Name Type Description Default
limit int

is the download limit to set (-1 to reset to default).

required

Returns:

Type Description
int

is the new download limit after setting.

set_incoming_peer_limit(limit)

Limit number of incoming peers.

Parameters:

Name Type Description Default
limit int

is the maximum number of incoming peers.

required

set_outgoing_peer_limit(limit)

Limit number of outgoing peers.

Parameters:

Name Type Description Default
limit int

is the maximum number of outgoing peers.

required

set_peer_ban(ban)

Ban a peer node.

Parameters:

Name Type Description Default
ban MoneroBan

contains information about a node to ban.

required

set_peer_bans(bans)

Ban peers nodes.

Parameters:

Name Type Description Default
bans list[MoneroBan]

are bans to apply against peer nodes.

required

set_upload_limit(limit)

Set the upload bandwidth limit.

Parameters:

Name Type Description Default
limit int

is the upload limit to set (-1 to reset to default).

required

Returns:

Type Description
int

is the new upload limit after setting.

start_mining(address, num_threads, is_background, ignore_battery)

Start mining.

Parameters:

Name Type Description Default
address str

is the address given miner rewards if the daemon mines a block.

required
num_threads int

is the number of mining threads to run.

required
is_background bool

specifies if the miner should run in the background or not.

required
ignore_battery bool

specifies if the battery state (e.g. on laptop) should be ignored or not.

required

stop()

Safely disconnect and shut down the daemon.

stop_mining()

Stop mining.

submit_block(block_blob)

Submit a mined block to the network.

Parameters:

Name Type Description Default
block_blob str

is the mined block to submit.

required

submit_blocks(block_blobs)

Submit mined blocks to the network.

Parameters:

Name Type Description Default
block_blobs list[str]

are the mined blocks to submit.

required

submit_tx_hex(tx_hex, do_not_relay=False)

Submits a transaction to the daemon's pool.

Parameters:

Name Type Description Default
tx_hex str

is the raw transaction hex to submit.

required

Returns:

Type Description
MoneroSubmitTxResult

the submission results.

wait_for_next_block_header()

Get the header of the next block added to the chain.

Returns:

Type Description
MoneroBlockHeader

the header of the next block added to the chain.

\ No newline at end of file + Daemon Interface - Monero Python
Skip to content

Daemon Interface

MoneroDaemon

Monero daemon interface.

__init__()

Initialize a Monero daemon.

add_listener(listener)

Register a listener to receive daemon notifications.

Parameters:

Name Type Description Default
listener MoneroDaemonListener

the listener to register.

required

check_for_update()

Check for update.

Returns:

Type Description
MoneroDaemonUpdateCheckResult

the result of the update check.

download_update(path='')

Download an update.

Parameters:

Name Type Description Default
path str

download path.

''

Returns:

Type Description
MoneroDaemonUpdateDownloadResult

the result of the update download.

generate_blocks(wallet_address, num_blocks, prev_block_hash=None, starting_nonce=None)

Generate blocks to a wallet address (regtest only).

Parameters:

Name Type Description Default
wallet_address str

is the address of the wallet to receive miner transactions if block is successfully mined.

required
num_blocks int

is the number of blocks to generate.

required
prev_block_hash str|None

is the hash of the previous block to build on top of (optional, builds on the current tip if not given).

None
starting_nonce int|None

is the starting nonce to use (optional).

None

Returns:

Type Description
MoneroGenerateBlocksResult

the result of generating blocks; height is the height of the last block generated.

get_alt_block_hashes()

Get known block hashes which are not on the main chain.

Returns:

Type Description
list[str]

known block hashes which are not on the main chain.

get_alt_chains()

Get alternative chains seen by the node.

Returns:

Type Description
list[MoneroAltChain]

alternative chains seen by the node.

get_block_by_hash(hash)

Get a block by hash.

Parameters:

Name Type Description Default
hash str

is the hash of the block to get.

required

Returns:

Type Description
MoneroBlock

the block with the given hash.

get_block_by_height(height)

Get a block by height.

Parameters:

Name Type Description Default
height int

is the height of the block to get.

required

Returns:

Type Description
MoneroBlock

the block at the given height.

get_block_hash(height)

Get a block's hash by its height.

Parameters:

Name Type Description Default
height int

is the height of the block hash to get.

required

Returns:

Type Description
str

the block's hash at the given height.

get_block_hashes(block_hashes, start_height)

Get block hashes as a binary request to the daemon.

Parameters:

Name Type Description Default
block_hashes list[str]

specify block hashes to fetch; first 10 blocks hash goes sequential, next goes in pow(2,n) offset, like 2, 4, 8, 16, 32, 64 and so on, and the last one is always genesis block.

required
start_height int

is the starting height of block hashes to return.

required

Returns:

Type Description
list[str]

the requested block hashes.

get_block_header_by_hash(hash)

Get a block header by its hash.

Parameters:

Name Type Description Default
hash str

is the hash of the block to get the header of.

required

Returns:

Type Description
MoneroBlockHeader

the block's header.

get_block_header_by_height(height)

Get a block header by its height.

Parameters:

Name Type Description Default
height int

is the height of the block to get the header of.

required

Returns:

Type Description
MoneroBlockHeader

the block's header.

get_block_headers_by_range(start_height, end_height)

Get block headers for the given range.

Parameters:

Name Type Description Default
start_height int

is the start height lower bound inclusive (optional).

required
end_height int

is the end height upper bound inclusive (optional).

required

Returns:

Type Description
list[MoneroBlockHeader]

block headers in the given range.

get_block_template(wallet_address, reserve_size=None)

Get a block template for mining a new block.

Parameters:

Name Type Description Default
wallet_address str

is the address of the wallet to receive miner transactions if block is successfully mined.

required
reserve_size int|None

is the reserve size (optional).

None

Returns:

Type Description
MoneroBlockTemplate

a block template for mining a new block.

get_blocks_by_hash(block_hashes, start_height, prune)

Get a block by hash.

Parameters:

Name Type Description Default
block_hashes list[str]

is the hash of the block to get.

required
start_height int

filter blocks by block height.

required
prune bool

prune hash.

required

Returns:

Type Description
list[MoneroBlock]

the block with the given hash.

get_blocks_by_height(heights)

Get blocks at the given heights.

Parameters:

Name Type Description Default
heights list[int]

are the heights of the blocks to get.

required

Returns:

Type Description
list[MoneroBlock]

blocks at the given heights.

get_blocks_by_range(start_height, end_height)

Get blocks in the given height range.

Parameters:

Name Type Description Default
start_height int

is the start height lower bound inclusive (optional).

required
end_height int

is the end height upper bound inclusive (optional).

required

Returns:

Type Description
list[MoneroBlock]

blocks in the given height range.

get_blocks_by_range_chunked(start_height, end_height, max_chunk_size=None)

Get blocks in the given height range as chunked requests so that each request is not too big.

Parameters:

Name Type Description Default
start_height int

is the start height lower bound inclusive (optional).

required
end_height int

is the end height upper bound inclusive (optional).

required
max_chunk_size int

is the maximum chunk size in any one request (default 3,000,000 bytes).

None

Returns:

Type Description
list[MoneroBlock]

blocks in the given height range.

get_download_limit()

Get the download bandwidth limit.

Returns:

Type Description
int

is the download bandwidth limit.

get_fee_estimate(grace_blocks=0)

Get mining fee estimates per kB.

Parameters:

Name Type Description Default
grace_blocks int

number of blocks we want the fee estimate to be valid for.

0

Returns:

Type Description
MoneroFeeEstimate

mining fee estimates per kB.

get_hard_fork_info()

Look up information regarding hard fork voting and readiness.

Returns:

Type Description
MoneroHardForkInfo

hard fork information.

get_height()

Get the number of blocks in the longest chain known to the node.

Returns:

Type Description
int

the number of blocks.

get_info()

Get general information about the state of the node and the network.

Returns:

Type Description
MoneroDaemonInfo

general information about the node and network.

get_key_image_spent_status(key_image)

Get the spent status of the given key image.

Parameters:

Name Type Description Default
key_image str

is key image hex to get the status of.

required

Returns:

Type Description
MoneroKeyImageSpentStatus

the status of the key image.

get_key_image_spent_statuses(key_images)

Get the spent status of each given key image.

Parameters:

Name Type Description Default
key_images list[str]

are hex key images to get the statuses of.

required

Returns:

Type Description
list[MoneroKeyImageSpentStatus]

the spent status for each key image.

get_known_peers()

Get all known peers including their last known online status.

Returns:

Type Description
list[MoneroPeer]

the daemon's known peers.

get_last_block_header()

Get the last block's header.

Returns:

Type Description
MoneroBlockHeader

the last block's header.

get_listeners()

Get the listeners registered with the daemon.

Returns:

Type Description
list[MoneroDaemonListener]

the registered listeners.

get_miner_tx_sum(height, num_blocks)

Gets the total emissions and fees from the genesis block to the current height.

Parameters:

Name Type Description Default
height int

is the height to start computing the miner sum.

required
num_blocks int

are the number of blocks to include in the sum.

required

Returns:

Type Description
MoneroMinerTxSum

the sum emission and fees since the geneis block.

get_mining_status()

Get the daemon's mining status.

Returns:

Type Description
MoneroMiningStatus

the daemon's mining status.

get_output_distribution(amounts, is_cumulative=None, start_height=None, end_height=None)

Creates an output distribution.

Parameters:

Name Type Description Default
amounts list[int]

are amounts of outputs to make the distribution with.

required
is_cumulative bool|None

specifies if the results should be cumulative (optional).

None
start_height int|None

is the start height lower bound inclusive (optional).

None
end_height int|None

is the end height upper bound inclusive (optional).

None

Returns:

Type Description
list[MoneroOutputDistributionEntry]

output distribution entries meeting the parameters.

get_output_histogram(amounts, min_count, max_count, is_unlocked, recent_cutoff)

Get a histogram of output amounts. For all amounts (possibly filtered by parameters), gives the number of outputs on the chain for that amount. RingCT outputs counts as 0 amount.

Parameters:

Name Type Description Default
amounts list[int]

are amounts of outputs to make the histogram with (atomic-units).

required
min_count Optional[int]

filter amounts with at least this number of outputs.

required
max_count Optional[int]

filter amounts with at most this number of outputs.

required
is_unlocked Optional[bool]

makes a histogram with outputs with the specified lock state.

required
recent_cutoff Optional[int]

exclude outputs from older than this timestamp.

required

Returns:

Type Description
list[MoneroOutputHistogramEntry]

output histogram entries meeting the parameters.

get_outputs(outputs)

Get outputs identified by a list of output amounts and indices as a binary request.

Parameters:

Name Type Description Default
outputs list[MoneroOutput]

identify each output by amount and index.

required

Returns:

Type Description
list[MoneroOutput]

the identified outputs.

get_peer_bans()

Get peer bans.

Returns:

Type Description
list[MoneroBan]

entries about banned peers.

get_peers()

Get peers with active incoming or outgoing connections to the node.

Returns:

Type Description
list[MoneroPeer]

the daemon's peers.

get_sync_info()

Get synchronization information.

Returns:

Type Description
MoneroDaemonSyncInfo

contains sync information.

get_tx(tx_hash, prune=False)

Get a transaction by hash.

Parameters:

Name Type Description Default
tx_hash str

is the hash of the transaction to get.

required
prune bool

specifies if the returned tx should be pruned (defaults to False).

False

Returns:

Type Description
MoneroTx | None

the transaction with the given hash or null if not found.

get_tx_hex(tx_hash, prune=False)

Get a transaction hex by hash.

Parameters:

Name Type Description Default
tx_hash str

is the hash of the transaction to get hex from.

required
prune bool

specifies if the returned tx hex should be pruned (defaults to False).

False

Returns:

Type Description
str | None

the tx hex with the given hash.

get_tx_hexes(tx_hashes, prune=False)

Get transaction hexes by hashes.

Parameters:

Name Type Description Default
tx_hashes list[str]

are hashes of transactions to get hexes from

required
prune bool

Prune transaction hashes.

False

Returns:

Type Description
list[str]

are the tx hexes.

get_tx_pool()

Get valid transactions seen by the node but not yet mined into a block, as well as spent key image information for the tx pool.

Returns:

Type Description
list[MoneroTx]

transactions in the transaction pool.

get_tx_pool_backlog()

Get all transaction pool backlog.

Returns:

Type Description
list[MoneroTxBacklogEntry]

transaction pool backlog entries.

get_tx_pool_hashes()

Get hashes of transactions in the transaction pool.

Returns:

Type Description
list[str]

hashes of transactions in the transaction pool.

get_tx_pool_stats()

Get transaction pool statistics.

Returns:

Type Description
MoneroTxPoolStats

statistics about the transaction pool.

get_txs(tx_hashes, prune=False)

Get transactions by hashes.

Parameters:

Name Type Description Default
tx_hashes list[str]

are hashes of transactions to get.

required
prune bool

Prune transactions.

False

Returns:

Type Description
list[MoneroTx]

found transactions with the given hashes.

get_upload_limit()

Get the upload bandwidth limit.

Returns:

Type Description
int

is the upload bandwidth limit.

get_version()

Gets the version of the daemon.

Returns:

Type Description
MoneroVersion

the version of the daemon.

is_trusted()

Indicates if the daemon is trusted or untrusted.

Returns:

Type Description
bool

True if the daemon is trusted, False otherwise.

prune_blockchain(check)

Prune the blockchain.

Parameters:

Name Type Description Default
check bool

specifies to check the pruning (default False).

required

Returns:

Type Description
MoneroPruneResult

the prune result.

relay_tx_by_hash(tx_hash)

Relays a transaction by hash.

Parameters:

Name Type Description Default
tx_hash str

identifies the transaction to relay.

required

relay_txs_by_hash(tx_hashes)

Relays transactions by hash.

Parameters:

Name Type Description Default
tx_hashes list[str]

identify the transactions to relay.

required

remove_listener(listener)

Unregister a listener to receive daemon notifications.

Parameters:

Name Type Description Default
listener MoneroDaemonListener

a previously registered listener to be unregistered.

required

reset_download_limit()

Reset the download bandwidth limit.

Returns:

Type Description
int

the download bandwidth limit after resetting.

reset_upload_limit()

Reset the upload bandwidth limit.

Returns:

Type Description
int

the upload bandwidth limit after resetting.

set_download_limit(limit)

Set the download bandwidth limit.

Parameters:

Name Type Description Default
limit int

is the download limit to set (-1 to reset to default).

required

Returns:

Type Description
int

is the new download limit after setting.

set_incoming_peer_limit(limit)

Limit number of incoming peers.

Parameters:

Name Type Description Default
limit int

is the maximum number of incoming peers.

required

set_outgoing_peer_limit(limit)

Limit number of outgoing peers.

Parameters:

Name Type Description Default
limit int

is the maximum number of outgoing peers.

required

set_peer_ban(ban)

Ban a peer node.

Parameters:

Name Type Description Default
ban MoneroBan

contains information about a node to ban.

required

set_peer_bans(bans)

Ban peers nodes.

Parameters:

Name Type Description Default
bans list[MoneroBan]

are bans to apply against peer nodes.

required

set_upload_limit(limit)

Set the upload bandwidth limit.

Parameters:

Name Type Description Default
limit int

is the upload limit to set (-1 to reset to default).

required

Returns:

Type Description
int

is the new upload limit after setting.

start_mining(address, num_threads, is_background, ignore_battery)

Start mining.

Parameters:

Name Type Description Default
address str

is the address given miner rewards if the daemon mines a block.

required
num_threads int

is the number of mining threads to run.

required
is_background bool

specifies if the miner should run in the background or not.

required
ignore_battery bool

specifies if the battery state (e.g. on laptop) should be ignored or not.

required

stop()

Safely disconnect and shut down the daemon.

stop_mining()

Stop mining.

submit_block(block_blob)

Submit a mined block to the network.

Parameters:

Name Type Description Default
block_blob str

is the mined block to submit.

required

submit_blocks(block_blobs)

Submit mined blocks to the network.

Parameters:

Name Type Description Default
block_blobs list[str]

are the mined blocks to submit.

required

submit_tx_hex(tx_hex, do_not_relay=False)

Submits a transaction to the daemon's pool.

Parameters:

Name Type Description Default
tx_hex str

is the raw transaction hex to submit.

required

Returns:

Type Description
MoneroSubmitTxResult

the submission results.

wait_for_next_block_header()

Get the header of the next block added to the chain.

Returns:

Type Description
MoneroBlockHeader

the header of the next block added to the chain.

\ No newline at end of file diff --git a/docs/mkdocs/public/api/data_model/daemon/index.html b/docs/mkdocs/public/api/data_model/daemon/index.html index 5f87ef6..c36df8a 100644 --- a/docs/mkdocs/public/api/data_model/daemon/index.html +++ b/docs/mkdocs/public/api/data_model/daemon/index.html @@ -1 +1 @@ - Daemon Data Model - Monero Python
Skip to content

Daemon Data Model

MoneroNetworkType

Bases: IntEnum

Enumerates a Monero network type_.

.. _Monero network type: https://docs.getmonero.org/infrastructure/networks/

MAINNET = 0 class-attribute instance-attribute

0 indicates Mainnet network_.

.. _Mainnet network: https://docs.getmonero.org/infrastructure/networks/#mainnet

STAGENET = 2 class-attribute instance-attribute

2 indicates Stagenet network_.

.. _Stagenet network: https://docs.getmonero.org/infrastructure/networks/#stagenet

TESTNET = 1 class-attribute instance-attribute

1 indicates Testnet network_.

.. _Testnet network: https://docs.getmonero.org/infrastructure/networks/#testnet

MoneroVersion

Bases: SerializableStruct

Models a Monero version.

is_release: bool | None instance-attribute

States if the monero software version corresponds to an official tagged release (True), or not (False).

number: int | None instance-attribute

Number of the monero software version.

__init__()

Initialize a new Monero version.

MoneroBlockHeader

Bases: SerializableStruct

Models a Monero block header which contains information about the block.

cumulative_difficulty: int | None instance-attribute

Cumulative difficulty of all blocks up to the block in the reply.

depth: int | None instance-attribute

The number of blocks succeeding this block on the blockchain. A larger number means an older block.

difficulty: int | None instance-attribute

The strength of the Monero network based on mining power.

hash: str | None instance-attribute

The hash of this block.

height: int | None instance-attribute

The number of blocks preceding this block on the blockchain.

long_term_weight: int | None instance-attribute

The long term block weight, based on the median weight of the preceding 100000 blocks.

major_version: int | None instance-attribute

The major version of the monero protocol at this block height.

miner_tx_hash: str | None instance-attribute

The hash of this block's coinbase transaction.

minor_version: int | None instance-attribute

The minor version of the monero protocol at this block height.

nonce: int | None instance-attribute

A cryptographic random one-time number used in mining a Monero block.

num_txs: int | None instance-attribute

Number of transactions included in this block.

orphan_status: bool | None instance-attribute

If True, this block is not part of the longest chain.

pow_hash: str | None instance-attribute

The hash, as a hexadecimal string, calculated from the block as proof-of-work.

prev_hash: str | None instance-attribute

The hash of the block immediately preceding this block in the chain.

reward: int | None instance-attribute

The amount of atomic-units rewarded to the miner. The reward is the sum of new coins created (the emission) and fees paid by transactions in this block. Note: 1 XMR = 1e12 atomic-units.

size: int | None instance-attribute

Backward compatibility, same as weight, use that instead.

timestamp: int | None instance-attribute

The unix time at which the block was recorded into the blockchain.

weight: int | None instance-attribute

The adjusted block size, in bytes. This is the raw size, plus a positive adjustment for any Bulletproof transactions with more than 2 outputs.

__init__()

Initialize a Monero block header.

copy()

Copy current block header.

Returns:

Type Description
MoneroBlockHeader

copied block header.

merge(other)

Merge current block header with another one.

Raises:

Type Description
Exception

on reconciliation error.

MoneroBlock

Bases: MoneroBlockHeader

Models a Monero block in the blockchain.

hex: str | None instance-attribute

Hexadecimal blob of block information.

miner_tx: MoneroTx | None instance-attribute

Miner transaction information.

tx_hashes: list[str] instance-attribute

List of hashes of non-coinbase transactions in the block.

txs: list[MoneroTx] instance-attribute

List of non-coinbase transactions in the block.

__init__()

Initialize a Monero block.

copy()

Copy current block.

Returns:

Type Description
MoneroBlock

copied block.

MoneroTx

Bases: SerializableStruct

Models a Monero transaction on the blockchain.

DEFAULT_PAYMENT_ID: str instance-attribute

Default tx payment id

block: MoneroBlock | None instance-attribute

Block including the transaction.

common_tx_sets: str | None instance-attribute

A hexadecimal string representing a set of unsigned transactions, or a set of signing keys used in a multisig transaction.

extra: list[int] instance-attribute

Usually called the payment ID but can be used to include any random 32 bytes.

fee: int | None instance-attribute

The amount of the mining fee included in the transaction, in atomic-units.

full_hex: str | None instance-attribute

Full transaction information as a hex string.

hash: str | None instance-attribute

The transaction hash.

in_tx_pool: bool | None instance-attribute

States if the transaction is in pool (True) or included in a block (False).

inputs: list[MoneroOutput] instance-attribute

List of inputs into transaction.

is_confirmed: bool | None instance-attribute

States if the transaction included in a block (True) or is in pool (False).

is_double_spend_seen: bool | None instance-attribute

States if the transaction is a double-spend (True) or not (False).

is_failed: bool | None instance-attribute

Indicates if the transaction validation has previously failed.

is_kept_by_block: bool | None instance-attribute

States if the transaction was included in a block at least once (True) or not (False).

is_miner_tx: bool | None instance-attribute

States if the transaction is a coinbase-transaction (True) or not (False).

is_relayed: bool | None instance-attribute

States if the transaction was relayed (True) or not (False).

key: str | None instance-attribute

The transaction key.

last_failed_hash: str | None instance-attribute

If the transaction validation has previously failed, this tells the previous transaction hash.

last_failed_height: int | None instance-attribute

If the transaction validation has previously failed, this tells at what height that occurred.

last_relayed_timestamp: int | None instance-attribute

Last unix time at which the transaction has been relayed.

max_used_block_hash: str | None instance-attribute

Tells the hash of the most recent block with an output used in this transaction.

max_used_block_height: int | None instance-attribute

Tells the height of the most recent block with an output used in this transaction.

metadata: str | None instance-attribute

Transaction metadata.

num_confirmations: int | None instance-attribute

Number of network confirmations.

output_indices: list[int] instance-attribute

Transaction indexes.

outputs: list[MoneroOutput] instance-attribute

Transaction outputs.

payment_id: str | None instance-attribute

Payment ID for this transaction.

prunable_hash: str | None instance-attribute

Keccak-256 hash of the prunable portion of the block.

prunable_hex: str | None instance-attribute

Prunable block encoded as a hex string.

pruned_hex: str | None instance-attribute

Pruned block encoded as hex string.

rct_sig_prunable: str | None instance-attribute

Prunable ring signature.

rct_signatures: str | None instance-attribute

Signatures used in ring signature to hide the true origin of the transaction.

received_timestamp: int | None instance-attribute

Unix time at chich the transaction has been received.

relay: bool | None instance-attribute

States if this transaction should be relayed (True) or not (False).

ring_size: int | None instance-attribute

The ring size of this transaction.

signatures: list[str] instance-attribute

List of signatures used in ring signature to hide the true origin of the transaction.

size: int | None instance-attribute

Backward compatibility, same as weight, use that instead.

unlock_time: int | None instance-attribute

If not 0, this tells when the transaction outputs are spendable.

version: int | None instance-attribute

Transaction version.

weight: int | None instance-attribute

The weight of this transaction in bytes.

__init__()

Initialize a new Monero transaction.

copy()

Copy current tx.

Returns:

Type Description
MoneroTx

tx copy.

get_height()

Get the transaction height.

Returns:

Type Description
int | None

The height of the transaction, if known.

merge(other)

Merge current tx with another one.

Parameters:

Name Type Description Default
other MoneroTx

other tx to merge with.

required

MoneroKeyImage

Bases: SerializableStruct

Models a Monero key image.

hex: str | None instance-attribute

The key image in hexadecimal format.

signature: str | None instance-attribute

The key image signature. None if not known.

__init__()

Initialize a Monero key image.

copy()

Copy current key image.

Returns:

Type Description
MoneroKeyImage

key image copy.

deserialize_key_images(key_images_json) staticmethod

Deserialize key images from a JSON string.

Parameters:

Name Type Description Default
key_images_json str

JSON string with serialized key images.

required

Returns:

Type Description
list[MoneroKeyImage]

Deserialized key images.

merge(other)

Merge current key image with another one.

Parameters:

Name Type Description Default
other MoneroKeyImage

other key image to merge with.

required

MoneroOutput

Bases: SerializableStruct

Models a Monero transaction output.

amount: int | None instance-attribute

Output amount in atomic-units.

index: int | None instance-attribute

Output index.

key_image: MoneroKeyImage | None instance-attribute

The key image of the output.

ring_output_indices: list[int] instance-attribute

Indices of ring outputs.

stealth_public_key: str | None instance-attribute

The public key of the output.

tx: MoneroTx instance-attribute

The transaction related to this output.

__init__()

Initialize a Monero output.

copy()

Copy current output.

Returns:

Type Description
MoneroOutput

output copy.

merge(other)

Merge current output wallet with another output.

Parameters:

Name Type Description Default
other MoneroOutput

other output to merge with.

required

MoneroAltChain

Bases: SerializableStruct

Models an alternative chain seen by the node.

block_hashes: list[str] instance-attribute

List of all block hashes in the alternative chain that are not in the main chain.

difficulty: int | None instance-attribute

Cumulative difficulty of all blocks in the alternative chain.

height: int | None instance-attribute

The block height of the first diverging block of this alternative chain.

length: int | None instance-attribute

The length in blocks of this alternative chain, after divergence.

main_chain_parent_block_hash: str | None instance-attribute

The hash of the greatest height block that is shared between the alternative chain and the main chain.

__init__()

Initialize a Monero alt chain info.

MoneroBan

Bases: SerializableStruct

Model a Monero banhammer.

host: str | None instance-attribute

Host ban.

ip: int | None instance-attribute

IP ban.

is_banned: bool | None instance-attribute

Indicates if ban on the host is active (True) or not (False).

seconds: int | None instance-attribute

Indicates the duration of the ban in seconds.

__init__()

Initialize a Monero banhammer.

MoneroPruneResult

Bases: SerializableStruct

Models the result of pruning the blockchain.

is_pruned: bool | None instance-attribute

Indicates if blockchain is pruned.

pruning_seed: int | None instance-attribute

Blockheight at which pruning began.

__init__()

Initialize a Monero prune result.

MoneroMiningStatus

Bases: SerializableStruct

Models a Monero daemon mining status.

address: str | None instance-attribute

Account address daemon is mining to. None if not mining.

is_active: bool | None instance-attribute

Indicates if mining is enabled.

is_background: bool | None instance-attribute

Indicates if mining is running in background.

num_threads: int | None instance-attribute

Number of running mining threads.

speed: int | None instance-attribute

Mining power in hashes per seconds.

__init__()

Initialize a Monero daemon mining status.

MoneroMinerTxSum

Bases: SerializableStruct

Model for the sum of miner emissions and fees.

emission_sum: int | None instance-attribute

The new coins emitted in atomic-units.

fee_sum: int | None instance-attribute

The sum of fees in atomic-units.

__init__()

Initialize a Monero miner transaction sum.

MoneroBlockTemplate

Bases: SerializableStruct

Monero block template to mine.

block_hashing_blob: str | None instance-attribute

Blob on which to try to find a valid nonce.

block_template_blob: str | None instance-attribute

Blob on which to try to mine a new block.

difficulty: int | None instance-attribute

Network difficulty.

expected_reward: int | None instance-attribute

Coinbase reward expected to be received if block is successfully mined.

height: int | None instance-attribute

Height on which to mine.

next_seed_hash: str | None instance-attribute

Hash of the next block to use as seed for Random-X proof-of-work.

prev_hash: str | None instance-attribute

Hash of the most recent block on which to mine the next block.

reserved_offset: int | None instance-attribute

Reserved offset.

seed_hash: str | None instance-attribute

Hash of block to use as seed for Random-X proof-of-work.

seed_height: int | None instance-attribute

Height of block to use as seed for Random-X proof-of-work.

__init__()

Initialize a Monero block template.

MoneroConnectionSpan

Bases: SerializableStruct

Monero daemon connection span.

connection_id: str | None instance-attribute

Id of connection

num_blocks: int | None instance-attribute

Number of blocks in this span

rate: int | None instance-attribute

Connection rate

remote_address: str | None instance-attribute

Peer address the node is downloading (or has downloaded) than span from.

size: int | None instance-attribute

Total number of bytes in that span's blocks (including txes).

speed: int | None instance-attribute

Connection speed.

start_height: int | None instance-attribute

Block height of the first block in that span.

__init__()

Initialize a Monero connection span.

MoneroPeer

Bases: SerializableStruct

Models a peer to the daemon.

address: str | None instance-attribute

The peer's address, actually IPv4 & port.

avg_download: int | None instance-attribute

Average bytes of data downloaded by node.

avg_upload: int | None instance-attribute

Average bytes of data uploaded by node.

connection_type: MoneroConnectionType | None instance-attribute

Type of peer connection.

current_download: int | None instance-attribute

Current bytes downloaded by node.

current_upload: int | None instance-attribute

Current bytes uploaded by node.

hash: str | None instance-attribute

Peer hash.

height: int | None instance-attribute

The peer blockchain height.

host: str | None instance-attribute

The peer host.

id: str | None instance-attribute

The node's ID on the network.

is_incoming: bool | None instance-attribute

Indicates if peer is pulling blocks from node.

is_local_host: bool | None instance-attribute

Indicates if peer is localhost.

is_local_ip: bool | None instance-attribute

Indicates if peer has a local ip address.

is_online: bool | None instance-attribute

Indicates if the peer is online.

last_seen_timestamp: int | None instance-attribute

Last activity timestamp of this peer.

live_time: int | None instance-attribute

Length of time the peer has been online.

num_receives: int | None instance-attribute

Total number of messages received from this peer.

num_sends: int | None instance-attribute

Total number of messages sent to this peer.

num_support_flags: int | None instance-attribute

Support flags number.

port: int | None instance-attribute

The port that the node is using to connect to the network.

pruning_seed: int | None instance-attribute

Block height at which pruning began.

receive_idle_time: int | None instance-attribute

Seconds since last data was received from this peer.

rpc_credits_per_hash: int | None instance-attribute

Credits for every hash calculated by client.

rpc_port: int | None instance-attribute

Peer RPC port.

send_idle_time: int | None instance-attribute

Seconds since the last data sent to this peer.

state: str | None instance-attribute

Peer state.

__init__()

Initialize a new Monero peer.

MoneroSubmitTxResult

Bases: MoneroRpcPaymentInfo

Models the result from submitting a tx to a daemon.

has_invalid_input: bool | None instance-attribute

Indicates if the transaction has an invalid input.

has_invalid_output: bool | None instance-attribute

Indicates if the transaction has an invalid output.

has_too_few_outputs: bool | None instance-attribute

Indicates if the transaction has too few outputs.

is_double_spend: bool | None instance-attribute

Indicates if the transaction is double spend.

is_fee_too_low: bool | None instance-attribute

Indicates if the transaction fee is too low.

is_good: bool | None instance-attribute

Indicates if the submission of the transaction was successfull.

is_mixin_too_low: bool | None instance-attribute

Indicates if the transaction mixin count is too low.

is_overspend: bool | None instance-attribute

Indicates if the transaction uses more money than available

is_relayed: bool | None instance-attribute

Indicates if the transaction has been relayed.

is_too_big: bool | None instance-attribute

Indicates if the transaction size is too big.

is_tx_extra_too_big: bool | None instance-attribute

Indicates if the transaction extra size is too big.

reason: str | None instance-attribute

Additional information. Currently empty or Not relayed if transaction was accepted but not relayed.

sanity_check_failed: bool | None instance-attribute

Indicates if the transaction sanity check has failed.

__init__()

Initialize a new submit transaction result.

MoneroTxBacklogEntry

TODO

__init__()

Intialize a new tx backlog entry.

MoneroOutputDistributionEntry

Bases: SerializableStruct

Models a Monero output distribution entry.

amount: int | None instance-attribute

Output amount in atomic-units.

base: int | None instance-attribute

The total number of outputs of amount in the chain before, not including, the block at start_height.

distribution: list[int] instance-attribute

The output distibution.

start_height: int | None instance-attribute

Not necessarily equal to start_height parameter especially for amount = 0 where start_height will be no less than the height of the v4 hardfork.

__init__()

Initialize a Monero output distribution entry.

MoneroOutputHistogramEntry

Bases: SerializableStruct

Models a Monero output histogram entry.

amount: int | None instance-attribute

Output amount in atomic-units.

num_instances: int | None instance-attribute

Number of outputs.

recent_instances: int | None instance-attribute

Number of recent outputs.

unlocked_instances: int | None instance-attribute

Number of unlocked outputs.

__init__()

Initialize a Monero output histogram entry.

MoneroTxPoolStats

Bases: SerializableStruct

Models transaction pool statistics.

bytes_max: int | None instance-attribute

Max transaction size in pool.

bytes_med: int | None instance-attribute

Median transaction size in pool.

bytes_min: int | None instance-attribute

Min transaction size in pool.

bytes_total: int | None instance-attribute

Total size of all transactions in pool.

fee_total: int | None instance-attribute

The sum of the fees for all transactions currently in the transaction pool atomic-units.

histo: dict[int, int] instance-attribute

Txs histogram (key for bytes, value for txs).

histo98pc: int | None instance-attribute

The time 98% of txes are younger than.

num10m: int | None instance-attribute

Number of transactions in pool for more than 10 minutes.

num_double_spends: int | None instance-attribute

Number of double spend transactions.

num_failing: int | None instance-attribute

Number of failing transactions.

num_not_relayed: int | None instance-attribute

Number of non-relayed transactions.

num_txs: int | None instance-attribute

Total number of transactions.

oldest_timestamp: int | None instance-attribute

Unix time of the oldest transaction in the pool.

__init__()

Initialize a Monero transaction pool statistics.

MoneroDaemonUpdateCheckResult

Bases: SerializableStruct

Models the result of checking for a daemon update.

auto_uri: str | None instance-attribute

URL automatically generated by the daemon to download the update.

hash: str | None instance-attribute

Integrity check hash.

is_update_available: bool | None instance-attribute

Indicates if an update is available to download.

user_uri: str | None instance-attribute

Alternative user URI.

version: str | None instance-attribute

Version available for download.

__init__()

Initialize a Monero update check result.

MoneroDaemonUpdateDownloadResult

Bases: MoneroDaemonUpdateCheckResult

Models the result of downloading a daemon update.

download_path: str | None instance-attribute

Path to download the update.

__init__()

Initialize a Monero update download result.

MoneroFeeEstimate

Bases: SerializableStruct

Models a Monero fee estimate.

fee: int | None instance-attribute

Amount of fees estimated per byte in atomic-units.

fees: list[int] instance-attribute

Represents the base fees at different priorities [slow, normal, fast, fastest].

quantization_mask: int | None instance-attribute

Final fee should be rounded up to an even multiple of this value.

__init__()

Initialize a Monero fee estimate.

MoneroDaemonInfo

Bases: MoneroRpcPaymentInfo

Models information got from a Monero daemon.

adjusted_timestamp: int | None instance-attribute

Current time approximated from chain data, as Unix time.

block_size_limit: int | None instance-attribute

Backward compatibility, same as block_weight_limit, use that instead.

block_size_median: int | None instance-attribute

Backward compatibility, same as block_weight_median, use that instead.

block_weight_limit: int | None instance-attribute

Maximum allowed adjusted block size based on latest 100000 blocks.

block_weight_median: int | None instance-attribute

Median adjusted block size of latest 100000 blocks.

bootstrap_daemon_address: str | None instance-attribute

Bootstrap-node to give immediate usability to wallets while syncing by proxying RPC to it.

cumulative_difficulty: int | None instance-attribute

Cumulative difficulty.

database_size: int | None instance-attribute

The size of the blockchain database, in bytes.

difficulty: int | None instance-attribute

The network difficulty.

free_space: int | None instance-attribute

Available disk space on the node.

height: int | None instance-attribute

Current length of longest chain known to daemon.

height_without_bootstrap: int | None instance-attribute

Current length of the local chain of the daemon.

is_busy_syncing: bool | None instance-attribute

States if new blocks are being added (True) or not (False).

is_offline: bool | None instance-attribute

States if the node is offline (True) or online (False).

is_restricted: bool | None instance-attribute

Indicates that the node RPC interface is restricted (True) or not (False).

is_synchronized: bool | None instance-attribute

States if the node is synchronized (True) or not (False).

network_type: MoneroNetworkType | None instance-attribute

Network type (MAINNET, TESTNET, or STAGENET).

num_alt_blocks: int | None instance-attribute

Number of alternative blocks to main chain.

num_incoming_connections: int | None instance-attribute

Number of peers connected to and pulling from your node.

num_offline_peers: int | None instance-attribute

Number of peers that are marked as not reacheable on the network.

num_online_peers: int | None instance-attribute

Number of peers that are marked as reacheble on the network.

num_outgoing_connections: int | None instance-attribute

Number of peers that you are connected to and getting information from.

num_rpc_connections: int | None instance-attribute

Number of RPC client connected to the daemon (Including this RPC request).

num_txs: int | None instance-attribute

Total number of non-coinbase transactions in the chain.

num_txs_pool: int | None instance-attribute

Number of transactions that have been broadcast but not included in a block.

start_timestamp: int | None instance-attribute

Start time of the daemon, as UNIX time.

target: int | None instance-attribute

Current target for next proof of work.

target_height: int | None instance-attribute

The height of the next block in the chain.

update_available: bool | None instance-attribute

States if a newer Monero software version is available.

version: str | None instance-attribute

The version of the Monero software the node is running.

was_bootstrap_ever_used: bool | None instance-attribute

States if a bootstrap node has ever been used since the daemon started.

__init__()

Initiliaze a Monero daemon info.

MoneroDaemonSyncInfo

Bases: MoneroRpcPaymentInfo

Models daemon synchronization information.

height: int | None instance-attribute

Daemon blockchain height.

next_needed_pruning_seed: int | None instance-attribute

The next pruning seed needed for pruned sync.

overview: str | None instance-attribute

Overview of current block queue where each character in the string represents a block set in the queue. '.' = requested but not received, 'o' = set received, 'm' = received set that matches the next blocks needed

peers: list[MoneroPeer] instance-attribute

List of peers connected to the node

spans: list[MoneroConnectionSpan] instance-attribute

Currently connected peers to download blocks from.

target_height: int | None instance-attribute

Target height the node is syncing from (will be 0 if node is fully synced).

__init__()

Initialize a Monero daemon sync info.

MoneroHardForkInfo

Bases: MoneroRpcPaymentInfo

Models a Monero look up information regarding hard fork voting and readiness.

earliest_height: int | None instance-attribute

Block height at which hard fork would be enabled if voted in.

is_enabled: bool | None instance-attribute

Tells if hard fork is enforced.

num_votes: int | None instance-attribute

Number of votes towards hard fork.

state: int | None instance-attribute

Current hard fork state. 0 (There is likely a hard fork), 1 (An update is needed to fork properly), or 2 (Everything looks good).

threshold: int | None instance-attribute

Minimum percent of votes to trigger hard fork. Default is 80.

version: int | None instance-attribute

The major block version for the fork.

voting: int | None instance-attribute

Hard fork voting status.

window: int | None instance-attribute

Number of blocks over which current votes are cast. Default is 10080 blocks.

__init__()

Initialize a Monero hard fork info.

MoneroDaemonListener

Receives notifications as a daemon is updated.

last_header: MoneroBlockHeader | None instance-attribute

Last block header added to the chain.

__init__()

Initialize a Monero daemon listener.

on_block_header(header)

Called when a new block is added to the chain.

Parameters:

Name Type Description Default
header MoneroBlockHeader

is the header of the block added to the chain.

required
\ No newline at end of file + Daemon Data Model - Monero Python
Skip to content

Daemon Data Model

MoneroNetworkType

Bases: IntEnum

Enumerates a Monero network type_.

.. _Monero network type: https://docs.getmonero.org/infrastructure/networks/

MAINNET = 0 class-attribute instance-attribute

0 indicates Mainnet network_.

.. _Mainnet network: https://docs.getmonero.org/infrastructure/networks/#mainnet

STAGENET = 2 class-attribute instance-attribute

2 indicates Stagenet network_.

.. _Stagenet network: https://docs.getmonero.org/infrastructure/networks/#stagenet

TESTNET = 1 class-attribute instance-attribute

1 indicates Testnet network_.

.. _Testnet network: https://docs.getmonero.org/infrastructure/networks/#testnet

MoneroVersion

Bases: SerializableStruct

Models a Monero version.

is_release: bool | None instance-attribute

States if the monero software version corresponds to an official tagged release (True), or not (False).

number: int | None instance-attribute

Number of the monero software version.

__init__()

Initialize a new Monero version.

MoneroBlockHeader

Bases: SerializableStruct

Models a Monero block header which contains information about the block.

cumulative_difficulty_high: int | None instance-attribute

Cumulative difficulty of all blocks up to the block in the reply.

cumulative_difficulty_low: int | None instance-attribute

Cumulative difficulty of all blocks up to the block in the reply.

depth: int | None instance-attribute

The number of blocks succeeding this block on the blockchain. A larger number means an older block.

difficulty_high: int | None instance-attribute

The strength of the Monero network based on mining power.

difficulty_low: int | None instance-attribute

The strength of the Monero network based on mining power.

hash: str | None instance-attribute

The hash of this block.

height: int | None instance-attribute

The number of blocks preceding this block on the blockchain.

long_term_weight: int | None instance-attribute

The long term block weight, based on the median weight of the preceding 100000 blocks.

major_version: int | None instance-attribute

The major version of the monero protocol at this block height.

miner_tx_hash: str | None instance-attribute

The hash of this block's coinbase transaction.

minor_version: int | None instance-attribute

The minor version of the monero protocol at this block height.

nonce: int | None instance-attribute

A cryptographic random one-time number used in mining a Monero block.

num_txs: int | None instance-attribute

Number of transactions included in this block.

orphan_status: bool | None instance-attribute

If True, this block is not part of the longest chain.

pow_hash: str | None instance-attribute

The hash, as a hexadecimal string, calculated from the block as proof-of-work.

prev_hash: str | None instance-attribute

The hash of the block immediately preceding this block in the chain.

reward: int | None instance-attribute

The amount of atomic-units rewarded to the miner. The reward is the sum of new coins created (the emission) and fees paid by transactions in this block. Note: 1 XMR = 1e12 atomic-units.

size: int | None instance-attribute

Backward compatibility, same as weight, use that instead.

timestamp: int | None instance-attribute

The unix time at which the block was recorded into the blockchain.

weight: int | None instance-attribute

The adjusted block size, in bytes. This is the raw size, plus a positive adjustment for any Bulletproof transactions with more than 2 outputs.

__init__()

Initialize a Monero block header.

copy()

Copy current block header.

Returns:

Type Description
MoneroBlockHeader

copied block header.

merge(other)

Merge current block header with another one.

Raises:

Type Description
Exception

on reconciliation error.

MoneroBlock

Bases: MoneroBlockHeader

Models a Monero block in the blockchain.

hex: str | None instance-attribute

Hexadecimal blob of block information.

miner_tx: MoneroTx | None instance-attribute

Miner transaction information.

tx_hashes: list[str] instance-attribute

List of hashes of non-coinbase transactions in the block.

txs: list[MoneroTx] instance-attribute

List of non-coinbase transactions in the block.

__init__()

Initialize a Monero block.

copy()

Copy current block.

Returns:

Type Description
MoneroBlock

copied block.

MoneroTx

Bases: SerializableStruct

Models a Monero transaction on the blockchain.

DEFAULT_PAYMENT_ID: str instance-attribute

Default tx payment id

block: MoneroBlock | None instance-attribute

Block including the transaction.

common_tx_sets: str | None instance-attribute

A hexadecimal string representing a set of unsigned transactions, or a set of signing keys used in a multisig transaction.

extra: list[int] instance-attribute

Usually called the payment ID but can be used to include any random 32 bytes.

fee: int | None instance-attribute

The amount of the mining fee included in the transaction, in atomic-units.

full_hex: str | None instance-attribute

Full transaction information as a hex string.

hash: str | None instance-attribute

The transaction hash.

in_tx_pool: bool | None instance-attribute

States if the transaction is in pool (True) or included in a block (False).

inputs: list[MoneroOutput] instance-attribute

List of inputs into transaction.

is_confirmed: bool | None instance-attribute

States if the transaction included in a block (True) or is in pool (False).

is_double_spend_seen: bool | None instance-attribute

States if the transaction is a double-spend (True) or not (False).

is_failed: bool | None instance-attribute

Indicates if the transaction validation has previously failed.

is_kept_by_block: bool | None instance-attribute

States if the transaction was included in a block at least once (True) or not (False).

is_miner_tx: bool | None instance-attribute

States if the transaction is a coinbase-transaction (True) or not (False).

is_relayed: bool | None instance-attribute

States if the transaction was relayed (True) or not (False).

key: str | None instance-attribute

The transaction key.

last_failed_hash: str | None instance-attribute

If the transaction validation has previously failed, this tells the previous transaction hash.

last_failed_height: int | None instance-attribute

If the transaction validation has previously failed, this tells at what height that occurred.

last_relayed_timestamp: int | None instance-attribute

Last unix time at which the transaction has been relayed.

max_used_block_hash: str | None instance-attribute

Tells the hash of the most recent block with an output used in this transaction.

max_used_block_height: int | None instance-attribute

Tells the height of the most recent block with an output used in this transaction.

metadata: str | None instance-attribute

Transaction metadata.

num_confirmations: int | None instance-attribute

Number of network confirmations.

output_indices: list[int] instance-attribute

Transaction indexes.

outputs: list[MoneroOutput] instance-attribute

Transaction outputs.

payment_id: str | None instance-attribute

Payment ID for this transaction.

prunable_hash: str | None instance-attribute

Keccak-256 hash of the prunable portion of the block.

prunable_hex: str | None instance-attribute

Prunable block encoded as a hex string.

pruned_hex: str | None instance-attribute

Pruned block encoded as hex string.

rct_sig_prunable: str | None instance-attribute

Prunable ring signature.

rct_signatures: str | None instance-attribute

Signatures used in ring signature to hide the true origin of the transaction.

received_timestamp: int | None instance-attribute

Unix time at chich the transaction has been received.

relay: bool | None instance-attribute

States if this transaction should be relayed (True) or not (False).

ring_size: int | None instance-attribute

The ring size of this transaction.

signatures: list[str] instance-attribute

List of signatures used in ring signature to hide the true origin of the transaction.

size: int | None instance-attribute

Backward compatibility, same as weight, use that instead.

unlock_time: int | None instance-attribute

If not 0, this tells when the transaction outputs are spendable.

version: int | None instance-attribute

Transaction version.

weight: int | None instance-attribute

The weight of this transaction in bytes.

__init__()

Initialize a new Monero transaction.

copy()

Copy current tx.

Returns:

Type Description
MoneroTx

tx copy.

get_height()

Get the transaction height.

Returns:

Type Description
int | None

The height of the transaction, if known.

merge(other)

Merge current tx with another one.

Parameters:

Name Type Description Default
other MoneroTx

other tx to merge with.

required

MoneroKeyImage

Bases: SerializableStruct

Models a Monero key image.

hex: str | None instance-attribute

The key image in hexadecimal format.

signature: str | None instance-attribute

The key image signature. None if not known.

__init__()

Initialize a Monero key image.

copy()

Copy current key image.

Returns:

Type Description
MoneroKeyImage

key image copy.

deserialize_key_images(key_images_json) staticmethod

Deserialize key images from a JSON string.

Parameters:

Name Type Description Default
key_images_json str

JSON string with serialized key images.

required

Returns:

Type Description
list[MoneroKeyImage]

Deserialized key images.

merge(other)

Merge current key image with another one.

Parameters:

Name Type Description Default
other MoneroKeyImage

other key image to merge with.

required

MoneroOutput

Bases: SerializableStruct

Models a Monero transaction output.

amount: int | None instance-attribute

Output amount in atomic-units.

index: int | None instance-attribute

Output index.

key_image: MoneroKeyImage | None instance-attribute

The key image of the output.

ring_output_indices: list[int] instance-attribute

Indices of ring outputs.

stealth_public_key: str | None instance-attribute

The public key of the output.

tx: MoneroTx instance-attribute

The transaction related to this output.

__init__()

Initialize a Monero output.

copy()

Copy current output.

Returns:

Type Description
MoneroOutput

output copy.

merge(other)

Merge current output wallet with another output.

Parameters:

Name Type Description Default
other MoneroOutput

other output to merge with.

required

MoneroAltChain

Bases: SerializableStruct

Models an alternative chain seen by the node.

block_hashes: list[str] instance-attribute

List of all block hashes in the alternative chain that are not in the main chain.

difficulty_high: int | None instance-attribute

Cumulative difficulty of all blocks in the alternative chain (Most-significant 64 bits of the 128-bit integer).

difficulty_low: int | None instance-attribute

Cumulative difficulty of all blocks in the alternative chain (Least-significant 64 bits of 128-bit integer).

height: int | None instance-attribute

The block height of the first diverging block of this alternative chain.

length: int | None instance-attribute

The length in blocks of this alternative chain, after divergence.

main_chain_parent_block_hash: str | None instance-attribute

The hash of the greatest height block that is shared between the alternative chain and the main chain.

__init__()

Initialize a Monero alt chain info.

MoneroBan

Bases: SerializableStruct

Model a Monero banhammer.

host: str | None instance-attribute

Host ban.

ip: int | None instance-attribute

IP ban.

is_banned: bool | None instance-attribute

Indicates if ban on the host is active (True) or not (False).

seconds: int | None instance-attribute

Indicates the duration of the ban in seconds.

__init__()

Initialize a Monero banhammer.

MoneroPruneResult

Bases: SerializableStruct

Models the result of pruning the blockchain.

is_pruned: bool | None instance-attribute

Indicates if blockchain is pruned.

pruning_seed: int | None instance-attribute

Blockheight at which pruning began.

__init__()

Initialize a Monero prune result.

MoneroMiningStatus

Bases: SerializableStruct

Models a Monero daemon mining status.

address: str | None instance-attribute

Account address daemon is mining to. None if not mining.

is_active: bool | None instance-attribute

Indicates if mining is enabled.

is_background: bool | None instance-attribute

Indicates if mining is running in background.

num_threads: int | None instance-attribute

Number of running mining threads.

speed: int | None instance-attribute

Mining power in hashes per seconds.

__init__()

Initialize a Monero daemon mining status.

MoneroMinerTxSum

Bases: SerializableStruct

Model for the sum of miner emissions and fees.

emission_sum_high: int | None instance-attribute

The new coins emitted in atomic-units. (Most significant 64 bits for 128 bit integer)

emission_sum_low: int | None instance-attribute

The new coins emitted in atomic-units. (Least significant 64 bits for 128 bit integer)

fee_sum_high: int | None instance-attribute

The sum of fees in atomic-units. (Most significant 64 bits for 128 bit integer)

fee_sum_low: int | None instance-attribute

The sum of fees in atomic-units. (Least significant 64 bits for 128 bit integer)

__init__()

Initialize a Monero miner transaction sum.

MoneroBlockTemplate

Bases: SerializableStruct

Monero block template to mine.

block_hashing_blob: str | None instance-attribute

Blob on which to try to find a valid nonce.

block_template_blob: str | None instance-attribute

Blob on which to try to mine a new block.

difficulty_high: int | None instance-attribute

Network difficulty (Most-significant 64 bits of 128-bit integer).

difficulty_low: int | None instance-attribute

Network difficulty (Least-significant 64 bits of 128-bit integer).

expected_reward: int | None instance-attribute

Coinbase reward expected to be received if block is successfully mined.

height: int | None instance-attribute

Height on which to mine.

next_seed_hash: str | None instance-attribute

Hash of the next block to use as seed for Random-X proof-of-work.

prev_hash: str | None instance-attribute

Hash of the most recent block on which to mine the next block.

reserved_offset: int | None instance-attribute

Reserved offset.

seed_hash: str | None instance-attribute

Hash of block to use as seed for Random-X proof-of-work.

seed_height: int | None instance-attribute

Height of block to use as seed for Random-X proof-of-work.

__init__()

Initialize a Monero block template.

MoneroConnectionSpan

Bases: SerializableStruct

Monero daemon connection span.

connection_id: str | None instance-attribute

Id of connection

num_blocks: int | None instance-attribute

Number of blocks in this span

rate: int | None instance-attribute

Connection rate

remote_address: str | None instance-attribute

Peer address the node is downloading (or has downloaded) than span from.

size: int | None instance-attribute

Total number of bytes in that span's blocks (including txes).

speed: int | None instance-attribute

Connection speed.

start_height: int | None instance-attribute

Block height of the first block in that span.

__init__()

Initialize a Monero connection span.

MoneroPeer

Bases: SerializableStruct

Models a peer to the daemon.

address: str | None instance-attribute

The peer's address, actually IPv4 & port.

avg_download: int | None instance-attribute

Average bytes of data downloaded by node.

avg_upload: int | None instance-attribute

Average bytes of data uploaded by node.

connection_type: MoneroConnectionType | None instance-attribute

Type of peer connection.

current_download: int | None instance-attribute

Current bytes downloaded by node.

current_upload: int | None instance-attribute

Current bytes uploaded by node.

hash: str | None instance-attribute

Peer hash.

height: int | None instance-attribute

The peer blockchain height.

host: str | None instance-attribute

The peer host.

id: str | None instance-attribute

The node's ID on the network.

is_incoming: bool | None instance-attribute

Indicates if peer is pulling blocks from node.

is_local_host: bool | None instance-attribute

Indicates if peer is localhost.

is_local_ip: bool | None instance-attribute

Indicates if peer has a local ip address.

is_online: bool | None instance-attribute

Indicates if the peer is online.

last_seen_timestamp: int | None instance-attribute

Last activity timestamp of this peer.

live_time: int | None instance-attribute

Length of time the peer has been online.

num_receives: int | None instance-attribute

Total number of messages received from this peer.

num_sends: int | None instance-attribute

Total number of messages sent to this peer.

num_support_flags: int | None instance-attribute

Support flags number.

port: int | None instance-attribute

The port that the node is using to connect to the network.

pruning_seed: int | None instance-attribute

Block height at which pruning began.

receive_idle_time: int | None instance-attribute

Seconds since last data was received from this peer.

rpc_credits_per_hash: int | None instance-attribute

Credits for every hash calculated by client.

rpc_port: int | None instance-attribute

Peer RPC port.

send_idle_time: int | None instance-attribute

Seconds since the last data sent to this peer.

state: str | None instance-attribute

Peer state.

__init__()

Initialize a new Monero peer.

MoneroSubmitTxResult

Bases: MoneroRpcPaymentInfo

Models the result from submitting a tx to a daemon.

has_invalid_input: bool | None instance-attribute

Indicates if the transaction has an invalid input.

has_invalid_output: bool | None instance-attribute

Indicates if the transaction has an invalid output.

has_too_few_outputs: bool | None instance-attribute

Indicates if the transaction has too few outputs.

is_double_spend: bool | None instance-attribute

Indicates if the transaction is double spend.

is_fee_too_low: bool | None instance-attribute

Indicates if the transaction fee is too low.

is_good: bool | None instance-attribute

Indicates if the submission of the transaction was successfull.

is_mixin_too_low: bool | None instance-attribute

Indicates if the transaction mixin count is too low.

is_overspend: bool | None instance-attribute

Indicates if the transaction uses more money than available

is_relayed: bool | None instance-attribute

Indicates if the transaction has been relayed.

is_too_big: bool | None instance-attribute

Indicates if the transaction size is too big.

is_tx_extra_too_big: bool | None instance-attribute

Indicates if the transaction extra size is too big.

reason: str | None instance-attribute

Additional information. Currently empty or Not relayed if transaction was accepted but not relayed.

sanity_check_failed: bool | None instance-attribute

Indicates if the transaction sanity check has failed.

__init__()

Initialize a new submit transaction result.

MoneroTxBacklogEntry

TODO

__init__()

Intialize a new tx backlog entry.

MoneroOutputDistributionEntry

Bases: SerializableStruct

Models a Monero output distribution entry.

amount: int | None instance-attribute

Output amount in atomic-units.

base: int | None instance-attribute

The total number of outputs of amount in the chain before, not including, the block at start_height.

distribution: list[int] instance-attribute

The output distibution.

start_height: int | None instance-attribute

Not necessarily equal to start_height parameter especially for amount = 0 where start_height will be no less than the height of the v4 hardfork.

__init__()

Initialize a Monero output distribution entry.

MoneroOutputHistogramEntry

Bases: SerializableStruct

Models a Monero output histogram entry.

amount: int | None instance-attribute

Output amount in atomic-units.

num_instances: int | None instance-attribute

Number of outputs.

recent_instances: int | None instance-attribute

Number of recent outputs.

unlocked_instances: int | None instance-attribute

Number of unlocked outputs.

__init__()

Initialize a Monero output histogram entry.

MoneroTxPoolStats

Bases: SerializableStruct

Models transaction pool statistics.

bytes_max: int | None instance-attribute

Max transaction size in pool.

bytes_med: int | None instance-attribute

Median transaction size in pool.

bytes_min: int | None instance-attribute

Min transaction size in pool.

bytes_total: int | None instance-attribute

Total size of all transactions in pool.

fee_total: int | None instance-attribute

The sum of the fees for all transactions currently in the transaction pool atomic-units.

histo: dict[int, int] instance-attribute

Txs histogram (key for bytes, value for txs).

histo98pc: int | None instance-attribute

The time 98% of txes are younger than.

num10m: int | None instance-attribute

Number of transactions in pool for more than 10 minutes.

num_double_spends: int | None instance-attribute

Number of double spend transactions.

num_failing: int | None instance-attribute

Number of failing transactions.

num_not_relayed: int | None instance-attribute

Number of non-relayed transactions.

num_txs: int | None instance-attribute

Total number of transactions.

oldest_timestamp: int | None instance-attribute

Unix time of the oldest transaction in the pool.

__init__()

Initialize a Monero transaction pool statistics.

MoneroDaemonUpdateCheckResult

Bases: SerializableStruct

Models the result of checking for a daemon update.

auto_uri: str | None instance-attribute

URL automatically generated by the daemon to download the update.

hash: str | None instance-attribute

Integrity check hash.

is_update_available: bool | None instance-attribute

Indicates if an update is available to download.

user_uri: str | None instance-attribute

Alternative user URI.

version: str | None instance-attribute

Version available for download.

__init__()

Initialize a Monero update check result.

MoneroDaemonUpdateDownloadResult

Bases: MoneroDaemonUpdateCheckResult

Models the result of downloading a daemon update.

download_path: str | None instance-attribute

Path to download the update.

__init__()

Initialize a Monero update download result.

MoneroFeeEstimate

Bases: SerializableStruct

Models a Monero fee estimate.

fee: int | None instance-attribute

Amount of fees estimated per byte in atomic-units.

fees: list[int] instance-attribute

Represents the base fees at different priorities [slow, normal, fast, fastest].

quantization_mask: int | None instance-attribute

Final fee should be rounded up to an even multiple of this value.

__init__()

Initialize a Monero fee estimate.

MoneroDaemonInfo

Bases: MoneroRpcPaymentInfo

Models information got from a Monero daemon.

adjusted_timestamp: int | None instance-attribute

Current time approximated from chain data, as Unix time.

block_size_limit: int | None instance-attribute

Backward compatibility, same as block_weight_limit, use that instead.

block_size_median: int | None instance-attribute

Backward compatibility, same as block_weight_median, use that instead.

block_weight_limit: int | None instance-attribute

Maximum allowed adjusted block size based on latest 100000 blocks.

block_weight_median: int | None instance-attribute

Median adjusted block size of latest 100000 blocks.

bootstrap_daemon_address: str | None instance-attribute

Bootstrap-node to give immediate usability to wallets while syncing by proxying RPC to it.

cumulative_difficulty_high: int | None instance-attribute

Most-significant 64 bits of the 128-bit cumulative difficulty.

cumulative_difficulty_low: int | None instance-attribute

Least-significant 64 bits of the 128-bit cumulative difficulty.

database_size: int | None instance-attribute

The size of the blockchain database, in bytes.

difficulty_high: int | None instance-attribute

The most-significant 64 bits of the 128-bit network difficulty.

difficulty_low: int | None instance-attribute

The least-significant 64 bits of the 128-bit network difficulty.

free_space: int | None instance-attribute

Available disk space on the node.

height: int | None instance-attribute

Current length of longest chain known to daemon.

height_without_bootstrap: int | None instance-attribute

Current length of the local chain of the daemon.

is_busy_syncing: bool | None instance-attribute

States if new blocks are being added (True) or not (False).

is_offline: bool | None instance-attribute

States if the node is offline (True) or online (False).

is_restricted: bool | None instance-attribute

Indicates that the node RPC interface is restricted (True) or not (False).

is_synchronized: bool | None instance-attribute

States if the node is synchronized (True) or not (False).

network_type: MoneroNetworkType | None instance-attribute

Network type (MAINNET, TESTNET, or STAGENET).

num_alt_blocks: int | None instance-attribute

Number of alternative blocks to main chain.

num_incoming_connections: int | None instance-attribute

Number of peers connected to and pulling from your node.

num_offline_peers: int | None instance-attribute

Number of peers that are marked as not reacheable on the network.

num_online_peers: int | None instance-attribute

Number of peers that are marked as reacheble on the network.

num_outgoing_connections: int | None instance-attribute

Number of peers that you are connected to and getting information from.

num_rpc_connections: int | None instance-attribute

Number of RPC client connected to the daemon (Including this RPC request).

num_txs: int | None instance-attribute

Total number of non-coinbase transactions in the chain.

num_txs_pool: int | None instance-attribute

Number of transactions that have been broadcast but not included in a block.

start_timestamp: int | None instance-attribute

Start time of the daemon, as UNIX time.

target: int | None instance-attribute

Current target for next proof of work.

target_height: int | None instance-attribute

The height of the next block in the chain.

update_available: bool | None instance-attribute

States if a newer Monero software version is available.

version: str | None instance-attribute

The version of the Monero software the node is running.

was_bootstrap_ever_used: bool | None instance-attribute

States if a bootstrap node has ever been used since the daemon started.

__init__()

Initiliaze a Monero daemon info.

MoneroDaemonSyncInfo

Bases: MoneroRpcPaymentInfo

Models daemon synchronization information.

height: int | None instance-attribute

Daemon blockchain height.

next_needed_pruning_seed: int | None instance-attribute

The next pruning seed needed for pruned sync.

overview: str | None instance-attribute

Overview of current block queue where each character in the string represents a block set in the queue. '.' = requested but not received, 'o' = set received, 'm' = received set that matches the next blocks needed

peers: list[MoneroPeer] instance-attribute

List of peers connected to the node

spans: list[MoneroConnectionSpan] instance-attribute

Currently connected peers to download blocks from.

target_height: int | None instance-attribute

Target height the node is syncing from (will be 0 if node is fully synced).

__init__()

Initialize a Monero daemon sync info.

MoneroHardForkInfo

Bases: MoneroRpcPaymentInfo

Models a Monero look up information regarding hard fork voting and readiness.

earliest_height: int | None instance-attribute

Block height at which hard fork would be enabled if voted in.

is_enabled: bool | None instance-attribute

Tells if hard fork is enforced.

num_votes: int | None instance-attribute

Number of votes towards hard fork.

state: int | None instance-attribute

Current hard fork state. 0 (There is likely a hard fork), 1 (An update is needed to fork properly), or 2 (Everything looks good).

threshold: int | None instance-attribute

Minimum percent of votes to trigger hard fork. Default is 80.

version: int | None instance-attribute

The major block version for the fork.

voting: int | None instance-attribute

Hard fork voting status.

window: int | None instance-attribute

Number of blocks over which current votes are cast. Default is 10080 blocks.

__init__()

Initialize a Monero hard fork info.

MoneroDaemonListener

Receives notifications as a daemon is updated.

last_header: MoneroBlockHeader | None instance-attribute

Last block header added to the chain.

__init__()

Initialize a Monero daemon listener.

on_block_header(header)

Called when a new block is added to the chain.

Parameters:

Name Type Description Default
header MoneroBlockHeader

is the header of the block added to the chain.

required
\ No newline at end of file diff --git a/docs/mkdocs/public/api/data_model/wallet/index.html b/docs/mkdocs/public/api/data_model/wallet/index.html index c06c2de..cf0cc86 100644 --- a/docs/mkdocs/public/api/data_model/wallet/index.html +++ b/docs/mkdocs/public/api/data_model/wallet/index.html @@ -1 +1 @@ - Wallet Data Model - Monero Python
Skip to content

Wallet Data Model

MoneroWalletConfig

Bases: SerializableStruct

Configures a wallet to create.

account_lookahead: int | None instance-attribute

Account index look ahead.

is_multisig: bool | None instance-attribute

Indicates if the wallet is a multisignature wallet.

language: str | None instance-attribute

The wallet language.

network_type: MoneroNetworkType | None instance-attribute

The wallet network type.

password: str | None instance-attribute

The wallet password.

path: str | None instance-attribute

The wallet path on file system.

primary_address: str | None instance-attribute

The wallet standard address.

private_spend_key: str | None instance-attribute

The wallet private spend key.

private_view_key: str | None instance-attribute

The wallet private view key.

restore_height: int | None instance-attribute

The wallet restore height.

save_current: bool | None instance-attribute

Save the wallet.

seed: str | None instance-attribute

The wallet mnemonic.

seed_offset: str | None instance-attribute

The wallet custom seed offset.

server: MoneroRpcConnection | None instance-attribute

The wallet RPC connection.

subaddress_lookahead: int | None instance-attribute

Subaddress index look ahead.

copy()

Copy this wallet config.

Returns:

Type Description
MoneroWalletConfig

Copy of the wallet config.

deserialize(config_json) staticmethod

Deserialize a Monero wallet config from a JSON string.

Parameters:

Name Type Description Default
config_json str

JSON string.

required

Returns:

Type Description
MoneroWalletConfig

The deserialized wallet config.

MoneroSyncResult

Bases: SerializableStruct

Models a result of syncing a wallet.

num_blocks_fetched: int instance-attribute

Number of blocks fetched.

received_money: bool instance-attribute

Indicates if money was received.

MoneroSubaddress

Bases: SerializableStruct

Models a Monero subaddress.

account_index: int | None instance-attribute

The subaddress account index.

address: str | None instance-attribute

Public address.

balance: int | None instance-attribute

The subaddress balance.

index: int | None instance-attribute

The subaddress index.

is_used: bool | None instance-attribute

Indicates if subaddress has been used in receiving funds.

label: str | None instance-attribute

The subaddress label.

num_blocks_to_unlock: int | None instance-attribute

Number of blocks to unlock receveid outputs.

num_unspent_outputs: int | None instance-attribute

The number of unspent outputs in this subaddress.

unlocked_balance: int | None instance-attribute

The subaddress unlocked balance.

__init__()

Initialize a Monero subaddress.

MoneroAccount

Bases: SerializableStruct

Models a Monero account.

balance: int | None instance-attribute

The account balance.

index: int | None instance-attribute

The account index.

primary_address: str | None instance-attribute

The account primary address.

subaddresses: list[MoneroSubaddress] instance-attribute

List of account subaddresses.

tag: str | None instance-attribute

The account tag.

unlocked_balance: int | None instance-attribute

The account unlocked balance.

__init__()

Initialize a Monero account.

MoneroDestination

Bases: SerializableStruct

Models an outgoing transfer destination.

address: str | None instance-attribute

Address of the receiver.

amount: int | None instance-attribute

Amount sent to this destination.

copy()

Copy current outgoing transfer destination.

Returns:

Type Description
MoneroDestination

outgoing transfer destination copy.

MoneroTransfer

Bases: SerializableStruct

Models a base transfer of funds to or from the wallet.

account_index: int | None instance-attribute

Index of the account related to this transfer.

amount: int | None instance-attribute

Transfer amount in atomic-units.

tx: MoneroTxWallet instance-attribute

Related wallet transaction.

__init__()

Initialize a Monero transfer.

copy()

Copy current transfer.

Returns:

Type Description
MoneroTransfer

transfer copy.

is_incoming()

Indicates if it is an incoming transfer (True) or not (False). Default None.

Returns:

Type Description
bool | None

True if current transfer is incoming, False if outgoing, None if unkown.

is_outgoing()

Indicates if it is an outgoing transfer (True) or not (False). Default None.

Returns:

Type Description
bool | None

True if current transfer is outgoing, False if incoming, None if unkown.

merge(other)

Merge current transfer with another one.

Parameters:

Name Type Description Default
other MoneroTransfer

other transfer to merge with.

required

MoneroIncomingTransfer

Bases: MoneroTransfer

Models an incoming transfer of funds to the wallet.

address: str | None instance-attribute

The address that received funds within this transfer.

num_suggested_confirmations: int | None instance-attribute

The number of suggested confirmations before moving funds.

subaddress_index: int | None instance-attribute

The subaddress index that received funds within this transfer.

__init__()

Initialize a Monero incoming transfer.

copy()

Copy current incoming transfer.

Returns:

Type Description
MoneroIncomingTransfer

incoming transfer copy.

MoneroOutgoingTransfer

Bases: MoneroTransfer

Models an outgoing transfer of funds from the wallet.

addresses: list[str] instance-attribute

Addresses from which the transfer originated.

destinations: list[MoneroDestination] instance-attribute

Outgoing transfer destinations.

subaddress_indices: list[int] instance-attribute

Subaddresses from which the transfer originated.

copy()

Copy current outgoing transfer.

Returns:

Type Description
MoneroOutgoingTransfer

outgoing transfer copy.

MoneroTransferQuery

Bases: MoneroTransfer

Configures a query to retrieve transfers.

All transfers are returned except those that do not meet the criteria defined in this query.

address: str | None instance-attribute

Select transfers involving particular address. Empty for all.

addresses: list[str] instance-attribute

Select transfers involving particular addresses. Empty for all.

destinations: list[MoneroDestination] instance-attribute

Select transfers involving particular destinations. Empty for all.

has_destinations: bool | None instance-attribute

Filter transfers with or without destinations. None for all.

incoming: bool | None instance-attribute

Filter incoming or outgoing transfers. None for all.

outgoing: bool | None instance-attribute

Filter incoming or outgoing transfers. None for all.

subaddress_index: int | None instance-attribute

Filter by subaddress index. None for all.

subaddress_indices: list[int] instance-attribute

Select transfers involving particular subaddresses. Empty for all.

tx_query: MoneroTxQuery | None instance-attribute

Related transaction query.

__init__()

Initialize a Monero transfer query.

copy()

Copy current transfer query.

Returns:

Type Description
MoneroTransferQuery

transfer query copy.

deserialize_from_block(transfer_query_json) staticmethod

Deserialize transfer query from json block.

Parameters:

Name Type Description Default
transfer_query_json str

json block with serialized transfer query.

required

Returns:

Type Description
MoneroTransferQuery

deserialized transfer query.

meets_criteria(transfer, query_parent=True)

Check if transfer meets all the criteria defined in this query.

Parameters:

Name Type Description Default
transfer MoneroTransfer

transfer to check if meets criteria.

required
query_parent bool

query parent tx query (default True).

True

Returns:

Type Description
bool

True if transfer meets all criteria defined in this query, False otherwise.

MoneroOutputWallet

Bases: MoneroOutput

Models a Monero output with wallet extensions.

account_index: int | None instance-attribute

The index of the account that owns this output.

is_frozen: bool | None instance-attribute

Indicates if the output is frozen (True) or not (False).

is_spent: bool | None instance-attribute

Indicates if the output is spent (True) or not (False).

subaddress_index: int | None instance-attribute

The index of the subaddress that owns this output.

__init__()

Initialize a Monero wallet output.

copy()

Copy current output wallet.

Returns:

Type Description
MoneroOutputWallet

output wallet copy.

MoneroOutputQuery

Bases: MoneroOutputWallet

Configures a query to retrieve wallet outputs (i.e. outputs that the wallet has or had the ability to spend).

All outputs are returned except those that do not meet the criteria defined in this query.

max_amount: int | None instance-attribute

Filter outputs above this amount.

min_amount: int | None instance-attribute

Filter outputs below this amount.

subaddress_indices: list[int] instance-attribute

Subadress indices to select (empty for all).

tx_query: MoneroTxQuery | None property

Related transaction query.

__init__()

Initialize a Monero output query.

copy()

Copy current output query.

Returns:

Type Description
MoneroOutputQuery

output query copy.

deserialize_from_block(output_query_json) staticmethod

Deserialize output query from block.

Parameters:

Name Type Description Default
output_query_json str

json query block.

required

Returns:

Type Description
MoneroOutputQuery

deserialized output query.

meets_criteria(output, query_parent=True)

Indicates if the output meets all the criteria defined within this query.

Parameters:

Name Type Description Default
output MoneroOutputWallet

Output to check.

required
query_parent bool

Query also parent.

True

Returns:

Type Description
bool

True if output meets all the criteria defined in this query, False otherwise.

set_tx_query(tx_query, output_query)

Set related transaction query.

This method sets query references constitutively.

Parameters:

Name Type Description Default
tx_query Optional[MoneroTxQuery]

Tx query to set.

required
output_query bool

If True sets outputs query in tx_query, otherwise inputs query.

required

MoneroTxWallet

Bases: MoneroTx

Models a Monero transaction in the context of a wallet.

change_address: str | None instance-attribute

Address to which the change amount of the transaction was sent.

change_amount: int | None instance-attribute

Change amount of the transaction.

extra_hex: str | None instance-attribute

Extra information about the transaction in hexadecimal format.

incoming_transfers: list[MoneroIncomingTransfer] instance-attribute

List of incoming transfer.

input_sum: int | None instance-attribute

Total input sum.

is_incoming: bool | None instance-attribute

Indicates if the transaction has incoming transfers.

is_locked: bool | None instance-attribute

Indicates if the transaction is locked.

is_outgoing: bool | None instance-attribute

Indicated if the transaction has outgoing transfer.

note: str | None instance-attribute

Transaction note.

num_dummy_outputs: int | None instance-attribute

Number of decoys of the transactions.

outgoing_transfer: MoneroOutgoingTransfer | None instance-attribute

The outgoing transfer related to this transaction.

output_sum: int | None instance-attribute

The total output amount sum originated from this transaction.

tx_set: MoneroTxSet | None instance-attribute

Set of transactions related to current tx.

__init__()

Initialize a new Monero tx wallet.

copy()

Copy current tx wallet.

Returns:

Type Description
MoneroTxWallet

tx wallet copy.

filter_outputs_wallet(query)

Get outputs filtered by query.

Parameters:

Name Type Description Default
query MoneroOutputQuery

query to filter outputs with.

required

Returns:

Type Description
list[MoneroOutputWallet]

outputs that meets all criteria defined in query.

filter_transfers(query)

Get transfers filtered by query.

Parameters:

Name Type Description Default
query MoneroTransferQuery

query to filter transfers with.

required

Returns:

Type Description
list[MoneroTransfer]

transfers that meets all criteria defined in query.

get_incoming_amount()

Get total amount received in current tx.

Returns:

Type Description
int

total amount received in current wallet tx.

get_inputs_wallet(query=None)

Get wallet inputs filtered by query.

Parameters:

Name Type Description Default
query MoneroOutputQuery

query to filter outputs with.

None

Returns:

Type Description
list[MoneroOutputWallet]

wallet outputs filtered by query.

get_outgoing_amount()

Get total amount spent in current tx.

Returns:

Type Description
int

total amount spent in current wallet tx.

MoneroTxQuery

Bases: MoneroTxWallet

Configures a query to retrieve transactions.

All transactions are returned except those that do not meet the criteria defined in this query.

has_payment_id: bool | None instance-attribute

Get transactions that have a payment id.

hashes: list[str] instance-attribute

Get transactions by hashes.

height: int | None instance-attribute

Get transactions by height.

include_outputs: int | None instance-attribute

Include outputs in transaction data.

input_query: MoneroOutputQuery | None instance-attribute

Query to apply on transaction inputs.

is_incoming: bool | None instance-attribute

Include incoming transactions.

is_outgoing: bool | None instance-attribute

Include outgoing transactions.

max_height: int | None instance-attribute

Get transactions below max height.

min_height: int | None instance-attribute

Get transactions above max height.

output_query: MoneroOutputQuery | None instance-attribute

Query to apply on transaction outputs.

payment_ids: list[str] instance-attribute

Get transactions with specific payment ids.

transfer_query: MoneroTransferQuery | None instance-attribute

Query to apply on transaction wallet transfer.

__init__()

Initiliaze a new Monero transaction query.

copy()

Copy current transaction query.

Returns:

Type Description
MoneroTxQuery

tx query copy.

deserialize_from_block(tx_query_json) staticmethod

Deserialize transaction query from JSON string.

Parameters:

Name Type Description Default
tx_query_json str

tx query as JSON string.

required

Returns:

Type Description
MoneroTxQuery

deserialized tx query.

meets_criteria(tx, query_children=False)

Check if transaction wallet meets all criteria defined in this query.

Parameters:

Name Type Description Default
tx MoneroTxWallet

Tx to check if meets criteria defined in this query.

required
query_children bool

Query child data.

False

Returns:

Type Description
bool

True if tx meets all criteria defined in this query, False otherwise.

MoneroTxSet

Bases: SerializableStruct

Groups transactions who share common hex data which is needed in order to sign and submit the transactions.

For example, multisig transactions created from create_txs() share a common hex string which is needed in order to sign and submit the multisig transactions.

multisig_tx_hex: str | None instance-attribute

Multisignature transaction hex.

signed_tx_hex: str | None instance-attribute

Signed transaction hex.

txs: list[MoneroTxWallet] instance-attribute

List of transactions defined in this set.

unsigned_tx_hex: str | None instance-attribute

Unsigned transaction hex.

__init__()

Initialize a Monero transaction set.

deserialize(tx_set_json) staticmethod

Deserialize a Monero transaction set from a JSON string.

Parameters:

Name Type Description Default
tx_set_json str

tx set as JSON string.

required

Returns:

Type Description
MoneroTxSet

The deseriliazed transaction set.

MoneroIntegratedAddress

Bases: SerializableStruct

Models a Monero integrated address.

integrated_address: str instance-attribute

The integrated address.

payment_id: str instance-attribute

The payment id related to this integrated address.

standard_address: str instance-attribute

The standard address related to this integrated address.

__init__()

Initialize a Monero integrated address.

MoneroTxPriority

Bases: IntEnum

Enumerates Monero transaction priorities.

DEFAULT = 0 class-attribute instance-attribute

0 Default transaction priority.

ELEVATED = 3 class-attribute instance-attribute

3 Elevated transaction priority.

NORMAL = 2 class-attribute instance-attribute

2 Normal transaction priority.

UNIMPORTANT = 1 class-attribute instance-attribute

1 Unimportant transaction priority.

MoneroTxConfig

Bases: SerializableStruct

Configures a transaction to send, sweep, or create a payment URI.

account_index: int | None instance-attribute

Account index to send funds from.

address: str | None instance-attribute

Transaction address destination.

amount: int | None instance-attribute

Transaction amount.

below_amount: int | None instance-attribute

Ignore output amount below.

can_split: bool | None instance-attribute

Indicates if transaction can be splitted in multiple transactions.

destinations: list[MoneroDestination] instance-attribute

Transaction outgoing destinations.

fee: int | None instance-attribute

Transaction fee.

key_image: str | None instance-attribute

Use a particular key image as input for transaction.

note: str | None instance-attribute

Transaction note.

payment_id: str | None instance-attribute

Transaction payment id.

priority: MoneroTxPriority | None instance-attribute

Transaction priority.

recipient_name: str | None instance-attribute

Recipient name.

relay: bool | None instance-attribute

Indicates if transaction should be relayed (True) or not (False).

ring_size: int | None instance-attribute

Transaction ring size

subaddress_indices: list[int] instance-attribute

Account subaddresses indices to send funds from.

subtract_fee_from: list[int] instance-attribute

Subtract fee from outputs.

sweep_each_subaddress: bool | None instance-attribute

Sweep each wallet subbaddress.

copy()

Copy current tx config.

Returns:

Type Description
MoneroTxConfig

tx config copy.

deserialize(config_json) staticmethod

Deserialize tx config from JSON string.

Parameters:

Name Type Description Default
config_json str

tx config in JSON format.

required

Returns:

Type Description
MoneroTxConfig

deserialized tx config.

get_normalized_destinations()

Get all destinations set in current tx config.

Returns:

Type Description
list[MoneroDestination]

normalized tx config destinations.

set_address(address)

Set the address of a single-destination configuration.

Parameters:

Name Type Description Default
address str

the address to set for the single destination.

required

MoneroKeyImageImportResult

Bases: SerializableStruct

Models results from importing key images.

height: int | None instance-attribute

Height at which the last key image was imported. Can be 0 if blockchain height is not known.

spent_amount: int | None instance-attribute

Amount (in atomic-units) spent from those key images.

unspent_amount: int | None instance-attribute

Amount (in atomic-units) still available from those key images.

__init__()

Initialize a Monero key image import result.

MoneroMessageSignatureType

Bases: IntEnum

Enumerates the type of a Monero message signature.

SIGN_WITH_SPEND_KEY = 0 class-attribute instance-attribute

0 Indicates that the message verification was signed with the wallet private spend key_.

.. _private spend key: https://docs.getmonero.org/cryptography/asymmetric/private-key/#private-spend-key

SIGN_WITH_VIEW_KEY = 1 class-attribute instance-attribute

1 Indicates that the message verification was signed with the wallet private view key_.

.. _private view key: https://docs.getmonero.org/cryptography/asymmetric/private-key/#private-spend-key

MoneroMessageSignatureResult

Bases: SerializableStruct

Models results from message verification.

is_good: bool instance-attribute

Indicates if the message verification was successful.

is_old: bool instance-attribute

Indicates if the message verification used old monero software.

signature_type: MoneroMessageSignatureType instance-attribute

Signature type used in the message verification.

version: int instance-attribute

Message signature version.

__init__()

Initialize a Monero message signature result.

MoneroCheck

Bases: SerializableStruct

Base model for results from checking a transaction or reserve proof.

is_good: bool instance-attribute

Indicates if check was successfull.

__init__()

Initialize a Monero check.

MoneroCheckTx

Bases: MoneroCheck

Models the results from checking a transaction key.

in_tx_pool: bool | None instance-attribute

States if the transaction is in pool (True) or included in a block (False)

num_confirmations: int | None instance-attribute

Transaction network confirmations.

received_amount: int | None instance-attribute

Amount received in the transaction.

__init__()

Initialize a Monero transaction check.

MoneroCheckReserve

Bases: MoneroCheck

Models the results from checking a reserve proof.

total_amount: int | None instance-attribute

The reserve total amount.

unconfirmed_spent_amount: int | None instance-attribute

The reserve unconfirmed spent amount.

__init__()

Initialize a Monero reserve check.

MoneroMultisigInfo

Bases: SerializableStruct

Models information about a multisig wallet.

is_multisig: bool instance-attribute

Indicates if the wallet is multisignature (True), or not (False).

is_ready: bool instance-attribute

Indicates if the wallet is ready to support multisignature operations (True) or not (False).

num_participants: int instance-attribute

Number of participants of the multisignature wallet.

threshold: int instance-attribute

Number of participants need in order to sign a transaction.

__init__()

Initialize a Monero multisignature info.

MoneroMultisigInitResult

Bases: SerializableStruct

Models the result of initializing a multisig wallet which results in the multisig wallet's address xor another multisig hex to share with participants to create the wallet.

address: str | None instance-attribute

The multisignature wallet address.

multisig_hex: str | None instance-attribute

The multisignature hex to share with other participants.

__init__()

Initialize a Monero multisignature initializing result.

MoneroMultisigSignResult

Bases: SerializableStruct

Models the result of signing multisig tx hex.

signed_multisig_tx_hex: str | None instance-attribute

Multisig transaction in hex format.

tx_hashes: list[str] instance-attribute

List of transaction hash.

__init__()

Initialize a Monero multisignature signature result.

MoneroAddressBookEntry

Bases: SerializableStruct

Monero address book entry model.

address: str | None instance-attribute

The book entry address.

description: str | None instance-attribute

The book entry description.

index: int | None instance-attribute

The book entry index.

payment_id: str | None instance-attribute

The book entry payment id.

MoneroAddressType

Bases: IntEnum

Models a Monero public address type_.

.. _Monero public address type: https://docs.getmonero.org/public-address/

INTEGRATED_ADDRESS = 1 class-attribute instance-attribute

1 Indicates that the Monero address format is integrated_.

.. _integrated: https://docs.getmonero.org/public-address/integrated-address/

PRIMARY_ADDRESS = 0 class-attribute instance-attribute

0 Indicates that the Monero address format is standard_, also known as primary.

.. _standard: https://docs.getmonero.org/public-address/standard-address/

SUBADDRESS = 2 class-attribute instance-attribute

2 Indicates that the Monero address format is subaddress_.

.. _subaddress: https://docs.getmonero.org/public-address/subaddress/

MoneroDecodedAddress

Bases: SerializableStruct

Maintains metadata for a decoded address.

address: str instance-attribute

The decoded address.

address_type: MoneroAddressType instance-attribute

Type of the decoded address.

network_type: MoneroNetworkType instance-attribute

Network type of the decoded address.

__init__(address, address_type, network_type)

Initialize a Monero decoded address.

Parameters:

Name Type Description Default
address str

The decoded address.

required
address_type MoneroAddressType

The type of the decoded address.

required
network_type MoneroNetworkType

Network type of the decoded address.

required

MoneroAccountTag

Bases: SerializableStruct

Models a Monero account tag.

account_indices: list[int] instance-attribute

Account indices with this tag.

label: str | None instance-attribute

The account tag label.

tag: str | None instance-attribute

The account tag.

MoneroWalletListener

Interface to receive wallet notifications.

__init__()

Initialize a wallet listener.

on_balances_changed(new_balance, new_unlocked_balance)

Invoked when the wallet's balances change.

Parameters:

Name Type Description Default
new_balance int

new balance.

required
new_unlocked_balance int

new unlocked balance.

required

on_new_block(height)

Invoked when a new block is processed.

Parameters:

Name Type Description Default
height int

the newly processed block.

required

on_output_received(output)

Invoked when the wallet receives an output.

Parameters:

Name Type Description Default
output MoneroOutputWallet

the received output.

required

on_output_spent(output)

Invoked when the wallet spends an output.

Parameters:

Name Type Description Default
output MoneroOutputWallet

the spent output.

required

on_sync_progress(height, start_height, end_height, percent_done, message)

Invoked when sync progress is made.

Parameters:

Name Type Description Default
height int

height of the synced block.

required
start_height int

starting height of the sync request.

required
end_height int

ending height of the sync request.

required
percent_done float

sync progress as a percentage.

required
message str

human-readable description of the current progress.

required
\ No newline at end of file + Wallet Data Model - Monero Python
Skip to content

Wallet Data Model

MoneroWalletConfig

Bases: SerializableStruct

Configures a wallet to create.

account_lookahead: int | None instance-attribute

Account index look ahead.

is_multisig: bool | None instance-attribute

Indicates if the wallet is a multisignature wallet.

language: str | None instance-attribute

The wallet language.

network_type: MoneroNetworkType | None instance-attribute

The wallet network type.

password: str | None instance-attribute

The wallet password.

path: str | None instance-attribute

The wallet path on file system.

primary_address: str | None instance-attribute

The wallet standard address.

private_spend_key: str | None instance-attribute

The wallet private spend key.

private_view_key: str | None instance-attribute

The wallet private view key.

regtest: bool | None instance-attribute

Indicates if wallet is regtest.

restore_height: int | None instance-attribute

The wallet restore height.

save_current: bool | None instance-attribute

Save the wallet.

seed: str | None instance-attribute

The wallet mnemonic.

seed_offset: str | None instance-attribute

The wallet custom seed offset.

server: MoneroRpcConnection | None instance-attribute

The wallet RPC connection.

subaddress_lookahead: int | None instance-attribute

Subaddress index look ahead.

copy()

Copy this wallet config.

Returns:

Type Description
MoneroWalletConfig

Copy of the wallet config.

deserialize(config_json) staticmethod

Deserialize a Monero wallet config from a JSON string.

Parameters:

Name Type Description Default
config_json str

JSON string.

required

Returns:

Type Description
MoneroWalletConfig

The deserialized wallet config.

MoneroSyncResult

Bases: SerializableStruct

Models a result of syncing a wallet.

num_blocks_fetched: int instance-attribute

Number of blocks fetched.

received_money: bool instance-attribute

Indicates if money was received.

MoneroSubaddress

Bases: SerializableStruct

Models a Monero subaddress.

account_index: int | None instance-attribute

The subaddress account index.

address: str | None instance-attribute

Public address.

balance: int | None instance-attribute

The subaddress balance.

index: int | None instance-attribute

The subaddress index.

is_used: bool | None instance-attribute

Indicates if subaddress has been used in receiving funds.

label: str | None instance-attribute

The subaddress label.

num_blocks_to_unlock: int | None instance-attribute

Number of blocks to unlock receveid outputs.

num_unspent_outputs: int | None instance-attribute

The number of unspent outputs in this subaddress.

unlocked_balance: int | None instance-attribute

The subaddress unlocked balance.

__init__()

Initialize a Monero subaddress.

MoneroAccount

Bases: SerializableStruct

Models a Monero account.

balance: int | None instance-attribute

The account balance.

index: int | None instance-attribute

The account index.

primary_address: str | None instance-attribute

The account primary address.

subaddresses: list[MoneroSubaddress] instance-attribute

List of account subaddresses.

tag: str | None instance-attribute

The account tag.

unlocked_balance: int | None instance-attribute

The account unlocked balance.

__init__()

Initialize a Monero account.

MoneroDestination

Bases: SerializableStruct

Models an outgoing transfer destination.

address: str | None instance-attribute

Address of the receiver.

amount: int | None instance-attribute

Amount sent to this destination.

copy()

Copy current outgoing transfer destination.

Returns:

Type Description
MoneroDestination

outgoing transfer destination copy.

MoneroTransfer

Bases: SerializableStruct

Models a base transfer of funds to or from the wallet.

account_index: int | None instance-attribute

Index of the account related to this transfer.

amount: int | None instance-attribute

Transfer amount in atomic-units.

tx: MoneroTxWallet instance-attribute

Related wallet transaction.

__init__()

Initialize a Monero transfer.

copy()

Copy current transfer.

Returns:

Type Description
MoneroTransfer

transfer copy.

is_incoming()

Indicates if it is an incoming transfer (True) or not (False). Default None.

Returns:

Type Description
bool | None

True if current transfer is incoming, False if outgoing, None if unkown.

is_outgoing()

Indicates if it is an outgoing transfer (True) or not (False). Default None.

Returns:

Type Description
bool | None

True if current transfer is outgoing, False if incoming, None if unkown.

merge(other)

Merge current transfer with another one.

Parameters:

Name Type Description Default
other MoneroTransfer

other transfer to merge with.

required

MoneroIncomingTransfer

Bases: MoneroTransfer

Models an incoming transfer of funds to the wallet.

address: str | None instance-attribute

The address that received funds within this transfer.

num_suggested_confirmations: int | None instance-attribute

The number of suggested confirmations before moving funds.

subaddress_index: int | None instance-attribute

The subaddress index that received funds within this transfer.

__init__()

Initialize a Monero incoming transfer.

copy()

Copy current incoming transfer.

Returns:

Type Description
MoneroIncomingTransfer

incoming transfer copy.

MoneroOutgoingTransfer

Bases: MoneroTransfer

Models an outgoing transfer of funds from the wallet.

addresses: list[str] instance-attribute

Addresses from which the transfer originated.

destinations: list[MoneroDestination] instance-attribute

Outgoing transfer destinations.

subaddress_indices: list[int] instance-attribute

Subaddresses from which the transfer originated.

copy()

Copy current outgoing transfer.

Returns:

Type Description
MoneroOutgoingTransfer

outgoing transfer copy.

MoneroTransferQuery

Bases: MoneroTransfer

Configures a query to retrieve transfers.

All transfers are returned except those that do not meet the criteria defined in this query.

address: str | None instance-attribute

Select transfers involving particular address. Empty for all.

addresses: list[str] instance-attribute

Select transfers involving particular addresses. Empty for all.

destinations: list[MoneroDestination] instance-attribute

Select transfers involving particular destinations. Empty for all.

has_destinations: bool | None instance-attribute

Filter transfers with or without destinations. None for all.

incoming: bool | None instance-attribute

Filter incoming or outgoing transfers. None for all.

outgoing: bool | None instance-attribute

Filter incoming or outgoing transfers. None for all.

subaddress_index: int | None instance-attribute

Filter by subaddress index. None for all.

subaddress_indices: list[int] instance-attribute

Select transfers involving particular subaddresses. Empty for all.

tx_query: MoneroTxQuery | None instance-attribute

Related transaction query.

__init__()

Initialize a Monero transfer query.

copy()

Copy current transfer query.

Returns:

Type Description
MoneroTransferQuery

transfer query copy.

deserialize_from_block(transfer_query_json) staticmethod

Deserialize transfer query from json block.

Parameters:

Name Type Description Default
transfer_query_json str

json block with serialized transfer query.

required

Returns:

Type Description
MoneroTransferQuery

deserialized transfer query.

meets_criteria(transfer, query_parent=True)

Check if transfer meets all the criteria defined in this query.

Parameters:

Name Type Description Default
transfer MoneroTransfer

transfer to check if meets criteria.

required
query_parent bool

query parent tx query (default True).

True

Returns:

Type Description
bool

True if transfer meets all criteria defined in this query, False otherwise.

MoneroOutputWallet

Bases: MoneroOutput

Models a Monero output with wallet extensions.

account_index: int | None instance-attribute

The index of the account that owns this output.

is_frozen: bool | None instance-attribute

Indicates if the output is frozen (True) or not (False).

is_spent: bool | None instance-attribute

Indicates if the output is spent (True) or not (False).

subaddress_index: int | None instance-attribute

The index of the subaddress that owns this output.

__init__()

Initialize a Monero wallet output.

copy()

Copy current output wallet.

Returns:

Type Description
MoneroOutputWallet

output wallet copy.

MoneroOutputQuery

Bases: MoneroOutputWallet

Configures a query to retrieve wallet outputs (i.e. outputs that the wallet has or had the ability to spend).

All outputs are returned except those that do not meet the criteria defined in this query.

max_amount: int | None instance-attribute

Filter outputs above this amount.

min_amount: int | None instance-attribute

Filter outputs below this amount.

subaddress_indices: list[int] instance-attribute

Subadress indices to select (empty for all).

tx_query: MoneroTxQuery | None property

Related transaction query.

__init__()

Initialize a Monero output query.

copy()

Copy current output query.

Returns:

Type Description
MoneroOutputQuery

output query copy.

deserialize_from_block(output_query_json) staticmethod

Deserialize output query from block.

Parameters:

Name Type Description Default
output_query_json str

json query block.

required

Returns:

Type Description
MoneroOutputQuery

deserialized output query.

meets_criteria(output, query_parent=True)

Indicates if the output meets all the criteria defined within this query.

Parameters:

Name Type Description Default
output MoneroOutputWallet

Output to check.

required
query_parent bool

Query also parent.

True

Returns:

Type Description
bool

True if output meets all the criteria defined in this query, False otherwise.

set_tx_query(tx_query, output_query)

Set related transaction query.

This method sets query references constitutively.

Parameters:

Name Type Description Default
tx_query Optional[MoneroTxQuery]

Tx query to set.

required
output_query bool

If True sets outputs query in tx_query, otherwise inputs query.

required

MoneroTxWallet

Bases: MoneroTx

Models a Monero transaction in the context of a wallet.

change_address: str | None instance-attribute

Address to which the change amount of the transaction was sent.

change_amount: int | None instance-attribute

Change amount of the transaction.

extra_hex: str | None instance-attribute

Extra information about the transaction in hexadecimal format.

incoming_transfers: list[MoneroIncomingTransfer] instance-attribute

List of incoming transfer.

input_sum: int | None instance-attribute

Total input sum.

is_incoming: bool | None instance-attribute

Indicates if the transaction has incoming transfers.

is_locked: bool | None instance-attribute

Indicates if the transaction is locked.

is_outgoing: bool | None instance-attribute

Indicated if the transaction has outgoing transfer.

note: str | None instance-attribute

Transaction note.

num_dummy_outputs: int | None instance-attribute

Number of decoys of the transactions.

outgoing_transfer: MoneroOutgoingTransfer | None instance-attribute

The outgoing transfer related to this transaction.

output_sum: int | None instance-attribute

The total output amount sum originated from this transaction.

tx_set: MoneroTxSet | None instance-attribute

Set of transactions related to current tx.

__init__()

Initialize a new Monero tx wallet.

copy()

Copy current tx wallet.

Returns:

Type Description
MoneroTxWallet

tx wallet copy.

filter_outputs_wallet(query)

Get outputs filtered by query.

Parameters:

Name Type Description Default
query MoneroOutputQuery

query to filter outputs with.

required

Returns:

Type Description
list[MoneroOutputWallet]

outputs that meets all criteria defined in query.

filter_transfers(query)

Get transfers filtered by query.

Parameters:

Name Type Description Default
query MoneroTransferQuery

query to filter transfers with.

required

Returns:

Type Description
list[MoneroTransfer]

transfers that meets all criteria defined in query.

get_incoming_amount()

Get total amount received in current tx.

Returns:

Type Description
int

total amount received in current wallet tx.

get_inputs_wallet(query=None)

Get wallet inputs filtered by query.

Parameters:

Name Type Description Default
query MoneroOutputQuery

query to filter outputs with.

None

Returns:

Type Description
list[MoneroOutputWallet]

wallet outputs filtered by query.

get_outgoing_amount()

Get total amount spent in current tx.

Returns:

Type Description
int

total amount spent in current wallet tx.

MoneroTxQuery

Bases: MoneroTxWallet

Configures a query to retrieve transactions.

All transactions are returned except those that do not meet the criteria defined in this query.

has_payment_id: bool | None instance-attribute

Get transactions that have a payment id.

hashes: list[str] instance-attribute

Get transactions by hashes.

height: int | None instance-attribute

Get transactions by height.

include_outputs: int | None instance-attribute

Include outputs in transaction data.

input_query: MoneroOutputQuery | None instance-attribute

Query to apply on transaction inputs.

is_incoming: bool | None instance-attribute

Include incoming transactions.

is_outgoing: bool | None instance-attribute

Include outgoing transactions.

max_height: int | None instance-attribute

Get transactions below max height.

min_height: int | None instance-attribute

Get transactions above max height.

output_query: MoneroOutputQuery | None instance-attribute

Query to apply on transaction outputs.

payment_ids: list[str] instance-attribute

Get transactions with specific payment ids.

transfer_query: MoneroTransferQuery | None instance-attribute

Query to apply on transaction wallet transfer.

__init__()

Initiliaze a new Monero transaction query.

copy()

Copy current transaction query.

Returns:

Type Description
MoneroTxQuery

tx query copy.

deserialize_from_block(tx_query_json) staticmethod

Deserialize transaction query from JSON string.

Parameters:

Name Type Description Default
tx_query_json str

tx query as JSON string.

required

Returns:

Type Description
MoneroTxQuery

deserialized tx query.

meets_criteria(tx, query_children=False)

Check if transaction wallet meets all criteria defined in this query.

Parameters:

Name Type Description Default
tx MoneroTxWallet

Tx to check if meets criteria defined in this query.

required
query_children bool

Query child data.

False

Returns:

Type Description
bool

True if tx meets all criteria defined in this query, False otherwise.

MoneroTxSet

Bases: SerializableStruct

Groups transactions who share common hex data which is needed in order to sign and submit the transactions.

For example, multisig transactions created from create_txs() share a common hex string which is needed in order to sign and submit the multisig transactions.

multisig_tx_hex: str | None instance-attribute

Multisignature transaction hex.

signed_tx_hex: str | None instance-attribute

Signed transaction hex.

txs: list[MoneroTxWallet] instance-attribute

List of transactions defined in this set.

unsigned_tx_hex: str | None instance-attribute

Unsigned transaction hex.

__init__()

Initialize a Monero transaction set.

deserialize(tx_set_json) staticmethod

Deserialize a Monero transaction set from a JSON string.

Parameters:

Name Type Description Default
tx_set_json str

tx set as JSON string.

required

Returns:

Type Description
MoneroTxSet

The deseriliazed transaction set.

MoneroIntegratedAddress

Bases: SerializableStruct

Models a Monero integrated address.

integrated_address: str instance-attribute

The integrated address.

payment_id: str instance-attribute

The payment id related to this integrated address.

standard_address: str instance-attribute

The standard address related to this integrated address.

__init__()

Initialize a Monero integrated address.

MoneroTxPriority

Bases: IntEnum

Enumerates Monero transaction priorities.

DEFAULT = 0 class-attribute instance-attribute

0 Default transaction priority.

ELEVATED = 3 class-attribute instance-attribute

3 Elevated transaction priority.

NORMAL = 2 class-attribute instance-attribute

2 Normal transaction priority.

UNIMPORTANT = 1 class-attribute instance-attribute

1 Unimportant transaction priority.

MoneroTxConfig

Bases: SerializableStruct

Configures a transaction to send, sweep, or create a payment URI.

account_index: int | None instance-attribute

Account index to send funds from.

address: str | None instance-attribute

Transaction address destination.

amount: int | None instance-attribute

Transaction amount.

below_amount: int | None instance-attribute

Ignore output amount below.

can_split: bool | None instance-attribute

Indicates if transaction can be splitted in multiple transactions.

destinations: list[MoneroDestination] instance-attribute

Transaction outgoing destinations.

fee: int | None instance-attribute

Transaction fee.

key_image: str | None instance-attribute

Use a particular key image as input for transaction.

note: str | None instance-attribute

Transaction note.

payment_id: str | None instance-attribute

Transaction payment id.

priority: MoneroTxPriority | None instance-attribute

Transaction priority.

recipient_name: str | None instance-attribute

Recipient name.

relay: bool | None instance-attribute

Indicates if transaction should be relayed (True) or not (False).

ring_size: int | None instance-attribute

Transaction ring size

subaddress_indices: list[int] instance-attribute

Account subaddresses indices to send funds from.

subtract_fee_from: list[int] instance-attribute

Subtract fee from outputs.

sweep_each_subaddress: bool | None instance-attribute

Sweep each wallet subbaddress.

copy()

Copy current tx config.

Returns:

Type Description
MoneroTxConfig

tx config copy.

deserialize(config_json) staticmethod

Deserialize tx config from JSON string.

Parameters:

Name Type Description Default
config_json str

tx config in JSON format.

required

Returns:

Type Description
MoneroTxConfig

deserialized tx config.

get_normalized_destinations()

Get all destinations set in current tx config.

Returns:

Type Description
list[MoneroDestination]

normalized tx config destinations.

set_address(address)

Set the address of a single-destination configuration.

Parameters:

Name Type Description Default
address str

the address to set for the single destination.

required

MoneroKeyImageImportResult

Bases: SerializableStruct

Models results from importing key images.

height: int | None instance-attribute

Height at which the last key image was imported. Can be 0 if blockchain height is not known.

spent_amount: int | None instance-attribute

Amount (in atomic-units) spent from those key images.

unspent_amount: int | None instance-attribute

Amount (in atomic-units) still available from those key images.

__init__()

Initialize a Monero key image import result.

MoneroMessageSignatureType

Bases: IntEnum

Enumerates the type of a Monero message signature.

SIGN_WITH_SPEND_KEY = 0 class-attribute instance-attribute

0 Indicates that the message verification was signed with the wallet private spend key_.

.. _private spend key: https://docs.getmonero.org/cryptography/asymmetric/private-key/#private-spend-key

SIGN_WITH_VIEW_KEY = 1 class-attribute instance-attribute

1 Indicates that the message verification was signed with the wallet private view key_.

.. _private view key: https://docs.getmonero.org/cryptography/asymmetric/private-key/#private-spend-key

MoneroMessageSignatureResult

Bases: SerializableStruct

Models results from message verification.

is_good: bool instance-attribute

Indicates if the message verification was successful.

is_old: bool instance-attribute

Indicates if the message verification used old monero software.

signature_type: MoneroMessageSignatureType instance-attribute

Signature type used in the message verification.

version: int instance-attribute

Message signature version.

__init__()

Initialize a Monero message signature result.

MoneroCheck

Bases: SerializableStruct

Base model for results from checking a transaction or reserve proof.

is_good: bool instance-attribute

Indicates if check was successfull.

__init__()

Initialize a Monero check.

MoneroCheckTx

Bases: MoneroCheck

Models the results from checking a transaction key.

in_tx_pool: bool | None instance-attribute

States if the transaction is in pool (True) or included in a block (False)

num_confirmations: int | None instance-attribute

Transaction network confirmations.

received_amount: int | None instance-attribute

Amount received in the transaction.

__init__()

Initialize a Monero transaction check.

MoneroCheckReserve

Bases: MoneroCheck

Models the results from checking a reserve proof.

total_amount: int | None instance-attribute

The reserve total amount.

unconfirmed_spent_amount: int | None instance-attribute

The reserve unconfirmed spent amount.

__init__()

Initialize a Monero reserve check.

MoneroMultisigInfo

Bases: SerializableStruct

Models information about a multisig wallet.

is_multisig: bool instance-attribute

Indicates if the wallet is multisignature (True), or not (False).

is_ready: bool instance-attribute

Indicates if the wallet is ready to support multisignature operations (True) or not (False).

num_participants: int instance-attribute

Number of participants of the multisignature wallet.

threshold: int instance-attribute

Number of participants need in order to sign a transaction.

__init__()

Initialize a Monero multisignature info.

MoneroMultisigInitResult

Bases: SerializableStruct

Models the result of initializing a multisig wallet which results in the multisig wallet's address xor another multisig hex to share with participants to create the wallet.

address: str | None instance-attribute

The multisignature wallet address.

multisig_hex: str | None instance-attribute

The multisignature hex to share with other participants.

__init__()

Initialize a Monero multisignature initializing result.

MoneroMultisigSignResult

Bases: SerializableStruct

Models the result of signing multisig tx hex.

signed_multisig_tx_hex: str | None instance-attribute

Multisig transaction in hex format.

tx_hashes: list[str] instance-attribute

List of transaction hash.

__init__()

Initialize a Monero multisignature signature result.

MoneroAddressBookEntry

Bases: SerializableStruct

Monero address book entry model.

address: str | None instance-attribute

The book entry address.

description: str | None instance-attribute

The book entry description.

index: int | None instance-attribute

The book entry index.

payment_id: str | None instance-attribute

The book entry payment id.

MoneroAddressType

Bases: IntEnum

Models a Monero public address type_.

.. _Monero public address type: https://docs.getmonero.org/public-address/

INTEGRATED_ADDRESS = 1 class-attribute instance-attribute

1 Indicates that the Monero address format is integrated_.

.. _integrated: https://docs.getmonero.org/public-address/integrated-address/

PRIMARY_ADDRESS = 0 class-attribute instance-attribute

0 Indicates that the Monero address format is standard_, also known as primary.

.. _standard: https://docs.getmonero.org/public-address/standard-address/

SUBADDRESS = 2 class-attribute instance-attribute

2 Indicates that the Monero address format is subaddress_.

.. _subaddress: https://docs.getmonero.org/public-address/subaddress/

MoneroDecodedAddress

Bases: SerializableStruct

Maintains metadata for a decoded address.

address: str instance-attribute

The decoded address.

address_type: MoneroAddressType instance-attribute

Type of the decoded address.

network_type: MoneroNetworkType instance-attribute

Network type of the decoded address.

__init__(address, address_type, network_type)

Initialize a Monero decoded address.

Parameters:

Name Type Description Default
address str

The decoded address.

required
address_type MoneroAddressType

The type of the decoded address.

required
network_type MoneroNetworkType

Network type of the decoded address.

required

MoneroAccountTag

Bases: SerializableStruct

Models a Monero account tag.

account_indices: list[int] instance-attribute

Account indices with this tag.

label: str | None instance-attribute

The account tag label.

tag: str | None instance-attribute

The account tag.

MoneroWalletListener

Interface to receive wallet notifications.

__init__()

Initialize a wallet listener.

on_balances_changed(new_balance, new_unlocked_balance)

Invoked when the wallet's balances change.

Parameters:

Name Type Description Default
new_balance int

new balance.

required
new_unlocked_balance int

new unlocked balance.

required

on_new_block(height)

Invoked when a new block is processed.

Parameters:

Name Type Description Default
height int

the newly processed block.

required

on_output_received(output)

Invoked when the wallet receives an output.

Parameters:

Name Type Description Default
output MoneroOutputWallet

the received output.

required

on_output_spent(output)

Invoked when the wallet spends an output.

Parameters:

Name Type Description Default
output MoneroOutputWallet

the spent output.

required

on_sync_progress(height, start_height, end_height, percent_done, message)

Invoked when sync progress is made.

Parameters:

Name Type Description Default
height int

height of the synced block.

required
start_height int

starting height of the sync request.

required
end_height int

ending height of the sync request.

required
percent_done float

sync progress as a percentage.

required
message str

human-readable description of the current progress.

required
\ No newline at end of file diff --git a/docs/mkdocs/public/api/utils/index.html b/docs/mkdocs/public/api/utils/index.html index 28a2ad6..76932ee 100644 --- a/docs/mkdocs/public/api/utils/index.html +++ b/docs/mkdocs/public/api/utils/index.html @@ -1 +1 @@ - Monero Utilities - Monero Python
Skip to content

Monero Utilities

MoneroUtils

Collection of Monero utilities.

atomic_units_to_xmr(amount_atomic_units) staticmethod

Convert atomic units to XMR.

Parameters:

Name Type Description Default
amount_atomic_units int

amount in atomic units to convert to XMR.

required

Returns:

Type Description
float

amount in XMR.

binary_blocks_to_json(bin) staticmethod

Deserialize blocks JSON string from binary format.

Parameters:

Name Type Description Default
bin bytes

blocks JSON string in binary format.

required

Returns:

Type Description
str

The deserialized blocks in JSON string format.

binary_to_dict(bin) staticmethod

Deserialize a dictionary from binary format.

Parameters:

Name Type Description Default
bin bytes

Dictionary in binary format.

required

Returns:

Type Description
dict[Any, Any]

Deserialized dictionary.

binary_to_json(bin) staticmethod

Deserialize a JSON string from binary format.

Parameters:

Name Type Description Default
bin bytes

JSON string in binary format.

required

Returns:

Type Description
str

The deserialized JSON string.

configure_logging(path, console) staticmethod

Initialize logging.

Parameters:

Name Type Description Default
path str

the path to write logs to.

required
console bool

specifies whether or not to write to the console.

required

dict_to_binary(dictionary) staticmethod

Converts a dictionary into binary format.

Parameters:

Name Type Description Default
dictionary dict

The dictionary to convert in binary format.

required

Returns:

Type Description
bytes

Binary format.

get_blocks_from_outputs(outputs) staticmethod

Get distinct blocks from outputs.

Parameters:

Name Type Description Default
outputs list[MoneroOutputWallet]

Outputs to get blocks from.

required

Returns:

Type Description
list[MoneroBlock]

Distinct blocks obtained from outputs.

get_blocks_from_transfers(transfers) staticmethod

Get distinct blocks from transfers.

Parameters:

Name Type Description Default
transfers list[MoneroTransfer]

Transfers to get blocks from.

required

Returns:

Type Description
list[MoneroBlock]

Distinct blocks obtained from transfers.

get_blocks_from_txs(txs) staticmethod

Get distinct blocks from transactions.

Parameters:

Name Type Description Default
txs list[MoneroTxWallet]

Transactions to get blocks from.

required

Returns:

Type Description
list[MoneroBlock]

Distinct blocks obtained from transactions.

get_integrated_address(network_type, standard_address, payment_id='') staticmethod

Get an integrated address.

Parameters:

Name Type Description Default
network_type MoneroNetworkType

is the network type of the integrated address.

required
standard_address str

is the address to derive the integrated address from.

required
payment_id str

optionally specifies the integrated address's payment id (defaults to random payment id).

''

Returns:

Type Description
MoneroIntegratedAddress

the integrated address.

get_payment_uri(config, network_type=MoneroNetworkType.MAINNET) staticmethod

Creates a payment URI from a tx configuration.

Parameters:

Name Type Description Default
config MoneroTxConfig

specifies configuration for a payment URI.

required
network_type MoneroNetworkType

address network type (optional).

MAINNET

Returns:

Type Description
str

the payment URI.

get_ring_size() staticmethod

Get network-enforced ring size.

Returns:

Type Description
int

network-enforced ring size.

get_version() staticmethod

Get the version of the monero-python library.

Returns:

Type Description
str

the version of this monero-python library

is_valid_address(address, network_type) staticmethod

Determine if the given address is valid.

Parameters:

Name Type Description Default
address str

is the address to validate.

required
network_type MoneroNetworkType

is the address's network type.

required

Returns:

Type Description
bool

True if the address is valid, False otherwise.

is_valid_language(language) staticmethod

Indicates if the given language is valid.

Parameters:

Name Type Description Default
language str

is the language to validate

required

Returns:

Type Description
bool

True if the language is valid, False otherwise.

is_valid_mnemonic(mnemonic) staticmethod

Indicates if a mnemonic is valid.

Parameters:

Name Type Description Default
mnemonic str

is the mnemonic to validate.

required

Returns:

Type Description
bool

True if the mnemonic is valid, False otherwise.

is_valid_payment_id(payment_id) staticmethod

Indicates if a payment id is valid.

Parameters:

Name Type Description Default
payment_id str

is the payment id to validate.

required

Returns:

Type Description
bool

True if the payment id is valid, False otherwise.

is_valid_private_spend_key(private_spend_key) staticmethod

Indicates if a private spend key is valid.

Parameters:

Name Type Description Default
private_spend_key str

is the private spend key to validate.

required

Returns:

Type Description
bool

True if the private spend key is valid, False otherwise.

is_valid_private_view_key(private_view_key) staticmethod

Indicates if a private view key is valid.

Parameters:

Name Type Description Default
private_view_key str

is the private view key to validate.

required

Returns:

Type Description
bool

True if the private view key is valid, False otherwise.

is_valid_public_spend_key(public_spend_key) staticmethod

Indicates if a public spend key is valid.

Parameters:

Name Type Description Default
public_spend_key str

is the public spend key to validate.

required

Returns:

Type Description
bool

True if the public spend key is valid, False otherwise.

is_valid_public_view_key(public_view_key) staticmethod

Indicates if a public view key is valid.

Parameters:

Name Type Description Default
public_view_key str

is the public view key to validate.

required

Returns:

Type Description
bool

True if the public view key is valid, False otherwise.

json_to_binary(json) staticmethod

Convert a JSON string into binary format.

Returns:

Type Description
bytes

Binary format.

set_log_level(loglevel) staticmethod

Set the library's log level with 0 being least verbose.

Parameters:

Name Type Description Default
loglevel int

the library's log level.

required

validate_address(address, network_type) staticmethod

Validates the given address.

Parameters:

Name Type Description Default
address str

is the address to validate.

required
network_type MoneroNetworkType

is the address's network type.

required

validate_mnemonic(mnemonic) staticmethod

Validates the given mnemonic phrase.

Parameters:

Name Type Description Default
mnemonic str

is the mnemonic to validate.

required

Raises:

Type Description
MoneroError

if the given mnemonic is invalid.

validate_payment_id(payment_id) staticmethod

Validate a payment id.

Parameters:

Name Type Description Default
payment_id str

is the payment id to validate.

required

Raises:

Type Description
MoneroError

if the given payment id is invalid.

validate_private_spend_key(private_spend_key) staticmethod

Validate a private spend key.

Parameters:

Name Type Description Default
private_spend_key str

is the private spend key to validate.

required

Raises:

Type Description
MoneroError

if the given private spend key is invalid.

validate_private_view_key(private_view_key) staticmethod

Validate a private view key.

Parameters:

Name Type Description Default
private_view_key str

is the private view key to validate.

required

Raises:

Type Description
MoneroError

if the given private view key is invalid.

validate_public_spend_key(public_spend_key) staticmethod

Validate a public spend key.

Parameters:

Name Type Description Default
public_spend_key str

is the public spend key to validate.

required

Raises:

Type Description
MoneroError

if the given public spend key is invalid.

validate_public_view_key(public_view_key) staticmethod

Validate a public view key.

Parameters:

Name Type Description Default
public_view_key str

is the public view key to validate.

required

Raises:

Type Description
MoneroError

if the given public view key is invalid.

xmr_to_atomic_units(amount_xmr) staticmethod

Convert XMR to atomic units.

Parameters:

Name Type Description Default
amount_xmr float

amount in XMR to convert to atomic units.

required

Returns:

Type Description
int

amount in atomic units.

\ No newline at end of file + Monero Utilities - Monero Python
Skip to content

Monero Utilities

MoneroUtils

Collection of Monero utilities.

atomic_units_to_xmr(amount_atomic_units) staticmethod

Convert atomic units to XMR.

Parameters:

Name Type Description Default
amount_atomic_units int

amount in atomic units to convert to XMR.

required

Returns:

Type Description
float

amount in XMR.

binary_blocks_to_json(bin) staticmethod

Deserialize blocks JSON string from binary format.

Parameters:

Name Type Description Default
bin bytes

blocks JSON string in binary format.

required

Returns:

Type Description
str

The deserialized blocks in JSON string format.

binary_to_dict(bin) staticmethod

Deserialize a dictionary from binary format.

Parameters:

Name Type Description Default
bin bytes

Dictionary in binary format.

required

Returns:

Type Description
dict[Any, Any]

Deserialized dictionary.

binary_to_json(bin) staticmethod

Deserialize a JSON string from binary format.

Parameters:

Name Type Description Default
bin bytes

JSON string in binary format.

required

Returns:

Type Description
str

The deserialized JSON string.

configure_logging(path, console) staticmethod

Initialize logging.

Parameters:

Name Type Description Default
path str

the path to write logs to.

required
console bool

specifies whether or not to write to the console.

required

dict_to_binary(dictionary) staticmethod

Converts a dictionary into binary format.

Parameters:

Name Type Description Default
dictionary dict

The dictionary to convert in binary format.

required

Returns:

Type Description
bytes

Binary format.

get_blocks_from_outputs(outputs) staticmethod

Get distinct blocks from outputs.

Parameters:

Name Type Description Default
outputs list[MoneroOutputWallet]

Outputs to get blocks from.

required

Returns:

Type Description
list[MoneroBlock]

Distinct blocks obtained from outputs.

get_blocks_from_transfers(transfers) staticmethod

Get distinct blocks from transfers.

Parameters:

Name Type Description Default
transfers list[MoneroTransfer]

Transfers to get blocks from.

required

Returns:

Type Description
list[MoneroBlock]

Distinct blocks obtained from transfers.

get_blocks_from_txs(txs) staticmethod

Get distinct blocks from transactions.

Parameters:

Name Type Description Default
txs list[MoneroTxWallet]

Transactions to get blocks from.

required

Returns:

Type Description
list[MoneroBlock]

Distinct blocks obtained from transactions.

get_integrated_address(network_type, standard_address, payment_id='') staticmethod

Get an integrated address.

Parameters:

Name Type Description Default
network_type MoneroNetworkType

is the network type of the integrated address.

required
standard_address str

is the address to derive the integrated address from.

required
payment_id str

optionally specifies the integrated address's payment id (defaults to random payment id).

''

Returns:

Type Description
MoneroIntegratedAddress

the integrated address.

get_payment_uri(config, network_type=MoneroNetworkType.MAINNET) staticmethod

Creates a payment URI from a tx configuration.

Parameters:

Name Type Description Default
config MoneroTxConfig

specifies configuration for a payment URI.

required
network_type MoneroNetworkType

address network type (optional).

MAINNET

Returns:

Type Description
str

the payment URI.

get_ring_size() staticmethod

Get network-enforced ring size.

Returns:

Type Description
int

network-enforced ring size.

get_version() staticmethod

Get the version of the monero-python library.

Returns:

Type Description
str

the version of this monero-python library

is_valid_address(address, network_type) staticmethod

Determine if the given address is valid.

Parameters:

Name Type Description Default
address str

is the address to validate.

required
network_type MoneroNetworkType

is the address's network type.

required

Returns:

Type Description
bool

True if the address is valid, False otherwise.

is_valid_language(language) staticmethod

Indicates if the given language is valid.

Parameters:

Name Type Description Default
language str

is the language to validate

required

Returns:

Type Description
bool

True if the language is valid, False otherwise.

is_valid_mnemonic(mnemonic, language='') staticmethod

Indicates if a mnemonic is valid.

Parameters:

Name Type Description Default
mnemonic str

is the mnemonic to validate.

required
language str

is the mnemonic expected language.

''

Returns:

Type Description
bool

True if the mnemonic is valid, False otherwise.

is_valid_payment_id(payment_id) staticmethod

Indicates if a payment id is valid.

Parameters:

Name Type Description Default
payment_id str

is the payment id to validate.

required

Returns:

Type Description
bool

True if the payment id is valid, False otherwise.

is_valid_private_spend_key(private_spend_key) staticmethod

Indicates if a private spend key is valid.

Parameters:

Name Type Description Default
private_spend_key str

is the private spend key to validate.

required

Returns:

Type Description
bool

True if the private spend key is valid, False otherwise.

is_valid_private_view_key(private_view_key) staticmethod

Indicates if a private view key is valid.

Parameters:

Name Type Description Default
private_view_key str

is the private view key to validate.

required

Returns:

Type Description
bool

True if the private view key is valid, False otherwise.

is_valid_public_spend_key(public_spend_key) staticmethod

Indicates if a public spend key is valid.

Parameters:

Name Type Description Default
public_spend_key str

is the public spend key to validate.

required

Returns:

Type Description
bool

True if the public spend key is valid, False otherwise.

is_valid_public_view_key(public_view_key) staticmethod

Indicates if a public view key is valid.

Parameters:

Name Type Description Default
public_view_key str

is the public view key to validate.

required

Returns:

Type Description
bool

True if the public view key is valid, False otherwise.

json_to_binary(json) staticmethod

Convert a JSON string into binary format.

Returns:

Type Description
bytes

Binary format.

log_debug(message) staticmethod

Log debug message.

Parameters:

Name Type Description Default
message str

the message to log.

required

log_error(message) staticmethod

Log error message.

Parameters:

Name Type Description Default
message str

the message to log.

required

log_info(message) staticmethod

Log info message.

Parameters:

Name Type Description Default
message str

the message to log.

required

log_trace(message) staticmethod

Log trace message.

Parameters:

Name Type Description Default
message str

the message to log.

required

log_warning(message) staticmethod

Log warning message.

Parameters:

Name Type Description Default
message str

the message to log.

required

set_log_categories(categories) staticmethod

Set the library's log categories.

Parameters:

Name Type Description Default
categories str

the library's log categories to set.

required

set_log_level(loglevel) staticmethod

Set the library's log level with 0 being least verbose.

Parameters:

Name Type Description Default
loglevel int

the library's log level.

required

validate_address(address, network_type) staticmethod

Validates the given address.

Parameters:

Name Type Description Default
address str

is the address to validate.

required
network_type MoneroNetworkType

is the address's network type.

required

validate_mnemonic(mnemonic, language='') staticmethod

Validates the given mnemonic phrase.

Parameters:

Name Type Description Default
mnemonic str

is the mnemonic to validate.

required
language str

is the mnemonic expected language.

''

Raises:

Type Description
MoneroError

if the given mnemonic is invalid.

validate_payment_id(payment_id) staticmethod

Validate a payment id.

Parameters:

Name Type Description Default
payment_id str

is the payment id to validate.

required

Raises:

Type Description
MoneroError

if the given payment id is invalid.

validate_private_spend_key(private_spend_key) staticmethod

Validate a private spend key.

Parameters:

Name Type Description Default
private_spend_key str

is the private spend key to validate.

required

Raises:

Type Description
MoneroError

if the given private spend key is invalid.

validate_private_view_key(private_view_key) staticmethod

Validate a private view key.

Parameters:

Name Type Description Default
private_view_key str

is the private view key to validate.

required

Raises:

Type Description
MoneroError

if the given private view key is invalid.

validate_public_spend_key(public_spend_key) staticmethod

Validate a public spend key.

Parameters:

Name Type Description Default
public_spend_key str

is the public spend key to validate.

required

Raises:

Type Description
MoneroError

if the given public spend key is invalid.

validate_public_view_key(public_view_key) staticmethod

Validate a public view key.

Parameters:

Name Type Description Default
public_view_key str

is the public view key to validate.

required

Raises:

Type Description
MoneroError

if the given public view key is invalid.

xmr_to_atomic_units(amount_xmr) staticmethod

Convert XMR to atomic units.

Parameters:

Name Type Description Default
amount_xmr float

amount in XMR to convert to atomic units.

required

Returns:

Type Description
int

amount in atomic units.

\ No newline at end of file diff --git a/docs/mkdocs/public/api/wallet/index.html b/docs/mkdocs/public/api/wallet/index.html index 2b2bf49..765629d 100644 --- a/docs/mkdocs/public/api/wallet/index.html +++ b/docs/mkdocs/public/api/wallet/index.html @@ -1 +1 @@ - Wallet Interface - Monero Python
Skip to content

Wallet Interface

MoneroWallet

Base wallet with default implementations.

DEFAULT_LANGUAGE: str instance-attribute

Default Monero wallet seed language.

__init__()

Initialize a Monero wallet.

add_address_book_entry(address, description)

Add an address book entry.

Parameters:

Name Type Description Default
address str

is the entry address.

required
description str

is the entry description (optional).

required

Returns:

Type Description
int

the index of the added entry.

add_listener(listener)

Register a listener receive wallet notifications.

Parameters:

Name Type Description Default
listener MoneroWalletListener

is the listener to receive wallet notifications.

required

change_password(old_password, new_password)

Change the wallet password.

Parameters:

Name Type Description Default
old_password str

is the wallet's old password.

required
new_password str

is the wallet's new password.

required

check_reserve_proof(address, message, signature)

Proves a wallet has a disposable reserve using a signature.

Parameters:

Name Type Description Default
address str

is the public wallet address.

required
message str

is a message included with the signature to further authenticate the proof (optional).

required
signature str

is the reserve proof signature to check.

required

Returns:

Type Description
MoneroCheckReserve

the result of checking the signature proof.

check_spend_proof(tx_hash, message, signature)

Prove a spend using a signature. Unlike proving a transaction, it does not require the destination public address.

Parameters:

Name Type Description Default
tx_hash str

specifies the transaction to prove.

required
message str

is a message included with the signature to further authenticate the proof (optional).

required
signature str

is the transaction signature to confirm.

required

Returns:

Type Description
bool

True if the signature is good, False otherwise.

check_tx_key(tx_hash, tx_key, address)

Check a transaction in the blockchain with its secret key.

Parameters:

Name Type Description Default
tx_hash str

specifies the transaction to check.

required
tx_key str

is the transaction's secret key.

required
address str

is the destination public address of the transaction.

required

Returns:

Type Description
MoneroCheckTx

the result of the check.

check_tx_proof(tx_hash, address, message, signature)

Prove a transaction by checking its signature.

Parameters:

Name Type Description Default
tx_hash str

specifies the transaction to prove.

required
address str

is the destination public address of the transaction.

required
message str

is a message included with the signature to further authenticate the proof (optional).

required
signature str

is the transaction signature to confirm.

required

Returns:

Type Description
MoneroCheckTx

the result of the check.

close(save=False)

Optionally save then close the wallet.

Parameters:

Name Type Description Default
save bool

specifies if the wallet should be saved before being closed (default False).

False

create_account(label='')

Create a new account with a label for the first subaddress.

Parameters:

Name Type Description Default
label str

specifies the label for the account's first subaddress (optional).

''

Returns:

Type Description
MoneroAccount

the created account.

create_subaddress(account_idx, label='')

Create a subaddress within an account.

Parameters:

Name Type Description Default
account_idx int

specifies the index of the account to create the subaddress within.

required
label str

specifies the the label for the subaddress (defaults to empty string).

''

Returns:

Type Description
MoneroSubaddress

the created subaddress.

create_tx(config)

Create a transaction to transfer funds from this wallet.

Parameters:

Name Type Description Default
config MoneroTxConfig

configures the transaction to create.

required

Returns:

Type Description
MoneroTxWallet

the created transaction.

create_txs(config)

Create one or more transactions to transfer funds from this wallet.

Parameters:

Name Type Description Default
config MoneroTxConfig

configures the transactions to create.

required

Returns:

Type Description
list[MoneroTxWallet]

the created transactions.

decode_integrated_address(integrated_address)

Decode an integrated address to get its standard address and payment id.

Parameters:

Name Type Description Default
integrated_address str

is an integrated address to decode.

required

Returns:

Type Description
MoneroIntegratedAddress

the decoded integrated address including standard address and payment id.

delete_address_book_entry(index)

Delete an address book entry.

Parameters:

Name Type Description Default
index int

is the index of the entry to delete.

required

describe_multisig_tx_set(multisig_tx_hex)

Describe a tx set containing unsigned or multisig tx hex to a new tx set containing structured transactions.

Parameters:

Name Type Description Default
multisig_tx_hex str

multisig tx hex.

required

Returns:

Type Description
MoneroTxSet

the tx set containing structured transactions.

describe_tx_set(tx_set)

Describes a tx set containing unsigned or multisig tx hex to a new tx set containing structured transactions.

Parameters:

Name Type Description Default
tx_set MoneroTxSet

is a tx set containing unsigned or multisig tx hex.

required

Returns:

Type Description
MoneroTxSet

the tx set containing structured transactions.

describe_unsigned_tx_set(unsigned_tx_hex)

Describe a tx set from unsigned tx hex.

Parameters:

Name Type Description Default
unsigned_tx_hex str

unsigned tx hex.

required

Returns:

Type Description
MoneroTxSet

the tx set containing structured transactions.

edit_address_book_entry(index, set_address, address, set_description, description)

Edit an address book entry.

Parameters:

Name Type Description Default
index int

is the index of the address book entry to edit.

required
set_address bool

specifies if the address should be updated.

required
address str

is the updated address.

required
set_description bool

specifies if the description should be updated.

required
description str

is the updated description.

required

exchange_multisig_keys(multisig_hexes, password)

Exchange multisig hex with participants in a M/N multisig wallet.

This process must be repeated with participants exactly N-M times.

Parameters:

Name Type Description Default
multisig_hexes list[str]

are multisig hex from each participant.

required
password str

is the wallet's password (TODO monero-project: redundant? wallet is created with password).

required

Returns:

Type Description
MoneroMultisigInitResult

the result which has the multisig's address xor this wallet's multisig hex to share with participants if not done.

export_key_images(all=False)

Export signed key images.

Parameters:

Name Type Description Default
all bool

export all key images if True, else export key images since the last export.

False

Returns:

Type Description
list[MoneroKeyImage]

the wallet's signed key images.

export_multisig_hex()

Export this wallet's multisig info as hex for other participants.

Returns:

Type Description
str

this wallet's multisig info as hex for other participants.

export_outputs(all=False)

Export outputs in hex format.

Parameters:

Name Type Description Default
all bool

export all outputs if True, else export outputs since the last export.

False

Returns:

Type Description
str

outputs in hex format, empty string if no outputs.

freeze_output(key_image)

Freeze an output.

Parameters:

Name Type Description Default
key_image str

key image of the output to freeze.

required

get_account_tags()

Return all account tags.

Returns:

Type Description
list[MoneroAccountTag]

the wallet's account tags.

get_address(account_idx, subaddress_idx)

Get the address of a specific subaddress.

Parameters:

Name Type Description Default
account_idx int

specifies the account index of the address's subaddress.

required
subaddress_idx int

specifies the subaddress index within the account.

required

Returns:

Type Description
str

the receive address of the specified subaddress.

get_address_index(address)

Get the account and subaddress index of the given address.

Parameters:

Name Type Description Default
address str

is the address to get the account and subaddress index from.

required

Returns:

Type Description
MoneroSubaddress

the account and subaddress indices.

Raises:

Type Description
MoneroError

exception if address is not a wallet address.

get_attribute(key)

Get an attribute.

Parameters:

Name Type Description Default
key str

is the attribute to get the value of.

required

Returns:

Type Description
str

attribute's value.

get_daemon_connection()

Get the wallet's daemon connection.

Returns:

Type Description
MoneroRpcConnection | None

the wallet's daemon connection.

get_daemon_height()

Get the height that the wallet's daemon is synced to.

Returns:

Type Description
int

the height that the wallet's daemon is synced to.

get_daemon_max_peer_height()

Get the maximum height of the peers the wallet's daemon is connected to.

Returns:

Type Description
int

the maximum height of the peers the wallet's daemon is connected to.

get_default_fee_priority()

Get the current default fee priority (unimportant, normal, elevated, etc).

Returns:

Type Description
MoneroTxPriority

the current fee priority.

get_height()

Get the height of the last block processed by the wallet (its index + 1).

Returns:

Type Description
int

the height of the last block processed by the wallet.

get_height_by_date(year, month, day)

Get the blockchain's height by date as a conservative estimate for scanning.

Parameters:

Name Type Description Default
year int

year of the height to get.

required
month int

month of the height to get as a number between 1 and 12.

required
day int

day of the height to get as a number between 1 and 31.

required

Returns:

Type Description
int

the blockchain's approximate height at the given date.

get_integrated_address(standard_address='', payment_id='')

Get an integrated address from a standard address and a payment id.

Parameters:

Name Type Description Default
standard_address str

is the integrated addresse's standard address (defaults to wallet's primary address).

''
payment_id str

is the integrated addresse's payment id (defaults to randomly generating new payment id).

''

Returns:

Type Description
MoneroIntegratedAddress

the integrated address.

get_listeners()

Get the listeners registered with the wallet.

Returns:

Type Description
list[MoneroWalletListener]

List of listener registered with the wallet.

get_multisig_info()

Get multisig info about this wallet.

Returns:

Type Description
MoneroMultisigInfo

multisig info about this wallet.

get_network_type()

Get the wallet's network type (mainnet, testnet, or stagenet).

Returns:

Type Description
MoneroNetworkType

the wallet's network type.

get_new_key_images_from_last_import()

Get new key images from the last imported outputs.

Returns:

Type Description
list[MoneroKeyImage]

the key images from the last imported outputs.

get_path()

Get the path of this wallet's file on disk.

Returns:

Type Description
str

the path of this wallet's file on disk.

get_payment_uri(config)

Creates a payment URI from a tx configuration.

Parameters:

Name Type Description Default
config MoneroTxConfig

specifies configuration for a potential tx.

required

Returns:

Type Description
str

is the payment uri.

get_primary_address()

Get the wallet's primary address.

Returns:

Type Description
str

the wallet's primary address.

get_private_spend_key()

Get the wallet's private spend key.

Returns:

Type Description
str

the wallet's private spend key.

get_private_view_key()

Get the wallet's private view key.

Returns:

Type Description
str

the wallet's private view key.

get_public_spend_key()

Get the wallet's public spend key.

Returns:

Type Description
str

the wallet's public spend key.

get_public_view_key()

Get the wallet's public view key.

Returns:

Type Description
str

the wallet's public view key.

get_reserve_proof_account(account_idx, amount, message)

Generate a signature to prove an available amount in an account.

Parameters:

Name Type Description Default
account_idx int

specifies the account to prove ownership of the amount.

required
amount int

is the minimum amount to prove as available in the account.

required
message str

is a message to include with the signature to further authenticate the proof (optional).

required

Returns:

Type Description
str

the reserve proof signature.

get_reserve_proof_wallet(message)

Generate a signature to prove the entire balance of the wallet.

Parameters:

Name Type Description Default
message str

is a message included with the signature to further authenticate the proof (optional).

required

Returns:

Type Description
str

the reserve proof signature.

get_restore_height()

Get the height of the first block that the wallet scans.

Returns:

Type Description
int

the height of the first block that the wallet scans.

get_seed()

Get the wallet's mnemonic phrase or seed.

Returns:

Type Description
str

the wallet's mnemonic phrase or seed.

get_seed_language()

Get the language of the wallet's mnemonic phrase or seed.

Returns:

Type Description
str

the language of the wallet's mnemonic phrase or seed.

get_spend_proof(tx_hash, message='')

Generate a signature to prove a spend. Unlike proving a transaction, it does not require the destination public address.

Parameters:

Name Type Description Default
tx_hash str

specifies the transaction to prove.

required
message str

is a message to include with the signature to further authenticate the proof (optional).

''

Returns:

Type Description
str

the transaction signature.

get_subaddress(account_idx, subaddress_idx)

Get a subaddress.

Parameters:

Name Type Description Default
account_idx int

specifies the index of the subaddress's account.

required
subaddress_idx int

specifies index of the subaddress within the account.

required

Returns:

Type Description
MoneroSubaddress

the retrieved subaddress.

get_tx(tx_hash)

Get single wallet transaction by hash.

Parameters:

Name Type Description Default
tx_hash str

Transaction hash.

required

Returns:

Type Description
MoneroTxWallet | None

wallet transaction.

get_tx_key(tx_hash)

Get a transaction's secret key from its hash.

Parameters:

Name Type Description Default
tx_hash str

is the transaction's hash.

required

Returns:

Type Description
str

is the transaction's secret key.

get_tx_note(tx_hash)

Get a transaction note.

Parameters:

Name Type Description Default
tx_hash str

specifies the transaction to get the note of.

required

Returns:

Type Description
str

the tx note.

get_tx_notes(tx_hashes)

Get notes for multiple transactions.

Parameters:

Name Type Description Default
tx_hashes list[str]

identify the transactions to get notes for.

required

Returns:

Type Description
list[str]

notes for the transactions.

get_tx_proof(tx_hash, address, message='')

Get a transaction signature to prove it.

Parameters:

Name Type Description Default
tx_hash str

specifies the transaction to prove.

required
address str

is the destination public address of the transaction.

required
message str

is a message to include with the signature to further authenticate the proof (optional).

''

Returns:

Type Description
str

the transaction signature.

get_version()

Get the wallet's version.

Returns:

Type Description
MoneroVersion

the wallet's version.

import_key_images(key_images)

Import signed key images and verify their spent status.

Parameters:

Name Type Description Default
key_images list[MoneroKeyImage]

are key images to import and verify (requires hex and signature).

required

Returns:

Type Description
MoneroKeyImageImportResult

results of the import.

import_multisig_hex(multisig_hexes)

Import multisig info as hex from other participants.

Note: If the daemon is not trusted, this method will not automatically update the spent status after importing peer multisig hex.

Parameters:

Name Type Description Default
multisig_hexes list[str]

are multisig hex from each participant.

required

Returns:

Type Description
int

the number of outputs signed with the given multisig hex.

import_outputs(outputs_hex)

Import outputs in hex format.

Parameters:

Name Type Description Default
outputs_hex str

are outputs in hex format.

required

Returns:

Type Description
int

the number of outputs imported.

is_closed()

Indicates if the wallet is closed.

Returns:

Type Description
bool

True if the wallet is closed, False otherwise.

is_connected_to_daemon()

Indicates if the wallet is connected a daemon.

Returns:

Type Description
bool

True if the wallet is connected to daemon, False otherwise.

is_daemon_trusted()

Indicates if the daemon is trusted or untrusted.

Returns:

Type Description
bool

True if the daemon is trusted, False otherwise.

is_multisig()

Indicates if this wallet is a multisig wallet.

Returns:

Type Description
bool

True if this is a multisig wallet, False otherwise.

is_multisig_import_needed()

Indicates if importing multisig data is needed for returning a correct balance.

Returns:

Type Description
bool

True if importing multisig data is needed for returning a correct balance, False otherwise.

is_output_frozen(key_image)

Check if an output is frozen.

Parameters:

Name Type Description Default
key_image str

key image of the output to check if frozen.

required

Returns:

Type Description
bool

True if the output is frozen, False otherwise.

is_synced()

Indicates if the wallet is synced with the daemon.

Returns:

Type Description
bool

True if the wallet is synced with the daemon, False otherwise.

is_view_only()

Indicates if the wallet is view-only, meaning it does have the private spend key and can therefore only observe incoming outputs.

Returns:

Type Description
bool

True if the wallet is view-only, False otherwise.

make_multisig(multisig_hexes, threshold, password)

Make this wallet multisig by importing multisig hex from participants.

Parameters:

Name Type Description Default
multisig_hexes list[str]

are multisig hex from each participant.

required
threshold int

is the number of signatures needed to sign transfers.

required
password str

is the wallet password.

required

Returns:

Type Description
str

this wallet's multisig hex to share with participants.

move_to(path, password)

Move the wallet from its current path to the given path.

Parameters:

Name Type Description Default
path str

is the new wallet's path.

required
password str

is the new wallet's password.

required

parse_payment_uri(uri)

Parses a payment URI to a tx configuration.

Parameters:

Name Type Description Default
uri str

is the payment uri to parse.

required

Returns:

Type Description
MoneroTxConfig

the tx configuration parsed from the uri.

prepare_multisig()

Get multisig info as hex to share with participants to begin creating a multisig wallet.

Returns:

Type Description
str

this wallet's multisig hex to share with participants.

remove_listener(listener)

Unregister a listener to receive wallet notifications.

Parameters:

Name Type Description Default
listener MoneroWalletListener

is the listener to unregister.

required

rescan_blockchain()

Rescan the blockchain from scratch, losing any information which cannot be recovered from the blockchain itself.

WARNING: This method discards local wallet data like destination addresses, tx secret keys, tx notes, etc.

rescan_spent()

Rescan the blockchain for spent outputs.

Note: this can only be called with a trusted daemon.

Example use case: peer multisig hex is import when connected to an untrusted daemon, so the wallet will not rescan spent outputs. Then the wallet connects to a trusted daemon. This method should be manually invoked to rescan outputs.

save()

Save the wallet at its current path.

scan_txs(tx_hashes)

Scan transactions by their hash/id.

Parameters:

Name Type Description Default
tx_hashes list[str]

tx hashes to scan.

required

set_account_label(account_idx, label)

Set a human-readable description for an account.

Parameters:

Name Type Description Default
account_idx int

account index.

required
label str

is the label to set.

required

set_account_tag_label(tag, label)

Sets a human-readable description for a tag.

Parameters:

Name Type Description Default
tag str

is the tag to set a description for.

required
label str

is the label to set for the tag.

required

set_attribute(key, val)

Set an arbitrary attribute.

Parameters:

Name Type Description Default
key str

is the attribute key.

required
val str

is the attribute value.

required

set_restore_height(restore_height)

Set the height of the first block that the wallet scans.

Parameters:

Name Type Description Default
restore_height int

is the height of the first block that the wallet scans.

required

set_subaddress_label(account_idx, subaddress_idx, label='')

Set a subaddress label.

Parameters:

Name Type Description Default
account_idx int

index of the account to set the label for.

required
subaddress_idx int

index of the subaddress to set the label for.

required
label str

the label to set (default '').

''

set_tx_note(tx_hash, note)

Set a note for a specific transaction.

Parameters:

Name Type Description Default
tx_hash str

specifies the transaction.

required
note str

specifies the note.

required

set_tx_notes(tx_hashes, notes)

Set notes for multiple transactions.

Parameters:

Name Type Description Default
tx_hashes list[str]

specify the transactions to set notes for.

required
notes list[str]

are the notes to set for the transactions.

required

sign_message(msg, signature_type, account_idx=0, subaddress_idx=0)

Sign a message.

Parameters:

Name Type Description Default
msg str

the message to sign.

required
signature_type MoneroMessageSignatureType

sign with spend key or spend key.

required
account_idx int

the account index of the message signature (default 0).

0
subaddress_idx int

the subaddress index of the message signature (default 0).

0

Returns:

Type Description
str

the message signature.

sign_multisig_tx_hex(multisig_tx_hex)

Sign previously created multisig transactions as represented by hex.

Parameters:

Name Type Description Default
multisig_tx_hex str

is the hex shared among the multisig transactions when they were created.

required

Returns:

Type Description
MoneroMultisigSignResult

the result of signing the multisig transactions.

sign_txs(unsigned_tx_hex)

Sign unsigned transactions from a view-only wallet.

Parameters:

Name Type Description Default
unsigned_tx_hex str

is unsigned transaction hex from when the transactions were created.

required

Returns:

Type Description
MoneroTxSet

the signed transaction set.

start_mining(num_threads=None, background_mining=None, ignore_battery=None)

Start mining.

Parameters:

Name Type Description Default
num_threads Optional[int]

is the number of threads created for mining (default None).

None
background_mining Optional[bool]

specifies if mining should occur in the background (default None).

None
ignore_battery Optional[bool]

specifies if the battery should be ignored for mining (default None).

None

start_syncing(sync_period_in_ms=10000)

Start background synchronizing with a maximum period between syncs.

Parameters:

Name Type Description Default
sync_period_in_ms int

maximum period between syncs in milliseconds.

10000

stop_mining()

Stop mining.

stop_syncing()

Stop the asynchronous thread to continuously synchronize the wallet with the daemon.

submit_multisig_tx_hex(signed_multisig_tx_hex)

Submit signed multisig transactions as represented by a hex string.

Parameters:

Name Type Description Default
signed_multisig_tx_hex str

is the signed multisig hex returned from sign_multisig_txs().

required

Returns:

Type Description
list[str]

the resulting transaction hashes.

submit_txs(signed_tx_hex)

Submit signed transactions from a view-only wallet.

Parameters:

Name Type Description Default
signed_tx_hex str

is signed transaction hex from sign_txs().

required

Returns:

Type Description
list[str]

the resulting transaction hashes.

sweep_dust(relay=False)

Sweep all unmixable dust outputs back to the wallet to make them easier to spend and mix.

Parameters:

Name Type Description Default
relay bool

specifies if the resulting transaction should be relayed (default False).

False

Returns:

Type Description
list[MoneroTxWallet]

the created transactions.

sweep_output(config)

Sweep an output with a given key image.

Parameters:

Name Type Description Default
config MoneroTxConfig

configures the sweep transaction.

required

Returns:

Type Description
MoneroTxWallet

the created transaction.

sweep_unlocked(config)

Sweep unlocked funds according to the given config.

Parameters:

Name Type Description Default
config MoneroTxConfig

is the sweep configuration.

required

Returns:

Type Description
list[MoneroTxWallet]

the created transactions.

tag_accounts(tag, account_indices)

Tag accounts.

Parameters:

Name Type Description Default
tag str

is the tag to apply to the specified accounts.

required
account_indices list[int]

are the indices of the accounts to tag.

required

thaw_output(key_image)

Thaw a frozen output.

Parameters:

Name Type Description Default
key_image str

key image of the output to thaw.

required

untag_accounts(account_indices)

Untag acconts.

Parameters:

Name Type Description Default
account_indices list[int]

are the indices of the accounts to untag.

required

verify_message(msg, address, signature)

Verify a message signature.

Parameters:

Name Type Description Default
msg str

the signed message.

required
address str

signing address.

required
signature str

signature.

required

Returns:

Type Description
MoneroMessageSignatureResult

the message signature result.

wait_for_next_block()

Wait for the next block to be added to the chain.

Returns:

Type Description
int

the height of the next block when it is added to the chain.

\ No newline at end of file + Wallet Interface - Monero Python
Skip to content

Wallet Interface

MoneroWallet

Base wallet with default implementations.

DEFAULT_LANGUAGE: str instance-attribute

Default Monero wallet seed language.

__init__()

Initialize a Monero wallet.

add_address_book_entry(address, description)

Add an address book entry.

Parameters:

Name Type Description Default
address str

is the entry address.

required
description str

is the entry description (optional).

required

Returns:

Type Description
int

the index of the added entry.

add_listener(listener)

Register a listener receive wallet notifications.

Parameters:

Name Type Description Default
listener MoneroWalletListener

is the listener to receive wallet notifications.

required

change_password(old_password, new_password)

Change the wallet password.

Parameters:

Name Type Description Default
old_password str

is the wallet's old password.

required
new_password str

is the wallet's new password.

required

check_reserve_proof(address, message, signature)

Proves a wallet has a disposable reserve using a signature.

Parameters:

Name Type Description Default
address str

is the public wallet address.

required
message str

is a message included with the signature to further authenticate the proof (optional).

required
signature str

is the reserve proof signature to check.

required

Returns:

Type Description
MoneroCheckReserve

the result of checking the signature proof.

check_spend_proof(tx_hash, message, signature)

Prove a spend using a signature. Unlike proving a transaction, it does not require the destination public address.

Parameters:

Name Type Description Default
tx_hash str

specifies the transaction to prove.

required
message str

is a message included with the signature to further authenticate the proof (optional).

required
signature str

is the transaction signature to confirm.

required

Returns:

Type Description
bool

True if the signature is good, False otherwise.

check_tx_key(tx_hash, tx_key, address)

Check a transaction in the blockchain with its secret key.

Parameters:

Name Type Description Default
tx_hash str

specifies the transaction to check.

required
tx_key str

is the transaction's secret key.

required
address str

is the destination public address of the transaction.

required

Returns:

Type Description
MoneroCheckTx

the result of the check.

check_tx_proof(tx_hash, address, message, signature)

Prove a transaction by checking its signature.

Parameters:

Name Type Description Default
tx_hash str

specifies the transaction to prove.

required
address str

is the destination public address of the transaction.

required
message str

is a message included with the signature to further authenticate the proof (optional).

required
signature str

is the transaction signature to confirm.

required

Returns:

Type Description
MoneroCheckTx

the result of the check.

close(save=False)

Optionally save then close the wallet.

Parameters:

Name Type Description Default
save bool

specifies if the wallet should be saved before being closed (default False).

False

create_account(label='')

Create a new account with a label for the first subaddress.

Parameters:

Name Type Description Default
label str

specifies the label for the account's first subaddress (optional).

''

Returns:

Type Description
MoneroAccount

the created account.

create_subaddress(account_idx, label='')

Create a subaddress within an account.

Parameters:

Name Type Description Default
account_idx int

specifies the index of the account to create the subaddress within.

required
label str

specifies the the label for the subaddress (defaults to empty string).

''

Returns:

Type Description
MoneroSubaddress

the created subaddress.

create_tx(config)

Create a transaction to transfer funds from this wallet.

Parameters:

Name Type Description Default
config MoneroTxConfig

configures the transaction to create.

required

Returns:

Type Description
MoneroTxWallet

the created transaction.

create_txs(config)

Create one or more transactions to transfer funds from this wallet.

Parameters:

Name Type Description Default
config MoneroTxConfig

configures the transactions to create.

required

Returns:

Type Description
list[MoneroTxWallet]

the created transactions.

decode_integrated_address(integrated_address)

Decode an integrated address to get its standard address and payment id.

Parameters:

Name Type Description Default
integrated_address str

is an integrated address to decode.

required

Returns:

Type Description
MoneroIntegratedAddress

the decoded integrated address including standard address and payment id.

delete_address_book_entry(index)

Delete an address book entry.

Parameters:

Name Type Description Default
index int

is the index of the entry to delete.

required

describe_multisig_tx_set(multisig_tx_hex)

Describe a tx set containing unsigned or multisig tx hex to a new tx set containing structured transactions.

Parameters:

Name Type Description Default
multisig_tx_hex str

multisig tx hex.

required

Returns:

Type Description
MoneroTxSet

the tx set containing structured transactions.

describe_tx_set(tx_set)

Describes a tx set containing unsigned or multisig tx hex to a new tx set containing structured transactions.

Parameters:

Name Type Description Default
tx_set MoneroTxSet

is a tx set containing unsigned or multisig tx hex.

required

Returns:

Type Description
MoneroTxSet

the tx set containing structured transactions.

describe_unsigned_tx_set(unsigned_tx_hex)

Describe a tx set from unsigned tx hex.

Parameters:

Name Type Description Default
unsigned_tx_hex str

unsigned tx hex.

required

Returns:

Type Description
MoneroTxSet

the tx set containing structured transactions.

edit_address_book_entry(index, set_address, address, set_description, description)

Edit an address book entry.

Parameters:

Name Type Description Default
index int

is the index of the address book entry to edit.

required
set_address bool

specifies if the address should be updated.

required
address str

is the updated address.

required
set_description bool

specifies if the description should be updated.

required
description str

is the updated description.

required

exchange_multisig_keys(multisig_hexes, password)

Exchange multisig hex with participants in a M/N multisig wallet.

This process must be repeated with participants exactly N-M times.

Parameters:

Name Type Description Default
multisig_hexes list[str]

are multisig hex from each participant.

required
password str

is the wallet's password (TODO monero-project: redundant? wallet is created with password).

required

Returns:

Type Description
MoneroMultisigInitResult

the result which has the multisig's address xor this wallet's multisig hex to share with participants if not done.

export_key_images(all=False)

Export signed key images.

Parameters:

Name Type Description Default
all bool

export all key images if True, else export key images since the last export.

False

Returns:

Type Description
MoneroKeyImageExportResult

the wallet's signed key images.

export_multisig_hex()

Export this wallet's multisig info as hex for other participants.

Returns:

Type Description
str

this wallet's multisig info as hex for other participants.

export_outputs(all=False)

Export outputs in hex format.

Parameters:

Name Type Description Default
all bool

export all outputs if True, else export outputs since the last export.

False

Returns:

Type Description
str

outputs in hex format, empty string if no outputs.

freeze_output(key_image)

Freeze an output.

Parameters:

Name Type Description Default
key_image str

key image of the output to freeze.

required

get_account_tags()

Return all account tags.

Returns:

Type Description
list[MoneroAccountTag]

the wallet's account tags.

get_address(account_idx, subaddress_idx)

Get the address of a specific subaddress.

Parameters:

Name Type Description Default
account_idx int

specifies the account index of the address's subaddress.

required
subaddress_idx int

specifies the subaddress index within the account.

required

Returns:

Type Description
str

the receive address of the specified subaddress.

get_address_index(address)

Get the account and subaddress index of the given address.

Parameters:

Name Type Description Default
address str

is the address to get the account and subaddress index from.

required

Returns:

Type Description
MoneroSubaddress

the account and subaddress indices.

Raises:

Type Description
MoneroError

exception if address is not a wallet address.

get_attribute(key)

Get an attribute.

Parameters:

Name Type Description Default
key str

is the attribute to get the value of.

required

Returns:

Type Description
str

attribute's value.

get_daemon_connection()

Get the wallet's daemon connection.

Returns:

Type Description
MoneroRpcConnection | None

the wallet's daemon connection.

get_daemon_height()

Get the height that the wallet's daemon is synced to.

Returns:

Type Description
int

the height that the wallet's daemon is synced to.

get_daemon_max_peer_height()

Get the maximum height of the peers the wallet's daemon is connected to.

Returns:

Type Description
int

the maximum height of the peers the wallet's daemon is connected to.

get_default_fee_priority()

Get the current default fee priority (unimportant, normal, elevated, etc).

Returns:

Type Description
MoneroTxPriority

the current fee priority.

get_height()

Get the height of the last block processed by the wallet (its index + 1).

Returns:

Type Description
int

the height of the last block processed by the wallet.

get_height_by_date(year, month, day)

Get the blockchain's height by date as a conservative estimate for scanning.

Parameters:

Name Type Description Default
year int

year of the height to get.

required
month int

month of the height to get as a number between 1 and 12.

required
day int

day of the height to get as a number between 1 and 31.

required

Returns:

Type Description
int

the blockchain's approximate height at the given date.

get_integrated_address(standard_address='', payment_id='')

Get an integrated address from a standard address and a payment id.

Parameters:

Name Type Description Default
standard_address str

is the integrated addresse's standard address (defaults to wallet's primary address).

''
payment_id str

is the integrated addresse's payment id (defaults to randomly generating new payment id).

''

Returns:

Type Description
MoneroIntegratedAddress

the integrated address.

get_listeners()

Get the listeners registered with the wallet.

Returns:

Type Description
list[MoneroWalletListener]

List of listener registered with the wallet.

get_multisig_info()

Get multisig info about this wallet.

Returns:

Type Description
MoneroMultisigInfo

multisig info about this wallet.

get_network_type()

Get the wallet's network type (mainnet, testnet, or stagenet).

Returns:

Type Description
MoneroNetworkType

the wallet's network type.

get_new_key_images_from_last_import()

Get new key images from the last imported outputs.

Returns:

Type Description
list[MoneroKeyImage]

the key images from the last imported outputs.

get_path()

Get the path of this wallet's file on disk.

Returns:

Type Description
str

the path of this wallet's file on disk.

get_payment_uri(config)

Creates a payment URI from a tx configuration.

Parameters:

Name Type Description Default
config MoneroTxConfig

specifies configuration for a potential tx.

required

Returns:

Type Description
str

is the payment uri.

get_primary_address()

Get the wallet's primary address.

Returns:

Type Description
str

the wallet's primary address.

get_private_spend_key()

Get the wallet's private spend key.

Returns:

Type Description
str

the wallet's private spend key.

get_private_view_key()

Get the wallet's private view key.

Returns:

Type Description
str

the wallet's private view key.

get_public_spend_key()

Get the wallet's public spend key.

Returns:

Type Description
str

the wallet's public spend key.

get_public_view_key()

Get the wallet's public view key.

Returns:

Type Description
str

the wallet's public view key.

get_reserve_proof_account(account_idx, amount, message)

Generate a signature to prove an available amount in an account.

Parameters:

Name Type Description Default
account_idx int

specifies the account to prove ownership of the amount.

required
amount int

is the minimum amount to prove as available in the account.

required
message str

is a message to include with the signature to further authenticate the proof (optional).

required

Returns:

Type Description
str

the reserve proof signature.

get_reserve_proof_wallet(message)

Generate a signature to prove the entire balance of the wallet.

Parameters:

Name Type Description Default
message str

is a message included with the signature to further authenticate the proof (optional).

required

Returns:

Type Description
str

the reserve proof signature.

get_restore_height()

Get the height of the first block that the wallet scans.

Returns:

Type Description
int

the height of the first block that the wallet scans.

get_seed()

Get the wallet's mnemonic phrase or seed.

Returns:

Type Description
str

the wallet's mnemonic phrase or seed.

get_seed_language()

Get the language of the wallet's mnemonic phrase or seed.

Returns:

Type Description
str

the language of the wallet's mnemonic phrase or seed.

get_spend_proof(tx_hash, message='')

Generate a signature to prove a spend. Unlike proving a transaction, it does not require the destination public address.

Parameters:

Name Type Description Default
tx_hash str

specifies the transaction to prove.

required
message str

is a message to include with the signature to further authenticate the proof (optional).

''

Returns:

Type Description
str

the transaction signature.

get_subaddress(account_idx, subaddress_idx)

Get a subaddress.

Parameters:

Name Type Description Default
account_idx int

specifies the index of the subaddress's account.

required
subaddress_idx int

specifies index of the subaddress within the account.

required

Returns:

Type Description
MoneroSubaddress

the retrieved subaddress.

get_tx(tx_hash)

Get single wallet transaction by hash.

Parameters:

Name Type Description Default
tx_hash str

Transaction hash.

required

Returns:

Type Description
MoneroTxWallet | None

wallet transaction.

get_tx_key(tx_hash)

Get a transaction's secret key from its hash.

Parameters:

Name Type Description Default
tx_hash str

is the transaction's hash.

required

Returns:

Type Description
str

is the transaction's secret key.

get_tx_note(tx_hash)

Get a transaction note.

Parameters:

Name Type Description Default
tx_hash str

specifies the transaction to get the note of.

required

Returns:

Type Description
str

the tx note.

get_tx_notes(tx_hashes)

Get notes for multiple transactions.

Parameters:

Name Type Description Default
tx_hashes list[str]

identify the transactions to get notes for.

required

Returns:

Type Description
list[str]

notes for the transactions.

get_tx_proof(tx_hash, address, message='')

Get a transaction signature to prove it.

Parameters:

Name Type Description Default
tx_hash str

specifies the transaction to prove.

required
address str

is the destination public address of the transaction.

required
message str

is a message to include with the signature to further authenticate the proof (optional).

''

Returns:

Type Description
str

the transaction signature.

get_version()

Get the wallet's version.

Returns:

Type Description
MoneroVersion

the wallet's version.

import_key_images(key_images, offset=0)

Import signed key images and verify their spent status.

Parameters:

Name Type Description Default
key_images list[MoneroKeyImage]

are key images to import and verify (requires hex and signature).

required
offset int

offset of the first key image among the wallet's outputs.

0

Returns:

Type Description
MoneroKeyImageImportResult

results of the import.

import_multisig_hex(multisig_hexes, refresh_after_import=True)

Import multisig info as hex from other participants.

Note: If the daemon is not trusted, this method will not automatically update the spent status after importing peer multisig hex.

Parameters:

Name Type Description Default
multisig_hexes list[str]

are multisig hex from each participant.

required
refresh_after_import bool

refresh wallet after import.

True

Returns:

Type Description
int

the number of outputs signed with the given multisig hex.

import_outputs(outputs_hex)

Import outputs in hex format.

Parameters:

Name Type Description Default
outputs_hex str

are outputs in hex format.

required

Returns:

Type Description
int

the number of outputs imported.

is_closed()

Indicates if the wallet is closed.

Returns:

Type Description
bool

True if the wallet is closed, False otherwise.

is_connected_to_daemon()

Indicates if the wallet is connected a daemon.

Returns:

Type Description
bool

True if the wallet is connected to daemon, False otherwise.

is_daemon_trusted()

Indicates if the daemon is trusted or untrusted.

Returns:

Type Description
bool

True if the daemon is trusted, False otherwise.

is_multisig()

Indicates if this wallet is a multisig wallet.

Returns:

Type Description
bool

True if this is a multisig wallet, False otherwise.

is_multisig_import_needed()

Indicates if importing multisig data is needed for returning a correct balance.

Returns:

Type Description
bool

True if importing multisig data is needed for returning a correct balance, False otherwise.

is_output_frozen(key_image)

Check if an output is frozen.

Parameters:

Name Type Description Default
key_image str

key image of the output to check if frozen.

required

Returns:

Type Description
bool

True if the output is frozen, False otherwise.

is_synced()

Indicates if the wallet is synced with the daemon.

Returns:

Type Description
bool

True if the wallet is synced with the daemon, False otherwise.

is_view_only()

Indicates if the wallet is view-only, meaning it does have the private spend key and can therefore only observe incoming outputs.

Returns:

Type Description
bool

True if the wallet is view-only, False otherwise.

make_multisig(multisig_hexes, threshold, password)

Make this wallet multisig by importing multisig hex from participants.

Parameters:

Name Type Description Default
multisig_hexes list[str]

are multisig hex from each participant.

required
threshold int

is the number of signatures needed to sign transfers.

required
password str

is the wallet password.

required

Returns:

Type Description
str

this wallet's multisig hex to share with participants.

move_to(path, password)

Move the wallet from its current path to the given path.

Parameters:

Name Type Description Default
path str

is the new wallet's path.

required
password str

is the new wallet's password.

required

parse_payment_uri(uri)

Parses a payment URI to a tx configuration.

Parameters:

Name Type Description Default
uri str

is the payment uri to parse.

required

Returns:

Type Description
MoneroTxConfig

the tx configuration parsed from the uri.

prepare_multisig()

Get multisig info as hex to share with participants to begin creating a multisig wallet.

Returns:

Type Description
str

this wallet's multisig hex to share with participants.

remove_listener(listener)

Unregister a listener to receive wallet notifications.

Parameters:

Name Type Description Default
listener MoneroWalletListener

is the listener to unregister.

required

rescan_blockchain()

Rescan the blockchain from scratch, losing any information which cannot be recovered from the blockchain itself.

WARNING: This method discards local wallet data like destination addresses, tx secret keys, tx notes, etc.

rescan_spent()

Rescan the blockchain for spent outputs.

Note: this can only be called with a trusted daemon.

Example use case: peer multisig hex is import when connected to an untrusted daemon, so the wallet will not rescan spent outputs. Then the wallet connects to a trusted daemon. This method should be manually invoked to rescan outputs.

save()

Save the wallet at its current path.

scan_txs(tx_hashes)

Scan transactions by their hash/id.

Parameters:

Name Type Description Default
tx_hashes list[str]

tx hashes to scan.

required

set_account_label(account_idx, label)

Set a human-readable description for an account.

Parameters:

Name Type Description Default
account_idx int

account index.

required
label str

is the label to set.

required

set_account_tag_label(tag, label)

Sets a human-readable description for a tag.

Parameters:

Name Type Description Default
tag str

is the tag to set a description for.

required
label str

is the label to set for the tag.

required

set_attribute(key, val)

Set an arbitrary attribute.

Parameters:

Name Type Description Default
key str

is the attribute key.

required
val str

is the attribute value.

required

set_restore_height(restore_height)

Set the height of the first block that the wallet scans.

Parameters:

Name Type Description Default
restore_height int

is the height of the first block that the wallet scans.

required

set_subaddress_label(account_idx, subaddress_idx, label='')

Set a subaddress label.

Parameters:

Name Type Description Default
account_idx int

index of the account to set the label for.

required
subaddress_idx int

index of the subaddress to set the label for.

required
label str

the label to set (default '').

''

set_tx_note(tx_hash, note)

Set a note for a specific transaction.

Parameters:

Name Type Description Default
tx_hash str

specifies the transaction.

required
note str

specifies the note.

required

set_tx_notes(tx_hashes, notes)

Set notes for multiple transactions.

Parameters:

Name Type Description Default
tx_hashes list[str]

specify the transactions to set notes for.

required
notes list[str]

are the notes to set for the transactions.

required

sign_message(msg, signature_type, account_idx=0, subaddress_idx=0)

Sign a message.

Parameters:

Name Type Description Default
msg str

the message to sign.

required
signature_type MoneroMessageSignatureType

sign with spend key or spend key.

required
account_idx int

the account index of the message signature (default 0).

0
subaddress_idx int

the subaddress index of the message signature (default 0).

0

Returns:

Type Description
str

the message signature.

sign_multisig_tx_hex(multisig_tx_hex)

Sign previously created multisig transactions as represented by hex.

Parameters:

Name Type Description Default
multisig_tx_hex str

is the hex shared among the multisig transactions when they were created.

required

Returns:

Type Description
MoneroMultisigSignResult

the result of signing the multisig transactions.

sign_txs(unsigned_tx_hex)

Sign unsigned transactions from a view-only wallet.

Parameters:

Name Type Description Default
unsigned_tx_hex str

is unsigned transaction hex from when the transactions were created.

required

Returns:

Type Description
MoneroTxSet

the signed transaction set.

start_mining(num_threads=None, background_mining=None, ignore_battery=None)

Start mining.

Parameters:

Name Type Description Default
num_threads Optional[int]

is the number of threads created for mining (default None).

None
background_mining Optional[bool]

specifies if mining should occur in the background (default None).

None
ignore_battery Optional[bool]

specifies if the battery should be ignored for mining (default None).

None

start_syncing(sync_period_in_ms=10000)

Start background synchronizing with a maximum period between syncs.

Parameters:

Name Type Description Default
sync_period_in_ms int

maximum period between syncs in milliseconds.

10000

stop_mining()

Stop mining.

stop_syncing()

Stop the asynchronous thread to continuously synchronize the wallet with the daemon.

submit_multisig_tx_hex(signed_multisig_tx_hex)

Submit signed multisig transactions as represented by a hex string.

Parameters:

Name Type Description Default
signed_multisig_tx_hex str

is the signed multisig hex returned from sign_multisig_txs().

required

Returns:

Type Description
list[str]

the resulting transaction hashes.

submit_txs(signed_tx_hex)

Submit signed transactions from a view-only wallet.

Parameters:

Name Type Description Default
signed_tx_hex str

is signed transaction hex from sign_txs().

required

Returns:

Type Description
list[str]

the resulting transaction hashes.

sweep_dust(relay=False)

Sweep all unmixable dust outputs back to the wallet to make them easier to spend and mix.

Parameters:

Name Type Description Default
relay bool

specifies if the resulting transaction should be relayed (default False).

False

Returns:

Type Description
list[MoneroTxWallet]

the created transactions.

sweep_output(config)

Sweep an output with a given key image.

Parameters:

Name Type Description Default
config MoneroTxConfig

configures the sweep transaction.

required

Returns:

Type Description
MoneroTxWallet

the created transaction.

sweep_unlocked(config)

Sweep unlocked funds according to the given config.

Parameters:

Name Type Description Default
config MoneroTxConfig

is the sweep configuration.

required

Returns:

Type Description
list[MoneroTxWallet]

the created transactions.

tag_accounts(tag, account_indices)

Tag accounts.

Parameters:

Name Type Description Default
tag str

is the tag to apply to the specified accounts.

required
account_indices list[int]

are the indices of the accounts to tag.

required

thaw_output(key_image)

Thaw a frozen output.

Parameters:

Name Type Description Default
key_image str

key image of the output to thaw.

required

untag_accounts(account_indices)

Untag accounts.

Parameters:

Name Type Description Default
account_indices list[int]

are the indices of the accounts to untag.

required

verify_message(msg, address, signature)

Verify a message signature.

Parameters:

Name Type Description Default
msg str

the signed message.

required
address str

signing address.

required
signature str

signature.

required

Returns:

Type Description
MoneroMessageSignatureResult

the message signature result.

wait_for_next_block()

Wait for the next block to be added to the chain.

Returns:

Type Description
int

the height of the next block when it is added to the chain.

\ No newline at end of file diff --git a/docs/mkdocs/public/api/wallet_full/index.html b/docs/mkdocs/public/api/wallet_full/index.html index 93a0b67..f5edccc 100644 --- a/docs/mkdocs/public/api/wallet_full/index.html +++ b/docs/mkdocs/public/api/wallet_full/index.html @@ -1 +1 @@ - Full Wallet - Monero Python
Skip to content

Full Wallet

MoneroWalletFull

Bases: MoneroWallet

Monero wallet implementation which uses monero-project's wallet2.

create_wallet(config) staticmethod

Create a new wallet with the given configuration.

Parameters:

Name Type Description Default
config MoneroWalletConfig

the wallet configuration.

required

Returns:

Type Description
MoneroWalletFull

reference to the wallet instance.

get_cache_file_buffer()

Get wallet cache file without using filesystem.

Returns:

Type Description
str

Cache file buffer.

get_keys_file_buffer(password, view_only)

Get wallet keys file without using filesystem.

Parameters:

Name Type Description Default
password str

The wallet password.

required
view_only bool

Get view-only keys.

required

Returns:

Type Description
str

Keys file buffer.

get_seed_languages() staticmethod

Get a list of available languages for the wallet's seed.

Returns:

Type Description
list[str]

the available languages for the wallet's seed.

open_wallet(path, password, nettype) staticmethod

Open an existing wallet from disk.

Parameters:

Name Type Description Default
path str

is the path to the wallet file to open.

required
password str

is the password of the wallet file to open.

required
nettype MoneroNetworkType

is the wallet's network type.

required

Returns:

Type Description
MoneroWalletFull

reference to the wallet instance.

wallet_exists(path) staticmethod

Indicates if a wallet exists at the given path.

Parameters:

Name Type Description Default
path str

is the path to check for a wallet.

required

Returns:

Type Description
bool

True if a wallet exists at the given path, False otherwise.

\ No newline at end of file + Full Wallet - Monero Python
Skip to content

Full Wallet

MoneroWalletFull

Bases: MoneroWallet

Monero wallet implementation which uses monero-project's wallet2.

create_wallet(config) staticmethod

Create a new wallet with the given configuration.

Parameters:

Name Type Description Default
config MoneroWalletConfig

the wallet configuration.

required

Returns:

Type Description
MoneroWalletFull

reference to the wallet instance.

get_cache_file_buffer()

Get wallet cache file without using filesystem.

Returns:

Type Description
str

Cache file buffer.

get_keys_file_buffer(password, view_only)

Get wallet keys file without using filesystem.

Parameters:

Name Type Description Default
password str

The wallet password.

required
view_only bool

Get view-only keys.

required

Returns:

Type Description
str

Keys file buffer.

get_seed_languages() staticmethod

Get a list of available languages for the wallet's seed.

Returns:

Type Description
list[str]

the available languages for the wallet's seed.

open_wallet(path, password, nettype, regtest=False) staticmethod

Open an existing wallet from disk.

Parameters:

Name Type Description Default
path str

is the path to the wallet file to open.

required
password str

is the password of the wallet file to open.

required
nettype MoneroNetworkType

is the wallet's network type.

required
regtest bool

indicates if wallet to open is a regtest wallet (optional).

False

Returns:

Type Description
MoneroWalletFull

reference to the wallet instance.

open_wallet_data(password, nettype, keys_data, cache_data, daemon_connection=MoneroRpcConnection(), regtest=False) staticmethod

Open an in-memory wallet from existing data buffers.

Parameters:

Name Type Description Default
password str

is the password of the wallet file to open.

required
nettype MoneroNetworkType

is the wallet's network type.

required
keys_data str

contains the contents of the ".keys" file.

required
cache_data str

contains the contents of the wallet cache file (no extension).

required
daemon_connection MoneroRpcConnection

is connection information to a daemon (default = an unconnected wallet).

MoneroRpcConnection()
regtest bool

indicates if wallet to open is a regtest wallet (optional).

False

Returns:

Type Description
MoneroWalletFull

reference to the wallet instance.

wallet_exists(path) staticmethod

Indicates if a wallet exists at the given path.

Parameters:

Name Type Description Default
path str

is the path to check for a wallet.

required

Returns:

Type Description
bool

True if a wallet exists at the given path, False otherwise.

\ No newline at end of file diff --git a/docs/mkdocs/public/index.html b/docs/mkdocs/public/index.html index 4794454..3a99727 100644 --- a/docs/mkdocs/public/index.html +++ b/docs/mkdocs/public/index.html @@ -1 +1 @@ - Monero Python Documentation - Monero Python
Skip to content

Monero Python Documentation

Welcome to the Monero Python documentation.

The aim of this project is to provide an intuitive and robust way to interact with the Monero cryptocurrency in Python using a clearly defined data model. It provides high level classes representing objects from the Monero environment, like wallets, accounts, addresses and transactions.

Developers can create Monero applications using JSON-RPC or Python bindings to monero v0.18.4.4 'Flourine Fermi'.

Contributions can be made via issues and pull requests on GitHub, or communicated via the #monero-python workgroup on Matrix.

GitHub Matrix

\ No newline at end of file + Monero Python Documentation - Monero Python
Skip to content

Monero Python Documentation

Welcome to the Monero Python documentation.

The aim of this project is to provide an intuitive and robust way to interact with the Monero cryptocurrency in Python using a clearly defined data model. It provides high level classes representing objects from the Monero environment, like wallets, accounts, addresses and transactions.

Developers can create Monero applications using JSON-RPC or Python bindings to monero v0.18.5.1 'Flourine Fermi'.

Contributions can be made via issues and pull requests on GitHub, or communicated via the #monero-python workgroup on Matrix.

GitHub Matrix

\ No newline at end of file diff --git a/docs/mkdocs/public/objects.inv b/docs/mkdocs/public/objects.inv index 5496043b5b6ef79f7b59f8ec186417aff919b797..cd7adecc43ce601460ebf93fa8b280986e68a35e 100644 GIT binary patch delta 13914 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 to the Monero Python documentation.

The aim of this project is to provide an intuitive and robust way to interact with the Monero cryptocurrency in Python using a clearly defined data model. It provides high level classes representing objects from the Monero environment, like wallets, accounts, addresses and transactions.

Developers can create Monero applications using JSON-RPC or Python bindings to monero v0.18.4.4 'Flourine Fermi'.

Contributions can be made via issues and pull requests on GitHub, or communicated via the #monero-python workgroup on Matrix.

GitHub Matrix

"},{"location":"api/architecture/","title":"Architecture","text":""},{"location":"api/connection/","title":"RPC Connection","text":""},{"location":"api/connection/#monero.MoneroRpcConnection","title":"MoneroRpcConnection","text":"

Bases: SerializableStruct

Models a connection to a daemon.

"},{"location":"api/connection/#monero.MoneroRpcConnection.password","title":"password: str | None property","text":"

Connection authentication password.

"},{"location":"api/connection/#monero.MoneroRpcConnection.priority","title":"priority: int instance-attribute","text":"

Connection priority.

"},{"location":"api/connection/#monero.MoneroRpcConnection.proxy_uri","title":"proxy_uri: str | None instance-attribute","text":"

Connection proxy address.

"},{"location":"api/connection/#monero.MoneroRpcConnection.response_time","title":"response_time: int | None property","text":"

Connection response time in milliseconds.

"},{"location":"api/connection/#monero.MoneroRpcConnection.timeout","title":"timeout: int instance-attribute","text":"

Connection timeout (milliseconds).

"},{"location":"api/connection/#monero.MoneroRpcConnection.uri","title":"uri: str | None instance-attribute","text":"

Connection uri.

"},{"location":"api/connection/#monero.MoneroRpcConnection.username","title":"username: str | None property","text":"

Connection authentication username.

"},{"location":"api/connection/#monero.MoneroRpcConnection.zmq_uri","title":"zmq_uri: str | None instance-attribute","text":"

ZMQ connection uri.

"},{"location":"api/connection/#monero.MoneroRpcConnection.before","title":"before(c1, c2, current_connection) staticmethod","text":"

Compare RPC connections.

Parameters:

Name Type Description Default c1 MoneroRpcConnection

connection.

required c2 MoneroRpcConnection

other connection.

required current_connection MoneroRpcConnection

current connection.

required

Returns:

Type Description bool

True if c1 comes before c2, False otherwise.

"},{"location":"api/connection/#monero.MoneroRpcConnection.check_connection","title":"check_connection(timeout_ms=20000)","text":"

Check the connection and update online, authentication, and response time status.

Parameters:

Name Type Description Default timeout_ms int

the maximum response time before considered offline.

20000

Returns:

Type Description bool

True if there is a change in status, False otherwise.

"},{"location":"api/connection/#monero.MoneroRpcConnection.compare","title":"compare(p1, p2) staticmethod","text":"

Compare connection priorities.

Parameters:

Name Type Description Default p1 int

first priority to check.

required p2 int

second priority to check.

required

Returns:

Type Description bool

True if p1 comes before p2, False otherwise.

"},{"location":"api/connection/#monero.MoneroRpcConnection.get_attribute","title":"get_attribute(key)","text":"

Returns RPC connection attribute.

Parameters:

Name Type Description Default key str

attribute key.

required

Returns:

Type Description str

attribute value.

"},{"location":"api/connection/#monero.MoneroRpcConnection.is_authenticated","title":"is_authenticated()","text":"

Indicates if the connection is authenticated according to the last call to check_connection().

Note: must call check_connection() manually.

Returns:

Type Description bool | None

True if authenticated or no authentication required, False if not authenticated, or None if check_connection() has not been called.

"},{"location":"api/connection/#monero.MoneroRpcConnection.is_connected","title":"is_connected()","text":"

Indicates if the connection is connected according to the last call to check_connection().

Note: must call check_connection() manually.

Returns:

Type Description bool | None

True or False to indicate if connected, or None if check_connection() has not been called.

"},{"location":"api/connection/#monero.MoneroRpcConnection.is_i2p","title":"is_i2p()","text":"

Indicates if the connection is a I2P connection.

Returns:

Type Description bool

True if connection is a I2P connection, False otherwise.

"},{"location":"api/connection/#monero.MoneroRpcConnection.is_onion","title":"is_onion()","text":"

Indicates if the connection is a TOR connection.

Returns:

Type Description bool

True if connection is a TOR connection, False otherwise.

"},{"location":"api/connection/#monero.MoneroRpcConnection.is_online","title":"is_online()","text":"

Indicates if the connection is online according to the last call to check_connection().

Note: must call check_connection() manually.

Returns:

Type Description bool | None

True or False to indicate if online, or None if check_connection() has not been called.

"},{"location":"api/connection/#monero.MoneroRpcConnection.send_binary_request","title":"send_binary_request(method, parameters=None)","text":"

Send a binary RPC request.

Parameters:

Name Type Description Default method str

is the path of the binary RPC method to invoke.

required parameters Optional[object]

are the request parameters (default None).

None

Returns:

Type Description bytes | None

the request's deserialized binary response.

"},{"location":"api/connection/#monero.MoneroRpcConnection.send_json_request","title":"send_json_request(method, parameters=None)","text":"

Send a request to the JSON-RPC API.

Parameters:

Name Type Description Default method str

is the method to request.

required parameters Optional[object]

are the request's input parameters (default None).

None

Returns:

Type Description object | None

the RPC API response as a map.

"},{"location":"api/connection/#monero.MoneroRpcConnection.send_path_request","title":"send_path_request(method, parameters=None)","text":"

Send a RPC request to the given path and with the given paramters.

E.g. /get_transactions with params.

Parameters:

Name Type Description Default method str

is the url path of the request to invoke.

required parameters Optional[object]

are request parameters sent in the body.

None

Returns:

Type Description object | None

the request's deserialized response.

"},{"location":"api/connection/#monero.MoneroRpcConnection.set_attribute","title":"set_attribute(key, value)","text":"

Set RPC connection attribute.

Parameters:

Name Type Description Default key str

key attribute.

required value str

value attribute.

required"},{"location":"api/connection/#monero.MoneroRpcConnection.set_credentials","title":"set_credentials(username, password)","text":"

Set RPC connection credentials.

Parameters:

Name Type Description Default username str

username used for RPC authentication.

required password str

passowrd user for RPC authentication.

required"},{"location":"api/daemon/","title":"Daemon Interface","text":""},{"location":"api/daemon/#monero.MoneroDaemon","title":"MoneroDaemon","text":"

Monero daemon interface.

"},{"location":"api/daemon/#monero.MoneroDaemon.__init__","title":"__init__()","text":"

Initialize a Monero daemon.

"},{"location":"api/daemon/#monero.MoneroDaemon.add_listener","title":"add_listener(listener)","text":"

Register a listener to receive daemon notifications.

Parameters:

Name Type Description Default listener MoneroDaemonListener

the listener to register.

required"},{"location":"api/daemon/#monero.MoneroDaemon.check_for_update","title":"check_for_update()","text":"

Check for update.

Returns:

Type Description MoneroDaemonUpdateCheckResult

the result of the update check.

"},{"location":"api/daemon/#monero.MoneroDaemon.download_update","title":"download_update(path='')","text":"

Download an update.

Parameters:

Name Type Description Default path str

download path.

''

Returns:

Type Description MoneroDaemonUpdateDownloadResult

the result of the update download.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_alt_block_hashes","title":"get_alt_block_hashes()","text":"

Get known block hashes which are not on the main chain.

Returns:

Type Description list[str]

known block hashes which are not on the main chain.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_alt_chains","title":"get_alt_chains()","text":"

Get alternative chains seen by the node.

Returns:

Type Description list[MoneroAltChain]

alternative chains seen by the node.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_block_by_hash","title":"get_block_by_hash(hash)","text":"

Get a block by hash.

Parameters:

Name Type Description Default hash str

is the hash of the block to get.

required

Returns:

Type Description MoneroBlock

the block with the given hash.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_block_by_height","title":"get_block_by_height(height)","text":"

Get a block by height.

Parameters:

Name Type Description Default height int

is the height of the block to get.

required

Returns:

Type Description MoneroBlock

the block at the given height.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_block_hash","title":"get_block_hash(height)","text":"

Get a block's hash by its height.

Parameters:

Name Type Description Default height int

is the height of the block hash to get.

required

Returns:

Type Description str

the block's hash at the given height.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_block_hashes","title":"get_block_hashes(block_hashes, start_height)","text":"

Get block hashes as a binary request to the daemon.

Parameters:

Name Type Description Default block_hashes list[str]

specify block hashes to fetch; first 10 blocks hash goes sequential, next goes in pow(2,n) offset, like 2, 4, 8, 16, 32, 64 and so on, and the last one is always genesis block.

required start_height int

is the starting height of block hashes to return.

required

Returns:

Type Description list[str]

the requested block hashes.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_block_header_by_hash","title":"get_block_header_by_hash(hash)","text":"

Get a block header by its hash.

Parameters:

Name Type Description Default hash str

is the hash of the block to get the header of.

required

Returns:

Type Description MoneroBlockHeader

the block's header.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_block_header_by_height","title":"get_block_header_by_height(height)","text":"

Get a block header by its height.

Parameters:

Name Type Description Default height int

is the height of the block to get the header of.

required

Returns:

Type Description MoneroBlockHeader

the block's header.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_block_headers_by_range","title":"get_block_headers_by_range(start_height, end_height)","text":"

Get block headers for the given range.

Parameters:

Name Type Description Default start_height int

is the start height lower bound inclusive (optional).

required end_height int

is the end height upper bound inclusive (optional).

required

Returns:

Type Description list[MoneroBlockHeader]

block headers in the given range.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_block_template","title":"get_block_template(wallet_address, reserve_size=None)","text":"

Get a block template for mining a new block.

Parameters:

Name Type Description Default wallet_address str

is the address of the wallet to receive miner transactions if block is successfully mined.

required

Returns:

Type Description MoneroBlockTemplate

a block template for mining a new block.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_blocks_by_hash","title":"get_blocks_by_hash(block_hashes, start_height, prune)","text":"

Get a block by hash.

Parameters:

Name Type Description Default block_hashes list[str]

is the hash of the block to get.

required start_height int

filter blocks by block height.

required prune bool

prune hash.

required

Returns:

Type Description list[MoneroBlock]

the block with the given hash.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_blocks_by_height","title":"get_blocks_by_height(heights)","text":"

Get blocks at the given heights.

Parameters:

Name Type Description Default heights list[int]

are the heights of the blocks to get.

required

Returns:

Type Description list[MoneroBlock]

blocks at the given heights.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_blocks_by_range","title":"get_blocks_by_range(start_height, end_height)","text":"

Get blocks in the given height range.

Parameters:

Name Type Description Default start_height int

is the start height lower bound inclusive (optional).

required end_height int

is the end height upper bound inclusive (optional).

required

Returns:

Type Description list[MoneroBlock]

blocks in the given height range.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_blocks_by_range_chunked","title":"get_blocks_by_range_chunked(start_height, end_height, max_chunk_size=None)","text":"

Get blocks in the given height range as chunked requests so that each request is not too big.

Parameters:

Name Type Description Default start_height int

is the start height lower bound inclusive (optional).

required end_height int

is the end height upper bound inclusive (optional).

required max_chunk_size int

is the maximum chunk size in any one request (default 3,000,000 bytes).

None

Returns:

Type Description list[MoneroBlock]

blocks in the given height range.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_download_limit","title":"get_download_limit()","text":"

Get the download bandwidth limit.

Returns:

Type Description int

is the download bandwidth limit.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_fee_estimate","title":"get_fee_estimate(grace_blocks=0)","text":"

Get mining fee estimates per kB.

Parameters:

Name Type Description Default grace_blocks int

number of blocks we want the fee estimate to be valid for.

0

Returns:

Type Description MoneroFeeEstimate

mining fee estimates per kB.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_hard_fork_info","title":"get_hard_fork_info()","text":"

Look up information regarding hard fork voting and readiness.

Returns:

Type Description MoneroHardForkInfo

hard fork information.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_height","title":"get_height()","text":"

Get the number of blocks in the longest chain known to the node.

Returns:

Type Description int

the number of blocks.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_info","title":"get_info()","text":"

Get general information about the state of the node and the network.

Returns:

Type Description MoneroDaemonInfo

general information about the node and network.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_key_image_spent_status","title":"get_key_image_spent_status(key_image)","text":"

Get the spent status of the given key image.

Parameters:

Name Type Description Default key_image str

is key image hex to get the status of.

required

Returns:

Type Description MoneroKeyImageSpentStatus

the status of the key image.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_key_image_spent_statuses","title":"get_key_image_spent_statuses(key_images)","text":"

Get the spent status of each given key image.

Parameters:

Name Type Description Default key_images list[str]

are hex key images to get the statuses of.

required

Returns:

Type Description list[MoneroKeyImageSpentStatus]

the spent status for each key image.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_known_peers","title":"get_known_peers()","text":"

Get all known peers including their last known online status.

Returns:

Type Description list[MoneroPeer]

the daemon's known peers.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_last_block_header","title":"get_last_block_header()","text":"

Get the last block's header.

Returns:

Type Description MoneroBlockHeader

the last block's header.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_listeners","title":"get_listeners()","text":"

Get the listeners registered with the daemon.

Returns:

Type Description list[MoneroDaemonListener]

the registered listeners.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_miner_tx_sum","title":"get_miner_tx_sum(height, num_blocks)","text":"

Gets the total emissions and fees from the genesis block to the current height.

Parameters:

Name Type Description Default height int

is the height to start computing the miner sum.

required num_blocks int

are the number of blocks to include in the sum.

required

Returns:

Type Description MoneroMinerTxSum

the sum emission and fees since the geneis block.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_mining_status","title":"get_mining_status()","text":"

Get the daemon's mining status.

Returns:

Type Description MoneroMiningStatus

the daemon's mining status.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_output_distribution","title":"get_output_distribution(amounts, is_cumulative=None, start_height=None, end_height=None)","text":"

Creates an output distribution.

Parameters:

Name Type Description Default amounts list[int]

are amounts of outputs to make the distribution with.

required

Returns:

Type Description list[MoneroOutputDistributionEntry]

output distribution entries meeting the parameters.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_output_histogram","title":"get_output_histogram(amounts, min_count, max_count, is_unlocked, recent_cutoff)","text":"

Get a histogram of output amounts. For all amounts (possibly filtered by parameters), gives the number of outputs on the chain for that amount. RingCT outputs counts as 0 amount.

Parameters:

Name Type Description Default amounts list[int]

are amounts of outputs to make the histogram with (atomic-units).

required min_count Optional[int]

filter amounts with at least this number of outputs.

required max_count Optional[int]

filter amounts with at most this number of outputs.

required is_unlocked Optional[bool]

makes a histogram with outputs with the specified lock state.

required recent_cutoff Optional[int]

exclude outputs from older than this timestamp.

required

Returns:

Type Description list[MoneroOutputHistogramEntry]

output histogram entries meeting the parameters.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_outputs","title":"get_outputs(outputs)","text":"

Get outputs identified by a list of output amounts and indices as a binary request.

Parameters:

Name Type Description Default outputs list[MoneroOutput]

identify each output by amount and index.

required

Returns:

Type Description list[MoneroOutput]

the identified outputs.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_peer_bans","title":"get_peer_bans()","text":"

Get peer bans.

Returns:

Type Description list[MoneroBan]

entries about banned peers.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_peers","title":"get_peers()","text":"

Get peers with active incoming or outgoing connections to the node.

Returns:

Type Description list[MoneroPeer]

the daemon's peers.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_sync_info","title":"get_sync_info()","text":"

Get synchronization information.

Returns:

Type Description MoneroDaemonSyncInfo

contains sync information.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_tx","title":"get_tx(tx_hash, prune=False)","text":"

Get a transaction by hash.

Parameters:

Name Type Description Default tx_hash str

is the hash of the transaction to get.

required prune bool

specifies if the returned tx should be pruned (defaults to False).

False

Returns:

Type Description MoneroTx | None

the transaction with the given hash or null if not found.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_tx_hex","title":"get_tx_hex(tx_hash, prune=False)","text":"

Get a transaction hex by hash.

Parameters:

Name Type Description Default tx_hash str

is the hash of the transaction to get hex from.

required prune bool

specifies if the returned tx hex should be pruned (defaults to False).

False

Returns:

Type Description str | None

the tx hex with the given hash.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_tx_hexes","title":"get_tx_hexes(tx_hashes, prune=False)","text":"

Get transaction hexes by hashes.

Parameters:

Name Type Description Default tx_hashes list[str]

are hashes of transactions to get hexes from

required prune bool

Prune transaction hashes.

False

Returns:

Type Description list[str]

are the tx hexes.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_tx_pool","title":"get_tx_pool()","text":"

Get valid transactions seen by the node but not yet mined into a block, as well as spent key image information for the tx pool.

Returns:

Type Description list[MoneroTx]

transactions in the transaction pool.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_tx_pool_backlog","title":"get_tx_pool_backlog()","text":"

Get all transaction pool backlog.

Returns:

Type Description list[MoneroTxBacklogEntry]

transaction pool backlog entries.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_tx_pool_hashes","title":"get_tx_pool_hashes()","text":"

Get hashes of transactions in the transaction pool.

Returns:

Type Description list[str]

hashes of transactions in the transaction pool.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_tx_pool_stats","title":"get_tx_pool_stats()","text":"

Get transaction pool statistics.

Returns:

Type Description MoneroTxPoolStats

statistics about the transaction pool.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_txs","title":"get_txs(tx_hashes, prune=False)","text":"

Get transactions by hashes.

Parameters:

Name Type Description Default tx_hashes list[str]

are hashes of transactions to get.

required prune bool

Prune transactions.

False

Returns:

Type Description list[MoneroTx]

found transactions with the given hashes.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_upload_limit","title":"get_upload_limit()","text":"

Get the upload bandwidth limit.

Returns:

Type Description int

is the upload bandwidth limit.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_version","title":"get_version()","text":"

Gets the version of the daemon.

Returns:

Type Description MoneroVersion

the version of the daemon.

"},{"location":"api/daemon/#monero.MoneroDaemon.is_trusted","title":"is_trusted()","text":"

Indicates if the daemon is trusted or untrusted.

Returns:

Type Description bool

True if the daemon is trusted, False otherwise.

"},{"location":"api/daemon/#monero.MoneroDaemon.prune_blockchain","title":"prune_blockchain(check)","text":"

Prune the blockchain.

Parameters:

Name Type Description Default check bool

specifies to check the pruning (default False).

required

Returns:

Type Description MoneroPruneResult

the prune result.

"},{"location":"api/daemon/#monero.MoneroDaemon.relay_tx_by_hash","title":"relay_tx_by_hash(tx_hash)","text":"

Relays a transaction by hash.

Parameters:

Name Type Description Default tx_hash str

identifies the transaction to relay.

required"},{"location":"api/daemon/#monero.MoneroDaemon.relay_txs_by_hash","title":"relay_txs_by_hash(tx_hashes)","text":"

Relays transactions by hash.

Parameters:

Name Type Description Default tx_hashes list[str]

identify the transactions to relay.

required"},{"location":"api/daemon/#monero.MoneroDaemon.remove_listener","title":"remove_listener(listener)","text":"

Unregister a listener to receive daemon notifications.

Parameters:

Name Type Description Default listener MoneroDaemonListener

a previously registered listener to be unregistered.

required"},{"location":"api/daemon/#monero.MoneroDaemon.reset_download_limit","title":"reset_download_limit()","text":"

Reset the download bandwidth limit.

Returns:

Type Description int

the download bandwidth limit after resetting.

"},{"location":"api/daemon/#monero.MoneroDaemon.reset_upload_limit","title":"reset_upload_limit()","text":"

Reset the upload bandwidth limit.

Returns:

Type Description int

the upload bandwidth limit after resetting.

"},{"location":"api/daemon/#monero.MoneroDaemon.set_download_limit","title":"set_download_limit(limit)","text":"

Set the download bandwidth limit.

Parameters:

Name Type Description Default limit int

is the download limit to set (-1 to reset to default).

required

Returns:

Type Description int

is the new download limit after setting.

"},{"location":"api/daemon/#monero.MoneroDaemon.set_incoming_peer_limit","title":"set_incoming_peer_limit(limit)","text":"

Limit number of incoming peers.

Parameters:

Name Type Description Default limit int

is the maximum number of incoming peers.

required"},{"location":"api/daemon/#monero.MoneroDaemon.set_outgoing_peer_limit","title":"set_outgoing_peer_limit(limit)","text":"

Limit number of outgoing peers.

Parameters:

Name Type Description Default limit int

is the maximum number of outgoing peers.

required"},{"location":"api/daemon/#monero.MoneroDaemon.set_peer_ban","title":"set_peer_ban(ban)","text":"

Ban a peer node.

Parameters:

Name Type Description Default ban MoneroBan

contains information about a node to ban.

required"},{"location":"api/daemon/#monero.MoneroDaemon.set_peer_bans","title":"set_peer_bans(bans)","text":"

Ban peers nodes.

Parameters:

Name Type Description Default bans list[MoneroBan]

are bans to apply against peer nodes.

required"},{"location":"api/daemon/#monero.MoneroDaemon.set_upload_limit","title":"set_upload_limit(limit)","text":"

Set the upload bandwidth limit.

Parameters:

Name Type Description Default limit int

is the upload limit to set (-1 to reset to default).

required

Returns:

Type Description int

is the new upload limit after setting.

"},{"location":"api/daemon/#monero.MoneroDaemon.start_mining","title":"start_mining(address, num_threads, is_background, ignore_battery)","text":"

Start mining.

Parameters:

Name Type Description Default address str

is the address given miner rewards if the daemon mines a block.

required num_threads int

is the number of mining threads to run.

required is_background bool

specifies if the miner should run in the background or not.

required ignore_battery bool

specifies if the battery state (e.g. on laptop) should be ignored or not.

required"},{"location":"api/daemon/#monero.MoneroDaemon.stop","title":"stop()","text":"

Safely disconnect and shut down the daemon.

"},{"location":"api/daemon/#monero.MoneroDaemon.stop_mining","title":"stop_mining()","text":"

Stop mining.

"},{"location":"api/daemon/#monero.MoneroDaemon.submit_block","title":"submit_block(block_blob)","text":"

Submit a mined block to the network.

Parameters:

Name Type Description Default block_blob str

is the mined block to submit.

required"},{"location":"api/daemon/#monero.MoneroDaemon.submit_blocks","title":"submit_blocks(block_blobs)","text":"

Submit mined blocks to the network.

Parameters:

Name Type Description Default block_blobs list[str]

are the mined blocks to submit.

required"},{"location":"api/daemon/#monero.MoneroDaemon.submit_tx_hex","title":"submit_tx_hex(tx_hex, do_not_relay=False)","text":"

Submits a transaction to the daemon's pool.

Parameters:

Name Type Description Default tx_hex str

is the raw transaction hex to submit.

required

Returns:

Type Description MoneroSubmitTxResult

the submission results.

"},{"location":"api/daemon/#monero.MoneroDaemon.wait_for_next_block_header","title":"wait_for_next_block_header()","text":"

Get the header of the next block added to the chain.

Returns:

Type Description MoneroBlockHeader

the header of the next block added to the chain.

"},{"location":"api/daemon_rpc/","title":"Daemon RPC","text":""},{"location":"api/daemon_rpc/#monero.MoneroDaemonRpc","title":"MoneroDaemonRpc","text":"

Bases: MoneroDaemon

Implements a MoneroDaemon using monerod-rpc_.

.. _monerod-rpc: https://docs.getmonero.org/rpc-library/monerod-rpc/

"},{"location":"api/daemon_rpc/#monero.MoneroDaemonRpc.get_rpc_connection","title":"get_rpc_connection()","text":"

Get the daemon's RPC connection.

Returns:

Type Description MoneroRpcConnection

the daemon's rpc connection.

"},{"location":"api/daemon_rpc/#monero.MoneroDaemonRpc.is_connected","title":"is_connected()","text":"

Indicates if the client is connected to the daemon via RPC.

Returns:

Type Description bool

True if the client is connected to the daemon, False otherwise.

"},{"location":"api/serializable_struct/","title":"Serializable Struct","text":""},{"location":"api/serializable_struct/#monero.SerializableStruct","title":"SerializableStruct","text":"

Bases: ABC

Base struct which can be serialized.

"},{"location":"api/serializable_struct/#monero.SerializableStruct.serialize","title":"serialize()","text":"

Serializes the struct to a json string.

Returns:

Type Description str

the struct serialized to a json string.

"},{"location":"api/utils/","title":"Monero Utilities","text":""},{"location":"api/utils/#monero.MoneroUtils","title":"MoneroUtils","text":"

Collection of Monero utilities.

"},{"location":"api/utils/#monero.MoneroUtils.atomic_units_to_xmr","title":"atomic_units_to_xmr(amount_atomic_units) staticmethod","text":"

Convert atomic units to XMR.

Parameters:

Name Type Description Default amount_atomic_units int

amount in atomic units to convert to XMR.

required

Returns:

Type Description float

amount in XMR.

"},{"location":"api/utils/#monero.MoneroUtils.binary_blocks_to_json","title":"binary_blocks_to_json(bin) staticmethod","text":"

Deserialize blocks JSON string from binary format.

Parameters:

Name Type Description Default bin bytes

blocks JSON string in binary format.

required

Returns:

Type Description str

The deserialized blocks in JSON string format.

"},{"location":"api/utils/#monero.MoneroUtils.binary_to_dict","title":"binary_to_dict(bin) staticmethod","text":"

Deserialize a dictionary from binary format.

Parameters:

Name Type Description Default bin bytes

Dictionary in binary format.

required

Returns:

Type Description dict[Any, Any]

Deserialized dictionary.

"},{"location":"api/utils/#monero.MoneroUtils.binary_to_json","title":"binary_to_json(bin) staticmethod","text":"

Deserialize a JSON string from binary format.

Parameters:

Name Type Description Default bin bytes

JSON string in binary format.

required

Returns:

Type Description str

The deserialized JSON string.

"},{"location":"api/utils/#monero.MoneroUtils.configure_logging","title":"configure_logging(path, console) staticmethod","text":"

Initialize logging.

Parameters:

Name Type Description Default path str

the path to write logs to.

required console bool

specifies whether or not to write to the console.

required"},{"location":"api/utils/#monero.MoneroUtils.dict_to_binary","title":"dict_to_binary(dictionary) staticmethod","text":"

Converts a dictionary into binary format.

Parameters:

Name Type Description Default dictionary dict

The dictionary to convert in binary format.

required

Returns:

Type Description bytes

Binary format.

"},{"location":"api/utils/#monero.MoneroUtils.get_blocks_from_outputs","title":"get_blocks_from_outputs(outputs) staticmethod","text":"

Get distinct blocks from outputs.

Parameters:

Name Type Description Default outputs list[MoneroOutputWallet]

Outputs to get blocks from.

required

Returns:

Type Description list[MoneroBlock]

Distinct blocks obtained from outputs.

"},{"location":"api/utils/#monero.MoneroUtils.get_blocks_from_transfers","title":"get_blocks_from_transfers(transfers) staticmethod","text":"

Get distinct blocks from transfers.

Parameters:

Name Type Description Default transfers list[MoneroTransfer]

Transfers to get blocks from.

required

Returns:

Type Description list[MoneroBlock]

Distinct blocks obtained from transfers.

"},{"location":"api/utils/#monero.MoneroUtils.get_blocks_from_txs","title":"get_blocks_from_txs(txs) staticmethod","text":"

Get distinct blocks from transactions.

Parameters:

Name Type Description Default txs list[MoneroTxWallet]

Transactions to get blocks from.

required

Returns:

Type Description list[MoneroBlock]

Distinct blocks obtained from transactions.

"},{"location":"api/utils/#monero.MoneroUtils.get_integrated_address","title":"get_integrated_address(network_type, standard_address, payment_id='') staticmethod","text":"

Get an integrated address.

Parameters:

Name Type Description Default network_type MoneroNetworkType

is the network type of the integrated address.

required standard_address str

is the address to derive the integrated address from.

required payment_id str

optionally specifies the integrated address's payment id (defaults to random payment id).

''

Returns:

Type Description MoneroIntegratedAddress

the integrated address.

"},{"location":"api/utils/#monero.MoneroUtils.get_payment_uri","title":"get_payment_uri(config, network_type=MoneroNetworkType.MAINNET) staticmethod","text":"

Creates a payment URI from a tx configuration.

Parameters:

Name Type Description Default config MoneroTxConfig

specifies configuration for a payment URI.

required network_type MoneroNetworkType

address network type (optional).

MAINNET

Returns:

Type Description str

the payment URI.

"},{"location":"api/utils/#monero.MoneroUtils.get_ring_size","title":"get_ring_size() staticmethod","text":"

Get network-enforced ring size.

Returns:

Type Description int

network-enforced ring size.

"},{"location":"api/utils/#monero.MoneroUtils.get_version","title":"get_version() staticmethod","text":"

Get the version of the monero-python library.

Returns:

Type Description str

the version of this monero-python library

"},{"location":"api/utils/#monero.MoneroUtils.is_valid_address","title":"is_valid_address(address, network_type) staticmethod","text":"

Determine if the given address is valid.

Parameters:

Name Type Description Default address str

is the address to validate.

required network_type MoneroNetworkType

is the address's network type.

required

Returns:

Type Description bool

True if the address is valid, False otherwise.

"},{"location":"api/utils/#monero.MoneroUtils.is_valid_language","title":"is_valid_language(language) staticmethod","text":"

Indicates if the given language is valid.

Parameters:

Name Type Description Default language str

is the language to validate

required

Returns:

Type Description bool

True if the language is valid, False otherwise.

"},{"location":"api/utils/#monero.MoneroUtils.is_valid_mnemonic","title":"is_valid_mnemonic(mnemonic) staticmethod","text":"

Indicates if a mnemonic is valid.

Parameters:

Name Type Description Default mnemonic str

is the mnemonic to validate.

required

Returns:

Type Description bool

True if the mnemonic is valid, False otherwise.

"},{"location":"api/utils/#monero.MoneroUtils.is_valid_payment_id","title":"is_valid_payment_id(payment_id) staticmethod","text":"

Indicates if a payment id is valid.

Parameters:

Name Type Description Default payment_id str

is the payment id to validate.

required

Returns:

Type Description bool

True if the payment id is valid, False otherwise.

"},{"location":"api/utils/#monero.MoneroUtils.is_valid_private_spend_key","title":"is_valid_private_spend_key(private_spend_key) staticmethod","text":"

Indicates if a private spend key is valid.

Parameters:

Name Type Description Default private_spend_key str

is the private spend key to validate.

required

Returns:

Type Description bool

True if the private spend key is valid, False otherwise.

"},{"location":"api/utils/#monero.MoneroUtils.is_valid_private_view_key","title":"is_valid_private_view_key(private_view_key) staticmethod","text":"

Indicates if a private view key is valid.

Parameters:

Name Type Description Default private_view_key str

is the private view key to validate.

required

Returns:

Type Description bool

True if the private view key is valid, False otherwise.

"},{"location":"api/utils/#monero.MoneroUtils.is_valid_public_spend_key","title":"is_valid_public_spend_key(public_spend_key) staticmethod","text":"

Indicates if a public spend key is valid.

Parameters:

Name Type Description Default public_spend_key str

is the public spend key to validate.

required

Returns:

Type Description bool

True if the public spend key is valid, False otherwise.

"},{"location":"api/utils/#monero.MoneroUtils.is_valid_public_view_key","title":"is_valid_public_view_key(public_view_key) staticmethod","text":"

Indicates if a public view key is valid.

Parameters:

Name Type Description Default public_view_key str

is the public view key to validate.

required

Returns:

Type Description bool

True if the public view key is valid, False otherwise.

"},{"location":"api/utils/#monero.MoneroUtils.json_to_binary","title":"json_to_binary(json) staticmethod","text":"

Convert a JSON string into binary format.

Returns:

Type Description bytes

Binary format.

"},{"location":"api/utils/#monero.MoneroUtils.set_log_level","title":"set_log_level(loglevel) staticmethod","text":"

Set the library's log level with 0 being least verbose.

Parameters:

Name Type Description Default loglevel int

the library's log level.

required"},{"location":"api/utils/#monero.MoneroUtils.validate_address","title":"validate_address(address, network_type) staticmethod","text":"

Validates the given address.

Parameters:

Name Type Description Default address str

is the address to validate.

required network_type MoneroNetworkType

is the address's network type.

required"},{"location":"api/utils/#monero.MoneroUtils.validate_mnemonic","title":"validate_mnemonic(mnemonic) staticmethod","text":"

Validates the given mnemonic phrase.

Parameters:

Name Type Description Default mnemonic str

is the mnemonic to validate.

required

Raises:

Type Description MoneroError

if the given mnemonic is invalid.

"},{"location":"api/utils/#monero.MoneroUtils.validate_payment_id","title":"validate_payment_id(payment_id) staticmethod","text":"

Validate a payment id.

Parameters:

Name Type Description Default payment_id str

is the payment id to validate.

required

Raises:

Type Description MoneroError

if the given payment id is invalid.

"},{"location":"api/utils/#monero.MoneroUtils.validate_private_spend_key","title":"validate_private_spend_key(private_spend_key) staticmethod","text":"

Validate a private spend key.

Parameters:

Name Type Description Default private_spend_key str

is the private spend key to validate.

required

Raises:

Type Description MoneroError

if the given private spend key is invalid.

"},{"location":"api/utils/#monero.MoneroUtils.validate_private_view_key","title":"validate_private_view_key(private_view_key) staticmethod","text":"

Validate a private view key.

Parameters:

Name Type Description Default private_view_key str

is the private view key to validate.

required

Raises:

Type Description MoneroError

if the given private view key is invalid.

"},{"location":"api/utils/#monero.MoneroUtils.validate_public_spend_key","title":"validate_public_spend_key(public_spend_key) staticmethod","text":"

Validate a public spend key.

Parameters:

Name Type Description Default public_spend_key str

is the public spend key to validate.

required

Raises:

Type Description MoneroError

if the given public spend key is invalid.

"},{"location":"api/utils/#monero.MoneroUtils.validate_public_view_key","title":"validate_public_view_key(public_view_key) staticmethod","text":"

Validate a public view key.

Parameters:

Name Type Description Default public_view_key str

is the public view key to validate.

required

Raises:

Type Description MoneroError

if the given public view key is invalid.

"},{"location":"api/utils/#monero.MoneroUtils.xmr_to_atomic_units","title":"xmr_to_atomic_units(amount_xmr) staticmethod","text":"

Convert XMR to atomic units.

Parameters:

Name Type Description Default amount_xmr float

amount in XMR to convert to atomic units.

required

Returns:

Type Description int

amount in atomic units.

"},{"location":"api/wallet/","title":"Wallet Interface","text":""},{"location":"api/wallet/#monero.MoneroWallet","title":"MoneroWallet","text":"

Base wallet with default implementations.

"},{"location":"api/wallet/#monero.MoneroWallet.DEFAULT_LANGUAGE","title":"DEFAULT_LANGUAGE: str instance-attribute","text":"

Default Monero wallet seed language.

"},{"location":"api/wallet/#monero.MoneroWallet.__init__","title":"__init__()","text":"

Initialize a Monero wallet.

"},{"location":"api/wallet/#monero.MoneroWallet.add_address_book_entry","title":"add_address_book_entry(address, description)","text":"

Add an address book entry.

Parameters:

Name Type Description Default address str

is the entry address.

required description str

is the entry description (optional).

required

Returns:

Type Description int

the index of the added entry.

"},{"location":"api/wallet/#monero.MoneroWallet.add_listener","title":"add_listener(listener)","text":"

Register a listener receive wallet notifications.

Parameters:

Name Type Description Default listener MoneroWalletListener

is the listener to receive wallet notifications.

required"},{"location":"api/wallet/#monero.MoneroWallet.change_password","title":"change_password(old_password, new_password)","text":"

Change the wallet password.

Parameters:

Name Type Description Default old_password str

is the wallet's old password.

required new_password str

is the wallet's new password.

required"},{"location":"api/wallet/#monero.MoneroWallet.check_reserve_proof","title":"check_reserve_proof(address, message, signature)","text":"

Proves a wallet has a disposable reserve using a signature.

Parameters:

Name Type Description Default address str

is the public wallet address.

required message str

is a message included with the signature to further authenticate the proof (optional).

required signature str

is the reserve proof signature to check.

required

Returns:

Type Description MoneroCheckReserve

the result of checking the signature proof.

"},{"location":"api/wallet/#monero.MoneroWallet.check_spend_proof","title":"check_spend_proof(tx_hash, message, signature)","text":"

Prove a spend using a signature. Unlike proving a transaction, it does not require the destination public address.

Parameters:

Name Type Description Default tx_hash str

specifies the transaction to prove.

required message str

is a message included with the signature to further authenticate the proof (optional).

required signature str

is the transaction signature to confirm.

required

Returns:

Type Description bool

True if the signature is good, False otherwise.

"},{"location":"api/wallet/#monero.MoneroWallet.check_tx_key","title":"check_tx_key(tx_hash, tx_key, address)","text":"

Check a transaction in the blockchain with its secret key.

Parameters:

Name Type Description Default tx_hash str

specifies the transaction to check.

required tx_key str

is the transaction's secret key.

required address str

is the destination public address of the transaction.

required

Returns:

Type Description MoneroCheckTx

the result of the check.

"},{"location":"api/wallet/#monero.MoneroWallet.check_tx_proof","title":"check_tx_proof(tx_hash, address, message, signature)","text":"

Prove a transaction by checking its signature.

Parameters:

Name Type Description Default tx_hash str

specifies the transaction to prove.

required address str

is the destination public address of the transaction.

required message str

is a message included with the signature to further authenticate the proof (optional).

required signature str

is the transaction signature to confirm.

required

Returns:

Type Description MoneroCheckTx

the result of the check.

"},{"location":"api/wallet/#monero.MoneroWallet.close","title":"close(save=False)","text":"

Optionally save then close the wallet.

Parameters:

Name Type Description Default save bool

specifies if the wallet should be saved before being closed (default False).

False"},{"location":"api/wallet/#monero.MoneroWallet.create_account","title":"create_account(label='')","text":"

Create a new account with a label for the first subaddress.

Parameters:

Name Type Description Default label str

specifies the label for the account's first subaddress (optional).

''

Returns:

Type Description MoneroAccount

the created account.

"},{"location":"api/wallet/#monero.MoneroWallet.create_subaddress","title":"create_subaddress(account_idx, label='')","text":"

Create a subaddress within an account.

Parameters:

Name Type Description Default account_idx int

specifies the index of the account to create the subaddress within.

required label str

specifies the the label for the subaddress (defaults to empty string).

''

Returns:

Type Description MoneroSubaddress

the created subaddress.

"},{"location":"api/wallet/#monero.MoneroWallet.create_tx","title":"create_tx(config)","text":"

Create a transaction to transfer funds from this wallet.

Parameters:

Name Type Description Default config MoneroTxConfig

configures the transaction to create.

required

Returns:

Type Description MoneroTxWallet

the created transaction.

"},{"location":"api/wallet/#monero.MoneroWallet.create_txs","title":"create_txs(config)","text":"

Create one or more transactions to transfer funds from this wallet.

Parameters:

Name Type Description Default config MoneroTxConfig

configures the transactions to create.

required

Returns:

Type Description list[MoneroTxWallet]

the created transactions.

"},{"location":"api/wallet/#monero.MoneroWallet.decode_integrated_address","title":"decode_integrated_address(integrated_address)","text":"

Decode an integrated address to get its standard address and payment id.

Parameters:

Name Type Description Default integrated_address str

is an integrated address to decode.

required

Returns:

Type Description MoneroIntegratedAddress

the decoded integrated address including standard address and payment id.

"},{"location":"api/wallet/#monero.MoneroWallet.delete_address_book_entry","title":"delete_address_book_entry(index)","text":"

Delete an address book entry.

Parameters:

Name Type Description Default index int

is the index of the entry to delete.

required"},{"location":"api/wallet/#monero.MoneroWallet.describe_multisig_tx_set","title":"describe_multisig_tx_set(multisig_tx_hex)","text":"

Describe a tx set containing unsigned or multisig tx hex to a new tx set containing structured transactions.

Parameters:

Name Type Description Default multisig_tx_hex str

multisig tx hex.

required

Returns:

Type Description MoneroTxSet

the tx set containing structured transactions.

"},{"location":"api/wallet/#monero.MoneroWallet.describe_tx_set","title":"describe_tx_set(tx_set)","text":"

Describes a tx set containing unsigned or multisig tx hex to a new tx set containing structured transactions.

Parameters:

Name Type Description Default tx_set MoneroTxSet

is a tx set containing unsigned or multisig tx hex.

required

Returns:

Type Description MoneroTxSet

the tx set containing structured transactions.

"},{"location":"api/wallet/#monero.MoneroWallet.describe_unsigned_tx_set","title":"describe_unsigned_tx_set(unsigned_tx_hex)","text":"

Describe a tx set from unsigned tx hex.

Parameters:

Name Type Description Default unsigned_tx_hex str

unsigned tx hex.

required

Returns:

Type Description MoneroTxSet

the tx set containing structured transactions.

"},{"location":"api/wallet/#monero.MoneroWallet.edit_address_book_entry","title":"edit_address_book_entry(index, set_address, address, set_description, description)","text":"

Edit an address book entry.

Parameters:

Name Type Description Default index int

is the index of the address book entry to edit.

required set_address bool

specifies if the address should be updated.

required address str

is the updated address.

required set_description bool

specifies if the description should be updated.

required description str

is the updated description.

required"},{"location":"api/wallet/#monero.MoneroWallet.exchange_multisig_keys","title":"exchange_multisig_keys(multisig_hexes, password)","text":"

Exchange multisig hex with participants in a M/N multisig wallet.

This process must be repeated with participants exactly N-M times.

Parameters:

Name Type Description Default multisig_hexes list[str]

are multisig hex from each participant.

required password str

is the wallet's password (TODO monero-project: redundant? wallet is created with password).

required

Returns:

Type Description MoneroMultisigInitResult

the result which has the multisig's address xor this wallet's multisig hex to share with participants if not done.

"},{"location":"api/wallet/#monero.MoneroWallet.export_key_images","title":"export_key_images(all=False)","text":"

Export signed key images.

Parameters:

Name Type Description Default all bool

export all key images if True, else export key images since the last export.

False

Returns:

Type Description list[MoneroKeyImage]

the wallet's signed key images.

"},{"location":"api/wallet/#monero.MoneroWallet.export_multisig_hex","title":"export_multisig_hex()","text":"

Export this wallet's multisig info as hex for other participants.

Returns:

Type Description str

this wallet's multisig info as hex for other participants.

"},{"location":"api/wallet/#monero.MoneroWallet.export_outputs","title":"export_outputs(all=False)","text":"

Export outputs in hex format.

Parameters:

Name Type Description Default all bool

export all outputs if True, else export outputs since the last export.

False

Returns:

Type Description str

outputs in hex format, empty string if no outputs.

"},{"location":"api/wallet/#monero.MoneroWallet.freeze_output","title":"freeze_output(key_image)","text":"

Freeze an output.

Parameters:

Name Type Description Default key_image str

key image of the output to freeze.

required"},{"location":"api/wallet/#monero.MoneroWallet.get_account_tags","title":"get_account_tags()","text":"

Return all account tags.

Returns:

Type Description list[MoneroAccountTag]

the wallet's account tags.

"},{"location":"api/wallet/#monero.MoneroWallet.get_address","title":"get_address(account_idx, subaddress_idx)","text":"

Get the address of a specific subaddress.

Parameters:

Name Type Description Default account_idx int

specifies the account index of the address's subaddress.

required subaddress_idx int

specifies the subaddress index within the account.

required

Returns:

Type Description str

the receive address of the specified subaddress.

"},{"location":"api/wallet/#monero.MoneroWallet.get_address_index","title":"get_address_index(address)","text":"

Get the account and subaddress index of the given address.

Parameters:

Name Type Description Default address str

is the address to get the account and subaddress index from.

required

Returns:

Type Description MoneroSubaddress

the account and subaddress indices.

Raises:

Type Description MoneroError

exception if address is not a wallet address.

"},{"location":"api/wallet/#monero.MoneroWallet.get_attribute","title":"get_attribute(key)","text":"

Get an attribute.

Parameters:

Name Type Description Default key str

is the attribute to get the value of.

required

Returns:

Type Description str

attribute's value.

"},{"location":"api/wallet/#monero.MoneroWallet.get_daemon_connection","title":"get_daemon_connection()","text":"

Get the wallet's daemon connection.

Returns:

Type Description MoneroRpcConnection | None

the wallet's daemon connection.

"},{"location":"api/wallet/#monero.MoneroWallet.get_daemon_height","title":"get_daemon_height()","text":"

Get the height that the wallet's daemon is synced to.

Returns:

Type Description int

the height that the wallet's daemon is synced to.

"},{"location":"api/wallet/#monero.MoneroWallet.get_daemon_max_peer_height","title":"get_daemon_max_peer_height()","text":"

Get the maximum height of the peers the wallet's daemon is connected to.

Returns:

Type Description int

the maximum height of the peers the wallet's daemon is connected to.

"},{"location":"api/wallet/#monero.MoneroWallet.get_default_fee_priority","title":"get_default_fee_priority()","text":"

Get the current default fee priority (unimportant, normal, elevated, etc).

Returns:

Type Description MoneroTxPriority

the current fee priority.

"},{"location":"api/wallet/#monero.MoneroWallet.get_height","title":"get_height()","text":"

Get the height of the last block processed by the wallet (its index + 1).

Returns:

Type Description int

the height of the last block processed by the wallet.

"},{"location":"api/wallet/#monero.MoneroWallet.get_height_by_date","title":"get_height_by_date(year, month, day)","text":"

Get the blockchain's height by date as a conservative estimate for scanning.

Parameters:

Name Type Description Default year int

year of the height to get.

required month int

month of the height to get as a number between 1 and 12.

required day int

day of the height to get as a number between 1 and 31.

required

Returns:

Type Description int

the blockchain's approximate height at the given date.

"},{"location":"api/wallet/#monero.MoneroWallet.get_integrated_address","title":"get_integrated_address(standard_address='', payment_id='')","text":"

Get an integrated address from a standard address and a payment id.

Parameters:

Name Type Description Default standard_address str

is the integrated addresse's standard address (defaults to wallet's primary address).

'' payment_id str

is the integrated addresse's payment id (defaults to randomly generating new payment id).

''

Returns:

Type Description MoneroIntegratedAddress

the integrated address.

"},{"location":"api/wallet/#monero.MoneroWallet.get_listeners","title":"get_listeners()","text":"

Get the listeners registered with the wallet.

Returns:

Type Description list[MoneroWalletListener]

List of listener registered with the wallet.

"},{"location":"api/wallet/#monero.MoneroWallet.get_multisig_info","title":"get_multisig_info()","text":"

Get multisig info about this wallet.

Returns:

Type Description MoneroMultisigInfo

multisig info about this wallet.

"},{"location":"api/wallet/#monero.MoneroWallet.get_network_type","title":"get_network_type()","text":"

Get the wallet's network type (mainnet, testnet, or stagenet).

Returns:

Type Description MoneroNetworkType

the wallet's network type.

"},{"location":"api/wallet/#monero.MoneroWallet.get_new_key_images_from_last_import","title":"get_new_key_images_from_last_import()","text":"

Get new key images from the last imported outputs.

Returns:

Type Description list[MoneroKeyImage]

the key images from the last imported outputs.

"},{"location":"api/wallet/#monero.MoneroWallet.get_path","title":"get_path()","text":"

Get the path of this wallet's file on disk.

Returns:

Type Description str

the path of this wallet's file on disk.

"},{"location":"api/wallet/#monero.MoneroWallet.get_payment_uri","title":"get_payment_uri(config)","text":"

Creates a payment URI from a tx configuration.

Parameters:

Name Type Description Default config MoneroTxConfig

specifies configuration for a potential tx.

required

Returns:

Type Description str

is the payment uri.

"},{"location":"api/wallet/#monero.MoneroWallet.get_primary_address","title":"get_primary_address()","text":"

Get the wallet's primary address.

Returns:

Type Description str

the wallet's primary address.

"},{"location":"api/wallet/#monero.MoneroWallet.get_private_spend_key","title":"get_private_spend_key()","text":"

Get the wallet's private spend key.

Returns:

Type Description str

the wallet's private spend key.

"},{"location":"api/wallet/#monero.MoneroWallet.get_private_view_key","title":"get_private_view_key()","text":"

Get the wallet's private view key.

Returns:

Type Description str

the wallet's private view key.

"},{"location":"api/wallet/#monero.MoneroWallet.get_public_spend_key","title":"get_public_spend_key()","text":"

Get the wallet's public spend key.

Returns:

Type Description str

the wallet's public spend key.

"},{"location":"api/wallet/#monero.MoneroWallet.get_public_view_key","title":"get_public_view_key()","text":"

Get the wallet's public view key.

Returns:

Type Description str

the wallet's public view key.

"},{"location":"api/wallet/#monero.MoneroWallet.get_reserve_proof_account","title":"get_reserve_proof_account(account_idx, amount, message)","text":"

Generate a signature to prove an available amount in an account.

Parameters:

Name Type Description Default account_idx int

specifies the account to prove ownership of the amount.

required amount int

is the minimum amount to prove as available in the account.

required message str

is a message to include with the signature to further authenticate the proof (optional).

required

Returns:

Type Description str

the reserve proof signature.

"},{"location":"api/wallet/#monero.MoneroWallet.get_reserve_proof_wallet","title":"get_reserve_proof_wallet(message)","text":"

Generate a signature to prove the entire balance of the wallet.

Parameters:

Name Type Description Default message str

is a message included with the signature to further authenticate the proof (optional).

required

Returns:

Type Description str

the reserve proof signature.

"},{"location":"api/wallet/#monero.MoneroWallet.get_restore_height","title":"get_restore_height()","text":"

Get the height of the first block that the wallet scans.

Returns:

Type Description int

the height of the first block that the wallet scans.

"},{"location":"api/wallet/#monero.MoneroWallet.get_seed","title":"get_seed()","text":"

Get the wallet's mnemonic phrase or seed.

Returns:

Type Description str

the wallet's mnemonic phrase or seed.

"},{"location":"api/wallet/#monero.MoneroWallet.get_seed_language","title":"get_seed_language()","text":"

Get the language of the wallet's mnemonic phrase or seed.

Returns:

Type Description str

the language of the wallet's mnemonic phrase or seed.

"},{"location":"api/wallet/#monero.MoneroWallet.get_spend_proof","title":"get_spend_proof(tx_hash, message='')","text":"

Generate a signature to prove a spend. Unlike proving a transaction, it does not require the destination public address.

Parameters:

Name Type Description Default tx_hash str

specifies the transaction to prove.

required message str

is a message to include with the signature to further authenticate the proof (optional).

''

Returns:

Type Description str

the transaction signature.

"},{"location":"api/wallet/#monero.MoneroWallet.get_subaddress","title":"get_subaddress(account_idx, subaddress_idx)","text":"

Get a subaddress.

Parameters:

Name Type Description Default account_idx int

specifies the index of the subaddress's account.

required subaddress_idx int

specifies index of the subaddress within the account.

required

Returns:

Type Description MoneroSubaddress

the retrieved subaddress.

"},{"location":"api/wallet/#monero.MoneroWallet.get_tx","title":"get_tx(tx_hash)","text":"

Get single wallet transaction by hash.

Parameters:

Name Type Description Default tx_hash str

Transaction hash.

required

Returns:

Type Description MoneroTxWallet | None

wallet transaction.

"},{"location":"api/wallet/#monero.MoneroWallet.get_tx_key","title":"get_tx_key(tx_hash)","text":"

Get a transaction's secret key from its hash.

Parameters:

Name Type Description Default tx_hash str

is the transaction's hash.

required

Returns:

Type Description str

is the transaction's secret key.

"},{"location":"api/wallet/#monero.MoneroWallet.get_tx_note","title":"get_tx_note(tx_hash)","text":"

Get a transaction note.

Parameters:

Name Type Description Default tx_hash str

specifies the transaction to get the note of.

required

Returns:

Type Description str

the tx note.

"},{"location":"api/wallet/#monero.MoneroWallet.get_tx_notes","title":"get_tx_notes(tx_hashes)","text":"

Get notes for multiple transactions.

Parameters:

Name Type Description Default tx_hashes list[str]

identify the transactions to get notes for.

required

Returns:

Type Description list[str]

notes for the transactions.

"},{"location":"api/wallet/#monero.MoneroWallet.get_tx_proof","title":"get_tx_proof(tx_hash, address, message='')","text":"

Get a transaction signature to prove it.

Parameters:

Name Type Description Default tx_hash str

specifies the transaction to prove.

required address str

is the destination public address of the transaction.

required message str

is a message to include with the signature to further authenticate the proof (optional).

''

Returns:

Type Description str

the transaction signature.

"},{"location":"api/wallet/#monero.MoneroWallet.get_version","title":"get_version()","text":"

Get the wallet's version.

Returns:

Type Description MoneroVersion

the wallet's version.

"},{"location":"api/wallet/#monero.MoneroWallet.import_key_images","title":"import_key_images(key_images)","text":"

Import signed key images and verify their spent status.

Parameters:

Name Type Description Default key_images list[MoneroKeyImage]

are key images to import and verify (requires hex and signature).

required

Returns:

Type Description MoneroKeyImageImportResult

results of the import.

"},{"location":"api/wallet/#monero.MoneroWallet.import_multisig_hex","title":"import_multisig_hex(multisig_hexes)","text":"

Import multisig info as hex from other participants.

Note: If the daemon is not trusted, this method will not automatically update the spent status after importing peer multisig hex.

Parameters:

Name Type Description Default multisig_hexes list[str]

are multisig hex from each participant.

required

Returns:

Type Description int

the number of outputs signed with the given multisig hex.

"},{"location":"api/wallet/#monero.MoneroWallet.import_outputs","title":"import_outputs(outputs_hex)","text":"

Import outputs in hex format.

Parameters:

Name Type Description Default outputs_hex str

are outputs in hex format.

required

Returns:

Type Description int

the number of outputs imported.

"},{"location":"api/wallet/#monero.MoneroWallet.is_closed","title":"is_closed()","text":"

Indicates if the wallet is closed.

Returns:

Type Description bool

True if the wallet is closed, False otherwise.

"},{"location":"api/wallet/#monero.MoneroWallet.is_connected_to_daemon","title":"is_connected_to_daemon()","text":"

Indicates if the wallet is connected a daemon.

Returns:

Type Description bool

True if the wallet is connected to daemon, False otherwise.

"},{"location":"api/wallet/#monero.MoneroWallet.is_daemon_trusted","title":"is_daemon_trusted()","text":"

Indicates if the daemon is trusted or untrusted.

Returns:

Type Description bool

True if the daemon is trusted, False otherwise.

"},{"location":"api/wallet/#monero.MoneroWallet.is_multisig","title":"is_multisig()","text":"

Indicates if this wallet is a multisig wallet.

Returns:

Type Description bool

True if this is a multisig wallet, False otherwise.

"},{"location":"api/wallet/#monero.MoneroWallet.is_multisig_import_needed","title":"is_multisig_import_needed()","text":"

Indicates if importing multisig data is needed for returning a correct balance.

Returns:

Type Description bool

True if importing multisig data is needed for returning a correct balance, False otherwise.

"},{"location":"api/wallet/#monero.MoneroWallet.is_output_frozen","title":"is_output_frozen(key_image)","text":"

Check if an output is frozen.

Parameters:

Name Type Description Default key_image str

key image of the output to check if frozen.

required

Returns:

Type Description bool

True if the output is frozen, False otherwise.

"},{"location":"api/wallet/#monero.MoneroWallet.is_synced","title":"is_synced()","text":"

Indicates if the wallet is synced with the daemon.

Returns:

Type Description bool

True if the wallet is synced with the daemon, False otherwise.

"},{"location":"api/wallet/#monero.MoneroWallet.is_view_only","title":"is_view_only()","text":"

Indicates if the wallet is view-only, meaning it does have the private spend key and can therefore only observe incoming outputs.

Returns:

Type Description bool

True if the wallet is view-only, False otherwise.

"},{"location":"api/wallet/#monero.MoneroWallet.make_multisig","title":"make_multisig(multisig_hexes, threshold, password)","text":"

Make this wallet multisig by importing multisig hex from participants.

Parameters:

Name Type Description Default multisig_hexes list[str]

are multisig hex from each participant.

required threshold int

is the number of signatures needed to sign transfers.

required password str

is the wallet password.

required

Returns:

Type Description str

this wallet's multisig hex to share with participants.

"},{"location":"api/wallet/#monero.MoneroWallet.move_to","title":"move_to(path, password)","text":"

Move the wallet from its current path to the given path.

Parameters:

Name Type Description Default path str

is the new wallet's path.

required password str

is the new wallet's password.

required"},{"location":"api/wallet/#monero.MoneroWallet.parse_payment_uri","title":"parse_payment_uri(uri)","text":"

Parses a payment URI to a tx configuration.

Parameters:

Name Type Description Default uri str

is the payment uri to parse.

required

Returns:

Type Description MoneroTxConfig

the tx configuration parsed from the uri.

"},{"location":"api/wallet/#monero.MoneroWallet.prepare_multisig","title":"prepare_multisig()","text":"

Get multisig info as hex to share with participants to begin creating a multisig wallet.

Returns:

Type Description str

this wallet's multisig hex to share with participants.

"},{"location":"api/wallet/#monero.MoneroWallet.remove_listener","title":"remove_listener(listener)","text":"

Unregister a listener to receive wallet notifications.

Parameters:

Name Type Description Default listener MoneroWalletListener

is the listener to unregister.

required"},{"location":"api/wallet/#monero.MoneroWallet.rescan_blockchain","title":"rescan_blockchain()","text":"

Rescan the blockchain from scratch, losing any information which cannot be recovered from the blockchain itself.

WARNING: This method discards local wallet data like destination addresses, tx secret keys, tx notes, etc.

"},{"location":"api/wallet/#monero.MoneroWallet.rescan_spent","title":"rescan_spent()","text":"

Rescan the blockchain for spent outputs.

Note: this can only be called with a trusted daemon.

Example use case: peer multisig hex is import when connected to an untrusted daemon, so the wallet will not rescan spent outputs. Then the wallet connects to a trusted daemon. This method should be manually invoked to rescan outputs.

"},{"location":"api/wallet/#monero.MoneroWallet.save","title":"save()","text":"

Save the wallet at its current path.

"},{"location":"api/wallet/#monero.MoneroWallet.scan_txs","title":"scan_txs(tx_hashes)","text":"

Scan transactions by their hash/id.

Parameters:

Name Type Description Default tx_hashes list[str]

tx hashes to scan.

required"},{"location":"api/wallet/#monero.MoneroWallet.set_account_label","title":"set_account_label(account_idx, label)","text":"

Set a human-readable description for an account.

Parameters:

Name Type Description Default account_idx int

account index.

required label str

is the label to set.

required"},{"location":"api/wallet/#monero.MoneroWallet.set_account_tag_label","title":"set_account_tag_label(tag, label)","text":"

Sets a human-readable description for a tag.

Parameters:

Name Type Description Default tag str

is the tag to set a description for.

required label str

is the label to set for the tag.

required"},{"location":"api/wallet/#monero.MoneroWallet.set_attribute","title":"set_attribute(key, val)","text":"

Set an arbitrary attribute.

Parameters:

Name Type Description Default key str

is the attribute key.

required val str

is the attribute value.

required"},{"location":"api/wallet/#monero.MoneroWallet.set_restore_height","title":"set_restore_height(restore_height)","text":"

Set the height of the first block that the wallet scans.

Parameters:

Name Type Description Default restore_height int

is the height of the first block that the wallet scans.

required"},{"location":"api/wallet/#monero.MoneroWallet.set_subaddress_label","title":"set_subaddress_label(account_idx, subaddress_idx, label='')","text":"

Set a subaddress label.

Parameters:

Name Type Description Default account_idx int

index of the account to set the label for.

required subaddress_idx int

index of the subaddress to set the label for.

required label str

the label to set (default '').

''"},{"location":"api/wallet/#monero.MoneroWallet.set_tx_note","title":"set_tx_note(tx_hash, note)","text":"

Set a note for a specific transaction.

Parameters:

Name Type Description Default tx_hash str

specifies the transaction.

required note str

specifies the note.

required"},{"location":"api/wallet/#monero.MoneroWallet.set_tx_notes","title":"set_tx_notes(tx_hashes, notes)","text":"

Set notes for multiple transactions.

Parameters:

Name Type Description Default tx_hashes list[str]

specify the transactions to set notes for.

required notes list[str]

are the notes to set for the transactions.

required"},{"location":"api/wallet/#monero.MoneroWallet.sign_message","title":"sign_message(msg, signature_type, account_idx=0, subaddress_idx=0)","text":"

Sign a message.

Parameters:

Name Type Description Default msg str

the message to sign.

required signature_type MoneroMessageSignatureType

sign with spend key or spend key.

required account_idx int

the account index of the message signature (default 0).

0 subaddress_idx int

the subaddress index of the message signature (default 0).

0

Returns:

Type Description str

the message signature.

"},{"location":"api/wallet/#monero.MoneroWallet.sign_multisig_tx_hex","title":"sign_multisig_tx_hex(multisig_tx_hex)","text":"

Sign previously created multisig transactions as represented by hex.

Parameters:

Name Type Description Default multisig_tx_hex str

is the hex shared among the multisig transactions when they were created.

required

Returns:

Type Description MoneroMultisigSignResult

the result of signing the multisig transactions.

"},{"location":"api/wallet/#monero.MoneroWallet.sign_txs","title":"sign_txs(unsigned_tx_hex)","text":"

Sign unsigned transactions from a view-only wallet.

Parameters:

Name Type Description Default unsigned_tx_hex str

is unsigned transaction hex from when the transactions were created.

required

Returns:

Type Description MoneroTxSet

the signed transaction set.

"},{"location":"api/wallet/#monero.MoneroWallet.start_mining","title":"start_mining(num_threads=None, background_mining=None, ignore_battery=None)","text":"

Start mining.

Parameters:

Name Type Description Default num_threads Optional[int]

is the number of threads created for mining (default None).

None background_mining Optional[bool]

specifies if mining should occur in the background (default None).

None ignore_battery Optional[bool]

specifies if the battery should be ignored for mining (default None).

None"},{"location":"api/wallet/#monero.MoneroWallet.start_syncing","title":"start_syncing(sync_period_in_ms=10000)","text":"

Start background synchronizing with a maximum period between syncs.

Parameters:

Name Type Description Default sync_period_in_ms int

maximum period between syncs in milliseconds.

10000"},{"location":"api/wallet/#monero.MoneroWallet.stop_mining","title":"stop_mining()","text":"

Stop mining.

"},{"location":"api/wallet/#monero.MoneroWallet.stop_syncing","title":"stop_syncing()","text":"

Stop the asynchronous thread to continuously synchronize the wallet with the daemon.

"},{"location":"api/wallet/#monero.MoneroWallet.submit_multisig_tx_hex","title":"submit_multisig_tx_hex(signed_multisig_tx_hex)","text":"

Submit signed multisig transactions as represented by a hex string.

Parameters:

Name Type Description Default signed_multisig_tx_hex str

is the signed multisig hex returned from sign_multisig_txs().

required

Returns:

Type Description list[str]

the resulting transaction hashes.

"},{"location":"api/wallet/#monero.MoneroWallet.submit_txs","title":"submit_txs(signed_tx_hex)","text":"

Submit signed transactions from a view-only wallet.

Parameters:

Name Type Description Default signed_tx_hex str

is signed transaction hex from sign_txs().

required

Returns:

Type Description list[str]

the resulting transaction hashes.

"},{"location":"api/wallet/#monero.MoneroWallet.sweep_dust","title":"sweep_dust(relay=False)","text":"

Sweep all unmixable dust outputs back to the wallet to make them easier to spend and mix.

Parameters:

Name Type Description Default relay bool

specifies if the resulting transaction should be relayed (default False).

False

Returns:

Type Description list[MoneroTxWallet]

the created transactions.

"},{"location":"api/wallet/#monero.MoneroWallet.sweep_output","title":"sweep_output(config)","text":"

Sweep an output with a given key image.

Parameters:

Name Type Description Default config MoneroTxConfig

configures the sweep transaction.

required

Returns:

Type Description MoneroTxWallet

the created transaction.

"},{"location":"api/wallet/#monero.MoneroWallet.sweep_unlocked","title":"sweep_unlocked(config)","text":"

Sweep unlocked funds according to the given config.

Parameters:

Name Type Description Default config MoneroTxConfig

is the sweep configuration.

required

Returns:

Type Description list[MoneroTxWallet]

the created transactions.

"},{"location":"api/wallet/#monero.MoneroWallet.tag_accounts","title":"tag_accounts(tag, account_indices)","text":"

Tag accounts.

Parameters:

Name Type Description Default tag str

is the tag to apply to the specified accounts.

required account_indices list[int]

are the indices of the accounts to tag.

required"},{"location":"api/wallet/#monero.MoneroWallet.thaw_output","title":"thaw_output(key_image)","text":"

Thaw a frozen output.

Parameters:

Name Type Description Default key_image str

key image of the output to thaw.

required"},{"location":"api/wallet/#monero.MoneroWallet.untag_accounts","title":"untag_accounts(account_indices)","text":"

Untag acconts.

Parameters:

Name Type Description Default account_indices list[int]

are the indices of the accounts to untag.

required"},{"location":"api/wallet/#monero.MoneroWallet.verify_message","title":"verify_message(msg, address, signature)","text":"

Verify a message signature.

Parameters:

Name Type Description Default msg str

the signed message.

required address str

signing address.

required signature str

signature.

required

Returns:

Type Description MoneroMessageSignatureResult

the message signature result.

"},{"location":"api/wallet/#monero.MoneroWallet.wait_for_next_block","title":"wait_for_next_block()","text":"

Wait for the next block to be added to the chain.

Returns:

Type Description int

the height of the next block when it is added to the chain.

"},{"location":"api/wallet_full/","title":"Full Wallet","text":""},{"location":"api/wallet_full/#monero.MoneroWalletFull","title":"MoneroWalletFull","text":"

Bases: MoneroWallet

Monero wallet implementation which uses monero-project's wallet2.

"},{"location":"api/wallet_full/#monero.MoneroWalletFull.create_wallet","title":"create_wallet(config) staticmethod","text":"

Create a new wallet with the given configuration.

Parameters:

Name Type Description Default config MoneroWalletConfig

the wallet configuration.

required

Returns:

Type Description MoneroWalletFull

reference to the wallet instance.

"},{"location":"api/wallet_full/#monero.MoneroWalletFull.get_cache_file_buffer","title":"get_cache_file_buffer()","text":"

Get wallet cache file without using filesystem.

Returns:

Type Description str

Cache file buffer.

"},{"location":"api/wallet_full/#monero.MoneroWalletFull.get_keys_file_buffer","title":"get_keys_file_buffer(password, view_only)","text":"

Get wallet keys file without using filesystem.

Parameters:

Name Type Description Default password str

The wallet password.

required view_only bool

Get view-only keys.

required

Returns:

Type Description str

Keys file buffer.

"},{"location":"api/wallet_full/#monero.MoneroWalletFull.get_seed_languages","title":"get_seed_languages() staticmethod","text":"

Get a list of available languages for the wallet's seed.

Returns:

Type Description list[str]

the available languages for the wallet's seed.

"},{"location":"api/wallet_full/#monero.MoneroWalletFull.open_wallet","title":"open_wallet(path, password, nettype) staticmethod","text":"

Open an existing wallet from disk.

Parameters:

Name Type Description Default path str

is the path to the wallet file to open.

required password str

is the password of the wallet file to open.

required nettype MoneroNetworkType

is the wallet's network type.

required

Returns:

Type Description MoneroWalletFull

reference to the wallet instance.

"},{"location":"api/wallet_full/#monero.MoneroWalletFull.wallet_exists","title":"wallet_exists(path) staticmethod","text":"

Indicates if a wallet exists at the given path.

Parameters:

Name Type Description Default path str

is the path to check for a wallet.

required

Returns:

Type Description bool

True if a wallet exists at the given path, False otherwise.

"},{"location":"api/wallet_keys/","title":"Keys-Only Wallet","text":""},{"location":"api/wallet_keys/#monero.MoneroWalletKeys","title":"MoneroWalletKeys","text":"

Bases: MoneroWallet

Implements a Monero wallet to provide basic key management.

"},{"location":"api/wallet_keys/#monero.MoneroWalletKeys.create_wallet_from_keys","title":"create_wallet_from_keys(config) staticmethod","text":"

Create a wallet from an address, view key, and spend key.

Parameters:

Name Type Description Default config MoneroWalletConfig

is the wallet configuration (network type, address, view key, spend key, language).

required

Returns:

Type Description MoneroWalletKeys

reference to the wallet instance.

"},{"location":"api/wallet_keys/#monero.MoneroWalletKeys.create_wallet_from_seed","title":"create_wallet_from_seed(config) staticmethod","text":"

Create a wallet from an existing mnemonic phrase or seed.

Parameters:

Name Type Description Default config MoneroWalletConfig

is the wallet configuration (network type, seed, seed offset, is_multisig).

required

Returns:

Type Description MoneroWalletKeys

reference to the wallet instance.

"},{"location":"api/wallet_keys/#monero.MoneroWalletKeys.create_wallet_random","title":"create_wallet_random(config) staticmethod","text":"

Create a new wallet with a randomly generated seed.

Parameters:

Name Type Description Default config MoneroWalletConfig

is the wallet configuration (network type and language).

required

Returns:

Type Description MoneroWalletKeys

reference to the wallet instance.

"},{"location":"api/wallet_keys/#monero.MoneroWalletKeys.get_seed_languages","title":"get_seed_languages() staticmethod","text":"

Get a list of available languages for the wallet's seed.

Returns:

Type Description list[str]

The available languages for the wallet's seed.

"},{"location":"api/wallet_rpc/","title":"RPC Wallet","text":""},{"location":"api/wallet_rpc/#monero.MoneroWalletRpc","title":"MoneroWalletRpc","text":"

Bases: MoneroWallet

Implements a Monero wallet using monero-wallet-rpc_.

.. _monero-wallet-rpc: https://docs.getmonero.org/rpc-library/wallet-rpc/

"},{"location":"api/wallet_rpc/#monero.MoneroWalletRpc.create_wallet","title":"create_wallet(config)","text":"

Create and open a wallet on the monero-wallet-rpc server.

Parameters:

Name Type Description Default config MoneroWalletConfig

configures the wallet to create.

required"},{"location":"api/wallet_rpc/#monero.MoneroWalletRpc.get_rpc_connection","title":"get_rpc_connection()","text":"

Get the wallet's RPC connection.

Returns:

Type Description MoneroRpcConnection | None

the wallet's rpc connection.

"},{"location":"api/wallet_rpc/#monero.MoneroWalletRpc.get_seed_languages","title":"get_seed_languages()","text":"

Get all supported wallet seed languages.

Returns:

Type Description list[str]

wallet's supported languages.

"},{"location":"api/wallet_rpc/#monero.MoneroWalletRpc.stop","title":"stop()","text":"

Save and close the current wallet and stop the RPC server.

"},{"location":"api/data_model/connection/","title":"Connection Data Model","text":""},{"location":"api/data_model/connection/#monero.SslOptions","title":"SslOptions","text":"

Bases: SerializableStruct

Models SSL options for a Monero rpc connection.

"},{"location":"api/data_model/connection/#monero.SslOptions.ssl_allow_any_cert","title":"ssl_allow_any_cert: bool | None instance-attribute","text":"

Allow any certificate.

"},{"location":"api/data_model/connection/#monero.SslOptions.ssl_allowed_fingerprints","title":"ssl_allowed_fingerprints: list[str] instance-attribute","text":"

Allowed ssl fingerprints.

"},{"location":"api/data_model/connection/#monero.SslOptions.ssl_ca_file","title":"ssl_ca_file: str | None instance-attribute","text":"

Path to ssl CA file.

"},{"location":"api/data_model/connection/#monero.SslOptions.ssl_certificate_path","title":"ssl_certificate_path: str | None instance-attribute","text":"

Path to private ssl certificate.

"},{"location":"api/data_model/connection/#monero.SslOptions.ssl_private_key_path","title":"ssl_private_key_path: str | None instance-attribute","text":"

Path to private ssl key.

"},{"location":"api/data_model/connection/#monero.SslOptions.__init__","title":"__init__()","text":"

Initialize a new rpc connection ssl options.

"},{"location":"api/data_model/connection/#monero.MoneroConnectionType","title":"MoneroConnectionType","text":"

Bases: IntEnum

Enumerates a connection type, wich can be IPV4, IPV6, TOR, I2P or INVALID.

"},{"location":"api/data_model/connection/#monero.MoneroConnectionType.I2P","title":"I2P = 4 class-attribute instance-attribute","text":"

4 Indicates that Monero connection type is I2P.

"},{"location":"api/data_model/connection/#monero.MoneroConnectionType.INVALID","title":"INVALID = 0 class-attribute instance-attribute","text":"

0 Indicates that Monero connection type is invalid.

"},{"location":"api/data_model/connection/#monero.MoneroConnectionType.IPV4","title":"IPV4 = 1 class-attribute instance-attribute","text":"

1 Indicates that Monero connection type is IPV4.

"},{"location":"api/data_model/connection/#monero.MoneroConnectionType.IPV6","title":"IPV6 = 2 class-attribute instance-attribute","text":"

2 Indicates that Monero connection type is IPV6.

"},{"location":"api/data_model/connection/#monero.MoneroConnectionType.TOR","title":"TOR = 3 class-attribute instance-attribute","text":"

3 Indicates that Monero connection type is TOR.

"},{"location":"api/data_model/daemon/","title":"Daemon Data Model","text":""},{"location":"api/data_model/daemon/#monero.MoneroNetworkType","title":"MoneroNetworkType","text":"

Bases: IntEnum

Enumerates a Monero network type_.

.. _Monero network type: https://docs.getmonero.org/infrastructure/networks/

"},{"location":"api/data_model/daemon/#monero.MoneroNetworkType.MAINNET","title":"MAINNET = 0 class-attribute instance-attribute","text":"

0 indicates Mainnet network_.

.. _Mainnet network: https://docs.getmonero.org/infrastructure/networks/#mainnet

"},{"location":"api/data_model/daemon/#monero.MoneroNetworkType.STAGENET","title":"STAGENET = 2 class-attribute instance-attribute","text":"

2 indicates Stagenet network_.

.. _Stagenet network: https://docs.getmonero.org/infrastructure/networks/#stagenet

"},{"location":"api/data_model/daemon/#monero.MoneroNetworkType.TESTNET","title":"TESTNET = 1 class-attribute instance-attribute","text":"

1 indicates Testnet network_.

.. _Testnet network: https://docs.getmonero.org/infrastructure/networks/#testnet

"},{"location":"api/data_model/daemon/#monero.MoneroVersion","title":"MoneroVersion","text":"

Bases: SerializableStruct

Models a Monero version.

"},{"location":"api/data_model/daemon/#monero.MoneroVersion.is_release","title":"is_release: bool | None instance-attribute","text":"

States if the monero software version corresponds to an official tagged release (True), or not (False).

"},{"location":"api/data_model/daemon/#monero.MoneroVersion.number","title":"number: int | None instance-attribute","text":"

Number of the monero software version.

"},{"location":"api/data_model/daemon/#monero.MoneroVersion.__init__","title":"__init__()","text":"

Initialize a new Monero version.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockHeader","title":"MoneroBlockHeader","text":"

Bases: SerializableStruct

Models a Monero block header which contains information about the block.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockHeader.cumulative_difficulty","title":"cumulative_difficulty: int | None instance-attribute","text":"

Cumulative difficulty of all blocks up to the block in the reply.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockHeader.depth","title":"depth: int | None instance-attribute","text":"

The number of blocks succeeding this block on the blockchain. A larger number means an older block.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockHeader.difficulty","title":"difficulty: int | None instance-attribute","text":"

The strength of the Monero network based on mining power.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockHeader.hash","title":"hash: str | None instance-attribute","text":"

The hash of this block.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockHeader.height","title":"height: int | None instance-attribute","text":"

The number of blocks preceding this block on the blockchain.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockHeader.long_term_weight","title":"long_term_weight: int | None instance-attribute","text":"

The long term block weight, based on the median weight of the preceding 100000 blocks.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockHeader.major_version","title":"major_version: int | None instance-attribute","text":"

The major version of the monero protocol at this block height.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockHeader.miner_tx_hash","title":"miner_tx_hash: str | None instance-attribute","text":"

The hash of this block's coinbase transaction.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockHeader.minor_version","title":"minor_version: int | None instance-attribute","text":"

The minor version of the monero protocol at this block height.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockHeader.nonce","title":"nonce: int | None instance-attribute","text":"

A cryptographic random one-time number used in mining a Monero block.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockHeader.num_txs","title":"num_txs: int | None instance-attribute","text":"

Number of transactions included in this block.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockHeader.orphan_status","title":"orphan_status: bool | None instance-attribute","text":"

If True, this block is not part of the longest chain.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockHeader.pow_hash","title":"pow_hash: str | None instance-attribute","text":"

The hash, as a hexadecimal string, calculated from the block as proof-of-work.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockHeader.prev_hash","title":"prev_hash: str | None instance-attribute","text":"

The hash of the block immediately preceding this block in the chain.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockHeader.reward","title":"reward: int | None instance-attribute","text":"

The amount of atomic-units rewarded to the miner. The reward is the sum of new coins created (the emission) and fees paid by transactions in this block. Note: 1 XMR = 1e12 atomic-units.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockHeader.size","title":"size: int | None instance-attribute","text":"

Backward compatibility, same as weight, use that instead.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockHeader.timestamp","title":"timestamp: int | None instance-attribute","text":"

The unix time at which the block was recorded into the blockchain.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockHeader.weight","title":"weight: int | None instance-attribute","text":"

The adjusted block size, in bytes. This is the raw size, plus a positive adjustment for any Bulletproof transactions with more than 2 outputs.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockHeader.__init__","title":"__init__()","text":"

Initialize a Monero block header.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockHeader.copy","title":"copy()","text":"

Copy current block header.

Returns:

Type Description MoneroBlockHeader

copied block header.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockHeader.merge","title":"merge(other)","text":"

Merge current block header with another one.

Raises:

Type Description Exception

on reconciliation error.

"},{"location":"api/data_model/daemon/#monero.MoneroBlock","title":"MoneroBlock","text":"

Bases: MoneroBlockHeader

Models a Monero block in the blockchain.

"},{"location":"api/data_model/daemon/#monero.MoneroBlock.hex","title":"hex: str | None instance-attribute","text":"

Hexadecimal blob of block information.

"},{"location":"api/data_model/daemon/#monero.MoneroBlock.miner_tx","title":"miner_tx: MoneroTx | None instance-attribute","text":"

Miner transaction information.

"},{"location":"api/data_model/daemon/#monero.MoneroBlock.tx_hashes","title":"tx_hashes: list[str] instance-attribute","text":"

List of hashes of non-coinbase transactions in the block.

"},{"location":"api/data_model/daemon/#monero.MoneroBlock.txs","title":"txs: list[MoneroTx] instance-attribute","text":"

List of non-coinbase transactions in the block.

"},{"location":"api/data_model/daemon/#monero.MoneroBlock.__init__","title":"__init__()","text":"

Initialize a Monero block.

"},{"location":"api/data_model/daemon/#monero.MoneroBlock.copy","title":"copy()","text":"

Copy current block.

Returns:

Type Description MoneroBlock

copied block.

"},{"location":"api/data_model/daemon/#monero.MoneroTx","title":"MoneroTx","text":"

Bases: SerializableStruct

Models a Monero transaction on the blockchain.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.DEFAULT_PAYMENT_ID","title":"DEFAULT_PAYMENT_ID: str instance-attribute","text":"

Default tx payment id

"},{"location":"api/data_model/daemon/#monero.MoneroTx.block","title":"block: MoneroBlock | None instance-attribute","text":"

Block including the transaction.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.common_tx_sets","title":"common_tx_sets: str | None instance-attribute","text":"

A hexadecimal string representing a set of unsigned transactions, or a set of signing keys used in a multisig transaction.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.extra","title":"extra: list[int] instance-attribute","text":"

Usually called the payment ID but can be used to include any random 32 bytes.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.fee","title":"fee: int | None instance-attribute","text":"

The amount of the mining fee included in the transaction, in atomic-units.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.full_hex","title":"full_hex: str | None instance-attribute","text":"

Full transaction information as a hex string.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.hash","title":"hash: str | None instance-attribute","text":"

The transaction hash.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.in_tx_pool","title":"in_tx_pool: bool | None instance-attribute","text":"

States if the transaction is in pool (True) or included in a block (False).

"},{"location":"api/data_model/daemon/#monero.MoneroTx.inputs","title":"inputs: list[MoneroOutput] instance-attribute","text":"

List of inputs into transaction.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.is_confirmed","title":"is_confirmed: bool | None instance-attribute","text":"

States if the transaction included in a block (True) or is in pool (False).

"},{"location":"api/data_model/daemon/#monero.MoneroTx.is_double_spend_seen","title":"is_double_spend_seen: bool | None instance-attribute","text":"

States if the transaction is a double-spend (True) or not (False).

"},{"location":"api/data_model/daemon/#monero.MoneroTx.is_failed","title":"is_failed: bool | None instance-attribute","text":"

Indicates if the transaction validation has previously failed.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.is_kept_by_block","title":"is_kept_by_block: bool | None instance-attribute","text":"

States if the transaction was included in a block at least once (True) or not (False).

"},{"location":"api/data_model/daemon/#monero.MoneroTx.is_miner_tx","title":"is_miner_tx: bool | None instance-attribute","text":"

States if the transaction is a coinbase-transaction (True) or not (False).

"},{"location":"api/data_model/daemon/#monero.MoneroTx.is_relayed","title":"is_relayed: bool | None instance-attribute","text":"

States if the transaction was relayed (True) or not (False).

"},{"location":"api/data_model/daemon/#monero.MoneroTx.key","title":"key: str | None instance-attribute","text":"

The transaction key.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.last_failed_hash","title":"last_failed_hash: str | None instance-attribute","text":"

If the transaction validation has previously failed, this tells the previous transaction hash.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.last_failed_height","title":"last_failed_height: int | None instance-attribute","text":"

If the transaction validation has previously failed, this tells at what height that occurred.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.last_relayed_timestamp","title":"last_relayed_timestamp: int | None instance-attribute","text":"

Last unix time at which the transaction has been relayed.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.max_used_block_hash","title":"max_used_block_hash: str | None instance-attribute","text":"

Tells the hash of the most recent block with an output used in this transaction.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.max_used_block_height","title":"max_used_block_height: int | None instance-attribute","text":"

Tells the height of the most recent block with an output used in this transaction.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.metadata","title":"metadata: str | None instance-attribute","text":"

Transaction metadata.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.num_confirmations","title":"num_confirmations: int | None instance-attribute","text":"

Number of network confirmations.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.output_indices","title":"output_indices: list[int] instance-attribute","text":"

Transaction indexes.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.outputs","title":"outputs: list[MoneroOutput] instance-attribute","text":"

Transaction outputs.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.payment_id","title":"payment_id: str | None instance-attribute","text":"

Payment ID for this transaction.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.prunable_hash","title":"prunable_hash: str | None instance-attribute","text":"

Keccak-256 hash of the prunable portion of the block.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.prunable_hex","title":"prunable_hex: str | None instance-attribute","text":"

Prunable block encoded as a hex string.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.pruned_hex","title":"pruned_hex: str | None instance-attribute","text":"

Pruned block encoded as hex string.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.rct_sig_prunable","title":"rct_sig_prunable: str | None instance-attribute","text":"

Prunable ring signature.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.rct_signatures","title":"rct_signatures: str | None instance-attribute","text":"

Signatures used in ring signature to hide the true origin of the transaction.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.received_timestamp","title":"received_timestamp: int | None instance-attribute","text":"

Unix time at chich the transaction has been received.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.relay","title":"relay: bool | None instance-attribute","text":"

States if this transaction should be relayed (True) or not (False).

"},{"location":"api/data_model/daemon/#monero.MoneroTx.ring_size","title":"ring_size: int | None instance-attribute","text":"

The ring size of this transaction.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.signatures","title":"signatures: list[str] instance-attribute","text":"

List of signatures used in ring signature to hide the true origin of the transaction.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.size","title":"size: int | None instance-attribute","text":"

Backward compatibility, same as weight, use that instead.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.unlock_time","title":"unlock_time: int | None instance-attribute","text":"

If not 0, this tells when the transaction outputs are spendable.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.version","title":"version: int | None instance-attribute","text":"

Transaction version.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.weight","title":"weight: int | None instance-attribute","text":"

The weight of this transaction in bytes.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.__init__","title":"__init__()","text":"

Initialize a new Monero transaction.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.copy","title":"copy()","text":"

Copy current tx.

Returns:

Type Description MoneroTx

tx copy.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.get_height","title":"get_height()","text":"

Get the transaction height.

Returns:

Type Description int | None

The height of the transaction, if known.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.merge","title":"merge(other)","text":"

Merge current tx with another one.

Parameters:

Name Type Description Default other MoneroTx

other tx to merge with.

required"},{"location":"api/data_model/daemon/#monero.MoneroKeyImage","title":"MoneroKeyImage","text":"

Bases: SerializableStruct

Models a Monero key image.

"},{"location":"api/data_model/daemon/#monero.MoneroKeyImage.hex","title":"hex: str | None instance-attribute","text":"

The key image in hexadecimal format.

"},{"location":"api/data_model/daemon/#monero.MoneroKeyImage.signature","title":"signature: str | None instance-attribute","text":"

The key image signature. None if not known.

"},{"location":"api/data_model/daemon/#monero.MoneroKeyImage.__init__","title":"__init__()","text":"

Initialize a Monero key image.

"},{"location":"api/data_model/daemon/#monero.MoneroKeyImage.copy","title":"copy()","text":"

Copy current key image.

Returns:

Type Description MoneroKeyImage

key image copy.

"},{"location":"api/data_model/daemon/#monero.MoneroKeyImage.deserialize_key_images","title":"deserialize_key_images(key_images_json) staticmethod","text":"

Deserialize key images from a JSON string.

Parameters:

Name Type Description Default key_images_json str

JSON string with serialized key images.

required

Returns:

Type Description list[MoneroKeyImage]

Deserialized key images.

"},{"location":"api/data_model/daemon/#monero.MoneroKeyImage.merge","title":"merge(other)","text":"

Merge current key image with another one.

Parameters:

Name Type Description Default other MoneroKeyImage

other key image to merge with.

required"},{"location":"api/data_model/daemon/#monero.MoneroOutput","title":"MoneroOutput","text":"

Bases: SerializableStruct

Models a Monero transaction output.

"},{"location":"api/data_model/daemon/#monero.MoneroOutput.amount","title":"amount: int | None instance-attribute","text":"

Output amount in atomic-units.

"},{"location":"api/data_model/daemon/#monero.MoneroOutput.index","title":"index: int | None instance-attribute","text":"

Output index.

"},{"location":"api/data_model/daemon/#monero.MoneroOutput.key_image","title":"key_image: MoneroKeyImage | None instance-attribute","text":"

The key image of the output.

"},{"location":"api/data_model/daemon/#monero.MoneroOutput.ring_output_indices","title":"ring_output_indices: list[int] instance-attribute","text":"

Indices of ring outputs.

"},{"location":"api/data_model/daemon/#monero.MoneroOutput.stealth_public_key","title":"stealth_public_key: str | None instance-attribute","text":"

The public key of the output.

"},{"location":"api/data_model/daemon/#monero.MoneroOutput.tx","title":"tx: MoneroTx instance-attribute","text":"

The transaction related to this output.

"},{"location":"api/data_model/daemon/#monero.MoneroOutput.__init__","title":"__init__()","text":"

Initialize a Monero output.

"},{"location":"api/data_model/daemon/#monero.MoneroOutput.copy","title":"copy()","text":"

Copy current output.

Returns:

Type Description MoneroOutput

output copy.

"},{"location":"api/data_model/daemon/#monero.MoneroOutput.merge","title":"merge(other)","text":"

Merge current output wallet with another output.

Parameters:

Name Type Description Default other MoneroOutput

other output to merge with.

required"},{"location":"api/data_model/daemon/#monero.MoneroAltChain","title":"MoneroAltChain","text":"

Bases: SerializableStruct

Models an alternative chain seen by the node.

"},{"location":"api/data_model/daemon/#monero.MoneroAltChain.block_hashes","title":"block_hashes: list[str] instance-attribute","text":"

List of all block hashes in the alternative chain that are not in the main chain.

"},{"location":"api/data_model/daemon/#monero.MoneroAltChain.difficulty","title":"difficulty: int | None instance-attribute","text":"

Cumulative difficulty of all blocks in the alternative chain.

"},{"location":"api/data_model/daemon/#monero.MoneroAltChain.height","title":"height: int | None instance-attribute","text":"

The block height of the first diverging block of this alternative chain.

"},{"location":"api/data_model/daemon/#monero.MoneroAltChain.length","title":"length: int | None instance-attribute","text":"

The length in blocks of this alternative chain, after divergence.

"},{"location":"api/data_model/daemon/#monero.MoneroAltChain.main_chain_parent_block_hash","title":"main_chain_parent_block_hash: str | None instance-attribute","text":"

The hash of the greatest height block that is shared between the alternative chain and the main chain.

"},{"location":"api/data_model/daemon/#monero.MoneroAltChain.__init__","title":"__init__()","text":"

Initialize a Monero alt chain info.

"},{"location":"api/data_model/daemon/#monero.MoneroBan","title":"MoneroBan","text":"

Bases: SerializableStruct

Model a Monero banhammer.

"},{"location":"api/data_model/daemon/#monero.MoneroBan.host","title":"host: str | None instance-attribute","text":"

Host ban.

"},{"location":"api/data_model/daemon/#monero.MoneroBan.ip","title":"ip: int | None instance-attribute","text":"

IP ban.

"},{"location":"api/data_model/daemon/#monero.MoneroBan.is_banned","title":"is_banned: bool | None instance-attribute","text":"

Indicates if ban on the host is active (True) or not (False).

"},{"location":"api/data_model/daemon/#monero.MoneroBan.seconds","title":"seconds: int | None instance-attribute","text":"

Indicates the duration of the ban in seconds.

"},{"location":"api/data_model/daemon/#monero.MoneroBan.__init__","title":"__init__()","text":"

Initialize a Monero banhammer.

"},{"location":"api/data_model/daemon/#monero.MoneroPruneResult","title":"MoneroPruneResult","text":"

Bases: SerializableStruct

Models the result of pruning the blockchain.

"},{"location":"api/data_model/daemon/#monero.MoneroPruneResult.is_pruned","title":"is_pruned: bool | None instance-attribute","text":"

Indicates if blockchain is pruned.

"},{"location":"api/data_model/daemon/#monero.MoneroPruneResult.pruning_seed","title":"pruning_seed: int | None instance-attribute","text":"

Blockheight at which pruning began.

"},{"location":"api/data_model/daemon/#monero.MoneroPruneResult.__init__","title":"__init__()","text":"

Initialize a Monero prune result.

"},{"location":"api/data_model/daemon/#monero.MoneroMiningStatus","title":"MoneroMiningStatus","text":"

Bases: SerializableStruct

Models a Monero daemon mining status.

"},{"location":"api/data_model/daemon/#monero.MoneroMiningStatus.address","title":"address: str | None instance-attribute","text":"

Account address daemon is mining to. None if not mining.

"},{"location":"api/data_model/daemon/#monero.MoneroMiningStatus.is_active","title":"is_active: bool | None instance-attribute","text":"

Indicates if mining is enabled.

"},{"location":"api/data_model/daemon/#monero.MoneroMiningStatus.is_background","title":"is_background: bool | None instance-attribute","text":"

Indicates if mining is running in background.

"},{"location":"api/data_model/daemon/#monero.MoneroMiningStatus.num_threads","title":"num_threads: int | None instance-attribute","text":"

Number of running mining threads.

"},{"location":"api/data_model/daemon/#monero.MoneroMiningStatus.speed","title":"speed: int | None instance-attribute","text":"

Mining power in hashes per seconds.

"},{"location":"api/data_model/daemon/#monero.MoneroMiningStatus.__init__","title":"__init__()","text":"

Initialize a Monero daemon mining status.

"},{"location":"api/data_model/daemon/#monero.MoneroMinerTxSum","title":"MoneroMinerTxSum","text":"

Bases: SerializableStruct

Model for the sum of miner emissions and fees.

"},{"location":"api/data_model/daemon/#monero.MoneroMinerTxSum.emission_sum","title":"emission_sum: int | None instance-attribute","text":"

The new coins emitted in atomic-units.

"},{"location":"api/data_model/daemon/#monero.MoneroMinerTxSum.fee_sum","title":"fee_sum: int | None instance-attribute","text":"

The sum of fees in atomic-units.

"},{"location":"api/data_model/daemon/#monero.MoneroMinerTxSum.__init__","title":"__init__()","text":"

Initialize a Monero miner transaction sum.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockTemplate","title":"MoneroBlockTemplate","text":"

Bases: SerializableStruct

Monero block template to mine.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockTemplate.block_hashing_blob","title":"block_hashing_blob: str | None instance-attribute","text":"

Blob on which to try to find a valid nonce.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockTemplate.block_template_blob","title":"block_template_blob: str | None instance-attribute","text":"

Blob on which to try to mine a new block.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockTemplate.difficulty","title":"difficulty: int | None instance-attribute","text":"

Network difficulty.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockTemplate.expected_reward","title":"expected_reward: int | None instance-attribute","text":"

Coinbase reward expected to be received if block is successfully mined.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockTemplate.height","title":"height: int | None instance-attribute","text":"

Height on which to mine.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockTemplate.next_seed_hash","title":"next_seed_hash: str | None instance-attribute","text":"

Hash of the next block to use as seed for Random-X proof-of-work.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockTemplate.prev_hash","title":"prev_hash: str | None instance-attribute","text":"

Hash of the most recent block on which to mine the next block.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockTemplate.reserved_offset","title":"reserved_offset: int | None instance-attribute","text":"

Reserved offset.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockTemplate.seed_hash","title":"seed_hash: str | None instance-attribute","text":"

Hash of block to use as seed for Random-X proof-of-work.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockTemplate.seed_height","title":"seed_height: int | None instance-attribute","text":"

Height of block to use as seed for Random-X proof-of-work.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockTemplate.__init__","title":"__init__()","text":"

Initialize a Monero block template.

"},{"location":"api/data_model/daemon/#monero.MoneroConnectionSpan","title":"MoneroConnectionSpan","text":"

Bases: SerializableStruct

Monero daemon connection span.

"},{"location":"api/data_model/daemon/#monero.MoneroConnectionSpan.connection_id","title":"connection_id: str | None instance-attribute","text":"

Id of connection

"},{"location":"api/data_model/daemon/#monero.MoneroConnectionSpan.num_blocks","title":"num_blocks: int | None instance-attribute","text":"

Number of blocks in this span

"},{"location":"api/data_model/daemon/#monero.MoneroConnectionSpan.rate","title":"rate: int | None instance-attribute","text":"

Connection rate

"},{"location":"api/data_model/daemon/#monero.MoneroConnectionSpan.remote_address","title":"remote_address: str | None instance-attribute","text":"

Peer address the node is downloading (or has downloaded) than span from.

"},{"location":"api/data_model/daemon/#monero.MoneroConnectionSpan.size","title":"size: int | None instance-attribute","text":"

Total number of bytes in that span's blocks (including txes).

"},{"location":"api/data_model/daemon/#monero.MoneroConnectionSpan.speed","title":"speed: int | None instance-attribute","text":"

Connection speed.

"},{"location":"api/data_model/daemon/#monero.MoneroConnectionSpan.start_height","title":"start_height: int | None instance-attribute","text":"

Block height of the first block in that span.

"},{"location":"api/data_model/daemon/#monero.MoneroConnectionSpan.__init__","title":"__init__()","text":"

Initialize a Monero connection span.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer","title":"MoneroPeer","text":"

Bases: SerializableStruct

Models a peer to the daemon.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer.address","title":"address: str | None instance-attribute","text":"

The peer's address, actually IPv4 & port.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer.avg_download","title":"avg_download: int | None instance-attribute","text":"

Average bytes of data downloaded by node.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer.avg_upload","title":"avg_upload: int | None instance-attribute","text":"

Average bytes of data uploaded by node.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer.connection_type","title":"connection_type: MoneroConnectionType | None instance-attribute","text":"

Type of peer connection.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer.current_download","title":"current_download: int | None instance-attribute","text":"

Current bytes downloaded by node.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer.current_upload","title":"current_upload: int | None instance-attribute","text":"

Current bytes uploaded by node.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer.hash","title":"hash: str | None instance-attribute","text":"

Peer hash.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer.height","title":"height: int | None instance-attribute","text":"

The peer blockchain height.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer.host","title":"host: str | None instance-attribute","text":"

The peer host.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer.id","title":"id: str | None instance-attribute","text":"

The node's ID on the network.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer.is_incoming","title":"is_incoming: bool | None instance-attribute","text":"

Indicates if peer is pulling blocks from node.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer.is_local_host","title":"is_local_host: bool | None instance-attribute","text":"

Indicates if peer is localhost.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer.is_local_ip","title":"is_local_ip: bool | None instance-attribute","text":"

Indicates if peer has a local ip address.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer.is_online","title":"is_online: bool | None instance-attribute","text":"

Indicates if the peer is online.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer.last_seen_timestamp","title":"last_seen_timestamp: int | None instance-attribute","text":"

Last activity timestamp of this peer.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer.live_time","title":"live_time: int | None instance-attribute","text":"

Length of time the peer has been online.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer.num_receives","title":"num_receives: int | None instance-attribute","text":"

Total number of messages received from this peer.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer.num_sends","title":"num_sends: int | None instance-attribute","text":"

Total number of messages sent to this peer.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer.num_support_flags","title":"num_support_flags: int | None instance-attribute","text":"

Support flags number.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer.port","title":"port: int | None instance-attribute","text":"

The port that the node is using to connect to the network.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer.pruning_seed","title":"pruning_seed: int | None instance-attribute","text":"

Block height at which pruning began.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer.receive_idle_time","title":"receive_idle_time: int | None instance-attribute","text":"

Seconds since last data was received from this peer.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer.rpc_credits_per_hash","title":"rpc_credits_per_hash: int | None instance-attribute","text":"

Credits for every hash calculated by client.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer.rpc_port","title":"rpc_port: int | None instance-attribute","text":"

Peer RPC port.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer.send_idle_time","title":"send_idle_time: int | None instance-attribute","text":"

Seconds since the last data sent to this peer.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer.state","title":"state: str | None instance-attribute","text":"

Peer state.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer.__init__","title":"__init__()","text":"

Initialize a new Monero peer.

"},{"location":"api/data_model/daemon/#monero.MoneroSubmitTxResult","title":"MoneroSubmitTxResult","text":"

Bases: MoneroRpcPaymentInfo

Models the result from submitting a tx to a daemon.

"},{"location":"api/data_model/daemon/#monero.MoneroSubmitTxResult.has_invalid_input","title":"has_invalid_input: bool | None instance-attribute","text":"

Indicates if the transaction has an invalid input.

"},{"location":"api/data_model/daemon/#monero.MoneroSubmitTxResult.has_invalid_output","title":"has_invalid_output: bool | None instance-attribute","text":"

Indicates if the transaction has an invalid output.

"},{"location":"api/data_model/daemon/#monero.MoneroSubmitTxResult.has_too_few_outputs","title":"has_too_few_outputs: bool | None instance-attribute","text":"

Indicates if the transaction has too few outputs.

"},{"location":"api/data_model/daemon/#monero.MoneroSubmitTxResult.is_double_spend","title":"is_double_spend: bool | None instance-attribute","text":"

Indicates if the transaction is double spend.

"},{"location":"api/data_model/daemon/#monero.MoneroSubmitTxResult.is_fee_too_low","title":"is_fee_too_low: bool | None instance-attribute","text":"

Indicates if the transaction fee is too low.

"},{"location":"api/data_model/daemon/#monero.MoneroSubmitTxResult.is_good","title":"is_good: bool | None instance-attribute","text":"

Indicates if the submission of the transaction was successfull.

"},{"location":"api/data_model/daemon/#monero.MoneroSubmitTxResult.is_mixin_too_low","title":"is_mixin_too_low: bool | None instance-attribute","text":"

Indicates if the transaction mixin count is too low.

"},{"location":"api/data_model/daemon/#monero.MoneroSubmitTxResult.is_overspend","title":"is_overspend: bool | None instance-attribute","text":"

Indicates if the transaction uses more money than available

"},{"location":"api/data_model/daemon/#monero.MoneroSubmitTxResult.is_relayed","title":"is_relayed: bool | None instance-attribute","text":"

Indicates if the transaction has been relayed.

"},{"location":"api/data_model/daemon/#monero.MoneroSubmitTxResult.is_too_big","title":"is_too_big: bool | None instance-attribute","text":"

Indicates if the transaction size is too big.

"},{"location":"api/data_model/daemon/#monero.MoneroSubmitTxResult.is_tx_extra_too_big","title":"is_tx_extra_too_big: bool | None instance-attribute","text":"

Indicates if the transaction extra size is too big.

"},{"location":"api/data_model/daemon/#monero.MoneroSubmitTxResult.reason","title":"reason: str | None instance-attribute","text":"

Additional information. Currently empty or Not relayed if transaction was accepted but not relayed.

"},{"location":"api/data_model/daemon/#monero.MoneroSubmitTxResult.sanity_check_failed","title":"sanity_check_failed: bool | None instance-attribute","text":"

Indicates if the transaction sanity check has failed.

"},{"location":"api/data_model/daemon/#monero.MoneroSubmitTxResult.__init__","title":"__init__()","text":"

Initialize a new submit transaction result.

"},{"location":"api/data_model/daemon/#monero.MoneroTxBacklogEntry","title":"MoneroTxBacklogEntry","text":"

TODO

"},{"location":"api/data_model/daemon/#monero.MoneroTxBacklogEntry.__init__","title":"__init__()","text":"

Intialize a new tx backlog entry.

"},{"location":"api/data_model/daemon/#monero.MoneroOutputDistributionEntry","title":"MoneroOutputDistributionEntry","text":"

Bases: SerializableStruct

Models a Monero output distribution entry.

"},{"location":"api/data_model/daemon/#monero.MoneroOutputDistributionEntry.amount","title":"amount: int | None instance-attribute","text":"

Output amount in atomic-units.

"},{"location":"api/data_model/daemon/#monero.MoneroOutputDistributionEntry.base","title":"base: int | None instance-attribute","text":"

The total number of outputs of amount in the chain before, not including, the block at start_height.

"},{"location":"api/data_model/daemon/#monero.MoneroOutputDistributionEntry.distribution","title":"distribution: list[int] instance-attribute","text":"

The output distibution.

"},{"location":"api/data_model/daemon/#monero.MoneroOutputDistributionEntry.start_height","title":"start_height: int | None instance-attribute","text":"

Not necessarily equal to start_height parameter especially for amount = 0 where start_height will be no less than the height of the v4 hardfork.

"},{"location":"api/data_model/daemon/#monero.MoneroOutputDistributionEntry.__init__","title":"__init__()","text":"

Initialize a Monero output distribution entry.

"},{"location":"api/data_model/daemon/#monero.MoneroOutputHistogramEntry","title":"MoneroOutputHistogramEntry","text":"

Bases: SerializableStruct

Models a Monero output histogram entry.

"},{"location":"api/data_model/daemon/#monero.MoneroOutputHistogramEntry.amount","title":"amount: int | None instance-attribute","text":"

Output amount in atomic-units.

"},{"location":"api/data_model/daemon/#monero.MoneroOutputHistogramEntry.num_instances","title":"num_instances: int | None instance-attribute","text":"

Number of outputs.

"},{"location":"api/data_model/daemon/#monero.MoneroOutputHistogramEntry.recent_instances","title":"recent_instances: int | None instance-attribute","text":"

Number of recent outputs.

"},{"location":"api/data_model/daemon/#monero.MoneroOutputHistogramEntry.unlocked_instances","title":"unlocked_instances: int | None instance-attribute","text":"

Number of unlocked outputs.

"},{"location":"api/data_model/daemon/#monero.MoneroOutputHistogramEntry.__init__","title":"__init__()","text":"

Initialize a Monero output histogram entry.

"},{"location":"api/data_model/daemon/#monero.MoneroTxPoolStats","title":"MoneroTxPoolStats","text":"

Bases: SerializableStruct

Models transaction pool statistics.

"},{"location":"api/data_model/daemon/#monero.MoneroTxPoolStats.bytes_max","title":"bytes_max: int | None instance-attribute","text":"

Max transaction size in pool.

"},{"location":"api/data_model/daemon/#monero.MoneroTxPoolStats.bytes_med","title":"bytes_med: int | None instance-attribute","text":"

Median transaction size in pool.

"},{"location":"api/data_model/daemon/#monero.MoneroTxPoolStats.bytes_min","title":"bytes_min: int | None instance-attribute","text":"

Min transaction size in pool.

"},{"location":"api/data_model/daemon/#monero.MoneroTxPoolStats.bytes_total","title":"bytes_total: int | None instance-attribute","text":"

Total size of all transactions in pool.

"},{"location":"api/data_model/daemon/#monero.MoneroTxPoolStats.fee_total","title":"fee_total: int | None instance-attribute","text":"

The sum of the fees for all transactions currently in the transaction pool atomic-units.

"},{"location":"api/data_model/daemon/#monero.MoneroTxPoolStats.histo","title":"histo: dict[int, int] instance-attribute","text":"

Txs histogram (key for bytes, value for txs).

"},{"location":"api/data_model/daemon/#monero.MoneroTxPoolStats.histo98pc","title":"histo98pc: int | None instance-attribute","text":"

The time 98% of txes are younger than.

"},{"location":"api/data_model/daemon/#monero.MoneroTxPoolStats.num10m","title":"num10m: int | None instance-attribute","text":"

Number of transactions in pool for more than 10 minutes.

"},{"location":"api/data_model/daemon/#monero.MoneroTxPoolStats.num_double_spends","title":"num_double_spends: int | None instance-attribute","text":"

Number of double spend transactions.

"},{"location":"api/data_model/daemon/#monero.MoneroTxPoolStats.num_failing","title":"num_failing: int | None instance-attribute","text":"

Number of failing transactions.

"},{"location":"api/data_model/daemon/#monero.MoneroTxPoolStats.num_not_relayed","title":"num_not_relayed: int | None instance-attribute","text":"

Number of non-relayed transactions.

"},{"location":"api/data_model/daemon/#monero.MoneroTxPoolStats.num_txs","title":"num_txs: int | None instance-attribute","text":"

Total number of transactions.

"},{"location":"api/data_model/daemon/#monero.MoneroTxPoolStats.oldest_timestamp","title":"oldest_timestamp: int | None instance-attribute","text":"

Unix time of the oldest transaction in the pool.

"},{"location":"api/data_model/daemon/#monero.MoneroTxPoolStats.__init__","title":"__init__()","text":"

Initialize a Monero transaction pool statistics.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonUpdateCheckResult","title":"MoneroDaemonUpdateCheckResult","text":"

Bases: SerializableStruct

Models the result of checking for a daemon update.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonUpdateCheckResult.auto_uri","title":"auto_uri: str | None instance-attribute","text":"

URL automatically generated by the daemon to download the update.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonUpdateCheckResult.hash","title":"hash: str | None instance-attribute","text":"

Integrity check hash.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonUpdateCheckResult.is_update_available","title":"is_update_available: bool | None instance-attribute","text":"

Indicates if an update is available to download.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonUpdateCheckResult.user_uri","title":"user_uri: str | None instance-attribute","text":"

Alternative user URI.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonUpdateCheckResult.version","title":"version: str | None instance-attribute","text":"

Version available for download.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonUpdateCheckResult.__init__","title":"__init__()","text":"

Initialize a Monero update check result.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonUpdateDownloadResult","title":"MoneroDaemonUpdateDownloadResult","text":"

Bases: MoneroDaemonUpdateCheckResult

Models the result of downloading a daemon update.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonUpdateDownloadResult.download_path","title":"download_path: str | None instance-attribute","text":"

Path to download the update.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonUpdateDownloadResult.__init__","title":"__init__()","text":"

Initialize a Monero update download result.

"},{"location":"api/data_model/daemon/#monero.MoneroFeeEstimate","title":"MoneroFeeEstimate","text":"

Bases: SerializableStruct

Models a Monero fee estimate.

"},{"location":"api/data_model/daemon/#monero.MoneroFeeEstimate.fee","title":"fee: int | None instance-attribute","text":"

Amount of fees estimated per byte in atomic-units.

"},{"location":"api/data_model/daemon/#monero.MoneroFeeEstimate.fees","title":"fees: list[int] instance-attribute","text":"

Represents the base fees at different priorities [slow, normal, fast, fastest].

"},{"location":"api/data_model/daemon/#monero.MoneroFeeEstimate.quantization_mask","title":"quantization_mask: int | None instance-attribute","text":"

Final fee should be rounded up to an even multiple of this value.

"},{"location":"api/data_model/daemon/#monero.MoneroFeeEstimate.__init__","title":"__init__()","text":"

Initialize a Monero fee estimate.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo","title":"MoneroDaemonInfo","text":"

Bases: MoneroRpcPaymentInfo

Models information got from a Monero daemon.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.adjusted_timestamp","title":"adjusted_timestamp: int | None instance-attribute","text":"

Current time approximated from chain data, as Unix time.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.block_size_limit","title":"block_size_limit: int | None instance-attribute","text":"

Backward compatibility, same as block_weight_limit, use that instead.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.block_size_median","title":"block_size_median: int | None instance-attribute","text":"

Backward compatibility, same as block_weight_median, use that instead.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.block_weight_limit","title":"block_weight_limit: int | None instance-attribute","text":"

Maximum allowed adjusted block size based on latest 100000 blocks.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.block_weight_median","title":"block_weight_median: int | None instance-attribute","text":"

Median adjusted block size of latest 100000 blocks.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.bootstrap_daemon_address","title":"bootstrap_daemon_address: str | None instance-attribute","text":"

Bootstrap-node to give immediate usability to wallets while syncing by proxying RPC to it.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.cumulative_difficulty","title":"cumulative_difficulty: int | None instance-attribute","text":"

Cumulative difficulty.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.database_size","title":"database_size: int | None instance-attribute","text":"

The size of the blockchain database, in bytes.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.difficulty","title":"difficulty: int | None instance-attribute","text":"

The network difficulty.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.free_space","title":"free_space: int | None instance-attribute","text":"

Available disk space on the node.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.height","title":"height: int | None instance-attribute","text":"

Current length of longest chain known to daemon.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.height_without_bootstrap","title":"height_without_bootstrap: int | None instance-attribute","text":"

Current length of the local chain of the daemon.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.is_busy_syncing","title":"is_busy_syncing: bool | None instance-attribute","text":"

States if new blocks are being added (True) or not (False).

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.is_offline","title":"is_offline: bool | None instance-attribute","text":"

States if the node is offline (True) or online (False).

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.is_restricted","title":"is_restricted: bool | None instance-attribute","text":"

Indicates that the node RPC interface is restricted (True) or not (False).

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.is_synchronized","title":"is_synchronized: bool | None instance-attribute","text":"

States if the node is synchronized (True) or not (False).

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.network_type","title":"network_type: MoneroNetworkType | None instance-attribute","text":"

Network type (MAINNET, TESTNET, or STAGENET).

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.num_alt_blocks","title":"num_alt_blocks: int | None instance-attribute","text":"

Number of alternative blocks to main chain.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.num_incoming_connections","title":"num_incoming_connections: int | None instance-attribute","text":"

Number of peers connected to and pulling from your node.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.num_offline_peers","title":"num_offline_peers: int | None instance-attribute","text":"

Number of peers that are marked as not reacheable on the network.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.num_online_peers","title":"num_online_peers: int | None instance-attribute","text":"

Number of peers that are marked as reacheble on the network.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.num_outgoing_connections","title":"num_outgoing_connections: int | None instance-attribute","text":"

Number of peers that you are connected to and getting information from.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.num_rpc_connections","title":"num_rpc_connections: int | None instance-attribute","text":"

Number of RPC client connected to the daemon (Including this RPC request).

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.num_txs","title":"num_txs: int | None instance-attribute","text":"

Total number of non-coinbase transactions in the chain.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.num_txs_pool","title":"num_txs_pool: int | None instance-attribute","text":"

Number of transactions that have been broadcast but not included in a block.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.start_timestamp","title":"start_timestamp: int | None instance-attribute","text":"

Start time of the daemon, as UNIX time.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.target","title":"target: int | None instance-attribute","text":"

Current target for next proof of work.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.target_height","title":"target_height: int | None instance-attribute","text":"

The height of the next block in the chain.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.update_available","title":"update_available: bool | None instance-attribute","text":"

States if a newer Monero software version is available.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.version","title":"version: str | None instance-attribute","text":"

The version of the Monero software the node is running.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.was_bootstrap_ever_used","title":"was_bootstrap_ever_used: bool | None instance-attribute","text":"

States if a bootstrap node has ever been used since the daemon started.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.__init__","title":"__init__()","text":"

Initiliaze a Monero daemon info.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonSyncInfo","title":"MoneroDaemonSyncInfo","text":"

Bases: MoneroRpcPaymentInfo

Models daemon synchronization information.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonSyncInfo.height","title":"height: int | None instance-attribute","text":"

Daemon blockchain height.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonSyncInfo.next_needed_pruning_seed","title":"next_needed_pruning_seed: int | None instance-attribute","text":"

The next pruning seed needed for pruned sync.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonSyncInfo.overview","title":"overview: str | None instance-attribute","text":"

Overview of current block queue where each character in the string represents a block set in the queue. '.' = requested but not received, 'o' = set received, 'm' = received set that matches the next blocks needed

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonSyncInfo.peers","title":"peers: list[MoneroPeer] instance-attribute","text":"

List of peers connected to the node

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonSyncInfo.spans","title":"spans: list[MoneroConnectionSpan] instance-attribute","text":"

Currently connected peers to download blocks from.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonSyncInfo.target_height","title":"target_height: int | None instance-attribute","text":"

Target height the node is syncing from (will be 0 if node is fully synced).

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonSyncInfo.__init__","title":"__init__()","text":"

Initialize a Monero daemon sync info.

"},{"location":"api/data_model/daemon/#monero.MoneroHardForkInfo","title":"MoneroHardForkInfo","text":"

Bases: MoneroRpcPaymentInfo

Models a Monero look up information regarding hard fork voting and readiness.

"},{"location":"api/data_model/daemon/#monero.MoneroHardForkInfo.earliest_height","title":"earliest_height: int | None instance-attribute","text":"

Block height at which hard fork would be enabled if voted in.

"},{"location":"api/data_model/daemon/#monero.MoneroHardForkInfo.is_enabled","title":"is_enabled: bool | None instance-attribute","text":"

Tells if hard fork is enforced.

"},{"location":"api/data_model/daemon/#monero.MoneroHardForkInfo.num_votes","title":"num_votes: int | None instance-attribute","text":"

Number of votes towards hard fork.

"},{"location":"api/data_model/daemon/#monero.MoneroHardForkInfo.state","title":"state: int | None instance-attribute","text":"

Current hard fork state. 0 (There is likely a hard fork), 1 (An update is needed to fork properly), or 2 (Everything looks good).

"},{"location":"api/data_model/daemon/#monero.MoneroHardForkInfo.threshold","title":"threshold: int | None instance-attribute","text":"

Minimum percent of votes to trigger hard fork. Default is 80.

"},{"location":"api/data_model/daemon/#monero.MoneroHardForkInfo.version","title":"version: int | None instance-attribute","text":"

The major block version for the fork.

"},{"location":"api/data_model/daemon/#monero.MoneroHardForkInfo.voting","title":"voting: int | None instance-attribute","text":"

Hard fork voting status.

"},{"location":"api/data_model/daemon/#monero.MoneroHardForkInfo.window","title":"window: int | None instance-attribute","text":"

Number of blocks over which current votes are cast. Default is 10080 blocks.

"},{"location":"api/data_model/daemon/#monero.MoneroHardForkInfo.__init__","title":"__init__()","text":"

Initialize a Monero hard fork info.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonListener","title":"MoneroDaemonListener","text":"

Receives notifications as a daemon is updated.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonListener.last_header","title":"last_header: MoneroBlockHeader | None instance-attribute","text":"

Last block header added to the chain.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonListener.__init__","title":"__init__()","text":"

Initialize a Monero daemon listener.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonListener.on_block_header","title":"on_block_header(header)","text":"

Called when a new block is added to the chain.

Parameters:

Name Type Description Default header MoneroBlockHeader

is the header of the block added to the chain.

required"},{"location":"api/data_model/wallet/","title":"Wallet Data Model","text":""},{"location":"api/data_model/wallet/#monero.MoneroWalletConfig","title":"MoneroWalletConfig","text":"

Bases: SerializableStruct

Configures a wallet to create.

"},{"location":"api/data_model/wallet/#monero.MoneroWalletConfig.account_lookahead","title":"account_lookahead: int | None instance-attribute","text":"

Account index look ahead.

"},{"location":"api/data_model/wallet/#monero.MoneroWalletConfig.is_multisig","title":"is_multisig: bool | None instance-attribute","text":"

Indicates if the wallet is a multisignature wallet.

"},{"location":"api/data_model/wallet/#monero.MoneroWalletConfig.language","title":"language: str | None instance-attribute","text":"

The wallet language.

"},{"location":"api/data_model/wallet/#monero.MoneroWalletConfig.network_type","title":"network_type: MoneroNetworkType | None instance-attribute","text":"

The wallet network type.

"},{"location":"api/data_model/wallet/#monero.MoneroWalletConfig.password","title":"password: str | None instance-attribute","text":"

The wallet password.

"},{"location":"api/data_model/wallet/#monero.MoneroWalletConfig.path","title":"path: str | None instance-attribute","text":"

The wallet path on file system.

"},{"location":"api/data_model/wallet/#monero.MoneroWalletConfig.primary_address","title":"primary_address: str | None instance-attribute","text":"

The wallet standard address.

"},{"location":"api/data_model/wallet/#monero.MoneroWalletConfig.private_spend_key","title":"private_spend_key: str | None instance-attribute","text":"

The wallet private spend key.

"},{"location":"api/data_model/wallet/#monero.MoneroWalletConfig.private_view_key","title":"private_view_key: str | None instance-attribute","text":"

The wallet private view key.

"},{"location":"api/data_model/wallet/#monero.MoneroWalletConfig.restore_height","title":"restore_height: int | None instance-attribute","text":"

The wallet restore height.

"},{"location":"api/data_model/wallet/#monero.MoneroWalletConfig.save_current","title":"save_current: bool | None instance-attribute","text":"

Save the wallet.

"},{"location":"api/data_model/wallet/#monero.MoneroWalletConfig.seed","title":"seed: str | None instance-attribute","text":"

The wallet mnemonic.

"},{"location":"api/data_model/wallet/#monero.MoneroWalletConfig.seed_offset","title":"seed_offset: str | None instance-attribute","text":"

The wallet custom seed offset.

"},{"location":"api/data_model/wallet/#monero.MoneroWalletConfig.server","title":"server: MoneroRpcConnection | None instance-attribute","text":"

The wallet RPC connection.

"},{"location":"api/data_model/wallet/#monero.MoneroWalletConfig.subaddress_lookahead","title":"subaddress_lookahead: int | None instance-attribute","text":"

Subaddress index look ahead.

"},{"location":"api/data_model/wallet/#monero.MoneroWalletConfig.copy","title":"copy()","text":"

Copy this wallet config.

Returns:

Type Description MoneroWalletConfig

Copy of the wallet config.

"},{"location":"api/data_model/wallet/#monero.MoneroWalletConfig.deserialize","title":"deserialize(config_json) staticmethod","text":"

Deserialize a Monero wallet config from a JSON string.

Parameters:

Name Type Description Default config_json str

JSON string.

required

Returns:

Type Description MoneroWalletConfig

The deserialized wallet config.

"},{"location":"api/data_model/wallet/#monero.MoneroSyncResult","title":"MoneroSyncResult","text":"

Bases: SerializableStruct

Models a result of syncing a wallet.

"},{"location":"api/data_model/wallet/#monero.MoneroSyncResult.num_blocks_fetched","title":"num_blocks_fetched: int instance-attribute","text":"

Number of blocks fetched.

"},{"location":"api/data_model/wallet/#monero.MoneroSyncResult.received_money","title":"received_money: bool instance-attribute","text":"

Indicates if money was received.

"},{"location":"api/data_model/wallet/#monero.MoneroSubaddress","title":"MoneroSubaddress","text":"

Bases: SerializableStruct

Models a Monero subaddress.

"},{"location":"api/data_model/wallet/#monero.MoneroSubaddress.account_index","title":"account_index: int | None instance-attribute","text":"

The subaddress account index.

"},{"location":"api/data_model/wallet/#monero.MoneroSubaddress.address","title":"address: str | None instance-attribute","text":"

Public address.

"},{"location":"api/data_model/wallet/#monero.MoneroSubaddress.balance","title":"balance: int | None instance-attribute","text":"

The subaddress balance.

"},{"location":"api/data_model/wallet/#monero.MoneroSubaddress.index","title":"index: int | None instance-attribute","text":"

The subaddress index.

"},{"location":"api/data_model/wallet/#monero.MoneroSubaddress.is_used","title":"is_used: bool | None instance-attribute","text":"

Indicates if subaddress has been used in receiving funds.

"},{"location":"api/data_model/wallet/#monero.MoneroSubaddress.label","title":"label: str | None instance-attribute","text":"

The subaddress label.

"},{"location":"api/data_model/wallet/#monero.MoneroSubaddress.num_blocks_to_unlock","title":"num_blocks_to_unlock: int | None instance-attribute","text":"

Number of blocks to unlock receveid outputs.

"},{"location":"api/data_model/wallet/#monero.MoneroSubaddress.num_unspent_outputs","title":"num_unspent_outputs: int | None instance-attribute","text":"

The number of unspent outputs in this subaddress.

"},{"location":"api/data_model/wallet/#monero.MoneroSubaddress.unlocked_balance","title":"unlocked_balance: int | None instance-attribute","text":"

The subaddress unlocked balance.

"},{"location":"api/data_model/wallet/#monero.MoneroSubaddress.__init__","title":"__init__()","text":"

Initialize a Monero subaddress.

"},{"location":"api/data_model/wallet/#monero.MoneroAccount","title":"MoneroAccount","text":"

Bases: SerializableStruct

Models a Monero account.

"},{"location":"api/data_model/wallet/#monero.MoneroAccount.balance","title":"balance: int | None instance-attribute","text":"

The account balance.

"},{"location":"api/data_model/wallet/#monero.MoneroAccount.index","title":"index: int | None instance-attribute","text":"

The account index.

"},{"location":"api/data_model/wallet/#monero.MoneroAccount.primary_address","title":"primary_address: str | None instance-attribute","text":"

The account primary address.

"},{"location":"api/data_model/wallet/#monero.MoneroAccount.subaddresses","title":"subaddresses: list[MoneroSubaddress] instance-attribute","text":"

List of account subaddresses.

"},{"location":"api/data_model/wallet/#monero.MoneroAccount.tag","title":"tag: str | None instance-attribute","text":"

The account tag.

"},{"location":"api/data_model/wallet/#monero.MoneroAccount.unlocked_balance","title":"unlocked_balance: int | None instance-attribute","text":"

The account unlocked balance.

"},{"location":"api/data_model/wallet/#monero.MoneroAccount.__init__","title":"__init__()","text":"

Initialize a Monero account.

"},{"location":"api/data_model/wallet/#monero.MoneroDestination","title":"MoneroDestination","text":"

Bases: SerializableStruct

Models an outgoing transfer destination.

"},{"location":"api/data_model/wallet/#monero.MoneroDestination.address","title":"address: str | None instance-attribute","text":"

Address of the receiver.

"},{"location":"api/data_model/wallet/#monero.MoneroDestination.amount","title":"amount: int | None instance-attribute","text":"

Amount sent to this destination.

"},{"location":"api/data_model/wallet/#monero.MoneroDestination.copy","title":"copy()","text":"

Copy current outgoing transfer destination.

Returns:

Type Description MoneroDestination

outgoing transfer destination copy.

"},{"location":"api/data_model/wallet/#monero.MoneroTransfer","title":"MoneroTransfer","text":"

Bases: SerializableStruct

Models a base transfer of funds to or from the wallet.

"},{"location":"api/data_model/wallet/#monero.MoneroTransfer.account_index","title":"account_index: int | None instance-attribute","text":"

Index of the account related to this transfer.

"},{"location":"api/data_model/wallet/#monero.MoneroTransfer.amount","title":"amount: int | None instance-attribute","text":"

Transfer amount in atomic-units.

"},{"location":"api/data_model/wallet/#monero.MoneroTransfer.tx","title":"tx: MoneroTxWallet instance-attribute","text":"

Related wallet transaction.

"},{"location":"api/data_model/wallet/#monero.MoneroTransfer.__init__","title":"__init__()","text":"

Initialize a Monero transfer.

"},{"location":"api/data_model/wallet/#monero.MoneroTransfer.copy","title":"copy()","text":"

Copy current transfer.

Returns:

Type Description MoneroTransfer

transfer copy.

"},{"location":"api/data_model/wallet/#monero.MoneroTransfer.is_incoming","title":"is_incoming()","text":"

Indicates if it is an incoming transfer (True) or not (False). Default None.

Returns:

Type Description bool | None

True if current transfer is incoming, False if outgoing, None if unkown.

"},{"location":"api/data_model/wallet/#monero.MoneroTransfer.is_outgoing","title":"is_outgoing()","text":"

Indicates if it is an outgoing transfer (True) or not (False). Default None.

Returns:

Type Description bool | None

True if current transfer is outgoing, False if incoming, None if unkown.

"},{"location":"api/data_model/wallet/#monero.MoneroTransfer.merge","title":"merge(other)","text":"

Merge current transfer with another one.

Parameters:

Name Type Description Default other MoneroTransfer

other transfer to merge with.

required"},{"location":"api/data_model/wallet/#monero.MoneroIncomingTransfer","title":"MoneroIncomingTransfer","text":"

Bases: MoneroTransfer

Models an incoming transfer of funds to the wallet.

"},{"location":"api/data_model/wallet/#monero.MoneroIncomingTransfer.address","title":"address: str | None instance-attribute","text":"

The address that received funds within this transfer.

"},{"location":"api/data_model/wallet/#monero.MoneroIncomingTransfer.num_suggested_confirmations","title":"num_suggested_confirmations: int | None instance-attribute","text":"

The number of suggested confirmations before moving funds.

"},{"location":"api/data_model/wallet/#monero.MoneroIncomingTransfer.subaddress_index","title":"subaddress_index: int | None instance-attribute","text":"

The subaddress index that received funds within this transfer.

"},{"location":"api/data_model/wallet/#monero.MoneroIncomingTransfer.__init__","title":"__init__()","text":"

Initialize a Monero incoming transfer.

"},{"location":"api/data_model/wallet/#monero.MoneroIncomingTransfer.copy","title":"copy()","text":"

Copy current incoming transfer.

Returns:

Type Description MoneroIncomingTransfer

incoming transfer copy.

"},{"location":"api/data_model/wallet/#monero.MoneroOutgoingTransfer","title":"MoneroOutgoingTransfer","text":"

Bases: MoneroTransfer

Models an outgoing transfer of funds from the wallet.

"},{"location":"api/data_model/wallet/#monero.MoneroOutgoingTransfer.addresses","title":"addresses: list[str] instance-attribute","text":"

Addresses from which the transfer originated.

"},{"location":"api/data_model/wallet/#monero.MoneroOutgoingTransfer.destinations","title":"destinations: list[MoneroDestination] instance-attribute","text":"

Outgoing transfer destinations.

"},{"location":"api/data_model/wallet/#monero.MoneroOutgoingTransfer.subaddress_indices","title":"subaddress_indices: list[int] instance-attribute","text":"

Subaddresses from which the transfer originated.

"},{"location":"api/data_model/wallet/#monero.MoneroOutgoingTransfer.copy","title":"copy()","text":"

Copy current outgoing transfer.

Returns:

Type Description MoneroOutgoingTransfer

outgoing transfer copy.

"},{"location":"api/data_model/wallet/#monero.MoneroTransferQuery","title":"MoneroTransferQuery","text":"

Bases: MoneroTransfer

Configures a query to retrieve transfers.

All transfers are returned except those that do not meet the criteria defined in this query.

"},{"location":"api/data_model/wallet/#monero.MoneroTransferQuery.address","title":"address: str | None instance-attribute","text":"

Select transfers involving particular address. Empty for all.

"},{"location":"api/data_model/wallet/#monero.MoneroTransferQuery.addresses","title":"addresses: list[str] instance-attribute","text":"

Select transfers involving particular addresses. Empty for all.

"},{"location":"api/data_model/wallet/#monero.MoneroTransferQuery.destinations","title":"destinations: list[MoneroDestination] instance-attribute","text":"

Select transfers involving particular destinations. Empty for all.

"},{"location":"api/data_model/wallet/#monero.MoneroTransferQuery.has_destinations","title":"has_destinations: bool | None instance-attribute","text":"

Filter transfers with or without destinations. None for all.

"},{"location":"api/data_model/wallet/#monero.MoneroTransferQuery.incoming","title":"incoming: bool | None instance-attribute","text":"

Filter incoming or outgoing transfers. None for all.

"},{"location":"api/data_model/wallet/#monero.MoneroTransferQuery.outgoing","title":"outgoing: bool | None instance-attribute","text":"

Filter incoming or outgoing transfers. None for all.

"},{"location":"api/data_model/wallet/#monero.MoneroTransferQuery.subaddress_index","title":"subaddress_index: int | None instance-attribute","text":"

Filter by subaddress index. None for all.

"},{"location":"api/data_model/wallet/#monero.MoneroTransferQuery.subaddress_indices","title":"subaddress_indices: list[int] instance-attribute","text":"

Select transfers involving particular subaddresses. Empty for all.

"},{"location":"api/data_model/wallet/#monero.MoneroTransferQuery.tx_query","title":"tx_query: MoneroTxQuery | None instance-attribute","text":"

Related transaction query.

"},{"location":"api/data_model/wallet/#monero.MoneroTransferQuery.__init__","title":"__init__()","text":"

Initialize a Monero transfer query.

"},{"location":"api/data_model/wallet/#monero.MoneroTransferQuery.copy","title":"copy()","text":"

Copy current transfer query.

Returns:

Type Description MoneroTransferQuery

transfer query copy.

"},{"location":"api/data_model/wallet/#monero.MoneroTransferQuery.deserialize_from_block","title":"deserialize_from_block(transfer_query_json) staticmethod","text":"

Deserialize transfer query from json block.

Parameters:

Name Type Description Default transfer_query_json str

json block with serialized transfer query.

required

Returns:

Type Description MoneroTransferQuery

deserialized transfer query.

"},{"location":"api/data_model/wallet/#monero.MoneroTransferQuery.meets_criteria","title":"meets_criteria(transfer, query_parent=True)","text":"

Check if transfer meets all the criteria defined in this query.

Parameters:

Name Type Description Default transfer MoneroTransfer

transfer to check if meets criteria.

required query_parent bool

query parent tx query (default True).

True

Returns:

Type Description bool

True if transfer meets all criteria defined in this query, False otherwise.

"},{"location":"api/data_model/wallet/#monero.MoneroOutputWallet","title":"MoneroOutputWallet","text":"

Bases: MoneroOutput

Models a Monero output with wallet extensions.

"},{"location":"api/data_model/wallet/#monero.MoneroOutputWallet.account_index","title":"account_index: int | None instance-attribute","text":"

The index of the account that owns this output.

"},{"location":"api/data_model/wallet/#monero.MoneroOutputWallet.is_frozen","title":"is_frozen: bool | None instance-attribute","text":"

Indicates if the output is frozen (True) or not (False).

"},{"location":"api/data_model/wallet/#monero.MoneroOutputWallet.is_spent","title":"is_spent: bool | None instance-attribute","text":"

Indicates if the output is spent (True) or not (False).

"},{"location":"api/data_model/wallet/#monero.MoneroOutputWallet.subaddress_index","title":"subaddress_index: int | None instance-attribute","text":"

The index of the subaddress that owns this output.

"},{"location":"api/data_model/wallet/#monero.MoneroOutputWallet.__init__","title":"__init__()","text":"

Initialize a Monero wallet output.

"},{"location":"api/data_model/wallet/#monero.MoneroOutputWallet.copy","title":"copy()","text":"

Copy current output wallet.

Returns:

Type Description MoneroOutputWallet

output wallet copy.

"},{"location":"api/data_model/wallet/#monero.MoneroOutputQuery","title":"MoneroOutputQuery","text":"

Bases: MoneroOutputWallet

Configures a query to retrieve wallet outputs (i.e. outputs that the wallet has or had the ability to spend).

All outputs are returned except those that do not meet the criteria defined in this query.

"},{"location":"api/data_model/wallet/#monero.MoneroOutputQuery.max_amount","title":"max_amount: int | None instance-attribute","text":"

Filter outputs above this amount.

"},{"location":"api/data_model/wallet/#monero.MoneroOutputQuery.min_amount","title":"min_amount: int | None instance-attribute","text":"

Filter outputs below this amount.

"},{"location":"api/data_model/wallet/#monero.MoneroOutputQuery.subaddress_indices","title":"subaddress_indices: list[int] instance-attribute","text":"

Subadress indices to select (empty for all).

"},{"location":"api/data_model/wallet/#monero.MoneroOutputQuery.tx_query","title":"tx_query: MoneroTxQuery | None property","text":"

Related transaction query.

"},{"location":"api/data_model/wallet/#monero.MoneroOutputQuery.__init__","title":"__init__()","text":"

Initialize a Monero output query.

"},{"location":"api/data_model/wallet/#monero.MoneroOutputQuery.copy","title":"copy()","text":"

Copy current output query.

Returns:

Type Description MoneroOutputQuery

output query copy.

"},{"location":"api/data_model/wallet/#monero.MoneroOutputQuery.deserialize_from_block","title":"deserialize_from_block(output_query_json) staticmethod","text":"

Deserialize output query from block.

Parameters:

Name Type Description Default output_query_json str

json query block.

required

Returns:

Type Description MoneroOutputQuery

deserialized output query.

"},{"location":"api/data_model/wallet/#monero.MoneroOutputQuery.meets_criteria","title":"meets_criteria(output, query_parent=True)","text":"

Indicates if the output meets all the criteria defined within this query.

Parameters:

Name Type Description Default output MoneroOutputWallet

Output to check.

required query_parent bool

Query also parent.

True

Returns:

Type Description bool

True if output meets all the criteria defined in this query, False otherwise.

"},{"location":"api/data_model/wallet/#monero.MoneroOutputQuery.set_tx_query","title":"set_tx_query(tx_query, output_query)","text":"

Set related transaction query.

This method sets query references constitutively.

Parameters:

Name Type Description Default tx_query Optional[MoneroTxQuery]

Tx query to set.

required output_query bool

If True sets outputs query in tx_query, otherwise inputs query.

required"},{"location":"api/data_model/wallet/#monero.MoneroTxWallet","title":"MoneroTxWallet","text":"

Bases: MoneroTx

Models a Monero transaction in the context of a wallet.

"},{"location":"api/data_model/wallet/#monero.MoneroTxWallet.change_address","title":"change_address: str | None instance-attribute","text":"

Address to which the change amount of the transaction was sent.

"},{"location":"api/data_model/wallet/#monero.MoneroTxWallet.change_amount","title":"change_amount: int | None instance-attribute","text":"

Change amount of the transaction.

"},{"location":"api/data_model/wallet/#monero.MoneroTxWallet.extra_hex","title":"extra_hex: str | None instance-attribute","text":"

Extra information about the transaction in hexadecimal format.

"},{"location":"api/data_model/wallet/#monero.MoneroTxWallet.incoming_transfers","title":"incoming_transfers: list[MoneroIncomingTransfer] instance-attribute","text":"

List of incoming transfer.

"},{"location":"api/data_model/wallet/#monero.MoneroTxWallet.input_sum","title":"input_sum: int | None instance-attribute","text":"

Total input sum.

"},{"location":"api/data_model/wallet/#monero.MoneroTxWallet.is_incoming","title":"is_incoming: bool | None instance-attribute","text":"

Indicates if the transaction has incoming transfers.

"},{"location":"api/data_model/wallet/#monero.MoneroTxWallet.is_locked","title":"is_locked: bool | None instance-attribute","text":"

Indicates if the transaction is locked.

"},{"location":"api/data_model/wallet/#monero.MoneroTxWallet.is_outgoing","title":"is_outgoing: bool | None instance-attribute","text":"

Indicated if the transaction has outgoing transfer.

"},{"location":"api/data_model/wallet/#monero.MoneroTxWallet.note","title":"note: str | None instance-attribute","text":"

Transaction note.

"},{"location":"api/data_model/wallet/#monero.MoneroTxWallet.num_dummy_outputs","title":"num_dummy_outputs: int | None instance-attribute","text":"

Number of decoys of the transactions.

"},{"location":"api/data_model/wallet/#monero.MoneroTxWallet.outgoing_transfer","title":"outgoing_transfer: MoneroOutgoingTransfer | None instance-attribute","text":"

The outgoing transfer related to this transaction.

"},{"location":"api/data_model/wallet/#monero.MoneroTxWallet.output_sum","title":"output_sum: int | None instance-attribute","text":"

The total output amount sum originated from this transaction.

"},{"location":"api/data_model/wallet/#monero.MoneroTxWallet.tx_set","title":"tx_set: MoneroTxSet | None instance-attribute","text":"

Set of transactions related to current tx.

"},{"location":"api/data_model/wallet/#monero.MoneroTxWallet.__init__","title":"__init__()","text":"

Initialize a new Monero tx wallet.

"},{"location":"api/data_model/wallet/#monero.MoneroTxWallet.copy","title":"copy()","text":"

Copy current tx wallet.

Returns:

Type Description MoneroTxWallet

tx wallet copy.

"},{"location":"api/data_model/wallet/#monero.MoneroTxWallet.filter_outputs_wallet","title":"filter_outputs_wallet(query)","text":"

Get outputs filtered by query.

Parameters:

Name Type Description Default query MoneroOutputQuery

query to filter outputs with.

required

Returns:

Type Description list[MoneroOutputWallet]

outputs that meets all criteria defined in query.

"},{"location":"api/data_model/wallet/#monero.MoneroTxWallet.filter_transfers","title":"filter_transfers(query)","text":"

Get transfers filtered by query.

Parameters:

Name Type Description Default query MoneroTransferQuery

query to filter transfers with.

required

Returns:

Type Description list[MoneroTransfer]

transfers that meets all criteria defined in query.

"},{"location":"api/data_model/wallet/#monero.MoneroTxWallet.get_incoming_amount","title":"get_incoming_amount()","text":"

Get total amount received in current tx.

Returns:

Type Description int

total amount received in current wallet tx.

"},{"location":"api/data_model/wallet/#monero.MoneroTxWallet.get_inputs_wallet","title":"get_inputs_wallet(query=None)","text":"

Get wallet inputs filtered by query.

Parameters:

Name Type Description Default query MoneroOutputQuery

query to filter outputs with.

None

Returns:

Type Description list[MoneroOutputWallet]

wallet outputs filtered by query.

"},{"location":"api/data_model/wallet/#monero.MoneroTxWallet.get_outgoing_amount","title":"get_outgoing_amount()","text":"

Get total amount spent in current tx.

Returns:

Type Description int

total amount spent in current wallet tx.

"},{"location":"api/data_model/wallet/#monero.MoneroTxQuery","title":"MoneroTxQuery","text":"

Bases: MoneroTxWallet

Configures a query to retrieve transactions.

All transactions are returned except those that do not meet the criteria defined in this query.

"},{"location":"api/data_model/wallet/#monero.MoneroTxQuery.has_payment_id","title":"has_payment_id: bool | None instance-attribute","text":"

Get transactions that have a payment id.

"},{"location":"api/data_model/wallet/#monero.MoneroTxQuery.hashes","title":"hashes: list[str] instance-attribute","text":"

Get transactions by hashes.

"},{"location":"api/data_model/wallet/#monero.MoneroTxQuery.height","title":"height: int | None instance-attribute","text":"

Get transactions by height.

"},{"location":"api/data_model/wallet/#monero.MoneroTxQuery.include_outputs","title":"include_outputs: int | None instance-attribute","text":"

Include outputs in transaction data.

"},{"location":"api/data_model/wallet/#monero.MoneroTxQuery.input_query","title":"input_query: MoneroOutputQuery | None instance-attribute","text":"

Query to apply on transaction inputs.

"},{"location":"api/data_model/wallet/#monero.MoneroTxQuery.is_incoming","title":"is_incoming: bool | None instance-attribute","text":"

Include incoming transactions.

"},{"location":"api/data_model/wallet/#monero.MoneroTxQuery.is_outgoing","title":"is_outgoing: bool | None instance-attribute","text":"

Include outgoing transactions.

"},{"location":"api/data_model/wallet/#monero.MoneroTxQuery.max_height","title":"max_height: int | None instance-attribute","text":"

Get transactions below max height.

"},{"location":"api/data_model/wallet/#monero.MoneroTxQuery.min_height","title":"min_height: int | None instance-attribute","text":"

Get transactions above max height.

"},{"location":"api/data_model/wallet/#monero.MoneroTxQuery.output_query","title":"output_query: MoneroOutputQuery | None instance-attribute","text":"

Query to apply on transaction outputs.

"},{"location":"api/data_model/wallet/#monero.MoneroTxQuery.payment_ids","title":"payment_ids: list[str] instance-attribute","text":"

Get transactions with specific payment ids.

"},{"location":"api/data_model/wallet/#monero.MoneroTxQuery.transfer_query","title":"transfer_query: MoneroTransferQuery | None instance-attribute","text":"

Query to apply on transaction wallet transfer.

"},{"location":"api/data_model/wallet/#monero.MoneroTxQuery.__init__","title":"__init__()","text":"

Initiliaze a new Monero transaction query.

"},{"location":"api/data_model/wallet/#monero.MoneroTxQuery.copy","title":"copy()","text":"

Copy current transaction query.

Returns:

Type Description MoneroTxQuery

tx query copy.

"},{"location":"api/data_model/wallet/#monero.MoneroTxQuery.deserialize_from_block","title":"deserialize_from_block(tx_query_json) staticmethod","text":"

Deserialize transaction query from JSON string.

Parameters:

Name Type Description Default tx_query_json str

tx query as JSON string.

required

Returns:

Type Description MoneroTxQuery

deserialized tx query.

"},{"location":"api/data_model/wallet/#monero.MoneroTxQuery.meets_criteria","title":"meets_criteria(tx, query_children=False)","text":"

Check if transaction wallet meets all criteria defined in this query.

Parameters:

Name Type Description Default tx MoneroTxWallet

Tx to check if meets criteria defined in this query.

required query_children bool

Query child data.

False

Returns:

Type Description bool

True if tx meets all criteria defined in this query, False otherwise.

"},{"location":"api/data_model/wallet/#monero.MoneroTxSet","title":"MoneroTxSet","text":"

Bases: SerializableStruct

Groups transactions who share common hex data which is needed in order to sign and submit the transactions.

For example, multisig transactions created from create_txs() share a common hex string which is needed in order to sign and submit the multisig transactions.

"},{"location":"api/data_model/wallet/#monero.MoneroTxSet.multisig_tx_hex","title":"multisig_tx_hex: str | None instance-attribute","text":"

Multisignature transaction hex.

"},{"location":"api/data_model/wallet/#monero.MoneroTxSet.signed_tx_hex","title":"signed_tx_hex: str | None instance-attribute","text":"

Signed transaction hex.

"},{"location":"api/data_model/wallet/#monero.MoneroTxSet.txs","title":"txs: list[MoneroTxWallet] instance-attribute","text":"

List of transactions defined in this set.

"},{"location":"api/data_model/wallet/#monero.MoneroTxSet.unsigned_tx_hex","title":"unsigned_tx_hex: str | None instance-attribute","text":"

Unsigned transaction hex.

"},{"location":"api/data_model/wallet/#monero.MoneroTxSet.__init__","title":"__init__()","text":"

Initialize a Monero transaction set.

"},{"location":"api/data_model/wallet/#monero.MoneroTxSet.deserialize","title":"deserialize(tx_set_json) staticmethod","text":"

Deserialize a Monero transaction set from a JSON string.

Parameters:

Name Type Description Default tx_set_json str

tx set as JSON string.

required

Returns:

Type Description MoneroTxSet

The deseriliazed transaction set.

"},{"location":"api/data_model/wallet/#monero.MoneroIntegratedAddress","title":"MoneroIntegratedAddress","text":"

Bases: SerializableStruct

Models a Monero integrated address.

"},{"location":"api/data_model/wallet/#monero.MoneroIntegratedAddress.integrated_address","title":"integrated_address: str instance-attribute","text":"

The integrated address.

"},{"location":"api/data_model/wallet/#monero.MoneroIntegratedAddress.payment_id","title":"payment_id: str instance-attribute","text":"

The payment id related to this integrated address.

"},{"location":"api/data_model/wallet/#monero.MoneroIntegratedAddress.standard_address","title":"standard_address: str instance-attribute","text":"

The standard address related to this integrated address.

"},{"location":"api/data_model/wallet/#monero.MoneroIntegratedAddress.__init__","title":"__init__()","text":"

Initialize a Monero integrated address.

"},{"location":"api/data_model/wallet/#monero.MoneroTxPriority","title":"MoneroTxPriority","text":"

Bases: IntEnum

Enumerates Monero transaction priorities.

"},{"location":"api/data_model/wallet/#monero.MoneroTxPriority.DEFAULT","title":"DEFAULT = 0 class-attribute instance-attribute","text":"

0 Default transaction priority.

"},{"location":"api/data_model/wallet/#monero.MoneroTxPriority.ELEVATED","title":"ELEVATED = 3 class-attribute instance-attribute","text":"

3 Elevated transaction priority.

"},{"location":"api/data_model/wallet/#monero.MoneroTxPriority.NORMAL","title":"NORMAL = 2 class-attribute instance-attribute","text":"

2 Normal transaction priority.

"},{"location":"api/data_model/wallet/#monero.MoneroTxPriority.UNIMPORTANT","title":"UNIMPORTANT = 1 class-attribute instance-attribute","text":"

1 Unimportant transaction priority.

"},{"location":"api/data_model/wallet/#monero.MoneroTxConfig","title":"MoneroTxConfig","text":"

Bases: SerializableStruct

Configures a transaction to send, sweep, or create a payment URI.

"},{"location":"api/data_model/wallet/#monero.MoneroTxConfig.account_index","title":"account_index: int | None instance-attribute","text":"

Account index to send funds from.

"},{"location":"api/data_model/wallet/#monero.MoneroTxConfig.address","title":"address: str | None instance-attribute","text":"

Transaction address destination.

"},{"location":"api/data_model/wallet/#monero.MoneroTxConfig.amount","title":"amount: int | None instance-attribute","text":"

Transaction amount.

"},{"location":"api/data_model/wallet/#monero.MoneroTxConfig.below_amount","title":"below_amount: int | None instance-attribute","text":"

Ignore output amount below.

"},{"location":"api/data_model/wallet/#monero.MoneroTxConfig.can_split","title":"can_split: bool | None instance-attribute","text":"

Indicates if transaction can be splitted in multiple transactions.

"},{"location":"api/data_model/wallet/#monero.MoneroTxConfig.destinations","title":"destinations: list[MoneroDestination] instance-attribute","text":"

Transaction outgoing destinations.

"},{"location":"api/data_model/wallet/#monero.MoneroTxConfig.fee","title":"fee: int | None instance-attribute","text":"

Transaction fee.

"},{"location":"api/data_model/wallet/#monero.MoneroTxConfig.key_image","title":"key_image: str | None instance-attribute","text":"

Use a particular key image as input for transaction.

"},{"location":"api/data_model/wallet/#monero.MoneroTxConfig.note","title":"note: str | None instance-attribute","text":"

Transaction note.

"},{"location":"api/data_model/wallet/#monero.MoneroTxConfig.payment_id","title":"payment_id: str | None instance-attribute","text":"

Transaction payment id.

"},{"location":"api/data_model/wallet/#monero.MoneroTxConfig.priority","title":"priority: MoneroTxPriority | None instance-attribute","text":"

Transaction priority.

"},{"location":"api/data_model/wallet/#monero.MoneroTxConfig.recipient_name","title":"recipient_name: str | None instance-attribute","text":"

Recipient name.

"},{"location":"api/data_model/wallet/#monero.MoneroTxConfig.relay","title":"relay: bool | None instance-attribute","text":"

Indicates if transaction should be relayed (True) or not (False).

"},{"location":"api/data_model/wallet/#monero.MoneroTxConfig.ring_size","title":"ring_size: int | None instance-attribute","text":"

Transaction ring size

"},{"location":"api/data_model/wallet/#monero.MoneroTxConfig.subaddress_indices","title":"subaddress_indices: list[int] instance-attribute","text":"

Account subaddresses indices to send funds from.

"},{"location":"api/data_model/wallet/#monero.MoneroTxConfig.subtract_fee_from","title":"subtract_fee_from: list[int] instance-attribute","text":"

Subtract fee from outputs.

"},{"location":"api/data_model/wallet/#monero.MoneroTxConfig.sweep_each_subaddress","title":"sweep_each_subaddress: bool | None instance-attribute","text":"

Sweep each wallet subbaddress.

"},{"location":"api/data_model/wallet/#monero.MoneroTxConfig.copy","title":"copy()","text":"

Copy current tx config.

Returns:

Type Description MoneroTxConfig

tx config copy.

"},{"location":"api/data_model/wallet/#monero.MoneroTxConfig.deserialize","title":"deserialize(config_json) staticmethod","text":"

Deserialize tx config from JSON string.

Parameters:

Name Type Description Default config_json str

tx config in JSON format.

required

Returns:

Type Description MoneroTxConfig

deserialized tx config.

"},{"location":"api/data_model/wallet/#monero.MoneroTxConfig.get_normalized_destinations","title":"get_normalized_destinations()","text":"

Get all destinations set in current tx config.

Returns:

Type Description list[MoneroDestination]

normalized tx config destinations.

"},{"location":"api/data_model/wallet/#monero.MoneroTxConfig.set_address","title":"set_address(address)","text":"

Set the address of a single-destination configuration.

Parameters:

Name Type Description Default address str

the address to set for the single destination.

required"},{"location":"api/data_model/wallet/#monero.MoneroKeyImageImportResult","title":"MoneroKeyImageImportResult","text":"

Bases: SerializableStruct

Models results from importing key images.

"},{"location":"api/data_model/wallet/#monero.MoneroKeyImageImportResult.height","title":"height: int | None instance-attribute","text":"

Height at which the last key image was imported. Can be 0 if blockchain height is not known.

"},{"location":"api/data_model/wallet/#monero.MoneroKeyImageImportResult.spent_amount","title":"spent_amount: int | None instance-attribute","text":"

Amount (in atomic-units) spent from those key images.

"},{"location":"api/data_model/wallet/#monero.MoneroKeyImageImportResult.unspent_amount","title":"unspent_amount: int | None instance-attribute","text":"

Amount (in atomic-units) still available from those key images.

"},{"location":"api/data_model/wallet/#monero.MoneroKeyImageImportResult.__init__","title":"__init__()","text":"

Initialize a Monero key image import result.

"},{"location":"api/data_model/wallet/#monero.MoneroMessageSignatureType","title":"MoneroMessageSignatureType","text":"

Bases: IntEnum

Enumerates the type of a Monero message signature.

"},{"location":"api/data_model/wallet/#monero.MoneroMessageSignatureType.SIGN_WITH_SPEND_KEY","title":"SIGN_WITH_SPEND_KEY = 0 class-attribute instance-attribute","text":"

0 Indicates that the message verification was signed with the wallet private spend key_.

.. _private spend key: https://docs.getmonero.org/cryptography/asymmetric/private-key/#private-spend-key

"},{"location":"api/data_model/wallet/#monero.MoneroMessageSignatureType.SIGN_WITH_VIEW_KEY","title":"SIGN_WITH_VIEW_KEY = 1 class-attribute instance-attribute","text":"

1 Indicates that the message verification was signed with the wallet private view key_.

.. _private view key: https://docs.getmonero.org/cryptography/asymmetric/private-key/#private-spend-key

"},{"location":"api/data_model/wallet/#monero.MoneroMessageSignatureResult","title":"MoneroMessageSignatureResult","text":"

Bases: SerializableStruct

Models results from message verification.

"},{"location":"api/data_model/wallet/#monero.MoneroMessageSignatureResult.is_good","title":"is_good: bool instance-attribute","text":"

Indicates if the message verification was successful.

"},{"location":"api/data_model/wallet/#monero.MoneroMessageSignatureResult.is_old","title":"is_old: bool instance-attribute","text":"

Indicates if the message verification used old monero software.

"},{"location":"api/data_model/wallet/#monero.MoneroMessageSignatureResult.signature_type","title":"signature_type: MoneroMessageSignatureType instance-attribute","text":"

Signature type used in the message verification.

"},{"location":"api/data_model/wallet/#monero.MoneroMessageSignatureResult.version","title":"version: int instance-attribute","text":"

Message signature version.

"},{"location":"api/data_model/wallet/#monero.MoneroMessageSignatureResult.__init__","title":"__init__()","text":"

Initialize a Monero message signature result.

"},{"location":"api/data_model/wallet/#monero.MoneroCheck","title":"MoneroCheck","text":"

Bases: SerializableStruct

Base model for results from checking a transaction or reserve proof.

"},{"location":"api/data_model/wallet/#monero.MoneroCheck.is_good","title":"is_good: bool instance-attribute","text":"

Indicates if check was successfull.

"},{"location":"api/data_model/wallet/#monero.MoneroCheck.__init__","title":"__init__()","text":"

Initialize a Monero check.

"},{"location":"api/data_model/wallet/#monero.MoneroCheckTx","title":"MoneroCheckTx","text":"

Bases: MoneroCheck

Models the results from checking a transaction key.

"},{"location":"api/data_model/wallet/#monero.MoneroCheckTx.in_tx_pool","title":"in_tx_pool: bool | None instance-attribute","text":"

States if the transaction is in pool (True) or included in a block (False)

"},{"location":"api/data_model/wallet/#monero.MoneroCheckTx.num_confirmations","title":"num_confirmations: int | None instance-attribute","text":"

Transaction network confirmations.

"},{"location":"api/data_model/wallet/#monero.MoneroCheckTx.received_amount","title":"received_amount: int | None instance-attribute","text":"

Amount received in the transaction.

"},{"location":"api/data_model/wallet/#monero.MoneroCheckTx.__init__","title":"__init__()","text":"

Initialize a Monero transaction check.

"},{"location":"api/data_model/wallet/#monero.MoneroCheckReserve","title":"MoneroCheckReserve","text":"

Bases: MoneroCheck

Models the results from checking a reserve proof.

"},{"location":"api/data_model/wallet/#monero.MoneroCheckReserve.total_amount","title":"total_amount: int | None instance-attribute","text":"

The reserve total amount.

"},{"location":"api/data_model/wallet/#monero.MoneroCheckReserve.unconfirmed_spent_amount","title":"unconfirmed_spent_amount: int | None instance-attribute","text":"

The reserve unconfirmed spent amount.

"},{"location":"api/data_model/wallet/#monero.MoneroCheckReserve.__init__","title":"__init__()","text":"

Initialize a Monero reserve check.

"},{"location":"api/data_model/wallet/#monero.MoneroMultisigInfo","title":"MoneroMultisigInfo","text":"

Bases: SerializableStruct

Models information about a multisig wallet.

"},{"location":"api/data_model/wallet/#monero.MoneroMultisigInfo.is_multisig","title":"is_multisig: bool instance-attribute","text":"

Indicates if the wallet is multisignature (True), or not (False).

"},{"location":"api/data_model/wallet/#monero.MoneroMultisigInfo.is_ready","title":"is_ready: bool instance-attribute","text":"

Indicates if the wallet is ready to support multisignature operations (True) or not (False).

"},{"location":"api/data_model/wallet/#monero.MoneroMultisigInfo.num_participants","title":"num_participants: int instance-attribute","text":"

Number of participants of the multisignature wallet.

"},{"location":"api/data_model/wallet/#monero.MoneroMultisigInfo.threshold","title":"threshold: int instance-attribute","text":"

Number of participants need in order to sign a transaction.

"},{"location":"api/data_model/wallet/#monero.MoneroMultisigInfo.__init__","title":"__init__()","text":"

Initialize a Monero multisignature info.

"},{"location":"api/data_model/wallet/#monero.MoneroMultisigInitResult","title":"MoneroMultisigInitResult","text":"

Bases: SerializableStruct

Models the result of initializing a multisig wallet which results in the multisig wallet's address xor another multisig hex to share with participants to create the wallet.

"},{"location":"api/data_model/wallet/#monero.MoneroMultisigInitResult.address","title":"address: str | None instance-attribute","text":"

The multisignature wallet address.

"},{"location":"api/data_model/wallet/#monero.MoneroMultisigInitResult.multisig_hex","title":"multisig_hex: str | None instance-attribute","text":"

The multisignature hex to share with other participants.

"},{"location":"api/data_model/wallet/#monero.MoneroMultisigInitResult.__init__","title":"__init__()","text":"

Initialize a Monero multisignature initializing result.

"},{"location":"api/data_model/wallet/#monero.MoneroMultisigSignResult","title":"MoneroMultisigSignResult","text":"

Bases: SerializableStruct

Models the result of signing multisig tx hex.

"},{"location":"api/data_model/wallet/#monero.MoneroMultisigSignResult.signed_multisig_tx_hex","title":"signed_multisig_tx_hex: str | None instance-attribute","text":"

Multisig transaction in hex format.

"},{"location":"api/data_model/wallet/#monero.MoneroMultisigSignResult.tx_hashes","title":"tx_hashes: list[str] instance-attribute","text":"

List of transaction hash.

"},{"location":"api/data_model/wallet/#monero.MoneroMultisigSignResult.__init__","title":"__init__()","text":"

Initialize a Monero multisignature signature result.

"},{"location":"api/data_model/wallet/#monero.MoneroAddressBookEntry","title":"MoneroAddressBookEntry","text":"

Bases: SerializableStruct

Monero address book entry model.

"},{"location":"api/data_model/wallet/#monero.MoneroAddressBookEntry.address","title":"address: str | None instance-attribute","text":"

The book entry address.

"},{"location":"api/data_model/wallet/#monero.MoneroAddressBookEntry.description","title":"description: str | None instance-attribute","text":"

The book entry description.

"},{"location":"api/data_model/wallet/#monero.MoneroAddressBookEntry.index","title":"index: int | None instance-attribute","text":"

The book entry index.

"},{"location":"api/data_model/wallet/#monero.MoneroAddressBookEntry.payment_id","title":"payment_id: str | None instance-attribute","text":"

The book entry payment id.

"},{"location":"api/data_model/wallet/#monero.MoneroAddressType","title":"MoneroAddressType","text":"

Bases: IntEnum

Models a Monero public address type_.

.. _Monero public address type: https://docs.getmonero.org/public-address/

"},{"location":"api/data_model/wallet/#monero.MoneroAddressType.INTEGRATED_ADDRESS","title":"INTEGRATED_ADDRESS = 1 class-attribute instance-attribute","text":"

1 Indicates that the Monero address format is integrated_.

.. _integrated: https://docs.getmonero.org/public-address/integrated-address/

"},{"location":"api/data_model/wallet/#monero.MoneroAddressType.PRIMARY_ADDRESS","title":"PRIMARY_ADDRESS = 0 class-attribute instance-attribute","text":"

0 Indicates that the Monero address format is standard_, also known as primary.

.. _standard: https://docs.getmonero.org/public-address/standard-address/

"},{"location":"api/data_model/wallet/#monero.MoneroAddressType.SUBADDRESS","title":"SUBADDRESS = 2 class-attribute instance-attribute","text":"

2 Indicates that the Monero address format is subaddress_.

.. _subaddress: https://docs.getmonero.org/public-address/subaddress/

"},{"location":"api/data_model/wallet/#monero.MoneroDecodedAddress","title":"MoneroDecodedAddress","text":"

Bases: SerializableStruct

Maintains metadata for a decoded address.

"},{"location":"api/data_model/wallet/#monero.MoneroDecodedAddress.address","title":"address: str instance-attribute","text":"

The decoded address.

"},{"location":"api/data_model/wallet/#monero.MoneroDecodedAddress.address_type","title":"address_type: MoneroAddressType instance-attribute","text":"

Type of the decoded address.

"},{"location":"api/data_model/wallet/#monero.MoneroDecodedAddress.network_type","title":"network_type: MoneroNetworkType instance-attribute","text":"

Network type of the decoded address.

"},{"location":"api/data_model/wallet/#monero.MoneroDecodedAddress.__init__","title":"__init__(address, address_type, network_type)","text":"

Initialize a Monero decoded address.

Parameters:

Name Type Description Default address str

The decoded address.

required address_type MoneroAddressType

The type of the decoded address.

required network_type MoneroNetworkType

Network type of the decoded address.

required"},{"location":"api/data_model/wallet/#monero.MoneroAccountTag","title":"MoneroAccountTag","text":"

Bases: SerializableStruct

Models a Monero account tag.

"},{"location":"api/data_model/wallet/#monero.MoneroAccountTag.account_indices","title":"account_indices: list[int] instance-attribute","text":"

Account indices with this tag.

"},{"location":"api/data_model/wallet/#monero.MoneroAccountTag.label","title":"label: str | None instance-attribute","text":"

The account tag label.

"},{"location":"api/data_model/wallet/#monero.MoneroAccountTag.tag","title":"tag: str | None instance-attribute","text":"

The account tag.

"},{"location":"api/data_model/wallet/#monero.MoneroWalletListener","title":"MoneroWalletListener","text":"

Interface to receive wallet notifications.

"},{"location":"api/data_model/wallet/#monero.MoneroWalletListener.__init__","title":"__init__()","text":"

Initialize a wallet listener.

"},{"location":"api/data_model/wallet/#monero.MoneroWalletListener.on_balances_changed","title":"on_balances_changed(new_balance, new_unlocked_balance)","text":"

Invoked when the wallet's balances change.

Parameters:

Name Type Description Default new_balance int

new balance.

required new_unlocked_balance int

new unlocked balance.

required"},{"location":"api/data_model/wallet/#monero.MoneroWalletListener.on_new_block","title":"on_new_block(height)","text":"

Invoked when a new block is processed.

Parameters:

Name Type Description Default height int

the newly processed block.

required"},{"location":"api/data_model/wallet/#monero.MoneroWalletListener.on_output_received","title":"on_output_received(output)","text":"

Invoked when the wallet receives an output.

Parameters:

Name Type Description Default output MoneroOutputWallet

the received output.

required"},{"location":"api/data_model/wallet/#monero.MoneroWalletListener.on_output_spent","title":"on_output_spent(output)","text":"

Invoked when the wallet spends an output.

Parameters:

Name Type Description Default output MoneroOutputWallet

the spent output.

required"},{"location":"api/data_model/wallet/#monero.MoneroWalletListener.on_sync_progress","title":"on_sync_progress(height, start_height, end_height, percent_done, message)","text":"

Invoked when sync progress is made.

Parameters:

Name Type Description Default height int

height of the synced block.

required start_height int

starting height of the sync request.

required end_height int

ending height of the sync request.

required percent_done float

sync progress as a percentage.

required message str

human-readable description of the current progress.

required"},{"location":"examples/connect_to_rpc_server/","title":"Connect to RPC Server","text":"

Developers can create and establish a connection to a rpc server conveniently with a MoneroRpcConnection:

from monero import MoneroRpcConnection\n\n# connect to a monerod or wallet rpc server\nconnection = MoneroRpcConnection(\"http:://rpc_server_uri:18089\")\n\n# set connection credentials if needed\nconnection.set_credentials(\"rpc_user\", \"rpc_password\")\n\n# check rpc connection\nconnection.check_connection()\n\nif not connection.is_connected():\n    raise Exception(\"Could not connect to RPC server.\")\n\nprint(\"Connection established to RPC server.\")\n

After successfully connecting to the rpc server, developers can also invoke methods of the JSON-RPC interface directly:

# invoke JSON-RPC method `get_version`\nresult = connection.send_json_request(\"get_version\")\nprint(f\"get_version JSON-RPC response: {result}\")\n

MoneroRpcConnection also accepts an optional proxy_uri parameter in its constructor, manageable even after a connection has been created. A prime example of use is to route your traffic via TOR:

Note

Setting a proxy_uri resets MoneroRpcConnection status.

# setup TOR proxy uri by instance attribute\nconnection.proxy_uri = \"127.0.0.1:9050\"\n\n# must recall `check_connection()` manually\nconnection.check_connection()\n
"},{"location":"examples/create_local_full_wallet/","title":"Create Local Full Wallet","text":"

MoneroWalletFull is another MoneroWallet implementation that fully wraps wallet2 API. With a full wallet developers can create wallet files and manage them locally.

Creating a MoneroWalletFull is very simple:

from monero import MoneroWalletConfig, MoneroWalletFull, MoneroNetworkType\n\n# setup wallet configuration\nconfig = MoneroWalletConfig()\n\n# setup wallet path\nconfig.path = \"test_wallet_full\"\n\n# setup wallet password\nconfig.password = \"supersecretpassword123\"\n\n# setup wallet network type\nconfig.network_type = MoneroNetworkType.TESTNET\n\nwallet = MoneroWalletFull.create_wallet(config)\n

Check if a Monero wallet exists at specific path:

if MoneroWalletFull.wallet_exists(\"test_wallet_full\"):\n    wallet = MoneroWalletFull.open_wallet(\"test_wallet_full\", \"supersecretpassword123\", MoneroNetworkType.TESTNET)\n
"},{"location":"examples/interact_with_daemon/","title":"Interact with RPC Daemon","text":"

MoneroDaemonRpc offers a MoneroDaemon implementation that interacts with monero-rpc server using calls to RPC, JSON-RPC and Binary interfaces.

Creating a MoneroDaemonRpc instance is very simple:

from monero import MoneroDaemonRpc\n\n# create RPC daemon connected to `monerod-rpc` server\ndaemon = MoneroDaemonRpc(\"http://monerod_rpc_uri:18081\")\n

It can also be done using a MoneroRpcConnection instance:

from monero import MoneroRpcConnection, MoneroDaemonRpc\n\n# create rpc connection\nconnection = MoneroRpcConnection(\"http://monerod_rpc_uri:18081\")\n\n# create daemon using RPC connection\ndaemon = MoneroDaemonRpc(connection)\n

Fetch daemon info and status:

# get general daemon rpc info\ndaemon_info = daemon.get_info()\nprint(f\"Daemon info: {daemon_info.serialize()}\")\n\n# get daemon specific sync info\nsync_info = daemon.get_sync_info()\nprint(f\"Sync info: {sync_info.serialize()}\")\n\n# get peer bans\nbans = daemon.get_peer_bans()\nfor ban in bans:\n    print(f\"Banned peer: {peer.serialize()}\")\n

Query blocks and txs on blockchain:

# get last block header added to blockchain\nlast_block = daemon.get_last_block_header()\nprint(f\"Last block header: {last_block.serialize()}\")\n\n# get specific block by height\nblock = daemon.get_block_by_height(1520000)\nprint(f\"Block fetched by height: {block.serialize()}\")\n\n# get specific block by hash\nblock = daemon.get_block_by_hash(\"...block hash...\")\nprint(f\"Block fetched by hash: {block.serialize()}\")\n\n# get alternative chains seen by the daemon\nchains = daemon.get_alt_chains()\nprint(f\"Found {len(chains)} alternative chains\")\n\n# get unconfirmed txs in pool\ntx_pool = daemon.get_tx_pool()\nfor tx in tx_pool:\n    print(f\"Found tx in pool: {tx.serialize()}\")\n\n# get specific tx added to chain\ntx = daemon.get_tx(\"...tx hash...\")\nprint(f\"Fetched tx: {tx.serialize()}\")\n

Relay mined blocks and signed txs:

# submit a mined block\ndaemon.submit_block(\"...block blob...\")\n\n# submit a signed tx\ntx: Monerotx = ...\ndaemon.submit_tx(tx.full_hex)\n
"},{"location":"examples/interact_with_wallet_rpc/","title":"Interact with RPC Wallet","text":"

MoneroWalletRpc offers a MoneroWallet implementation that interacts with monero-wallet-rpc using calls to the JSON-RPC interface.

Creating a MoneroWalletRpc instance is very simple:

from monero import MoneroWalletRpc\n\n# create RPC wallet connected to `monero-wallet-rpc` server\nwallet = MoneroWalletRpc(\"http://wallet_rpc_uri:18081\")\n

It can also be done using a MoneroRpcConnection instance:

from monero import MoneroRpcConnection, MoneroWalletRpc\n\n# create rpc connection\nconnection = MoneroRpcConnection(\"http://wallet_rpc_uri:18081\")\n\n# create wallet using RPC connection\nwallet = MoneroWalletRpc(connection)\n

Let's create a new wallet file:

# build wallet configuration\nconfig: MoneroWalletConfig = ...\n\n# create new wallet file in rpc server\nwallet.create_wallet(config)\n

Or open an already existing wallet:

# open wallet with config\nwallet.open_wallet(config)\n\n# or open by path and password\nwallet.open_wallet(\"wallet_path\", \"wallet_password\")\n

And fetch some info:

# get wallet information\nprimary_address: str = wallet.get_primary_address()\nview_key: str = wallet.get_private_view_key()\nseed: str = wallet.get_seed()\nbalance: int = wallet.get_balance()\n\nprint(f\"primary address: {primary_address}\")\nprint(f\"view_key: {view_key}\")\nprint(f\"seed: {seed}\")\nprint(f\"balance: {balance}\")\n
"},{"location":"examples/query_wallet_txs_and_transfers/","title":"Query Wallet Txs and Transfers","text":"

The MoneroWallet interface offers methods for fetching transactions, transfers and outputs from wallet's cache:

  • MoneroWallet.get_txs(query: MoneroTxQuery) -> list[MoneroTxWallet]
  • MoneroWallet.get_transfers(query: MoneroTransferQuery) -> list[MoneroTransfer]
  • MoneroWallet.get_outputs(query: MoneroOutputQuery) -> list[MoneroOutputWallet]

This methods can be used with a MoneroTxQuery, MoneroTransferQuery, MoneroOutputQuery, wich will filter all records that doesn't match criteria defined in the query.

Example of fetching wallet txs with a basic MoneroTxQuery:

from monero import (\n    MoneroWallet, MoneroTxQuery,\n    MoneroTxWallet\n)\n\n# open a wallet with txs data\nwallet: MoneroWallet = ...\n\n# create and setup a new tx query to filter txs with\nquery = MoneroTxQuery()\n\n# fetch only outgoing txs\nquery.is_incoming = False\nquery.is_outgoing = True\n\n# include outputs in tx data\nquery.include_outputs = True\n\n# filter tx by height range\nquery.min_height = 150000\nquery.max_height = 300000\n\n# or get txs at specific height\nquery.height = 152000\n\n# fetch txs that meets criteria from wallet\ntxs: list[MoneroTxWallet] = wallet.get_txs(query)\n\n# print fetched txs\nfor tx in txs:\n    print(f\"Found tx: {tx.serialize()}\")\n

Example of fetching wallet transfers with a MoneroTransferQuery:

from monero import (\n    MoneroWallet, MoneroTransferQuery,\n    MoneroTransfer\n)\n\n# open a wallet with txs data\nwallet: MoneroWallet = ...\n\n# create and setup a new tx query to filter transfers with\nquery = MoneroTransferQuery()\n\n# fetch only incoming transfers\nquery.is_incoming = True\nquery.is_outgoing = False\n\n# filter by account and subaddress index\nquery.account_index = 1\nquery.subaddress_indices = [0, 1, 2, 3]\n\n# fetch transfers that meets criteria from wallet\ntransfers: list[MoneroTransferWallet] = wallet.get_transfers(query)\n\n# print fetched txs\nfor transfer in transfers:\n    print(f\"Found transfer: {transfer.serialize()}\")\n
"},{"location":"examples/sending_payments/","title":"Sending Payments","text":"

In order to send payments with a MoneroWallet, developers must setup a MoneroTxConfig:

from monero import MoneroTxConfig\n\n# create and setup transaction configuration\ntx_config = MoneroTxConfig()\n\n# specify source account index\ntx_config.account_index = 0\n\n# specify address and destination amount\ntx_config.address = \"...destination address...\"\ntx_config.amount = 1000000000\n\n# relay tx to the network\ntx_config.relay = True\n\n# create txs with configuration\ntxs: list[MoneroTxWallet] = wallet.create_txs(tx_config)\n\nfor tx in txs:\n    print(f\"Created tx: {tx.serialize()}\")\n

Is possible to setup also multiple destinations in transaction configuration:

tx_config.destinations.append(MoneroDestination(\"...destination address1...\", 1000000000))\n\n...\n\ntx_config.destinations.append(MoneroDestination(\"...destination addressN...\", 1000000000))\n\n# split into multiple txs\ntx_config.can_split = True\n
"},{"location":"examples/using_keys_only_wallet/","title":"Using Keys-Only Wallet","text":"

MoneroWalletKeys is a MoneroWallet implementation that supports only basic keys operations, without files or RPC calls.

Creating a in-memory keys-only wallet with MoneroWalletKeys is very simple:

from monero import MoneroWalletKeys, MoneroWalletConfig, MoneroNetworkType\n\n# setup wallet configuration\nconfig = MoneroWalletConfig()\nconfig.network_type = MoneroNetworkType.TESTNET\n\n# create random wallet\nwallet = MoneroWalletKeys.create_wallet_random(config)\n

Restore specific wallet from seed:

config.seed = \"...wallet seed...\"\n\n# restore wallet from seed\nwallet = MoneroWalletKeys.create_wallet_from_seed(config)\n

Or from wallet keys:

config.primary_address = \"...wallet primary address...\"\nconfig.private_view_key = \"...wallet private view key...\"\n\n# restore wallet from keys\nwallet = MoneroWalletKeys.create_wallet_from_keys(config)\n
"}]} \ No newline at end of file +{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"Monero Python Documentation","text":"

Welcome to the Monero Python documentation.

The aim of this project is to provide an intuitive and robust way to interact with the Monero cryptocurrency in Python using a clearly defined data model. It provides high level classes representing objects from the Monero environment, like wallets, accounts, addresses and transactions.

Developers can create Monero applications using JSON-RPC or Python bindings to monero v0.18.5.1 'Flourine Fermi'.

Contributions can be made via issues and pull requests on GitHub, or communicated via the #monero-python workgroup on Matrix.

GitHub Matrix

"},{"location":"api/architecture/","title":"Architecture","text":""},{"location":"api/connection/","title":"RPC Connection","text":""},{"location":"api/connection/#monero.MoneroRpcConnection","title":"MoneroRpcConnection","text":"

Bases: SerializableStruct

Models a connection to a daemon.

"},{"location":"api/connection/#monero.MoneroRpcConnection.password","title":"password: str | None property","text":"

Connection authentication password.

"},{"location":"api/connection/#monero.MoneroRpcConnection.priority","title":"priority: int instance-attribute","text":"

Connection priority.

"},{"location":"api/connection/#monero.MoneroRpcConnection.proxy_uri","title":"proxy_uri: str | None instance-attribute","text":"

Connection proxy address.

"},{"location":"api/connection/#monero.MoneroRpcConnection.response_time","title":"response_time: int | None property","text":"

Connection response time in milliseconds.

"},{"location":"api/connection/#monero.MoneroRpcConnection.timeout_ms","title":"timeout_ms: int instance-attribute","text":"

Connection timeout (milliseconds).

"},{"location":"api/connection/#monero.MoneroRpcConnection.uri","title":"uri: str | None instance-attribute","text":"

Connection uri.

"},{"location":"api/connection/#monero.MoneroRpcConnection.username","title":"username: str | None property","text":"

Connection authentication username.

"},{"location":"api/connection/#monero.MoneroRpcConnection.zmq_uri","title":"zmq_uri: str | None instance-attribute","text":"

ZMQ connection uri.

"},{"location":"api/connection/#monero.MoneroRpcConnection.check_connection","title":"check_connection(timeout_ms=None)","text":"

Check the connection and update online, authentication, and response time status.

Parameters:

Name Type Description Default timeout_ms int|None

the maximum response time before considered offline.

None

Returns:

Type Description bool

True if there is a change in status, False otherwise.

"},{"location":"api/connection/#monero.MoneroRpcConnection.compare","title":"compare(p1, p2) staticmethod","text":"

Compare connection priorities.

Parameters:

Name Type Description Default p1 int

first priority to check.

required p2 int

second priority to check.

required

Returns:

Type Description bool

True if p1 comes before p2, False otherwise.

"},{"location":"api/connection/#monero.MoneroRpcConnection.get_attribute","title":"get_attribute(key)","text":"

Returns RPC connection attribute.

Parameters:

Name Type Description Default key str

attribute key.

required

Returns:

Type Description str

attribute value.

"},{"location":"api/connection/#monero.MoneroRpcConnection.is_authenticated","title":"is_authenticated()","text":"

Indicates if the connection is authenticated according to the last call to check_connection().

Note: must call check_connection() manually.

Returns:

Type Description bool | None

True if authenticated or no authentication required, False if not authenticated, or None if check_connection() has not been called.

"},{"location":"api/connection/#monero.MoneroRpcConnection.is_connected","title":"is_connected()","text":"

Indicates if the connection is connected according to the last call to check_connection().

Note: must call check_connection() manually.

Returns:

Type Description bool | None

True or False to indicate if connected, or None if check_connection() has not been called.

"},{"location":"api/connection/#monero.MoneroRpcConnection.is_i2p","title":"is_i2p()","text":"

Indicates if the connection is a I2P connection.

Returns:

Type Description bool

True if connection is a I2P connection, False otherwise.

"},{"location":"api/connection/#monero.MoneroRpcConnection.is_onion","title":"is_onion()","text":"

Indicates if the connection is a TOR connection.

Returns:

Type Description bool

True if connection is a TOR connection, False otherwise.

"},{"location":"api/connection/#monero.MoneroRpcConnection.is_online","title":"is_online()","text":"

Indicates if the connection is online according to the last call to check_connection().

Note: must call check_connection() manually.

Returns:

Type Description bool | None

True or False to indicate if online, or None if check_connection() has not been called.

"},{"location":"api/connection/#monero.MoneroRpcConnection.send_binary_request","title":"send_binary_request(method, parameters=None, timeout_ms=None)","text":"

Send a binary RPC request.

Parameters:

Name Type Description Default method str

is the path of the binary RPC method to invoke.

required parameters Optional[object]

are the request parameters (default None).

None timeout_ms Optional[int]

request timeout in milliseconds.

None

Returns:

Type Description bytes | None

the request's deserialized binary response.

"},{"location":"api/connection/#monero.MoneroRpcConnection.send_json_request","title":"send_json_request(method, parameters=None, timeout_ms=None)","text":"

Send a request to the JSON-RPC API.

Parameters:

Name Type Description Default method str

is the method to request.

required parameters Optional[object]

are the request's input parameters (default None).

None timeout_ms Optional[int]

request timeout in milliseconds.

None

Returns:

Type Description object | None

the RPC API response as a map.

"},{"location":"api/connection/#monero.MoneroRpcConnection.send_path_request","title":"send_path_request(method, parameters=None, timeout_ms=None)","text":"

Send a RPC request to the given path and with the given paramters.

E.g. /get_transactions with params.

Parameters:

Name Type Description Default method str

is the url path of the request to invoke.

required parameters Optional[object]

are request parameters sent in the body.

None timeout_ms Optional[int]

request timeout in milliseconds.

None

Returns:

Type Description object | None

the request's deserialized response.

"},{"location":"api/connection/#monero.MoneroRpcConnection.set_attribute","title":"set_attribute(key, value)","text":"

Set RPC connection attribute.

Parameters:

Name Type Description Default key str

key attribute.

required value str

value attribute.

required"},{"location":"api/connection/#monero.MoneroRpcConnection.set_credentials","title":"set_credentials(username, password)","text":"

Set RPC connection credentials.

Parameters:

Name Type Description Default username str

username used for RPC authentication.

required password str

passowrd user for RPC authentication.

required"},{"location":"api/daemon/","title":"Daemon Interface","text":""},{"location":"api/daemon/#monero.MoneroDaemon","title":"MoneroDaemon","text":"

Monero daemon interface.

"},{"location":"api/daemon/#monero.MoneroDaemon.__init__","title":"__init__()","text":"

Initialize a Monero daemon.

"},{"location":"api/daemon/#monero.MoneroDaemon.add_listener","title":"add_listener(listener)","text":"

Register a listener to receive daemon notifications.

Parameters:

Name Type Description Default listener MoneroDaemonListener

the listener to register.

required"},{"location":"api/daemon/#monero.MoneroDaemon.check_for_update","title":"check_for_update()","text":"

Check for update.

Returns:

Type Description MoneroDaemonUpdateCheckResult

the result of the update check.

"},{"location":"api/daemon/#monero.MoneroDaemon.download_update","title":"download_update(path='')","text":"

Download an update.

Parameters:

Name Type Description Default path str

download path.

''

Returns:

Type Description MoneroDaemonUpdateDownloadResult

the result of the update download.

"},{"location":"api/daemon/#monero.MoneroDaemon.generate_blocks","title":"generate_blocks(wallet_address, num_blocks, prev_block_hash=None, starting_nonce=None)","text":"

Generate blocks to a wallet address (regtest only).

Parameters:

Name Type Description Default wallet_address str

is the address of the wallet to receive miner transactions if block is successfully mined.

required num_blocks int

is the number of blocks to generate.

required prev_block_hash str|None

is the hash of the previous block to build on top of (optional, builds on the current tip if not given).

None starting_nonce int|None

is the starting nonce to use (optional).

None

Returns:

Type Description MoneroGenerateBlocksResult

the result of generating blocks; height is the height of the last block generated.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_alt_block_hashes","title":"get_alt_block_hashes()","text":"

Get known block hashes which are not on the main chain.

Returns:

Type Description list[str]

known block hashes which are not on the main chain.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_alt_chains","title":"get_alt_chains()","text":"

Get alternative chains seen by the node.

Returns:

Type Description list[MoneroAltChain]

alternative chains seen by the node.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_block_by_hash","title":"get_block_by_hash(hash)","text":"

Get a block by hash.

Parameters:

Name Type Description Default hash str

is the hash of the block to get.

required

Returns:

Type Description MoneroBlock

the block with the given hash.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_block_by_height","title":"get_block_by_height(height)","text":"

Get a block by height.

Parameters:

Name Type Description Default height int

is the height of the block to get.

required

Returns:

Type Description MoneroBlock

the block at the given height.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_block_hash","title":"get_block_hash(height)","text":"

Get a block's hash by its height.

Parameters:

Name Type Description Default height int

is the height of the block hash to get.

required

Returns:

Type Description str

the block's hash at the given height.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_block_hashes","title":"get_block_hashes(block_hashes, start_height)","text":"

Get block hashes as a binary request to the daemon.

Parameters:

Name Type Description Default block_hashes list[str]

specify block hashes to fetch; first 10 blocks hash goes sequential, next goes in pow(2,n) offset, like 2, 4, 8, 16, 32, 64 and so on, and the last one is always genesis block.

required start_height int

is the starting height of block hashes to return.

required

Returns:

Type Description list[str]

the requested block hashes.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_block_header_by_hash","title":"get_block_header_by_hash(hash)","text":"

Get a block header by its hash.

Parameters:

Name Type Description Default hash str

is the hash of the block to get the header of.

required

Returns:

Type Description MoneroBlockHeader

the block's header.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_block_header_by_height","title":"get_block_header_by_height(height)","text":"

Get a block header by its height.

Parameters:

Name Type Description Default height int

is the height of the block to get the header of.

required

Returns:

Type Description MoneroBlockHeader

the block's header.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_block_headers_by_range","title":"get_block_headers_by_range(start_height, end_height)","text":"

Get block headers for the given range.

Parameters:

Name Type Description Default start_height int

is the start height lower bound inclusive (optional).

required end_height int

is the end height upper bound inclusive (optional).

required

Returns:

Type Description list[MoneroBlockHeader]

block headers in the given range.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_block_template","title":"get_block_template(wallet_address, reserve_size=None)","text":"

Get a block template for mining a new block.

Parameters:

Name Type Description Default wallet_address str

is the address of the wallet to receive miner transactions if block is successfully mined.

required reserve_size int|None

is the reserve size (optional).

None

Returns:

Type Description MoneroBlockTemplate

a block template for mining a new block.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_blocks_by_hash","title":"get_blocks_by_hash(block_hashes, start_height, prune)","text":"

Get a block by hash.

Parameters:

Name Type Description Default block_hashes list[str]

is the hash of the block to get.

required start_height int

filter blocks by block height.

required prune bool

prune hash.

required

Returns:

Type Description list[MoneroBlock]

the block with the given hash.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_blocks_by_height","title":"get_blocks_by_height(heights)","text":"

Get blocks at the given heights.

Parameters:

Name Type Description Default heights list[int]

are the heights of the blocks to get.

required

Returns:

Type Description list[MoneroBlock]

blocks at the given heights.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_blocks_by_range","title":"get_blocks_by_range(start_height, end_height)","text":"

Get blocks in the given height range.

Parameters:

Name Type Description Default start_height int

is the start height lower bound inclusive (optional).

required end_height int

is the end height upper bound inclusive (optional).

required

Returns:

Type Description list[MoneroBlock]

blocks in the given height range.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_blocks_by_range_chunked","title":"get_blocks_by_range_chunked(start_height, end_height, max_chunk_size=None)","text":"

Get blocks in the given height range as chunked requests so that each request is not too big.

Parameters:

Name Type Description Default start_height int

is the start height lower bound inclusive (optional).

required end_height int

is the end height upper bound inclusive (optional).

required max_chunk_size int

is the maximum chunk size in any one request (default 3,000,000 bytes).

None

Returns:

Type Description list[MoneroBlock]

blocks in the given height range.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_download_limit","title":"get_download_limit()","text":"

Get the download bandwidth limit.

Returns:

Type Description int

is the download bandwidth limit.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_fee_estimate","title":"get_fee_estimate(grace_blocks=0)","text":"

Get mining fee estimates per kB.

Parameters:

Name Type Description Default grace_blocks int

number of blocks we want the fee estimate to be valid for.

0

Returns:

Type Description MoneroFeeEstimate

mining fee estimates per kB.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_hard_fork_info","title":"get_hard_fork_info()","text":"

Look up information regarding hard fork voting and readiness.

Returns:

Type Description MoneroHardForkInfo

hard fork information.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_height","title":"get_height()","text":"

Get the number of blocks in the longest chain known to the node.

Returns:

Type Description int

the number of blocks.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_info","title":"get_info()","text":"

Get general information about the state of the node and the network.

Returns:

Type Description MoneroDaemonInfo

general information about the node and network.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_key_image_spent_status","title":"get_key_image_spent_status(key_image)","text":"

Get the spent status of the given key image.

Parameters:

Name Type Description Default key_image str

is key image hex to get the status of.

required

Returns:

Type Description MoneroKeyImageSpentStatus

the status of the key image.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_key_image_spent_statuses","title":"get_key_image_spent_statuses(key_images)","text":"

Get the spent status of each given key image.

Parameters:

Name Type Description Default key_images list[str]

are hex key images to get the statuses of.

required

Returns:

Type Description list[MoneroKeyImageSpentStatus]

the spent status for each key image.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_known_peers","title":"get_known_peers()","text":"

Get all known peers including their last known online status.

Returns:

Type Description list[MoneroPeer]

the daemon's known peers.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_last_block_header","title":"get_last_block_header()","text":"

Get the last block's header.

Returns:

Type Description MoneroBlockHeader

the last block's header.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_listeners","title":"get_listeners()","text":"

Get the listeners registered with the daemon.

Returns:

Type Description list[MoneroDaemonListener]

the registered listeners.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_miner_tx_sum","title":"get_miner_tx_sum(height, num_blocks)","text":"

Gets the total emissions and fees from the genesis block to the current height.

Parameters:

Name Type Description Default height int

is the height to start computing the miner sum.

required num_blocks int

are the number of blocks to include in the sum.

required

Returns:

Type Description MoneroMinerTxSum

the sum emission and fees since the geneis block.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_mining_status","title":"get_mining_status()","text":"

Get the daemon's mining status.

Returns:

Type Description MoneroMiningStatus

the daemon's mining status.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_output_distribution","title":"get_output_distribution(amounts, is_cumulative=None, start_height=None, end_height=None)","text":"

Creates an output distribution.

Parameters:

Name Type Description Default amounts list[int]

are amounts of outputs to make the distribution with.

required is_cumulative bool|None

specifies if the results should be cumulative (optional).

None start_height int|None

is the start height lower bound inclusive (optional).

None end_height int|None

is the end height upper bound inclusive (optional).

None

Returns:

Type Description list[MoneroOutputDistributionEntry]

output distribution entries meeting the parameters.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_output_histogram","title":"get_output_histogram(amounts, min_count, max_count, is_unlocked, recent_cutoff)","text":"

Get a histogram of output amounts. For all amounts (possibly filtered by parameters), gives the number of outputs on the chain for that amount. RingCT outputs counts as 0 amount.

Parameters:

Name Type Description Default amounts list[int]

are amounts of outputs to make the histogram with (atomic-units).

required min_count Optional[int]

filter amounts with at least this number of outputs.

required max_count Optional[int]

filter amounts with at most this number of outputs.

required is_unlocked Optional[bool]

makes a histogram with outputs with the specified lock state.

required recent_cutoff Optional[int]

exclude outputs from older than this timestamp.

required

Returns:

Type Description list[MoneroOutputHistogramEntry]

output histogram entries meeting the parameters.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_outputs","title":"get_outputs(outputs)","text":"

Get outputs identified by a list of output amounts and indices as a binary request.

Parameters:

Name Type Description Default outputs list[MoneroOutput]

identify each output by amount and index.

required

Returns:

Type Description list[MoneroOutput]

the identified outputs.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_peer_bans","title":"get_peer_bans()","text":"

Get peer bans.

Returns:

Type Description list[MoneroBan]

entries about banned peers.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_peers","title":"get_peers()","text":"

Get peers with active incoming or outgoing connections to the node.

Returns:

Type Description list[MoneroPeer]

the daemon's peers.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_sync_info","title":"get_sync_info()","text":"

Get synchronization information.

Returns:

Type Description MoneroDaemonSyncInfo

contains sync information.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_tx","title":"get_tx(tx_hash, prune=False)","text":"

Get a transaction by hash.

Parameters:

Name Type Description Default tx_hash str

is the hash of the transaction to get.

required prune bool

specifies if the returned tx should be pruned (defaults to False).

False

Returns:

Type Description MoneroTx | None

the transaction with the given hash or null if not found.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_tx_hex","title":"get_tx_hex(tx_hash, prune=False)","text":"

Get a transaction hex by hash.

Parameters:

Name Type Description Default tx_hash str

is the hash of the transaction to get hex from.

required prune bool

specifies if the returned tx hex should be pruned (defaults to False).

False

Returns:

Type Description str | None

the tx hex with the given hash.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_tx_hexes","title":"get_tx_hexes(tx_hashes, prune=False)","text":"

Get transaction hexes by hashes.

Parameters:

Name Type Description Default tx_hashes list[str]

are hashes of transactions to get hexes from

required prune bool

Prune transaction hashes.

False

Returns:

Type Description list[str]

are the tx hexes.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_tx_pool","title":"get_tx_pool()","text":"

Get valid transactions seen by the node but not yet mined into a block, as well as spent key image information for the tx pool.

Returns:

Type Description list[MoneroTx]

transactions in the transaction pool.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_tx_pool_backlog","title":"get_tx_pool_backlog()","text":"

Get all transaction pool backlog.

Returns:

Type Description list[MoneroTxBacklogEntry]

transaction pool backlog entries.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_tx_pool_hashes","title":"get_tx_pool_hashes()","text":"

Get hashes of transactions in the transaction pool.

Returns:

Type Description list[str]

hashes of transactions in the transaction pool.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_tx_pool_stats","title":"get_tx_pool_stats()","text":"

Get transaction pool statistics.

Returns:

Type Description MoneroTxPoolStats

statistics about the transaction pool.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_txs","title":"get_txs(tx_hashes, prune=False)","text":"

Get transactions by hashes.

Parameters:

Name Type Description Default tx_hashes list[str]

are hashes of transactions to get.

required prune bool

Prune transactions.

False

Returns:

Type Description list[MoneroTx]

found transactions with the given hashes.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_upload_limit","title":"get_upload_limit()","text":"

Get the upload bandwidth limit.

Returns:

Type Description int

is the upload bandwidth limit.

"},{"location":"api/daemon/#monero.MoneroDaemon.get_version","title":"get_version()","text":"

Gets the version of the daemon.

Returns:

Type Description MoneroVersion

the version of the daemon.

"},{"location":"api/daemon/#monero.MoneroDaemon.is_trusted","title":"is_trusted()","text":"

Indicates if the daemon is trusted or untrusted.

Returns:

Type Description bool

True if the daemon is trusted, False otherwise.

"},{"location":"api/daemon/#monero.MoneroDaemon.prune_blockchain","title":"prune_blockchain(check)","text":"

Prune the blockchain.

Parameters:

Name Type Description Default check bool

specifies to check the pruning (default False).

required

Returns:

Type Description MoneroPruneResult

the prune result.

"},{"location":"api/daemon/#monero.MoneroDaemon.relay_tx_by_hash","title":"relay_tx_by_hash(tx_hash)","text":"

Relays a transaction by hash.

Parameters:

Name Type Description Default tx_hash str

identifies the transaction to relay.

required"},{"location":"api/daemon/#monero.MoneroDaemon.relay_txs_by_hash","title":"relay_txs_by_hash(tx_hashes)","text":"

Relays transactions by hash.

Parameters:

Name Type Description Default tx_hashes list[str]

identify the transactions to relay.

required"},{"location":"api/daemon/#monero.MoneroDaemon.remove_listener","title":"remove_listener(listener)","text":"

Unregister a listener to receive daemon notifications.

Parameters:

Name Type Description Default listener MoneroDaemonListener

a previously registered listener to be unregistered.

required"},{"location":"api/daemon/#monero.MoneroDaemon.reset_download_limit","title":"reset_download_limit()","text":"

Reset the download bandwidth limit.

Returns:

Type Description int

the download bandwidth limit after resetting.

"},{"location":"api/daemon/#monero.MoneroDaemon.reset_upload_limit","title":"reset_upload_limit()","text":"

Reset the upload bandwidth limit.

Returns:

Type Description int

the upload bandwidth limit after resetting.

"},{"location":"api/daemon/#monero.MoneroDaemon.set_download_limit","title":"set_download_limit(limit)","text":"

Set the download bandwidth limit.

Parameters:

Name Type Description Default limit int

is the download limit to set (-1 to reset to default).

required

Returns:

Type Description int

is the new download limit after setting.

"},{"location":"api/daemon/#monero.MoneroDaemon.set_incoming_peer_limit","title":"set_incoming_peer_limit(limit)","text":"

Limit number of incoming peers.

Parameters:

Name Type Description Default limit int

is the maximum number of incoming peers.

required"},{"location":"api/daemon/#monero.MoneroDaemon.set_outgoing_peer_limit","title":"set_outgoing_peer_limit(limit)","text":"

Limit number of outgoing peers.

Parameters:

Name Type Description Default limit int

is the maximum number of outgoing peers.

required"},{"location":"api/daemon/#monero.MoneroDaemon.set_peer_ban","title":"set_peer_ban(ban)","text":"

Ban a peer node.

Parameters:

Name Type Description Default ban MoneroBan

contains information about a node to ban.

required"},{"location":"api/daemon/#monero.MoneroDaemon.set_peer_bans","title":"set_peer_bans(bans)","text":"

Ban peers nodes.

Parameters:

Name Type Description Default bans list[MoneroBan]

are bans to apply against peer nodes.

required"},{"location":"api/daemon/#monero.MoneroDaemon.set_upload_limit","title":"set_upload_limit(limit)","text":"

Set the upload bandwidth limit.

Parameters:

Name Type Description Default limit int

is the upload limit to set (-1 to reset to default).

required

Returns:

Type Description int

is the new upload limit after setting.

"},{"location":"api/daemon/#monero.MoneroDaemon.start_mining","title":"start_mining(address, num_threads, is_background, ignore_battery)","text":"

Start mining.

Parameters:

Name Type Description Default address str

is the address given miner rewards if the daemon mines a block.

required num_threads int

is the number of mining threads to run.

required is_background bool

specifies if the miner should run in the background or not.

required ignore_battery bool

specifies if the battery state (e.g. on laptop) should be ignored or not.

required"},{"location":"api/daemon/#monero.MoneroDaemon.stop","title":"stop()","text":"

Safely disconnect and shut down the daemon.

"},{"location":"api/daemon/#monero.MoneroDaemon.stop_mining","title":"stop_mining()","text":"

Stop mining.

"},{"location":"api/daemon/#monero.MoneroDaemon.submit_block","title":"submit_block(block_blob)","text":"

Submit a mined block to the network.

Parameters:

Name Type Description Default block_blob str

is the mined block to submit.

required"},{"location":"api/daemon/#monero.MoneroDaemon.submit_blocks","title":"submit_blocks(block_blobs)","text":"

Submit mined blocks to the network.

Parameters:

Name Type Description Default block_blobs list[str]

are the mined blocks to submit.

required"},{"location":"api/daemon/#monero.MoneroDaemon.submit_tx_hex","title":"submit_tx_hex(tx_hex, do_not_relay=False)","text":"

Submits a transaction to the daemon's pool.

Parameters:

Name Type Description Default tx_hex str

is the raw transaction hex to submit.

required

Returns:

Type Description MoneroSubmitTxResult

the submission results.

"},{"location":"api/daemon/#monero.MoneroDaemon.wait_for_next_block_header","title":"wait_for_next_block_header()","text":"

Get the header of the next block added to the chain.

Returns:

Type Description MoneroBlockHeader

the header of the next block added to the chain.

"},{"location":"api/daemon_rpc/","title":"Daemon RPC","text":""},{"location":"api/daemon_rpc/#monero.MoneroDaemonRpc","title":"MoneroDaemonRpc","text":"

Bases: MoneroDaemon

Implements a MoneroDaemon using monerod-rpc_.

.. _monerod-rpc: https://docs.getmonero.org/rpc-library/monerod-rpc/

"},{"location":"api/daemon_rpc/#monero.MoneroDaemonRpc.get_rpc_connection","title":"get_rpc_connection()","text":"

Get the daemon's RPC connection.

Returns:

Type Description MoneroRpcConnection

the daemon's rpc connection.

"},{"location":"api/daemon_rpc/#monero.MoneroDaemonRpc.is_connected","title":"is_connected()","text":"

Indicates if the client is connected to the daemon via RPC.

Returns:

Type Description bool

True if the client is connected to the daemon, False otherwise.

"},{"location":"api/serializable_struct/","title":"Serializable Struct","text":""},{"location":"api/serializable_struct/#monero.SerializableStruct","title":"SerializableStruct","text":"

Bases: ABC

Base struct which can be serialized.

"},{"location":"api/serializable_struct/#monero.SerializableStruct.serialize","title":"serialize()","text":"

Serializes the struct to a json string.

Returns:

Type Description str

the struct serialized to a json string.

"},{"location":"api/utils/","title":"Monero Utilities","text":""},{"location":"api/utils/#monero.MoneroUtils","title":"MoneroUtils","text":"

Collection of Monero utilities.

"},{"location":"api/utils/#monero.MoneroUtils.atomic_units_to_xmr","title":"atomic_units_to_xmr(amount_atomic_units) staticmethod","text":"

Convert atomic units to XMR.

Parameters:

Name Type Description Default amount_atomic_units int

amount in atomic units to convert to XMR.

required

Returns:

Type Description float

amount in XMR.

"},{"location":"api/utils/#monero.MoneroUtils.binary_blocks_to_json","title":"binary_blocks_to_json(bin) staticmethod","text":"

Deserialize blocks JSON string from binary format.

Parameters:

Name Type Description Default bin bytes

blocks JSON string in binary format.

required

Returns:

Type Description str

The deserialized blocks in JSON string format.

"},{"location":"api/utils/#monero.MoneroUtils.binary_to_dict","title":"binary_to_dict(bin) staticmethod","text":"

Deserialize a dictionary from binary format.

Parameters:

Name Type Description Default bin bytes

Dictionary in binary format.

required

Returns:

Type Description dict[Any, Any]

Deserialized dictionary.

"},{"location":"api/utils/#monero.MoneroUtils.binary_to_json","title":"binary_to_json(bin) staticmethod","text":"

Deserialize a JSON string from binary format.

Parameters:

Name Type Description Default bin bytes

JSON string in binary format.

required

Returns:

Type Description str

The deserialized JSON string.

"},{"location":"api/utils/#monero.MoneroUtils.configure_logging","title":"configure_logging(path, console) staticmethod","text":"

Initialize logging.

Parameters:

Name Type Description Default path str

the path to write logs to.

required console bool

specifies whether or not to write to the console.

required"},{"location":"api/utils/#monero.MoneroUtils.dict_to_binary","title":"dict_to_binary(dictionary) staticmethod","text":"

Converts a dictionary into binary format.

Parameters:

Name Type Description Default dictionary dict

The dictionary to convert in binary format.

required

Returns:

Type Description bytes

Binary format.

"},{"location":"api/utils/#monero.MoneroUtils.get_blocks_from_outputs","title":"get_blocks_from_outputs(outputs) staticmethod","text":"

Get distinct blocks from outputs.

Parameters:

Name Type Description Default outputs list[MoneroOutputWallet]

Outputs to get blocks from.

required

Returns:

Type Description list[MoneroBlock]

Distinct blocks obtained from outputs.

"},{"location":"api/utils/#monero.MoneroUtils.get_blocks_from_transfers","title":"get_blocks_from_transfers(transfers) staticmethod","text":"

Get distinct blocks from transfers.

Parameters:

Name Type Description Default transfers list[MoneroTransfer]

Transfers to get blocks from.

required

Returns:

Type Description list[MoneroBlock]

Distinct blocks obtained from transfers.

"},{"location":"api/utils/#monero.MoneroUtils.get_blocks_from_txs","title":"get_blocks_from_txs(txs) staticmethod","text":"

Get distinct blocks from transactions.

Parameters:

Name Type Description Default txs list[MoneroTxWallet]

Transactions to get blocks from.

required

Returns:

Type Description list[MoneroBlock]

Distinct blocks obtained from transactions.

"},{"location":"api/utils/#monero.MoneroUtils.get_integrated_address","title":"get_integrated_address(network_type, standard_address, payment_id='') staticmethod","text":"

Get an integrated address.

Parameters:

Name Type Description Default network_type MoneroNetworkType

is the network type of the integrated address.

required standard_address str

is the address to derive the integrated address from.

required payment_id str

optionally specifies the integrated address's payment id (defaults to random payment id).

''

Returns:

Type Description MoneroIntegratedAddress

the integrated address.

"},{"location":"api/utils/#monero.MoneroUtils.get_payment_uri","title":"get_payment_uri(config, network_type=MoneroNetworkType.MAINNET) staticmethod","text":"

Creates a payment URI from a tx configuration.

Parameters:

Name Type Description Default config MoneroTxConfig

specifies configuration for a payment URI.

required network_type MoneroNetworkType

address network type (optional).

MAINNET

Returns:

Type Description str

the payment URI.

"},{"location":"api/utils/#monero.MoneroUtils.get_ring_size","title":"get_ring_size() staticmethod","text":"

Get network-enforced ring size.

Returns:

Type Description int

network-enforced ring size.

"},{"location":"api/utils/#monero.MoneroUtils.get_version","title":"get_version() staticmethod","text":"

Get the version of the monero-python library.

Returns:

Type Description str

the version of this monero-python library

"},{"location":"api/utils/#monero.MoneroUtils.is_valid_address","title":"is_valid_address(address, network_type) staticmethod","text":"

Determine if the given address is valid.

Parameters:

Name Type Description Default address str

is the address to validate.

required network_type MoneroNetworkType

is the address's network type.

required

Returns:

Type Description bool

True if the address is valid, False otherwise.

"},{"location":"api/utils/#monero.MoneroUtils.is_valid_language","title":"is_valid_language(language) staticmethod","text":"

Indicates if the given language is valid.

Parameters:

Name Type Description Default language str

is the language to validate

required

Returns:

Type Description bool

True if the language is valid, False otherwise.

"},{"location":"api/utils/#monero.MoneroUtils.is_valid_mnemonic","title":"is_valid_mnemonic(mnemonic, language='') staticmethod","text":"

Indicates if a mnemonic is valid.

Parameters:

Name Type Description Default mnemonic str

is the mnemonic to validate.

required language str

is the mnemonic expected language.

''

Returns:

Type Description bool

True if the mnemonic is valid, False otherwise.

"},{"location":"api/utils/#monero.MoneroUtils.is_valid_payment_id","title":"is_valid_payment_id(payment_id) staticmethod","text":"

Indicates if a payment id is valid.

Parameters:

Name Type Description Default payment_id str

is the payment id to validate.

required

Returns:

Type Description bool

True if the payment id is valid, False otherwise.

"},{"location":"api/utils/#monero.MoneroUtils.is_valid_private_spend_key","title":"is_valid_private_spend_key(private_spend_key) staticmethod","text":"

Indicates if a private spend key is valid.

Parameters:

Name Type Description Default private_spend_key str

is the private spend key to validate.

required

Returns:

Type Description bool

True if the private spend key is valid, False otherwise.

"},{"location":"api/utils/#monero.MoneroUtils.is_valid_private_view_key","title":"is_valid_private_view_key(private_view_key) staticmethod","text":"

Indicates if a private view key is valid.

Parameters:

Name Type Description Default private_view_key str

is the private view key to validate.

required

Returns:

Type Description bool

True if the private view key is valid, False otherwise.

"},{"location":"api/utils/#monero.MoneroUtils.is_valid_public_spend_key","title":"is_valid_public_spend_key(public_spend_key) staticmethod","text":"

Indicates if a public spend key is valid.

Parameters:

Name Type Description Default public_spend_key str

is the public spend key to validate.

required

Returns:

Type Description bool

True if the public spend key is valid, False otherwise.

"},{"location":"api/utils/#monero.MoneroUtils.is_valid_public_view_key","title":"is_valid_public_view_key(public_view_key) staticmethod","text":"

Indicates if a public view key is valid.

Parameters:

Name Type Description Default public_view_key str

is the public view key to validate.

required

Returns:

Type Description bool

True if the public view key is valid, False otherwise.

"},{"location":"api/utils/#monero.MoneroUtils.json_to_binary","title":"json_to_binary(json) staticmethod","text":"

Convert a JSON string into binary format.

Returns:

Type Description bytes

Binary format.

"},{"location":"api/utils/#monero.MoneroUtils.log_debug","title":"log_debug(message) staticmethod","text":"

Log debug message.

Parameters:

Name Type Description Default message str

the message to log.

required"},{"location":"api/utils/#monero.MoneroUtils.log_error","title":"log_error(message) staticmethod","text":"

Log error message.

Parameters:

Name Type Description Default message str

the message to log.

required"},{"location":"api/utils/#monero.MoneroUtils.log_info","title":"log_info(message) staticmethod","text":"

Log info message.

Parameters:

Name Type Description Default message str

the message to log.

required"},{"location":"api/utils/#monero.MoneroUtils.log_trace","title":"log_trace(message) staticmethod","text":"

Log trace message.

Parameters:

Name Type Description Default message str

the message to log.

required"},{"location":"api/utils/#monero.MoneroUtils.log_warning","title":"log_warning(message) staticmethod","text":"

Log warning message.

Parameters:

Name Type Description Default message str

the message to log.

required"},{"location":"api/utils/#monero.MoneroUtils.set_log_categories","title":"set_log_categories(categories) staticmethod","text":"

Set the library's log categories.

Parameters:

Name Type Description Default categories str

the library's log categories to set.

required"},{"location":"api/utils/#monero.MoneroUtils.set_log_level","title":"set_log_level(loglevel) staticmethod","text":"

Set the library's log level with 0 being least verbose.

Parameters:

Name Type Description Default loglevel int

the library's log level.

required"},{"location":"api/utils/#monero.MoneroUtils.validate_address","title":"validate_address(address, network_type) staticmethod","text":"

Validates the given address.

Parameters:

Name Type Description Default address str

is the address to validate.

required network_type MoneroNetworkType

is the address's network type.

required"},{"location":"api/utils/#monero.MoneroUtils.validate_mnemonic","title":"validate_mnemonic(mnemonic, language='') staticmethod","text":"

Validates the given mnemonic phrase.

Parameters:

Name Type Description Default mnemonic str

is the mnemonic to validate.

required language str

is the mnemonic expected language.

''

Raises:

Type Description MoneroError

if the given mnemonic is invalid.

"},{"location":"api/utils/#monero.MoneroUtils.validate_payment_id","title":"validate_payment_id(payment_id) staticmethod","text":"

Validate a payment id.

Parameters:

Name Type Description Default payment_id str

is the payment id to validate.

required

Raises:

Type Description MoneroError

if the given payment id is invalid.

"},{"location":"api/utils/#monero.MoneroUtils.validate_private_spend_key","title":"validate_private_spend_key(private_spend_key) staticmethod","text":"

Validate a private spend key.

Parameters:

Name Type Description Default private_spend_key str

is the private spend key to validate.

required

Raises:

Type Description MoneroError

if the given private spend key is invalid.

"},{"location":"api/utils/#monero.MoneroUtils.validate_private_view_key","title":"validate_private_view_key(private_view_key) staticmethod","text":"

Validate a private view key.

Parameters:

Name Type Description Default private_view_key str

is the private view key to validate.

required

Raises:

Type Description MoneroError

if the given private view key is invalid.

"},{"location":"api/utils/#monero.MoneroUtils.validate_public_spend_key","title":"validate_public_spend_key(public_spend_key) staticmethod","text":"

Validate a public spend key.

Parameters:

Name Type Description Default public_spend_key str

is the public spend key to validate.

required

Raises:

Type Description MoneroError

if the given public spend key is invalid.

"},{"location":"api/utils/#monero.MoneroUtils.validate_public_view_key","title":"validate_public_view_key(public_view_key) staticmethod","text":"

Validate a public view key.

Parameters:

Name Type Description Default public_view_key str

is the public view key to validate.

required

Raises:

Type Description MoneroError

if the given public view key is invalid.

"},{"location":"api/utils/#monero.MoneroUtils.xmr_to_atomic_units","title":"xmr_to_atomic_units(amount_xmr) staticmethod","text":"

Convert XMR to atomic units.

Parameters:

Name Type Description Default amount_xmr float

amount in XMR to convert to atomic units.

required

Returns:

Type Description int

amount in atomic units.

"},{"location":"api/wallet/","title":"Wallet Interface","text":""},{"location":"api/wallet/#monero.MoneroWallet","title":"MoneroWallet","text":"

Base wallet with default implementations.

"},{"location":"api/wallet/#monero.MoneroWallet.DEFAULT_LANGUAGE","title":"DEFAULT_LANGUAGE: str instance-attribute","text":"

Default Monero wallet seed language.

"},{"location":"api/wallet/#monero.MoneroWallet.__init__","title":"__init__()","text":"

Initialize a Monero wallet.

"},{"location":"api/wallet/#monero.MoneroWallet.add_address_book_entry","title":"add_address_book_entry(address, description)","text":"

Add an address book entry.

Parameters:

Name Type Description Default address str

is the entry address.

required description str

is the entry description (optional).

required

Returns:

Type Description int

the index of the added entry.

"},{"location":"api/wallet/#monero.MoneroWallet.add_listener","title":"add_listener(listener)","text":"

Register a listener receive wallet notifications.

Parameters:

Name Type Description Default listener MoneroWalletListener

is the listener to receive wallet notifications.

required"},{"location":"api/wallet/#monero.MoneroWallet.change_password","title":"change_password(old_password, new_password)","text":"

Change the wallet password.

Parameters:

Name Type Description Default old_password str

is the wallet's old password.

required new_password str

is the wallet's new password.

required"},{"location":"api/wallet/#monero.MoneroWallet.check_reserve_proof","title":"check_reserve_proof(address, message, signature)","text":"

Proves a wallet has a disposable reserve using a signature.

Parameters:

Name Type Description Default address str

is the public wallet address.

required message str

is a message included with the signature to further authenticate the proof (optional).

required signature str

is the reserve proof signature to check.

required

Returns:

Type Description MoneroCheckReserve

the result of checking the signature proof.

"},{"location":"api/wallet/#monero.MoneroWallet.check_spend_proof","title":"check_spend_proof(tx_hash, message, signature)","text":"

Prove a spend using a signature. Unlike proving a transaction, it does not require the destination public address.

Parameters:

Name Type Description Default tx_hash str

specifies the transaction to prove.

required message str

is a message included with the signature to further authenticate the proof (optional).

required signature str

is the transaction signature to confirm.

required

Returns:

Type Description bool

True if the signature is good, False otherwise.

"},{"location":"api/wallet/#monero.MoneroWallet.check_tx_key","title":"check_tx_key(tx_hash, tx_key, address)","text":"

Check a transaction in the blockchain with its secret key.

Parameters:

Name Type Description Default tx_hash str

specifies the transaction to check.

required tx_key str

is the transaction's secret key.

required address str

is the destination public address of the transaction.

required

Returns:

Type Description MoneroCheckTx

the result of the check.

"},{"location":"api/wallet/#monero.MoneroWallet.check_tx_proof","title":"check_tx_proof(tx_hash, address, message, signature)","text":"

Prove a transaction by checking its signature.

Parameters:

Name Type Description Default tx_hash str

specifies the transaction to prove.

required address str

is the destination public address of the transaction.

required message str

is a message included with the signature to further authenticate the proof (optional).

required signature str

is the transaction signature to confirm.

required

Returns:

Type Description MoneroCheckTx

the result of the check.

"},{"location":"api/wallet/#monero.MoneroWallet.close","title":"close(save=False)","text":"

Optionally save then close the wallet.

Parameters:

Name Type Description Default save bool

specifies if the wallet should be saved before being closed (default False).

False"},{"location":"api/wallet/#monero.MoneroWallet.create_account","title":"create_account(label='')","text":"

Create a new account with a label for the first subaddress.

Parameters:

Name Type Description Default label str

specifies the label for the account's first subaddress (optional).

''

Returns:

Type Description MoneroAccount

the created account.

"},{"location":"api/wallet/#monero.MoneroWallet.create_subaddress","title":"create_subaddress(account_idx, label='')","text":"

Create a subaddress within an account.

Parameters:

Name Type Description Default account_idx int

specifies the index of the account to create the subaddress within.

required label str

specifies the the label for the subaddress (defaults to empty string).

''

Returns:

Type Description MoneroSubaddress

the created subaddress.

"},{"location":"api/wallet/#monero.MoneroWallet.create_tx","title":"create_tx(config)","text":"

Create a transaction to transfer funds from this wallet.

Parameters:

Name Type Description Default config MoneroTxConfig

configures the transaction to create.

required

Returns:

Type Description MoneroTxWallet

the created transaction.

"},{"location":"api/wallet/#monero.MoneroWallet.create_txs","title":"create_txs(config)","text":"

Create one or more transactions to transfer funds from this wallet.

Parameters:

Name Type Description Default config MoneroTxConfig

configures the transactions to create.

required

Returns:

Type Description list[MoneroTxWallet]

the created transactions.

"},{"location":"api/wallet/#monero.MoneroWallet.decode_integrated_address","title":"decode_integrated_address(integrated_address)","text":"

Decode an integrated address to get its standard address and payment id.

Parameters:

Name Type Description Default integrated_address str

is an integrated address to decode.

required

Returns:

Type Description MoneroIntegratedAddress

the decoded integrated address including standard address and payment id.

"},{"location":"api/wallet/#monero.MoneroWallet.delete_address_book_entry","title":"delete_address_book_entry(index)","text":"

Delete an address book entry.

Parameters:

Name Type Description Default index int

is the index of the entry to delete.

required"},{"location":"api/wallet/#monero.MoneroWallet.describe_multisig_tx_set","title":"describe_multisig_tx_set(multisig_tx_hex)","text":"

Describe a tx set containing unsigned or multisig tx hex to a new tx set containing structured transactions.

Parameters:

Name Type Description Default multisig_tx_hex str

multisig tx hex.

required

Returns:

Type Description MoneroTxSet

the tx set containing structured transactions.

"},{"location":"api/wallet/#monero.MoneroWallet.describe_tx_set","title":"describe_tx_set(tx_set)","text":"

Describes a tx set containing unsigned or multisig tx hex to a new tx set containing structured transactions.

Parameters:

Name Type Description Default tx_set MoneroTxSet

is a tx set containing unsigned or multisig tx hex.

required

Returns:

Type Description MoneroTxSet

the tx set containing structured transactions.

"},{"location":"api/wallet/#monero.MoneroWallet.describe_unsigned_tx_set","title":"describe_unsigned_tx_set(unsigned_tx_hex)","text":"

Describe a tx set from unsigned tx hex.

Parameters:

Name Type Description Default unsigned_tx_hex str

unsigned tx hex.

required

Returns:

Type Description MoneroTxSet

the tx set containing structured transactions.

"},{"location":"api/wallet/#monero.MoneroWallet.edit_address_book_entry","title":"edit_address_book_entry(index, set_address, address, set_description, description)","text":"

Edit an address book entry.

Parameters:

Name Type Description Default index int

is the index of the address book entry to edit.

required set_address bool

specifies if the address should be updated.

required address str

is the updated address.

required set_description bool

specifies if the description should be updated.

required description str

is the updated description.

required"},{"location":"api/wallet/#monero.MoneroWallet.exchange_multisig_keys","title":"exchange_multisig_keys(multisig_hexes, password)","text":"

Exchange multisig hex with participants in a M/N multisig wallet.

This process must be repeated with participants exactly N-M times.

Parameters:

Name Type Description Default multisig_hexes list[str]

are multisig hex from each participant.

required password str

is the wallet's password (TODO monero-project: redundant? wallet is created with password).

required

Returns:

Type Description MoneroMultisigInitResult

the result which has the multisig's address xor this wallet's multisig hex to share with participants if not done.

"},{"location":"api/wallet/#monero.MoneroWallet.export_key_images","title":"export_key_images(all=False)","text":"

Export signed key images.

Parameters:

Name Type Description Default all bool

export all key images if True, else export key images since the last export.

False

Returns:

Type Description MoneroKeyImageExportResult

the wallet's signed key images.

"},{"location":"api/wallet/#monero.MoneroWallet.export_multisig_hex","title":"export_multisig_hex()","text":"

Export this wallet's multisig info as hex for other participants.

Returns:

Type Description str

this wallet's multisig info as hex for other participants.

"},{"location":"api/wallet/#monero.MoneroWallet.export_outputs","title":"export_outputs(all=False)","text":"

Export outputs in hex format.

Parameters:

Name Type Description Default all bool

export all outputs if True, else export outputs since the last export.

False

Returns:

Type Description str

outputs in hex format, empty string if no outputs.

"},{"location":"api/wallet/#monero.MoneroWallet.freeze_output","title":"freeze_output(key_image)","text":"

Freeze an output.

Parameters:

Name Type Description Default key_image str

key image of the output to freeze.

required"},{"location":"api/wallet/#monero.MoneroWallet.get_account_tags","title":"get_account_tags()","text":"

Return all account tags.

Returns:

Type Description list[MoneroAccountTag]

the wallet's account tags.

"},{"location":"api/wallet/#monero.MoneroWallet.get_address","title":"get_address(account_idx, subaddress_idx)","text":"

Get the address of a specific subaddress.

Parameters:

Name Type Description Default account_idx int

specifies the account index of the address's subaddress.

required subaddress_idx int

specifies the subaddress index within the account.

required

Returns:

Type Description str

the receive address of the specified subaddress.

"},{"location":"api/wallet/#monero.MoneroWallet.get_address_index","title":"get_address_index(address)","text":"

Get the account and subaddress index of the given address.

Parameters:

Name Type Description Default address str

is the address to get the account and subaddress index from.

required

Returns:

Type Description MoneroSubaddress

the account and subaddress indices.

Raises:

Type Description MoneroError

exception if address is not a wallet address.

"},{"location":"api/wallet/#monero.MoneroWallet.get_attribute","title":"get_attribute(key)","text":"

Get an attribute.

Parameters:

Name Type Description Default key str

is the attribute to get the value of.

required

Returns:

Type Description str

attribute's value.

"},{"location":"api/wallet/#monero.MoneroWallet.get_daemon_connection","title":"get_daemon_connection()","text":"

Get the wallet's daemon connection.

Returns:

Type Description MoneroRpcConnection | None

the wallet's daemon connection.

"},{"location":"api/wallet/#monero.MoneroWallet.get_daemon_height","title":"get_daemon_height()","text":"

Get the height that the wallet's daemon is synced to.

Returns:

Type Description int

the height that the wallet's daemon is synced to.

"},{"location":"api/wallet/#monero.MoneroWallet.get_daemon_max_peer_height","title":"get_daemon_max_peer_height()","text":"

Get the maximum height of the peers the wallet's daemon is connected to.

Returns:

Type Description int

the maximum height of the peers the wallet's daemon is connected to.

"},{"location":"api/wallet/#monero.MoneroWallet.get_default_fee_priority","title":"get_default_fee_priority()","text":"

Get the current default fee priority (unimportant, normal, elevated, etc).

Returns:

Type Description MoneroTxPriority

the current fee priority.

"},{"location":"api/wallet/#monero.MoneroWallet.get_height","title":"get_height()","text":"

Get the height of the last block processed by the wallet (its index + 1).

Returns:

Type Description int

the height of the last block processed by the wallet.

"},{"location":"api/wallet/#monero.MoneroWallet.get_height_by_date","title":"get_height_by_date(year, month, day)","text":"

Get the blockchain's height by date as a conservative estimate for scanning.

Parameters:

Name Type Description Default year int

year of the height to get.

required month int

month of the height to get as a number between 1 and 12.

required day int

day of the height to get as a number between 1 and 31.

required

Returns:

Type Description int

the blockchain's approximate height at the given date.

"},{"location":"api/wallet/#monero.MoneroWallet.get_integrated_address","title":"get_integrated_address(standard_address='', payment_id='')","text":"

Get an integrated address from a standard address and a payment id.

Parameters:

Name Type Description Default standard_address str

is the integrated addresse's standard address (defaults to wallet's primary address).

'' payment_id str

is the integrated addresse's payment id (defaults to randomly generating new payment id).

''

Returns:

Type Description MoneroIntegratedAddress

the integrated address.

"},{"location":"api/wallet/#monero.MoneroWallet.get_listeners","title":"get_listeners()","text":"

Get the listeners registered with the wallet.

Returns:

Type Description list[MoneroWalletListener]

List of listener registered with the wallet.

"},{"location":"api/wallet/#monero.MoneroWallet.get_multisig_info","title":"get_multisig_info()","text":"

Get multisig info about this wallet.

Returns:

Type Description MoneroMultisigInfo

multisig info about this wallet.

"},{"location":"api/wallet/#monero.MoneroWallet.get_network_type","title":"get_network_type()","text":"

Get the wallet's network type (mainnet, testnet, or stagenet).

Returns:

Type Description MoneroNetworkType

the wallet's network type.

"},{"location":"api/wallet/#monero.MoneroWallet.get_new_key_images_from_last_import","title":"get_new_key_images_from_last_import()","text":"

Get new key images from the last imported outputs.

Returns:

Type Description list[MoneroKeyImage]

the key images from the last imported outputs.

"},{"location":"api/wallet/#monero.MoneroWallet.get_path","title":"get_path()","text":"

Get the path of this wallet's file on disk.

Returns:

Type Description str

the path of this wallet's file on disk.

"},{"location":"api/wallet/#monero.MoneroWallet.get_payment_uri","title":"get_payment_uri(config)","text":"

Creates a payment URI from a tx configuration.

Parameters:

Name Type Description Default config MoneroTxConfig

specifies configuration for a potential tx.

required

Returns:

Type Description str

is the payment uri.

"},{"location":"api/wallet/#monero.MoneroWallet.get_primary_address","title":"get_primary_address()","text":"

Get the wallet's primary address.

Returns:

Type Description str

the wallet's primary address.

"},{"location":"api/wallet/#monero.MoneroWallet.get_private_spend_key","title":"get_private_spend_key()","text":"

Get the wallet's private spend key.

Returns:

Type Description str

the wallet's private spend key.

"},{"location":"api/wallet/#monero.MoneroWallet.get_private_view_key","title":"get_private_view_key()","text":"

Get the wallet's private view key.

Returns:

Type Description str

the wallet's private view key.

"},{"location":"api/wallet/#monero.MoneroWallet.get_public_spend_key","title":"get_public_spend_key()","text":"

Get the wallet's public spend key.

Returns:

Type Description str

the wallet's public spend key.

"},{"location":"api/wallet/#monero.MoneroWallet.get_public_view_key","title":"get_public_view_key()","text":"

Get the wallet's public view key.

Returns:

Type Description str

the wallet's public view key.

"},{"location":"api/wallet/#monero.MoneroWallet.get_reserve_proof_account","title":"get_reserve_proof_account(account_idx, amount, message)","text":"

Generate a signature to prove an available amount in an account.

Parameters:

Name Type Description Default account_idx int

specifies the account to prove ownership of the amount.

required amount int

is the minimum amount to prove as available in the account.

required message str

is a message to include with the signature to further authenticate the proof (optional).

required

Returns:

Type Description str

the reserve proof signature.

"},{"location":"api/wallet/#monero.MoneroWallet.get_reserve_proof_wallet","title":"get_reserve_proof_wallet(message)","text":"

Generate a signature to prove the entire balance of the wallet.

Parameters:

Name Type Description Default message str

is a message included with the signature to further authenticate the proof (optional).

required

Returns:

Type Description str

the reserve proof signature.

"},{"location":"api/wallet/#monero.MoneroWallet.get_restore_height","title":"get_restore_height()","text":"

Get the height of the first block that the wallet scans.

Returns:

Type Description int

the height of the first block that the wallet scans.

"},{"location":"api/wallet/#monero.MoneroWallet.get_seed","title":"get_seed()","text":"

Get the wallet's mnemonic phrase or seed.

Returns:

Type Description str

the wallet's mnemonic phrase or seed.

"},{"location":"api/wallet/#monero.MoneroWallet.get_seed_language","title":"get_seed_language()","text":"

Get the language of the wallet's mnemonic phrase or seed.

Returns:

Type Description str

the language of the wallet's mnemonic phrase or seed.

"},{"location":"api/wallet/#monero.MoneroWallet.get_spend_proof","title":"get_spend_proof(tx_hash, message='')","text":"

Generate a signature to prove a spend. Unlike proving a transaction, it does not require the destination public address.

Parameters:

Name Type Description Default tx_hash str

specifies the transaction to prove.

required message str

is a message to include with the signature to further authenticate the proof (optional).

''

Returns:

Type Description str

the transaction signature.

"},{"location":"api/wallet/#monero.MoneroWallet.get_subaddress","title":"get_subaddress(account_idx, subaddress_idx)","text":"

Get a subaddress.

Parameters:

Name Type Description Default account_idx int

specifies the index of the subaddress's account.

required subaddress_idx int

specifies index of the subaddress within the account.

required

Returns:

Type Description MoneroSubaddress

the retrieved subaddress.

"},{"location":"api/wallet/#monero.MoneroWallet.get_tx","title":"get_tx(tx_hash)","text":"

Get single wallet transaction by hash.

Parameters:

Name Type Description Default tx_hash str

Transaction hash.

required

Returns:

Type Description MoneroTxWallet | None

wallet transaction.

"},{"location":"api/wallet/#monero.MoneroWallet.get_tx_key","title":"get_tx_key(tx_hash)","text":"

Get a transaction's secret key from its hash.

Parameters:

Name Type Description Default tx_hash str

is the transaction's hash.

required

Returns:

Type Description str

is the transaction's secret key.

"},{"location":"api/wallet/#monero.MoneroWallet.get_tx_note","title":"get_tx_note(tx_hash)","text":"

Get a transaction note.

Parameters:

Name Type Description Default tx_hash str

specifies the transaction to get the note of.

required

Returns:

Type Description str

the tx note.

"},{"location":"api/wallet/#monero.MoneroWallet.get_tx_notes","title":"get_tx_notes(tx_hashes)","text":"

Get notes for multiple transactions.

Parameters:

Name Type Description Default tx_hashes list[str]

identify the transactions to get notes for.

required

Returns:

Type Description list[str]

notes for the transactions.

"},{"location":"api/wallet/#monero.MoneroWallet.get_tx_proof","title":"get_tx_proof(tx_hash, address, message='')","text":"

Get a transaction signature to prove it.

Parameters:

Name Type Description Default tx_hash str

specifies the transaction to prove.

required address str

is the destination public address of the transaction.

required message str

is a message to include with the signature to further authenticate the proof (optional).

''

Returns:

Type Description str

the transaction signature.

"},{"location":"api/wallet/#monero.MoneroWallet.get_version","title":"get_version()","text":"

Get the wallet's version.

Returns:

Type Description MoneroVersion

the wallet's version.

"},{"location":"api/wallet/#monero.MoneroWallet.import_key_images","title":"import_key_images(key_images, offset=0)","text":"

Import signed key images and verify their spent status.

Parameters:

Name Type Description Default key_images list[MoneroKeyImage]

are key images to import and verify (requires hex and signature).

required offset int

offset of the first key image among the wallet's outputs.

0

Returns:

Type Description MoneroKeyImageImportResult

results of the import.

"},{"location":"api/wallet/#monero.MoneroWallet.import_multisig_hex","title":"import_multisig_hex(multisig_hexes, refresh_after_import=True)","text":"

Import multisig info as hex from other participants.

Note: If the daemon is not trusted, this method will not automatically update the spent status after importing peer multisig hex.

Parameters:

Name Type Description Default multisig_hexes list[str]

are multisig hex from each participant.

required refresh_after_import bool

refresh wallet after import.

True

Returns:

Type Description int

the number of outputs signed with the given multisig hex.

"},{"location":"api/wallet/#monero.MoneroWallet.import_outputs","title":"import_outputs(outputs_hex)","text":"

Import outputs in hex format.

Parameters:

Name Type Description Default outputs_hex str

are outputs in hex format.

required

Returns:

Type Description int

the number of outputs imported.

"},{"location":"api/wallet/#monero.MoneroWallet.is_closed","title":"is_closed()","text":"

Indicates if the wallet is closed.

Returns:

Type Description bool

True if the wallet is closed, False otherwise.

"},{"location":"api/wallet/#monero.MoneroWallet.is_connected_to_daemon","title":"is_connected_to_daemon()","text":"

Indicates if the wallet is connected a daemon.

Returns:

Type Description bool

True if the wallet is connected to daemon, False otherwise.

"},{"location":"api/wallet/#monero.MoneroWallet.is_daemon_trusted","title":"is_daemon_trusted()","text":"

Indicates if the daemon is trusted or untrusted.

Returns:

Type Description bool

True if the daemon is trusted, False otherwise.

"},{"location":"api/wallet/#monero.MoneroWallet.is_multisig","title":"is_multisig()","text":"

Indicates if this wallet is a multisig wallet.

Returns:

Type Description bool

True if this is a multisig wallet, False otherwise.

"},{"location":"api/wallet/#monero.MoneroWallet.is_multisig_import_needed","title":"is_multisig_import_needed()","text":"

Indicates if importing multisig data is needed for returning a correct balance.

Returns:

Type Description bool

True if importing multisig data is needed for returning a correct balance, False otherwise.

"},{"location":"api/wallet/#monero.MoneroWallet.is_output_frozen","title":"is_output_frozen(key_image)","text":"

Check if an output is frozen.

Parameters:

Name Type Description Default key_image str

key image of the output to check if frozen.

required

Returns:

Type Description bool

True if the output is frozen, False otherwise.

"},{"location":"api/wallet/#monero.MoneroWallet.is_synced","title":"is_synced()","text":"

Indicates if the wallet is synced with the daemon.

Returns:

Type Description bool

True if the wallet is synced with the daemon, False otherwise.

"},{"location":"api/wallet/#monero.MoneroWallet.is_view_only","title":"is_view_only()","text":"

Indicates if the wallet is view-only, meaning it does have the private spend key and can therefore only observe incoming outputs.

Returns:

Type Description bool

True if the wallet is view-only, False otherwise.

"},{"location":"api/wallet/#monero.MoneroWallet.make_multisig","title":"make_multisig(multisig_hexes, threshold, password)","text":"

Make this wallet multisig by importing multisig hex from participants.

Parameters:

Name Type Description Default multisig_hexes list[str]

are multisig hex from each participant.

required threshold int

is the number of signatures needed to sign transfers.

required password str

is the wallet password.

required

Returns:

Type Description str

this wallet's multisig hex to share with participants.

"},{"location":"api/wallet/#monero.MoneroWallet.move_to","title":"move_to(path, password)","text":"

Move the wallet from its current path to the given path.

Parameters:

Name Type Description Default path str

is the new wallet's path.

required password str

is the new wallet's password.

required"},{"location":"api/wallet/#monero.MoneroWallet.parse_payment_uri","title":"parse_payment_uri(uri)","text":"

Parses a payment URI to a tx configuration.

Parameters:

Name Type Description Default uri str

is the payment uri to parse.

required

Returns:

Type Description MoneroTxConfig

the tx configuration parsed from the uri.

"},{"location":"api/wallet/#monero.MoneroWallet.prepare_multisig","title":"prepare_multisig()","text":"

Get multisig info as hex to share with participants to begin creating a multisig wallet.

Returns:

Type Description str

this wallet's multisig hex to share with participants.

"},{"location":"api/wallet/#monero.MoneroWallet.remove_listener","title":"remove_listener(listener)","text":"

Unregister a listener to receive wallet notifications.

Parameters:

Name Type Description Default listener MoneroWalletListener

is the listener to unregister.

required"},{"location":"api/wallet/#monero.MoneroWallet.rescan_blockchain","title":"rescan_blockchain()","text":"

Rescan the blockchain from scratch, losing any information which cannot be recovered from the blockchain itself.

WARNING: This method discards local wallet data like destination addresses, tx secret keys, tx notes, etc.

"},{"location":"api/wallet/#monero.MoneroWallet.rescan_spent","title":"rescan_spent()","text":"

Rescan the blockchain for spent outputs.

Note: this can only be called with a trusted daemon.

Example use case: peer multisig hex is import when connected to an untrusted daemon, so the wallet will not rescan spent outputs. Then the wallet connects to a trusted daemon. This method should be manually invoked to rescan outputs.

"},{"location":"api/wallet/#monero.MoneroWallet.save","title":"save()","text":"

Save the wallet at its current path.

"},{"location":"api/wallet/#monero.MoneroWallet.scan_txs","title":"scan_txs(tx_hashes)","text":"

Scan transactions by their hash/id.

Parameters:

Name Type Description Default tx_hashes list[str]

tx hashes to scan.

required"},{"location":"api/wallet/#monero.MoneroWallet.set_account_label","title":"set_account_label(account_idx, label)","text":"

Set a human-readable description for an account.

Parameters:

Name Type Description Default account_idx int

account index.

required label str

is the label to set.

required"},{"location":"api/wallet/#monero.MoneroWallet.set_account_tag_label","title":"set_account_tag_label(tag, label)","text":"

Sets a human-readable description for a tag.

Parameters:

Name Type Description Default tag str

is the tag to set a description for.

required label str

is the label to set for the tag.

required"},{"location":"api/wallet/#monero.MoneroWallet.set_attribute","title":"set_attribute(key, val)","text":"

Set an arbitrary attribute.

Parameters:

Name Type Description Default key str

is the attribute key.

required val str

is the attribute value.

required"},{"location":"api/wallet/#monero.MoneroWallet.set_restore_height","title":"set_restore_height(restore_height)","text":"

Set the height of the first block that the wallet scans.

Parameters:

Name Type Description Default restore_height int

is the height of the first block that the wallet scans.

required"},{"location":"api/wallet/#monero.MoneroWallet.set_subaddress_label","title":"set_subaddress_label(account_idx, subaddress_idx, label='')","text":"

Set a subaddress label.

Parameters:

Name Type Description Default account_idx int

index of the account to set the label for.

required subaddress_idx int

index of the subaddress to set the label for.

required label str

the label to set (default '').

''"},{"location":"api/wallet/#monero.MoneroWallet.set_tx_note","title":"set_tx_note(tx_hash, note)","text":"

Set a note for a specific transaction.

Parameters:

Name Type Description Default tx_hash str

specifies the transaction.

required note str

specifies the note.

required"},{"location":"api/wallet/#monero.MoneroWallet.set_tx_notes","title":"set_tx_notes(tx_hashes, notes)","text":"

Set notes for multiple transactions.

Parameters:

Name Type Description Default tx_hashes list[str]

specify the transactions to set notes for.

required notes list[str]

are the notes to set for the transactions.

required"},{"location":"api/wallet/#monero.MoneroWallet.sign_message","title":"sign_message(msg, signature_type, account_idx=0, subaddress_idx=0)","text":"

Sign a message.

Parameters:

Name Type Description Default msg str

the message to sign.

required signature_type MoneroMessageSignatureType

sign with spend key or spend key.

required account_idx int

the account index of the message signature (default 0).

0 subaddress_idx int

the subaddress index of the message signature (default 0).

0

Returns:

Type Description str

the message signature.

"},{"location":"api/wallet/#monero.MoneroWallet.sign_multisig_tx_hex","title":"sign_multisig_tx_hex(multisig_tx_hex)","text":"

Sign previously created multisig transactions as represented by hex.

Parameters:

Name Type Description Default multisig_tx_hex str

is the hex shared among the multisig transactions when they were created.

required

Returns:

Type Description MoneroMultisigSignResult

the result of signing the multisig transactions.

"},{"location":"api/wallet/#monero.MoneroWallet.sign_txs","title":"sign_txs(unsigned_tx_hex)","text":"

Sign unsigned transactions from a view-only wallet.

Parameters:

Name Type Description Default unsigned_tx_hex str

is unsigned transaction hex from when the transactions were created.

required

Returns:

Type Description MoneroTxSet

the signed transaction set.

"},{"location":"api/wallet/#monero.MoneroWallet.start_mining","title":"start_mining(num_threads=None, background_mining=None, ignore_battery=None)","text":"

Start mining.

Parameters:

Name Type Description Default num_threads Optional[int]

is the number of threads created for mining (default None).

None background_mining Optional[bool]

specifies if mining should occur in the background (default None).

None ignore_battery Optional[bool]

specifies if the battery should be ignored for mining (default None).

None"},{"location":"api/wallet/#monero.MoneroWallet.start_syncing","title":"start_syncing(sync_period_in_ms=10000)","text":"

Start background synchronizing with a maximum period between syncs.

Parameters:

Name Type Description Default sync_period_in_ms int

maximum period between syncs in milliseconds.

10000"},{"location":"api/wallet/#monero.MoneroWallet.stop_mining","title":"stop_mining()","text":"

Stop mining.

"},{"location":"api/wallet/#monero.MoneroWallet.stop_syncing","title":"stop_syncing()","text":"

Stop the asynchronous thread to continuously synchronize the wallet with the daemon.

"},{"location":"api/wallet/#monero.MoneroWallet.submit_multisig_tx_hex","title":"submit_multisig_tx_hex(signed_multisig_tx_hex)","text":"

Submit signed multisig transactions as represented by a hex string.

Parameters:

Name Type Description Default signed_multisig_tx_hex str

is the signed multisig hex returned from sign_multisig_txs().

required

Returns:

Type Description list[str]

the resulting transaction hashes.

"},{"location":"api/wallet/#monero.MoneroWallet.submit_txs","title":"submit_txs(signed_tx_hex)","text":"

Submit signed transactions from a view-only wallet.

Parameters:

Name Type Description Default signed_tx_hex str

is signed transaction hex from sign_txs().

required

Returns:

Type Description list[str]

the resulting transaction hashes.

"},{"location":"api/wallet/#monero.MoneroWallet.sweep_dust","title":"sweep_dust(relay=False)","text":"

Sweep all unmixable dust outputs back to the wallet to make them easier to spend and mix.

Parameters:

Name Type Description Default relay bool

specifies if the resulting transaction should be relayed (default False).

False

Returns:

Type Description list[MoneroTxWallet]

the created transactions.

"},{"location":"api/wallet/#monero.MoneroWallet.sweep_output","title":"sweep_output(config)","text":"

Sweep an output with a given key image.

Parameters:

Name Type Description Default config MoneroTxConfig

configures the sweep transaction.

required

Returns:

Type Description MoneroTxWallet

the created transaction.

"},{"location":"api/wallet/#monero.MoneroWallet.sweep_unlocked","title":"sweep_unlocked(config)","text":"

Sweep unlocked funds according to the given config.

Parameters:

Name Type Description Default config MoneroTxConfig

is the sweep configuration.

required

Returns:

Type Description list[MoneroTxWallet]

the created transactions.

"},{"location":"api/wallet/#monero.MoneroWallet.tag_accounts","title":"tag_accounts(tag, account_indices)","text":"

Tag accounts.

Parameters:

Name Type Description Default tag str

is the tag to apply to the specified accounts.

required account_indices list[int]

are the indices of the accounts to tag.

required"},{"location":"api/wallet/#monero.MoneroWallet.thaw_output","title":"thaw_output(key_image)","text":"

Thaw a frozen output.

Parameters:

Name Type Description Default key_image str

key image of the output to thaw.

required"},{"location":"api/wallet/#monero.MoneroWallet.untag_accounts","title":"untag_accounts(account_indices)","text":"

Untag accounts.

Parameters:

Name Type Description Default account_indices list[int]

are the indices of the accounts to untag.

required"},{"location":"api/wallet/#monero.MoneroWallet.verify_message","title":"verify_message(msg, address, signature)","text":"

Verify a message signature.

Parameters:

Name Type Description Default msg str

the signed message.

required address str

signing address.

required signature str

signature.

required

Returns:

Type Description MoneroMessageSignatureResult

the message signature result.

"},{"location":"api/wallet/#monero.MoneroWallet.wait_for_next_block","title":"wait_for_next_block()","text":"

Wait for the next block to be added to the chain.

Returns:

Type Description int

the height of the next block when it is added to the chain.

"},{"location":"api/wallet_full/","title":"Full Wallet","text":""},{"location":"api/wallet_full/#monero.MoneroWalletFull","title":"MoneroWalletFull","text":"

Bases: MoneroWallet

Monero wallet implementation which uses monero-project's wallet2.

"},{"location":"api/wallet_full/#monero.MoneroWalletFull.create_wallet","title":"create_wallet(config) staticmethod","text":"

Create a new wallet with the given configuration.

Parameters:

Name Type Description Default config MoneroWalletConfig

the wallet configuration.

required

Returns:

Type Description MoneroWalletFull

reference to the wallet instance.

"},{"location":"api/wallet_full/#monero.MoneroWalletFull.get_cache_file_buffer","title":"get_cache_file_buffer()","text":"

Get wallet cache file without using filesystem.

Returns:

Type Description str

Cache file buffer.

"},{"location":"api/wallet_full/#monero.MoneroWalletFull.get_keys_file_buffer","title":"get_keys_file_buffer(password, view_only)","text":"

Get wallet keys file without using filesystem.

Parameters:

Name Type Description Default password str

The wallet password.

required view_only bool

Get view-only keys.

required

Returns:

Type Description str

Keys file buffer.

"},{"location":"api/wallet_full/#monero.MoneroWalletFull.get_seed_languages","title":"get_seed_languages() staticmethod","text":"

Get a list of available languages for the wallet's seed.

Returns:

Type Description list[str]

the available languages for the wallet's seed.

"},{"location":"api/wallet_full/#monero.MoneroWalletFull.open_wallet","title":"open_wallet(path, password, nettype, regtest=False) staticmethod","text":"

Open an existing wallet from disk.

Parameters:

Name Type Description Default path str

is the path to the wallet file to open.

required password str

is the password of the wallet file to open.

required nettype MoneroNetworkType

is the wallet's network type.

required regtest bool

indicates if wallet to open is a regtest wallet (optional).

False

Returns:

Type Description MoneroWalletFull

reference to the wallet instance.

"},{"location":"api/wallet_full/#monero.MoneroWalletFull.open_wallet_data","title":"open_wallet_data(password, nettype, keys_data, cache_data, daemon_connection=MoneroRpcConnection(), regtest=False) staticmethod","text":"

Open an in-memory wallet from existing data buffers.

Parameters:

Name Type Description Default password str

is the password of the wallet file to open.

required nettype MoneroNetworkType

is the wallet's network type.

required keys_data str

contains the contents of the \".keys\" file.

required cache_data str

contains the contents of the wallet cache file (no extension).

required daemon_connection MoneroRpcConnection

is connection information to a daemon (default = an unconnected wallet).

MoneroRpcConnection() regtest bool

indicates if wallet to open is a regtest wallet (optional).

False

Returns:

Type Description MoneroWalletFull

reference to the wallet instance.

"},{"location":"api/wallet_full/#monero.MoneroWalletFull.wallet_exists","title":"wallet_exists(path) staticmethod","text":"

Indicates if a wallet exists at the given path.

Parameters:

Name Type Description Default path str

is the path to check for a wallet.

required

Returns:

Type Description bool

True if a wallet exists at the given path, False otherwise.

"},{"location":"api/wallet_keys/","title":"Keys-Only Wallet","text":""},{"location":"api/wallet_keys/#monero.MoneroWalletKeys","title":"MoneroWalletKeys","text":"

Bases: MoneroWallet

Implements a Monero wallet to provide basic key management.

"},{"location":"api/wallet_keys/#monero.MoneroWalletKeys.create_wallet_from_keys","title":"create_wallet_from_keys(config) staticmethod","text":"

Create a wallet from an address, view key, and spend key.

Parameters:

Name Type Description Default config MoneroWalletConfig

is the wallet configuration (network type, address, view key, spend key, language).

required

Returns:

Type Description MoneroWalletKeys

reference to the wallet instance.

"},{"location":"api/wallet_keys/#monero.MoneroWalletKeys.create_wallet_from_seed","title":"create_wallet_from_seed(config) staticmethod","text":"

Create a wallet from an existing mnemonic phrase or seed.

Parameters:

Name Type Description Default config MoneroWalletConfig

is the wallet configuration (network type, seed, seed offset, is_multisig).

required

Returns:

Type Description MoneroWalletKeys

reference to the wallet instance.

"},{"location":"api/wallet_keys/#monero.MoneroWalletKeys.create_wallet_random","title":"create_wallet_random(config) staticmethod","text":"

Create a new wallet with a randomly generated seed.

Parameters:

Name Type Description Default config MoneroWalletConfig

is the wallet configuration (network type and language).

required

Returns:

Type Description MoneroWalletKeys

reference to the wallet instance.

"},{"location":"api/wallet_keys/#monero.MoneroWalletKeys.get_seed_languages","title":"get_seed_languages() staticmethod","text":"

Get a list of available languages for the wallet's seed.

Returns:

Type Description list[str]

The available languages for the wallet's seed.

"},{"location":"api/wallet_rpc/","title":"RPC Wallet","text":""},{"location":"api/wallet_rpc/#monero.MoneroWalletRpc","title":"MoneroWalletRpc","text":"

Bases: MoneroWallet

Implements a Monero wallet using monero-wallet-rpc_.

.. _monero-wallet-rpc: https://docs.getmonero.org/rpc-library/wallet-rpc/

"},{"location":"api/wallet_rpc/#monero.MoneroWalletRpc.create_wallet","title":"create_wallet(config)","text":"

Create and open a wallet on the monero-wallet-rpc server.

Parameters:

Name Type Description Default config MoneroWalletConfig

configures the wallet to create.

required"},{"location":"api/wallet_rpc/#monero.MoneroWalletRpc.get_rpc_connection","title":"get_rpc_connection()","text":"

Get the wallet's RPC connection.

Returns:

Type Description MoneroRpcConnection | None

the wallet's rpc connection.

"},{"location":"api/wallet_rpc/#monero.MoneroWalletRpc.get_seed_languages","title":"get_seed_languages()","text":"

Get all supported wallet seed languages.

Returns:

Type Description list[str]

wallet's supported languages.

"},{"location":"api/wallet_rpc/#monero.MoneroWalletRpc.stop","title":"stop()","text":"

Save and close the current wallet and stop the RPC server.

"},{"location":"api/data_model/connection/","title":"Connection Data Model","text":""},{"location":"api/data_model/connection/#monero.SslOptions","title":"SslOptions","text":"

Bases: SerializableStruct

Models SSL options for a Monero rpc connection.

"},{"location":"api/data_model/connection/#monero.SslOptions.ssl_allow_any_cert","title":"ssl_allow_any_cert: bool | None instance-attribute","text":"

Allow any certificate.

"},{"location":"api/data_model/connection/#monero.SslOptions.ssl_allowed_fingerprints","title":"ssl_allowed_fingerprints: list[str] instance-attribute","text":"

Allowed ssl fingerprints.

"},{"location":"api/data_model/connection/#monero.SslOptions.ssl_ca_file","title":"ssl_ca_file: str | None instance-attribute","text":"

Path to ssl CA file.

"},{"location":"api/data_model/connection/#monero.SslOptions.ssl_certificate_path","title":"ssl_certificate_path: str | None instance-attribute","text":"

Path to private ssl certificate.

"},{"location":"api/data_model/connection/#monero.SslOptions.ssl_private_key_path","title":"ssl_private_key_path: str | None instance-attribute","text":"

Path to private ssl key.

"},{"location":"api/data_model/connection/#monero.SslOptions.__init__","title":"__init__()","text":"

Initialize a new rpc connection ssl options.

"},{"location":"api/data_model/connection/#monero.MoneroConnectionType","title":"MoneroConnectionType","text":"

Bases: IntEnum

Enumerates a connection type, wich can be IPV4, IPV6, TOR, I2P or INVALID.

"},{"location":"api/data_model/connection/#monero.MoneroConnectionType.I2P","title":"I2P = 4 class-attribute instance-attribute","text":"

4 Indicates that Monero connection type is I2P.

"},{"location":"api/data_model/connection/#monero.MoneroConnectionType.INVALID","title":"INVALID = 0 class-attribute instance-attribute","text":"

0 Indicates that Monero connection type is invalid.

"},{"location":"api/data_model/connection/#monero.MoneroConnectionType.IPV4","title":"IPV4 = 1 class-attribute instance-attribute","text":"

1 Indicates that Monero connection type is IPV4.

"},{"location":"api/data_model/connection/#monero.MoneroConnectionType.IPV6","title":"IPV6 = 2 class-attribute instance-attribute","text":"

2 Indicates that Monero connection type is IPV6.

"},{"location":"api/data_model/connection/#monero.MoneroConnectionType.TOR","title":"TOR = 3 class-attribute instance-attribute","text":"

3 Indicates that Monero connection type is TOR.

"},{"location":"api/data_model/daemon/","title":"Daemon Data Model","text":""},{"location":"api/data_model/daemon/#monero.MoneroNetworkType","title":"MoneroNetworkType","text":"

Bases: IntEnum

Enumerates a Monero network type_.

.. _Monero network type: https://docs.getmonero.org/infrastructure/networks/

"},{"location":"api/data_model/daemon/#monero.MoneroNetworkType.MAINNET","title":"MAINNET = 0 class-attribute instance-attribute","text":"

0 indicates Mainnet network_.

.. _Mainnet network: https://docs.getmonero.org/infrastructure/networks/#mainnet

"},{"location":"api/data_model/daemon/#monero.MoneroNetworkType.STAGENET","title":"STAGENET = 2 class-attribute instance-attribute","text":"

2 indicates Stagenet network_.

.. _Stagenet network: https://docs.getmonero.org/infrastructure/networks/#stagenet

"},{"location":"api/data_model/daemon/#monero.MoneroNetworkType.TESTNET","title":"TESTNET = 1 class-attribute instance-attribute","text":"

1 indicates Testnet network_.

.. _Testnet network: https://docs.getmonero.org/infrastructure/networks/#testnet

"},{"location":"api/data_model/daemon/#monero.MoneroVersion","title":"MoneroVersion","text":"

Bases: SerializableStruct

Models a Monero version.

"},{"location":"api/data_model/daemon/#monero.MoneroVersion.is_release","title":"is_release: bool | None instance-attribute","text":"

States if the monero software version corresponds to an official tagged release (True), or not (False).

"},{"location":"api/data_model/daemon/#monero.MoneroVersion.number","title":"number: int | None instance-attribute","text":"

Number of the monero software version.

"},{"location":"api/data_model/daemon/#monero.MoneroVersion.__init__","title":"__init__()","text":"

Initialize a new Monero version.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockHeader","title":"MoneroBlockHeader","text":"

Bases: SerializableStruct

Models a Monero block header which contains information about the block.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockHeader.cumulative_difficulty_high","title":"cumulative_difficulty_high: int | None instance-attribute","text":"

Cumulative difficulty of all blocks up to the block in the reply.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockHeader.cumulative_difficulty_low","title":"cumulative_difficulty_low: int | None instance-attribute","text":"

Cumulative difficulty of all blocks up to the block in the reply.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockHeader.depth","title":"depth: int | None instance-attribute","text":"

The number of blocks succeeding this block on the blockchain. A larger number means an older block.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockHeader.difficulty_high","title":"difficulty_high: int | None instance-attribute","text":"

The strength of the Monero network based on mining power.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockHeader.difficulty_low","title":"difficulty_low: int | None instance-attribute","text":"

The strength of the Monero network based on mining power.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockHeader.hash","title":"hash: str | None instance-attribute","text":"

The hash of this block.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockHeader.height","title":"height: int | None instance-attribute","text":"

The number of blocks preceding this block on the blockchain.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockHeader.long_term_weight","title":"long_term_weight: int | None instance-attribute","text":"

The long term block weight, based on the median weight of the preceding 100000 blocks.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockHeader.major_version","title":"major_version: int | None instance-attribute","text":"

The major version of the monero protocol at this block height.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockHeader.miner_tx_hash","title":"miner_tx_hash: str | None instance-attribute","text":"

The hash of this block's coinbase transaction.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockHeader.minor_version","title":"minor_version: int | None instance-attribute","text":"

The minor version of the monero protocol at this block height.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockHeader.nonce","title":"nonce: int | None instance-attribute","text":"

A cryptographic random one-time number used in mining a Monero block.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockHeader.num_txs","title":"num_txs: int | None instance-attribute","text":"

Number of transactions included in this block.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockHeader.orphan_status","title":"orphan_status: bool | None instance-attribute","text":"

If True, this block is not part of the longest chain.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockHeader.pow_hash","title":"pow_hash: str | None instance-attribute","text":"

The hash, as a hexadecimal string, calculated from the block as proof-of-work.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockHeader.prev_hash","title":"prev_hash: str | None instance-attribute","text":"

The hash of the block immediately preceding this block in the chain.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockHeader.reward","title":"reward: int | None instance-attribute","text":"

The amount of atomic-units rewarded to the miner. The reward is the sum of new coins created (the emission) and fees paid by transactions in this block. Note: 1 XMR = 1e12 atomic-units.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockHeader.size","title":"size: int | None instance-attribute","text":"

Backward compatibility, same as weight, use that instead.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockHeader.timestamp","title":"timestamp: int | None instance-attribute","text":"

The unix time at which the block was recorded into the blockchain.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockHeader.weight","title":"weight: int | None instance-attribute","text":"

The adjusted block size, in bytes. This is the raw size, plus a positive adjustment for any Bulletproof transactions with more than 2 outputs.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockHeader.__init__","title":"__init__()","text":"

Initialize a Monero block header.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockHeader.copy","title":"copy()","text":"

Copy current block header.

Returns:

Type Description MoneroBlockHeader

copied block header.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockHeader.merge","title":"merge(other)","text":"

Merge current block header with another one.

Raises:

Type Description Exception

on reconciliation error.

"},{"location":"api/data_model/daemon/#monero.MoneroBlock","title":"MoneroBlock","text":"

Bases: MoneroBlockHeader

Models a Monero block in the blockchain.

"},{"location":"api/data_model/daemon/#monero.MoneroBlock.hex","title":"hex: str | None instance-attribute","text":"

Hexadecimal blob of block information.

"},{"location":"api/data_model/daemon/#monero.MoneroBlock.miner_tx","title":"miner_tx: MoneroTx | None instance-attribute","text":"

Miner transaction information.

"},{"location":"api/data_model/daemon/#monero.MoneroBlock.tx_hashes","title":"tx_hashes: list[str] instance-attribute","text":"

List of hashes of non-coinbase transactions in the block.

"},{"location":"api/data_model/daemon/#monero.MoneroBlock.txs","title":"txs: list[MoneroTx] instance-attribute","text":"

List of non-coinbase transactions in the block.

"},{"location":"api/data_model/daemon/#monero.MoneroBlock.__init__","title":"__init__()","text":"

Initialize a Monero block.

"},{"location":"api/data_model/daemon/#monero.MoneroBlock.copy","title":"copy()","text":"

Copy current block.

Returns:

Type Description MoneroBlock

copied block.

"},{"location":"api/data_model/daemon/#monero.MoneroTx","title":"MoneroTx","text":"

Bases: SerializableStruct

Models a Monero transaction on the blockchain.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.DEFAULT_PAYMENT_ID","title":"DEFAULT_PAYMENT_ID: str instance-attribute","text":"

Default tx payment id

"},{"location":"api/data_model/daemon/#monero.MoneroTx.block","title":"block: MoneroBlock | None instance-attribute","text":"

Block including the transaction.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.common_tx_sets","title":"common_tx_sets: str | None instance-attribute","text":"

A hexadecimal string representing a set of unsigned transactions, or a set of signing keys used in a multisig transaction.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.extra","title":"extra: list[int] instance-attribute","text":"

Usually called the payment ID but can be used to include any random 32 bytes.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.fee","title":"fee: int | None instance-attribute","text":"

The amount of the mining fee included in the transaction, in atomic-units.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.full_hex","title":"full_hex: str | None instance-attribute","text":"

Full transaction information as a hex string.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.hash","title":"hash: str | None instance-attribute","text":"

The transaction hash.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.in_tx_pool","title":"in_tx_pool: bool | None instance-attribute","text":"

States if the transaction is in pool (True) or included in a block (False).

"},{"location":"api/data_model/daemon/#monero.MoneroTx.inputs","title":"inputs: list[MoneroOutput] instance-attribute","text":"

List of inputs into transaction.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.is_confirmed","title":"is_confirmed: bool | None instance-attribute","text":"

States if the transaction included in a block (True) or is in pool (False).

"},{"location":"api/data_model/daemon/#monero.MoneroTx.is_double_spend_seen","title":"is_double_spend_seen: bool | None instance-attribute","text":"

States if the transaction is a double-spend (True) or not (False).

"},{"location":"api/data_model/daemon/#monero.MoneroTx.is_failed","title":"is_failed: bool | None instance-attribute","text":"

Indicates if the transaction validation has previously failed.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.is_kept_by_block","title":"is_kept_by_block: bool | None instance-attribute","text":"

States if the transaction was included in a block at least once (True) or not (False).

"},{"location":"api/data_model/daemon/#monero.MoneroTx.is_miner_tx","title":"is_miner_tx: bool | None instance-attribute","text":"

States if the transaction is a coinbase-transaction (True) or not (False).

"},{"location":"api/data_model/daemon/#monero.MoneroTx.is_relayed","title":"is_relayed: bool | None instance-attribute","text":"

States if the transaction was relayed (True) or not (False).

"},{"location":"api/data_model/daemon/#monero.MoneroTx.key","title":"key: str | None instance-attribute","text":"

The transaction key.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.last_failed_hash","title":"last_failed_hash: str | None instance-attribute","text":"

If the transaction validation has previously failed, this tells the previous transaction hash.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.last_failed_height","title":"last_failed_height: int | None instance-attribute","text":"

If the transaction validation has previously failed, this tells at what height that occurred.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.last_relayed_timestamp","title":"last_relayed_timestamp: int | None instance-attribute","text":"

Last unix time at which the transaction has been relayed.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.max_used_block_hash","title":"max_used_block_hash: str | None instance-attribute","text":"

Tells the hash of the most recent block with an output used in this transaction.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.max_used_block_height","title":"max_used_block_height: int | None instance-attribute","text":"

Tells the height of the most recent block with an output used in this transaction.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.metadata","title":"metadata: str | None instance-attribute","text":"

Transaction metadata.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.num_confirmations","title":"num_confirmations: int | None instance-attribute","text":"

Number of network confirmations.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.output_indices","title":"output_indices: list[int] instance-attribute","text":"

Transaction indexes.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.outputs","title":"outputs: list[MoneroOutput] instance-attribute","text":"

Transaction outputs.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.payment_id","title":"payment_id: str | None instance-attribute","text":"

Payment ID for this transaction.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.prunable_hash","title":"prunable_hash: str | None instance-attribute","text":"

Keccak-256 hash of the prunable portion of the block.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.prunable_hex","title":"prunable_hex: str | None instance-attribute","text":"

Prunable block encoded as a hex string.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.pruned_hex","title":"pruned_hex: str | None instance-attribute","text":"

Pruned block encoded as hex string.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.rct_sig_prunable","title":"rct_sig_prunable: str | None instance-attribute","text":"

Prunable ring signature.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.rct_signatures","title":"rct_signatures: str | None instance-attribute","text":"

Signatures used in ring signature to hide the true origin of the transaction.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.received_timestamp","title":"received_timestamp: int | None instance-attribute","text":"

Unix time at chich the transaction has been received.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.relay","title":"relay: bool | None instance-attribute","text":"

States if this transaction should be relayed (True) or not (False).

"},{"location":"api/data_model/daemon/#monero.MoneroTx.ring_size","title":"ring_size: int | None instance-attribute","text":"

The ring size of this transaction.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.signatures","title":"signatures: list[str] instance-attribute","text":"

List of signatures used in ring signature to hide the true origin of the transaction.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.size","title":"size: int | None instance-attribute","text":"

Backward compatibility, same as weight, use that instead.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.unlock_time","title":"unlock_time: int | None instance-attribute","text":"

If not 0, this tells when the transaction outputs are spendable.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.version","title":"version: int | None instance-attribute","text":"

Transaction version.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.weight","title":"weight: int | None instance-attribute","text":"

The weight of this transaction in bytes.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.__init__","title":"__init__()","text":"

Initialize a new Monero transaction.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.copy","title":"copy()","text":"

Copy current tx.

Returns:

Type Description MoneroTx

tx copy.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.get_height","title":"get_height()","text":"

Get the transaction height.

Returns:

Type Description int | None

The height of the transaction, if known.

"},{"location":"api/data_model/daemon/#monero.MoneroTx.merge","title":"merge(other)","text":"

Merge current tx with another one.

Parameters:

Name Type Description Default other MoneroTx

other tx to merge with.

required"},{"location":"api/data_model/daemon/#monero.MoneroKeyImage","title":"MoneroKeyImage","text":"

Bases: SerializableStruct

Models a Monero key image.

"},{"location":"api/data_model/daemon/#monero.MoneroKeyImage.hex","title":"hex: str | None instance-attribute","text":"

The key image in hexadecimal format.

"},{"location":"api/data_model/daemon/#monero.MoneroKeyImage.signature","title":"signature: str | None instance-attribute","text":"

The key image signature. None if not known.

"},{"location":"api/data_model/daemon/#monero.MoneroKeyImage.__init__","title":"__init__()","text":"

Initialize a Monero key image.

"},{"location":"api/data_model/daemon/#monero.MoneroKeyImage.copy","title":"copy()","text":"

Copy current key image.

Returns:

Type Description MoneroKeyImage

key image copy.

"},{"location":"api/data_model/daemon/#monero.MoneroKeyImage.deserialize_key_images","title":"deserialize_key_images(key_images_json) staticmethod","text":"

Deserialize key images from a JSON string.

Parameters:

Name Type Description Default key_images_json str

JSON string with serialized key images.

required

Returns:

Type Description list[MoneroKeyImage]

Deserialized key images.

"},{"location":"api/data_model/daemon/#monero.MoneroKeyImage.merge","title":"merge(other)","text":"

Merge current key image with another one.

Parameters:

Name Type Description Default other MoneroKeyImage

other key image to merge with.

required"},{"location":"api/data_model/daemon/#monero.MoneroOutput","title":"MoneroOutput","text":"

Bases: SerializableStruct

Models a Monero transaction output.

"},{"location":"api/data_model/daemon/#monero.MoneroOutput.amount","title":"amount: int | None instance-attribute","text":"

Output amount in atomic-units.

"},{"location":"api/data_model/daemon/#monero.MoneroOutput.index","title":"index: int | None instance-attribute","text":"

Output index.

"},{"location":"api/data_model/daemon/#monero.MoneroOutput.key_image","title":"key_image: MoneroKeyImage | None instance-attribute","text":"

The key image of the output.

"},{"location":"api/data_model/daemon/#monero.MoneroOutput.ring_output_indices","title":"ring_output_indices: list[int] instance-attribute","text":"

Indices of ring outputs.

"},{"location":"api/data_model/daemon/#monero.MoneroOutput.stealth_public_key","title":"stealth_public_key: str | None instance-attribute","text":"

The public key of the output.

"},{"location":"api/data_model/daemon/#monero.MoneroOutput.tx","title":"tx: MoneroTx instance-attribute","text":"

The transaction related to this output.

"},{"location":"api/data_model/daemon/#monero.MoneroOutput.__init__","title":"__init__()","text":"

Initialize a Monero output.

"},{"location":"api/data_model/daemon/#monero.MoneroOutput.copy","title":"copy()","text":"

Copy current output.

Returns:

Type Description MoneroOutput

output copy.

"},{"location":"api/data_model/daemon/#monero.MoneroOutput.merge","title":"merge(other)","text":"

Merge current output wallet with another output.

Parameters:

Name Type Description Default other MoneroOutput

other output to merge with.

required"},{"location":"api/data_model/daemon/#monero.MoneroAltChain","title":"MoneroAltChain","text":"

Bases: SerializableStruct

Models an alternative chain seen by the node.

"},{"location":"api/data_model/daemon/#monero.MoneroAltChain.block_hashes","title":"block_hashes: list[str] instance-attribute","text":"

List of all block hashes in the alternative chain that are not in the main chain.

"},{"location":"api/data_model/daemon/#monero.MoneroAltChain.difficulty_high","title":"difficulty_high: int | None instance-attribute","text":"

Cumulative difficulty of all blocks in the alternative chain (Most-significant 64 bits of the 128-bit integer).

"},{"location":"api/data_model/daemon/#monero.MoneroAltChain.difficulty_low","title":"difficulty_low: int | None instance-attribute","text":"

Cumulative difficulty of all blocks in the alternative chain (Least-significant 64 bits of 128-bit integer).

"},{"location":"api/data_model/daemon/#monero.MoneroAltChain.height","title":"height: int | None instance-attribute","text":"

The block height of the first diverging block of this alternative chain.

"},{"location":"api/data_model/daemon/#monero.MoneroAltChain.length","title":"length: int | None instance-attribute","text":"

The length in blocks of this alternative chain, after divergence.

"},{"location":"api/data_model/daemon/#monero.MoneroAltChain.main_chain_parent_block_hash","title":"main_chain_parent_block_hash: str | None instance-attribute","text":"

The hash of the greatest height block that is shared between the alternative chain and the main chain.

"},{"location":"api/data_model/daemon/#monero.MoneroAltChain.__init__","title":"__init__()","text":"

Initialize a Monero alt chain info.

"},{"location":"api/data_model/daemon/#monero.MoneroBan","title":"MoneroBan","text":"

Bases: SerializableStruct

Model a Monero banhammer.

"},{"location":"api/data_model/daemon/#monero.MoneroBan.host","title":"host: str | None instance-attribute","text":"

Host ban.

"},{"location":"api/data_model/daemon/#monero.MoneroBan.ip","title":"ip: int | None instance-attribute","text":"

IP ban.

"},{"location":"api/data_model/daemon/#monero.MoneroBan.is_banned","title":"is_banned: bool | None instance-attribute","text":"

Indicates if ban on the host is active (True) or not (False).

"},{"location":"api/data_model/daemon/#monero.MoneroBan.seconds","title":"seconds: int | None instance-attribute","text":"

Indicates the duration of the ban in seconds.

"},{"location":"api/data_model/daemon/#monero.MoneroBan.__init__","title":"__init__()","text":"

Initialize a Monero banhammer.

"},{"location":"api/data_model/daemon/#monero.MoneroPruneResult","title":"MoneroPruneResult","text":"

Bases: SerializableStruct

Models the result of pruning the blockchain.

"},{"location":"api/data_model/daemon/#monero.MoneroPruneResult.is_pruned","title":"is_pruned: bool | None instance-attribute","text":"

Indicates if blockchain is pruned.

"},{"location":"api/data_model/daemon/#monero.MoneroPruneResult.pruning_seed","title":"pruning_seed: int | None instance-attribute","text":"

Blockheight at which pruning began.

"},{"location":"api/data_model/daemon/#monero.MoneroPruneResult.__init__","title":"__init__()","text":"

Initialize a Monero prune result.

"},{"location":"api/data_model/daemon/#monero.MoneroMiningStatus","title":"MoneroMiningStatus","text":"

Bases: SerializableStruct

Models a Monero daemon mining status.

"},{"location":"api/data_model/daemon/#monero.MoneroMiningStatus.address","title":"address: str | None instance-attribute","text":"

Account address daemon is mining to. None if not mining.

"},{"location":"api/data_model/daemon/#monero.MoneroMiningStatus.is_active","title":"is_active: bool | None instance-attribute","text":"

Indicates if mining is enabled.

"},{"location":"api/data_model/daemon/#monero.MoneroMiningStatus.is_background","title":"is_background: bool | None instance-attribute","text":"

Indicates if mining is running in background.

"},{"location":"api/data_model/daemon/#monero.MoneroMiningStatus.num_threads","title":"num_threads: int | None instance-attribute","text":"

Number of running mining threads.

"},{"location":"api/data_model/daemon/#monero.MoneroMiningStatus.speed","title":"speed: int | None instance-attribute","text":"

Mining power in hashes per seconds.

"},{"location":"api/data_model/daemon/#monero.MoneroMiningStatus.__init__","title":"__init__()","text":"

Initialize a Monero daemon mining status.

"},{"location":"api/data_model/daemon/#monero.MoneroMinerTxSum","title":"MoneroMinerTxSum","text":"

Bases: SerializableStruct

Model for the sum of miner emissions and fees.

"},{"location":"api/data_model/daemon/#monero.MoneroMinerTxSum.emission_sum_high","title":"emission_sum_high: int | None instance-attribute","text":"

The new coins emitted in atomic-units. (Most significant 64 bits for 128 bit integer)

"},{"location":"api/data_model/daemon/#monero.MoneroMinerTxSum.emission_sum_low","title":"emission_sum_low: int | None instance-attribute","text":"

The new coins emitted in atomic-units. (Least significant 64 bits for 128 bit integer)

"},{"location":"api/data_model/daemon/#monero.MoneroMinerTxSum.fee_sum_high","title":"fee_sum_high: int | None instance-attribute","text":"

The sum of fees in atomic-units. (Most significant 64 bits for 128 bit integer)

"},{"location":"api/data_model/daemon/#monero.MoneroMinerTxSum.fee_sum_low","title":"fee_sum_low: int | None instance-attribute","text":"

The sum of fees in atomic-units. (Least significant 64 bits for 128 bit integer)

"},{"location":"api/data_model/daemon/#monero.MoneroMinerTxSum.__init__","title":"__init__()","text":"

Initialize a Monero miner transaction sum.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockTemplate","title":"MoneroBlockTemplate","text":"

Bases: SerializableStruct

Monero block template to mine.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockTemplate.block_hashing_blob","title":"block_hashing_blob: str | None instance-attribute","text":"

Blob on which to try to find a valid nonce.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockTemplate.block_template_blob","title":"block_template_blob: str | None instance-attribute","text":"

Blob on which to try to mine a new block.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockTemplate.difficulty_high","title":"difficulty_high: int | None instance-attribute","text":"

Network difficulty (Most-significant 64 bits of 128-bit integer).

"},{"location":"api/data_model/daemon/#monero.MoneroBlockTemplate.difficulty_low","title":"difficulty_low: int | None instance-attribute","text":"

Network difficulty (Least-significant 64 bits of 128-bit integer).

"},{"location":"api/data_model/daemon/#monero.MoneroBlockTemplate.expected_reward","title":"expected_reward: int | None instance-attribute","text":"

Coinbase reward expected to be received if block is successfully mined.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockTemplate.height","title":"height: int | None instance-attribute","text":"

Height on which to mine.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockTemplate.next_seed_hash","title":"next_seed_hash: str | None instance-attribute","text":"

Hash of the next block to use as seed for Random-X proof-of-work.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockTemplate.prev_hash","title":"prev_hash: str | None instance-attribute","text":"

Hash of the most recent block on which to mine the next block.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockTemplate.reserved_offset","title":"reserved_offset: int | None instance-attribute","text":"

Reserved offset.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockTemplate.seed_hash","title":"seed_hash: str | None instance-attribute","text":"

Hash of block to use as seed for Random-X proof-of-work.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockTemplate.seed_height","title":"seed_height: int | None instance-attribute","text":"

Height of block to use as seed for Random-X proof-of-work.

"},{"location":"api/data_model/daemon/#monero.MoneroBlockTemplate.__init__","title":"__init__()","text":"

Initialize a Monero block template.

"},{"location":"api/data_model/daemon/#monero.MoneroConnectionSpan","title":"MoneroConnectionSpan","text":"

Bases: SerializableStruct

Monero daemon connection span.

"},{"location":"api/data_model/daemon/#monero.MoneroConnectionSpan.connection_id","title":"connection_id: str | None instance-attribute","text":"

Id of connection

"},{"location":"api/data_model/daemon/#monero.MoneroConnectionSpan.num_blocks","title":"num_blocks: int | None instance-attribute","text":"

Number of blocks in this span

"},{"location":"api/data_model/daemon/#monero.MoneroConnectionSpan.rate","title":"rate: int | None instance-attribute","text":"

Connection rate

"},{"location":"api/data_model/daemon/#monero.MoneroConnectionSpan.remote_address","title":"remote_address: str | None instance-attribute","text":"

Peer address the node is downloading (or has downloaded) than span from.

"},{"location":"api/data_model/daemon/#monero.MoneroConnectionSpan.size","title":"size: int | None instance-attribute","text":"

Total number of bytes in that span's blocks (including txes).

"},{"location":"api/data_model/daemon/#monero.MoneroConnectionSpan.speed","title":"speed: int | None instance-attribute","text":"

Connection speed.

"},{"location":"api/data_model/daemon/#monero.MoneroConnectionSpan.start_height","title":"start_height: int | None instance-attribute","text":"

Block height of the first block in that span.

"},{"location":"api/data_model/daemon/#monero.MoneroConnectionSpan.__init__","title":"__init__()","text":"

Initialize a Monero connection span.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer","title":"MoneroPeer","text":"

Bases: SerializableStruct

Models a peer to the daemon.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer.address","title":"address: str | None instance-attribute","text":"

The peer's address, actually IPv4 & port.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer.avg_download","title":"avg_download: int | None instance-attribute","text":"

Average bytes of data downloaded by node.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer.avg_upload","title":"avg_upload: int | None instance-attribute","text":"

Average bytes of data uploaded by node.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer.connection_type","title":"connection_type: MoneroConnectionType | None instance-attribute","text":"

Type of peer connection.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer.current_download","title":"current_download: int | None instance-attribute","text":"

Current bytes downloaded by node.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer.current_upload","title":"current_upload: int | None instance-attribute","text":"

Current bytes uploaded by node.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer.hash","title":"hash: str | None instance-attribute","text":"

Peer hash.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer.height","title":"height: int | None instance-attribute","text":"

The peer blockchain height.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer.host","title":"host: str | None instance-attribute","text":"

The peer host.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer.id","title":"id: str | None instance-attribute","text":"

The node's ID on the network.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer.is_incoming","title":"is_incoming: bool | None instance-attribute","text":"

Indicates if peer is pulling blocks from node.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer.is_local_host","title":"is_local_host: bool | None instance-attribute","text":"

Indicates if peer is localhost.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer.is_local_ip","title":"is_local_ip: bool | None instance-attribute","text":"

Indicates if peer has a local ip address.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer.is_online","title":"is_online: bool | None instance-attribute","text":"

Indicates if the peer is online.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer.last_seen_timestamp","title":"last_seen_timestamp: int | None instance-attribute","text":"

Last activity timestamp of this peer.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer.live_time","title":"live_time: int | None instance-attribute","text":"

Length of time the peer has been online.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer.num_receives","title":"num_receives: int | None instance-attribute","text":"

Total number of messages received from this peer.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer.num_sends","title":"num_sends: int | None instance-attribute","text":"

Total number of messages sent to this peer.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer.num_support_flags","title":"num_support_flags: int | None instance-attribute","text":"

Support flags number.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer.port","title":"port: int | None instance-attribute","text":"

The port that the node is using to connect to the network.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer.pruning_seed","title":"pruning_seed: int | None instance-attribute","text":"

Block height at which pruning began.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer.receive_idle_time","title":"receive_idle_time: int | None instance-attribute","text":"

Seconds since last data was received from this peer.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer.rpc_credits_per_hash","title":"rpc_credits_per_hash: int | None instance-attribute","text":"

Credits for every hash calculated by client.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer.rpc_port","title":"rpc_port: int | None instance-attribute","text":"

Peer RPC port.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer.send_idle_time","title":"send_idle_time: int | None instance-attribute","text":"

Seconds since the last data sent to this peer.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer.state","title":"state: str | None instance-attribute","text":"

Peer state.

"},{"location":"api/data_model/daemon/#monero.MoneroPeer.__init__","title":"__init__()","text":"

Initialize a new Monero peer.

"},{"location":"api/data_model/daemon/#monero.MoneroSubmitTxResult","title":"MoneroSubmitTxResult","text":"

Bases: MoneroRpcPaymentInfo

Models the result from submitting a tx to a daemon.

"},{"location":"api/data_model/daemon/#monero.MoneroSubmitTxResult.has_invalid_input","title":"has_invalid_input: bool | None instance-attribute","text":"

Indicates if the transaction has an invalid input.

"},{"location":"api/data_model/daemon/#monero.MoneroSubmitTxResult.has_invalid_output","title":"has_invalid_output: bool | None instance-attribute","text":"

Indicates if the transaction has an invalid output.

"},{"location":"api/data_model/daemon/#monero.MoneroSubmitTxResult.has_too_few_outputs","title":"has_too_few_outputs: bool | None instance-attribute","text":"

Indicates if the transaction has too few outputs.

"},{"location":"api/data_model/daemon/#monero.MoneroSubmitTxResult.is_double_spend","title":"is_double_spend: bool | None instance-attribute","text":"

Indicates if the transaction is double spend.

"},{"location":"api/data_model/daemon/#monero.MoneroSubmitTxResult.is_fee_too_low","title":"is_fee_too_low: bool | None instance-attribute","text":"

Indicates if the transaction fee is too low.

"},{"location":"api/data_model/daemon/#monero.MoneroSubmitTxResult.is_good","title":"is_good: bool | None instance-attribute","text":"

Indicates if the submission of the transaction was successfull.

"},{"location":"api/data_model/daemon/#monero.MoneroSubmitTxResult.is_mixin_too_low","title":"is_mixin_too_low: bool | None instance-attribute","text":"

Indicates if the transaction mixin count is too low.

"},{"location":"api/data_model/daemon/#monero.MoneroSubmitTxResult.is_overspend","title":"is_overspend: bool | None instance-attribute","text":"

Indicates if the transaction uses more money than available

"},{"location":"api/data_model/daemon/#monero.MoneroSubmitTxResult.is_relayed","title":"is_relayed: bool | None instance-attribute","text":"

Indicates if the transaction has been relayed.

"},{"location":"api/data_model/daemon/#monero.MoneroSubmitTxResult.is_too_big","title":"is_too_big: bool | None instance-attribute","text":"

Indicates if the transaction size is too big.

"},{"location":"api/data_model/daemon/#monero.MoneroSubmitTxResult.is_tx_extra_too_big","title":"is_tx_extra_too_big: bool | None instance-attribute","text":"

Indicates if the transaction extra size is too big.

"},{"location":"api/data_model/daemon/#monero.MoneroSubmitTxResult.reason","title":"reason: str | None instance-attribute","text":"

Additional information. Currently empty or Not relayed if transaction was accepted but not relayed.

"},{"location":"api/data_model/daemon/#monero.MoneroSubmitTxResult.sanity_check_failed","title":"sanity_check_failed: bool | None instance-attribute","text":"

Indicates if the transaction sanity check has failed.

"},{"location":"api/data_model/daemon/#monero.MoneroSubmitTxResult.__init__","title":"__init__()","text":"

Initialize a new submit transaction result.

"},{"location":"api/data_model/daemon/#monero.MoneroTxBacklogEntry","title":"MoneroTxBacklogEntry","text":"

TODO

"},{"location":"api/data_model/daemon/#monero.MoneroTxBacklogEntry.__init__","title":"__init__()","text":"

Intialize a new tx backlog entry.

"},{"location":"api/data_model/daemon/#monero.MoneroOutputDistributionEntry","title":"MoneroOutputDistributionEntry","text":"

Bases: SerializableStruct

Models a Monero output distribution entry.

"},{"location":"api/data_model/daemon/#monero.MoneroOutputDistributionEntry.amount","title":"amount: int | None instance-attribute","text":"

Output amount in atomic-units.

"},{"location":"api/data_model/daemon/#monero.MoneroOutputDistributionEntry.base","title":"base: int | None instance-attribute","text":"

The total number of outputs of amount in the chain before, not including, the block at start_height.

"},{"location":"api/data_model/daemon/#monero.MoneroOutputDistributionEntry.distribution","title":"distribution: list[int] instance-attribute","text":"

The output distibution.

"},{"location":"api/data_model/daemon/#monero.MoneroOutputDistributionEntry.start_height","title":"start_height: int | None instance-attribute","text":"

Not necessarily equal to start_height parameter especially for amount = 0 where start_height will be no less than the height of the v4 hardfork.

"},{"location":"api/data_model/daemon/#monero.MoneroOutputDistributionEntry.__init__","title":"__init__()","text":"

Initialize a Monero output distribution entry.

"},{"location":"api/data_model/daemon/#monero.MoneroOutputHistogramEntry","title":"MoneroOutputHistogramEntry","text":"

Bases: SerializableStruct

Models a Monero output histogram entry.

"},{"location":"api/data_model/daemon/#monero.MoneroOutputHistogramEntry.amount","title":"amount: int | None instance-attribute","text":"

Output amount in atomic-units.

"},{"location":"api/data_model/daemon/#monero.MoneroOutputHistogramEntry.num_instances","title":"num_instances: int | None instance-attribute","text":"

Number of outputs.

"},{"location":"api/data_model/daemon/#monero.MoneroOutputHistogramEntry.recent_instances","title":"recent_instances: int | None instance-attribute","text":"

Number of recent outputs.

"},{"location":"api/data_model/daemon/#monero.MoneroOutputHistogramEntry.unlocked_instances","title":"unlocked_instances: int | None instance-attribute","text":"

Number of unlocked outputs.

"},{"location":"api/data_model/daemon/#monero.MoneroOutputHistogramEntry.__init__","title":"__init__()","text":"

Initialize a Monero output histogram entry.

"},{"location":"api/data_model/daemon/#monero.MoneroTxPoolStats","title":"MoneroTxPoolStats","text":"

Bases: SerializableStruct

Models transaction pool statistics.

"},{"location":"api/data_model/daemon/#monero.MoneroTxPoolStats.bytes_max","title":"bytes_max: int | None instance-attribute","text":"

Max transaction size in pool.

"},{"location":"api/data_model/daemon/#monero.MoneroTxPoolStats.bytes_med","title":"bytes_med: int | None instance-attribute","text":"

Median transaction size in pool.

"},{"location":"api/data_model/daemon/#monero.MoneroTxPoolStats.bytes_min","title":"bytes_min: int | None instance-attribute","text":"

Min transaction size in pool.

"},{"location":"api/data_model/daemon/#monero.MoneroTxPoolStats.bytes_total","title":"bytes_total: int | None instance-attribute","text":"

Total size of all transactions in pool.

"},{"location":"api/data_model/daemon/#monero.MoneroTxPoolStats.fee_total","title":"fee_total: int | None instance-attribute","text":"

The sum of the fees for all transactions currently in the transaction pool atomic-units.

"},{"location":"api/data_model/daemon/#monero.MoneroTxPoolStats.histo","title":"histo: dict[int, int] instance-attribute","text":"

Txs histogram (key for bytes, value for txs).

"},{"location":"api/data_model/daemon/#monero.MoneroTxPoolStats.histo98pc","title":"histo98pc: int | None instance-attribute","text":"

The time 98% of txes are younger than.

"},{"location":"api/data_model/daemon/#monero.MoneroTxPoolStats.num10m","title":"num10m: int | None instance-attribute","text":"

Number of transactions in pool for more than 10 minutes.

"},{"location":"api/data_model/daemon/#monero.MoneroTxPoolStats.num_double_spends","title":"num_double_spends: int | None instance-attribute","text":"

Number of double spend transactions.

"},{"location":"api/data_model/daemon/#monero.MoneroTxPoolStats.num_failing","title":"num_failing: int | None instance-attribute","text":"

Number of failing transactions.

"},{"location":"api/data_model/daemon/#monero.MoneroTxPoolStats.num_not_relayed","title":"num_not_relayed: int | None instance-attribute","text":"

Number of non-relayed transactions.

"},{"location":"api/data_model/daemon/#monero.MoneroTxPoolStats.num_txs","title":"num_txs: int | None instance-attribute","text":"

Total number of transactions.

"},{"location":"api/data_model/daemon/#monero.MoneroTxPoolStats.oldest_timestamp","title":"oldest_timestamp: int | None instance-attribute","text":"

Unix time of the oldest transaction in the pool.

"},{"location":"api/data_model/daemon/#monero.MoneroTxPoolStats.__init__","title":"__init__()","text":"

Initialize a Monero transaction pool statistics.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonUpdateCheckResult","title":"MoneroDaemonUpdateCheckResult","text":"

Bases: SerializableStruct

Models the result of checking for a daemon update.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonUpdateCheckResult.auto_uri","title":"auto_uri: str | None instance-attribute","text":"

URL automatically generated by the daemon to download the update.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonUpdateCheckResult.hash","title":"hash: str | None instance-attribute","text":"

Integrity check hash.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonUpdateCheckResult.is_update_available","title":"is_update_available: bool | None instance-attribute","text":"

Indicates if an update is available to download.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonUpdateCheckResult.user_uri","title":"user_uri: str | None instance-attribute","text":"

Alternative user URI.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonUpdateCheckResult.version","title":"version: str | None instance-attribute","text":"

Version available for download.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonUpdateCheckResult.__init__","title":"__init__()","text":"

Initialize a Monero update check result.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonUpdateDownloadResult","title":"MoneroDaemonUpdateDownloadResult","text":"

Bases: MoneroDaemonUpdateCheckResult

Models the result of downloading a daemon update.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonUpdateDownloadResult.download_path","title":"download_path: str | None instance-attribute","text":"

Path to download the update.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonUpdateDownloadResult.__init__","title":"__init__()","text":"

Initialize a Monero update download result.

"},{"location":"api/data_model/daemon/#monero.MoneroFeeEstimate","title":"MoneroFeeEstimate","text":"

Bases: SerializableStruct

Models a Monero fee estimate.

"},{"location":"api/data_model/daemon/#monero.MoneroFeeEstimate.fee","title":"fee: int | None instance-attribute","text":"

Amount of fees estimated per byte in atomic-units.

"},{"location":"api/data_model/daemon/#monero.MoneroFeeEstimate.fees","title":"fees: list[int] instance-attribute","text":"

Represents the base fees at different priorities [slow, normal, fast, fastest].

"},{"location":"api/data_model/daemon/#monero.MoneroFeeEstimate.quantization_mask","title":"quantization_mask: int | None instance-attribute","text":"

Final fee should be rounded up to an even multiple of this value.

"},{"location":"api/data_model/daemon/#monero.MoneroFeeEstimate.__init__","title":"__init__()","text":"

Initialize a Monero fee estimate.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo","title":"MoneroDaemonInfo","text":"

Bases: MoneroRpcPaymentInfo

Models information got from a Monero daemon.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.adjusted_timestamp","title":"adjusted_timestamp: int | None instance-attribute","text":"

Current time approximated from chain data, as Unix time.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.block_size_limit","title":"block_size_limit: int | None instance-attribute","text":"

Backward compatibility, same as block_weight_limit, use that instead.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.block_size_median","title":"block_size_median: int | None instance-attribute","text":"

Backward compatibility, same as block_weight_median, use that instead.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.block_weight_limit","title":"block_weight_limit: int | None instance-attribute","text":"

Maximum allowed adjusted block size based on latest 100000 blocks.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.block_weight_median","title":"block_weight_median: int | None instance-attribute","text":"

Median adjusted block size of latest 100000 blocks.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.bootstrap_daemon_address","title":"bootstrap_daemon_address: str | None instance-attribute","text":"

Bootstrap-node to give immediate usability to wallets while syncing by proxying RPC to it.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.cumulative_difficulty_high","title":"cumulative_difficulty_high: int | None instance-attribute","text":"

Most-significant 64 bits of the 128-bit cumulative difficulty.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.cumulative_difficulty_low","title":"cumulative_difficulty_low: int | None instance-attribute","text":"

Least-significant 64 bits of the 128-bit cumulative difficulty.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.database_size","title":"database_size: int | None instance-attribute","text":"

The size of the blockchain database, in bytes.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.difficulty_high","title":"difficulty_high: int | None instance-attribute","text":"

The most-significant 64 bits of the 128-bit network difficulty.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.difficulty_low","title":"difficulty_low: int | None instance-attribute","text":"

The least-significant 64 bits of the 128-bit network difficulty.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.free_space","title":"free_space: int | None instance-attribute","text":"

Available disk space on the node.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.height","title":"height: int | None instance-attribute","text":"

Current length of longest chain known to daemon.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.height_without_bootstrap","title":"height_without_bootstrap: int | None instance-attribute","text":"

Current length of the local chain of the daemon.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.is_busy_syncing","title":"is_busy_syncing: bool | None instance-attribute","text":"

States if new blocks are being added (True) or not (False).

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.is_offline","title":"is_offline: bool | None instance-attribute","text":"

States if the node is offline (True) or online (False).

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.is_restricted","title":"is_restricted: bool | None instance-attribute","text":"

Indicates that the node RPC interface is restricted (True) or not (False).

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.is_synchronized","title":"is_synchronized: bool | None instance-attribute","text":"

States if the node is synchronized (True) or not (False).

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.network_type","title":"network_type: MoneroNetworkType | None instance-attribute","text":"

Network type (MAINNET, TESTNET, or STAGENET).

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.num_alt_blocks","title":"num_alt_blocks: int | None instance-attribute","text":"

Number of alternative blocks to main chain.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.num_incoming_connections","title":"num_incoming_connections: int | None instance-attribute","text":"

Number of peers connected to and pulling from your node.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.num_offline_peers","title":"num_offline_peers: int | None instance-attribute","text":"

Number of peers that are marked as not reacheable on the network.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.num_online_peers","title":"num_online_peers: int | None instance-attribute","text":"

Number of peers that are marked as reacheble on the network.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.num_outgoing_connections","title":"num_outgoing_connections: int | None instance-attribute","text":"

Number of peers that you are connected to and getting information from.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.num_rpc_connections","title":"num_rpc_connections: int | None instance-attribute","text":"

Number of RPC client connected to the daemon (Including this RPC request).

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.num_txs","title":"num_txs: int | None instance-attribute","text":"

Total number of non-coinbase transactions in the chain.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.num_txs_pool","title":"num_txs_pool: int | None instance-attribute","text":"

Number of transactions that have been broadcast but not included in a block.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.start_timestamp","title":"start_timestamp: int | None instance-attribute","text":"

Start time of the daemon, as UNIX time.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.target","title":"target: int | None instance-attribute","text":"

Current target for next proof of work.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.target_height","title":"target_height: int | None instance-attribute","text":"

The height of the next block in the chain.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.update_available","title":"update_available: bool | None instance-attribute","text":"

States if a newer Monero software version is available.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.version","title":"version: str | None instance-attribute","text":"

The version of the Monero software the node is running.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.was_bootstrap_ever_used","title":"was_bootstrap_ever_used: bool | None instance-attribute","text":"

States if a bootstrap node has ever been used since the daemon started.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonInfo.__init__","title":"__init__()","text":"

Initiliaze a Monero daemon info.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonSyncInfo","title":"MoneroDaemonSyncInfo","text":"

Bases: MoneroRpcPaymentInfo

Models daemon synchronization information.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonSyncInfo.height","title":"height: int | None instance-attribute","text":"

Daemon blockchain height.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonSyncInfo.next_needed_pruning_seed","title":"next_needed_pruning_seed: int | None instance-attribute","text":"

The next pruning seed needed for pruned sync.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonSyncInfo.overview","title":"overview: str | None instance-attribute","text":"

Overview of current block queue where each character in the string represents a block set in the queue. '.' = requested but not received, 'o' = set received, 'm' = received set that matches the next blocks needed

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonSyncInfo.peers","title":"peers: list[MoneroPeer] instance-attribute","text":"

List of peers connected to the node

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonSyncInfo.spans","title":"spans: list[MoneroConnectionSpan] instance-attribute","text":"

Currently connected peers to download blocks from.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonSyncInfo.target_height","title":"target_height: int | None instance-attribute","text":"

Target height the node is syncing from (will be 0 if node is fully synced).

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonSyncInfo.__init__","title":"__init__()","text":"

Initialize a Monero daemon sync info.

"},{"location":"api/data_model/daemon/#monero.MoneroHardForkInfo","title":"MoneroHardForkInfo","text":"

Bases: MoneroRpcPaymentInfo

Models a Monero look up information regarding hard fork voting and readiness.

"},{"location":"api/data_model/daemon/#monero.MoneroHardForkInfo.earliest_height","title":"earliest_height: int | None instance-attribute","text":"

Block height at which hard fork would be enabled if voted in.

"},{"location":"api/data_model/daemon/#monero.MoneroHardForkInfo.is_enabled","title":"is_enabled: bool | None instance-attribute","text":"

Tells if hard fork is enforced.

"},{"location":"api/data_model/daemon/#monero.MoneroHardForkInfo.num_votes","title":"num_votes: int | None instance-attribute","text":"

Number of votes towards hard fork.

"},{"location":"api/data_model/daemon/#monero.MoneroHardForkInfo.state","title":"state: int | None instance-attribute","text":"

Current hard fork state. 0 (There is likely a hard fork), 1 (An update is needed to fork properly), or 2 (Everything looks good).

"},{"location":"api/data_model/daemon/#monero.MoneroHardForkInfo.threshold","title":"threshold: int | None instance-attribute","text":"

Minimum percent of votes to trigger hard fork. Default is 80.

"},{"location":"api/data_model/daemon/#monero.MoneroHardForkInfo.version","title":"version: int | None instance-attribute","text":"

The major block version for the fork.

"},{"location":"api/data_model/daemon/#monero.MoneroHardForkInfo.voting","title":"voting: int | None instance-attribute","text":"

Hard fork voting status.

"},{"location":"api/data_model/daemon/#monero.MoneroHardForkInfo.window","title":"window: int | None instance-attribute","text":"

Number of blocks over which current votes are cast. Default is 10080 blocks.

"},{"location":"api/data_model/daemon/#monero.MoneroHardForkInfo.__init__","title":"__init__()","text":"

Initialize a Monero hard fork info.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonListener","title":"MoneroDaemonListener","text":"

Receives notifications as a daemon is updated.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonListener.last_header","title":"last_header: MoneroBlockHeader | None instance-attribute","text":"

Last block header added to the chain.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonListener.__init__","title":"__init__()","text":"

Initialize a Monero daemon listener.

"},{"location":"api/data_model/daemon/#monero.MoneroDaemonListener.on_block_header","title":"on_block_header(header)","text":"

Called when a new block is added to the chain.

Parameters:

Name Type Description Default header MoneroBlockHeader

is the header of the block added to the chain.

required"},{"location":"api/data_model/wallet/","title":"Wallet Data Model","text":""},{"location":"api/data_model/wallet/#monero.MoneroWalletConfig","title":"MoneroWalletConfig","text":"

Bases: SerializableStruct

Configures a wallet to create.

"},{"location":"api/data_model/wallet/#monero.MoneroWalletConfig.account_lookahead","title":"account_lookahead: int | None instance-attribute","text":"

Account index look ahead.

"},{"location":"api/data_model/wallet/#monero.MoneroWalletConfig.is_multisig","title":"is_multisig: bool | None instance-attribute","text":"

Indicates if the wallet is a multisignature wallet.

"},{"location":"api/data_model/wallet/#monero.MoneroWalletConfig.language","title":"language: str | None instance-attribute","text":"

The wallet language.

"},{"location":"api/data_model/wallet/#monero.MoneroWalletConfig.network_type","title":"network_type: MoneroNetworkType | None instance-attribute","text":"

The wallet network type.

"},{"location":"api/data_model/wallet/#monero.MoneroWalletConfig.password","title":"password: str | None instance-attribute","text":"

The wallet password.

"},{"location":"api/data_model/wallet/#monero.MoneroWalletConfig.path","title":"path: str | None instance-attribute","text":"

The wallet path on file system.

"},{"location":"api/data_model/wallet/#monero.MoneroWalletConfig.primary_address","title":"primary_address: str | None instance-attribute","text":"

The wallet standard address.

"},{"location":"api/data_model/wallet/#monero.MoneroWalletConfig.private_spend_key","title":"private_spend_key: str | None instance-attribute","text":"

The wallet private spend key.

"},{"location":"api/data_model/wallet/#monero.MoneroWalletConfig.private_view_key","title":"private_view_key: str | None instance-attribute","text":"

The wallet private view key.

"},{"location":"api/data_model/wallet/#monero.MoneroWalletConfig.regtest","title":"regtest: bool | None instance-attribute","text":"

Indicates if wallet is regtest.

"},{"location":"api/data_model/wallet/#monero.MoneroWalletConfig.restore_height","title":"restore_height: int | None instance-attribute","text":"

The wallet restore height.

"},{"location":"api/data_model/wallet/#monero.MoneroWalletConfig.save_current","title":"save_current: bool | None instance-attribute","text":"

Save the wallet.

"},{"location":"api/data_model/wallet/#monero.MoneroWalletConfig.seed","title":"seed: str | None instance-attribute","text":"

The wallet mnemonic.

"},{"location":"api/data_model/wallet/#monero.MoneroWalletConfig.seed_offset","title":"seed_offset: str | None instance-attribute","text":"

The wallet custom seed offset.

"},{"location":"api/data_model/wallet/#monero.MoneroWalletConfig.server","title":"server: MoneroRpcConnection | None instance-attribute","text":"

The wallet RPC connection.

"},{"location":"api/data_model/wallet/#monero.MoneroWalletConfig.subaddress_lookahead","title":"subaddress_lookahead: int | None instance-attribute","text":"

Subaddress index look ahead.

"},{"location":"api/data_model/wallet/#monero.MoneroWalletConfig.copy","title":"copy()","text":"

Copy this wallet config.

Returns:

Type Description MoneroWalletConfig

Copy of the wallet config.

"},{"location":"api/data_model/wallet/#monero.MoneroWalletConfig.deserialize","title":"deserialize(config_json) staticmethod","text":"

Deserialize a Monero wallet config from a JSON string.

Parameters:

Name Type Description Default config_json str

JSON string.

required

Returns:

Type Description MoneroWalletConfig

The deserialized wallet config.

"},{"location":"api/data_model/wallet/#monero.MoneroSyncResult","title":"MoneroSyncResult","text":"

Bases: SerializableStruct

Models a result of syncing a wallet.

"},{"location":"api/data_model/wallet/#monero.MoneroSyncResult.num_blocks_fetched","title":"num_blocks_fetched: int instance-attribute","text":"

Number of blocks fetched.

"},{"location":"api/data_model/wallet/#monero.MoneroSyncResult.received_money","title":"received_money: bool instance-attribute","text":"

Indicates if money was received.

"},{"location":"api/data_model/wallet/#monero.MoneroSubaddress","title":"MoneroSubaddress","text":"

Bases: SerializableStruct

Models a Monero subaddress.

"},{"location":"api/data_model/wallet/#monero.MoneroSubaddress.account_index","title":"account_index: int | None instance-attribute","text":"

The subaddress account index.

"},{"location":"api/data_model/wallet/#monero.MoneroSubaddress.address","title":"address: str | None instance-attribute","text":"

Public address.

"},{"location":"api/data_model/wallet/#monero.MoneroSubaddress.balance","title":"balance: int | None instance-attribute","text":"

The subaddress balance.

"},{"location":"api/data_model/wallet/#monero.MoneroSubaddress.index","title":"index: int | None instance-attribute","text":"

The subaddress index.

"},{"location":"api/data_model/wallet/#monero.MoneroSubaddress.is_used","title":"is_used: bool | None instance-attribute","text":"

Indicates if subaddress has been used in receiving funds.

"},{"location":"api/data_model/wallet/#monero.MoneroSubaddress.label","title":"label: str | None instance-attribute","text":"

The subaddress label.

"},{"location":"api/data_model/wallet/#monero.MoneroSubaddress.num_blocks_to_unlock","title":"num_blocks_to_unlock: int | None instance-attribute","text":"

Number of blocks to unlock receveid outputs.

"},{"location":"api/data_model/wallet/#monero.MoneroSubaddress.num_unspent_outputs","title":"num_unspent_outputs: int | None instance-attribute","text":"

The number of unspent outputs in this subaddress.

"},{"location":"api/data_model/wallet/#monero.MoneroSubaddress.unlocked_balance","title":"unlocked_balance: int | None instance-attribute","text":"

The subaddress unlocked balance.

"},{"location":"api/data_model/wallet/#monero.MoneroSubaddress.__init__","title":"__init__()","text":"

Initialize a Monero subaddress.

"},{"location":"api/data_model/wallet/#monero.MoneroAccount","title":"MoneroAccount","text":"

Bases: SerializableStruct

Models a Monero account.

"},{"location":"api/data_model/wallet/#monero.MoneroAccount.balance","title":"balance: int | None instance-attribute","text":"

The account balance.

"},{"location":"api/data_model/wallet/#monero.MoneroAccount.index","title":"index: int | None instance-attribute","text":"

The account index.

"},{"location":"api/data_model/wallet/#monero.MoneroAccount.primary_address","title":"primary_address: str | None instance-attribute","text":"

The account primary address.

"},{"location":"api/data_model/wallet/#monero.MoneroAccount.subaddresses","title":"subaddresses: list[MoneroSubaddress] instance-attribute","text":"

List of account subaddresses.

"},{"location":"api/data_model/wallet/#monero.MoneroAccount.tag","title":"tag: str | None instance-attribute","text":"

The account tag.

"},{"location":"api/data_model/wallet/#monero.MoneroAccount.unlocked_balance","title":"unlocked_balance: int | None instance-attribute","text":"

The account unlocked balance.

"},{"location":"api/data_model/wallet/#monero.MoneroAccount.__init__","title":"__init__()","text":"

Initialize a Monero account.

"},{"location":"api/data_model/wallet/#monero.MoneroDestination","title":"MoneroDestination","text":"

Bases: SerializableStruct

Models an outgoing transfer destination.

"},{"location":"api/data_model/wallet/#monero.MoneroDestination.address","title":"address: str | None instance-attribute","text":"

Address of the receiver.

"},{"location":"api/data_model/wallet/#monero.MoneroDestination.amount","title":"amount: int | None instance-attribute","text":"

Amount sent to this destination.

"},{"location":"api/data_model/wallet/#monero.MoneroDestination.copy","title":"copy()","text":"

Copy current outgoing transfer destination.

Returns:

Type Description MoneroDestination

outgoing transfer destination copy.

"},{"location":"api/data_model/wallet/#monero.MoneroTransfer","title":"MoneroTransfer","text":"

Bases: SerializableStruct

Models a base transfer of funds to or from the wallet.

"},{"location":"api/data_model/wallet/#monero.MoneroTransfer.account_index","title":"account_index: int | None instance-attribute","text":"

Index of the account related to this transfer.

"},{"location":"api/data_model/wallet/#monero.MoneroTransfer.amount","title":"amount: int | None instance-attribute","text":"

Transfer amount in atomic-units.

"},{"location":"api/data_model/wallet/#monero.MoneroTransfer.tx","title":"tx: MoneroTxWallet instance-attribute","text":"

Related wallet transaction.

"},{"location":"api/data_model/wallet/#monero.MoneroTransfer.__init__","title":"__init__()","text":"

Initialize a Monero transfer.

"},{"location":"api/data_model/wallet/#monero.MoneroTransfer.copy","title":"copy()","text":"

Copy current transfer.

Returns:

Type Description MoneroTransfer

transfer copy.

"},{"location":"api/data_model/wallet/#monero.MoneroTransfer.is_incoming","title":"is_incoming()","text":"

Indicates if it is an incoming transfer (True) or not (False). Default None.

Returns:

Type Description bool | None

True if current transfer is incoming, False if outgoing, None if unkown.

"},{"location":"api/data_model/wallet/#monero.MoneroTransfer.is_outgoing","title":"is_outgoing()","text":"

Indicates if it is an outgoing transfer (True) or not (False). Default None.

Returns:

Type Description bool | None

True if current transfer is outgoing, False if incoming, None if unkown.

"},{"location":"api/data_model/wallet/#monero.MoneroTransfer.merge","title":"merge(other)","text":"

Merge current transfer with another one.

Parameters:

Name Type Description Default other MoneroTransfer

other transfer to merge with.

required"},{"location":"api/data_model/wallet/#monero.MoneroIncomingTransfer","title":"MoneroIncomingTransfer","text":"

Bases: MoneroTransfer

Models an incoming transfer of funds to the wallet.

"},{"location":"api/data_model/wallet/#monero.MoneroIncomingTransfer.address","title":"address: str | None instance-attribute","text":"

The address that received funds within this transfer.

"},{"location":"api/data_model/wallet/#monero.MoneroIncomingTransfer.num_suggested_confirmations","title":"num_suggested_confirmations: int | None instance-attribute","text":"

The number of suggested confirmations before moving funds.

"},{"location":"api/data_model/wallet/#monero.MoneroIncomingTransfer.subaddress_index","title":"subaddress_index: int | None instance-attribute","text":"

The subaddress index that received funds within this transfer.

"},{"location":"api/data_model/wallet/#monero.MoneroIncomingTransfer.__init__","title":"__init__()","text":"

Initialize a Monero incoming transfer.

"},{"location":"api/data_model/wallet/#monero.MoneroIncomingTransfer.copy","title":"copy()","text":"

Copy current incoming transfer.

Returns:

Type Description MoneroIncomingTransfer

incoming transfer copy.

"},{"location":"api/data_model/wallet/#monero.MoneroOutgoingTransfer","title":"MoneroOutgoingTransfer","text":"

Bases: MoneroTransfer

Models an outgoing transfer of funds from the wallet.

"},{"location":"api/data_model/wallet/#monero.MoneroOutgoingTransfer.addresses","title":"addresses: list[str] instance-attribute","text":"

Addresses from which the transfer originated.

"},{"location":"api/data_model/wallet/#monero.MoneroOutgoingTransfer.destinations","title":"destinations: list[MoneroDestination] instance-attribute","text":"

Outgoing transfer destinations.

"},{"location":"api/data_model/wallet/#monero.MoneroOutgoingTransfer.subaddress_indices","title":"subaddress_indices: list[int] instance-attribute","text":"

Subaddresses from which the transfer originated.

"},{"location":"api/data_model/wallet/#monero.MoneroOutgoingTransfer.copy","title":"copy()","text":"

Copy current outgoing transfer.

Returns:

Type Description MoneroOutgoingTransfer

outgoing transfer copy.

"},{"location":"api/data_model/wallet/#monero.MoneroTransferQuery","title":"MoneroTransferQuery","text":"

Bases: MoneroTransfer

Configures a query to retrieve transfers.

All transfers are returned except those that do not meet the criteria defined in this query.

"},{"location":"api/data_model/wallet/#monero.MoneroTransferQuery.address","title":"address: str | None instance-attribute","text":"

Select transfers involving particular address. Empty for all.

"},{"location":"api/data_model/wallet/#monero.MoneroTransferQuery.addresses","title":"addresses: list[str] instance-attribute","text":"

Select transfers involving particular addresses. Empty for all.

"},{"location":"api/data_model/wallet/#monero.MoneroTransferQuery.destinations","title":"destinations: list[MoneroDestination] instance-attribute","text":"

Select transfers involving particular destinations. Empty for all.

"},{"location":"api/data_model/wallet/#monero.MoneroTransferQuery.has_destinations","title":"has_destinations: bool | None instance-attribute","text":"

Filter transfers with or without destinations. None for all.

"},{"location":"api/data_model/wallet/#monero.MoneroTransferQuery.incoming","title":"incoming: bool | None instance-attribute","text":"

Filter incoming or outgoing transfers. None for all.

"},{"location":"api/data_model/wallet/#monero.MoneroTransferQuery.outgoing","title":"outgoing: bool | None instance-attribute","text":"

Filter incoming or outgoing transfers. None for all.

"},{"location":"api/data_model/wallet/#monero.MoneroTransferQuery.subaddress_index","title":"subaddress_index: int | None instance-attribute","text":"

Filter by subaddress index. None for all.

"},{"location":"api/data_model/wallet/#monero.MoneroTransferQuery.subaddress_indices","title":"subaddress_indices: list[int] instance-attribute","text":"

Select transfers involving particular subaddresses. Empty for all.

"},{"location":"api/data_model/wallet/#monero.MoneroTransferQuery.tx_query","title":"tx_query: MoneroTxQuery | None instance-attribute","text":"

Related transaction query.

"},{"location":"api/data_model/wallet/#monero.MoneroTransferQuery.__init__","title":"__init__()","text":"

Initialize a Monero transfer query.

"},{"location":"api/data_model/wallet/#monero.MoneroTransferQuery.copy","title":"copy()","text":"

Copy current transfer query.

Returns:

Type Description MoneroTransferQuery

transfer query copy.

"},{"location":"api/data_model/wallet/#monero.MoneroTransferQuery.deserialize_from_block","title":"deserialize_from_block(transfer_query_json) staticmethod","text":"

Deserialize transfer query from json block.

Parameters:

Name Type Description Default transfer_query_json str

json block with serialized transfer query.

required

Returns:

Type Description MoneroTransferQuery

deserialized transfer query.

"},{"location":"api/data_model/wallet/#monero.MoneroTransferQuery.meets_criteria","title":"meets_criteria(transfer, query_parent=True)","text":"

Check if transfer meets all the criteria defined in this query.

Parameters:

Name Type Description Default transfer MoneroTransfer

transfer to check if meets criteria.

required query_parent bool

query parent tx query (default True).

True

Returns:

Type Description bool

True if transfer meets all criteria defined in this query, False otherwise.

"},{"location":"api/data_model/wallet/#monero.MoneroOutputWallet","title":"MoneroOutputWallet","text":"

Bases: MoneroOutput

Models a Monero output with wallet extensions.

"},{"location":"api/data_model/wallet/#monero.MoneroOutputWallet.account_index","title":"account_index: int | None instance-attribute","text":"

The index of the account that owns this output.

"},{"location":"api/data_model/wallet/#monero.MoneroOutputWallet.is_frozen","title":"is_frozen: bool | None instance-attribute","text":"

Indicates if the output is frozen (True) or not (False).

"},{"location":"api/data_model/wallet/#monero.MoneroOutputWallet.is_spent","title":"is_spent: bool | None instance-attribute","text":"

Indicates if the output is spent (True) or not (False).

"},{"location":"api/data_model/wallet/#monero.MoneroOutputWallet.subaddress_index","title":"subaddress_index: int | None instance-attribute","text":"

The index of the subaddress that owns this output.

"},{"location":"api/data_model/wallet/#monero.MoneroOutputWallet.__init__","title":"__init__()","text":"

Initialize a Monero wallet output.

"},{"location":"api/data_model/wallet/#monero.MoneroOutputWallet.copy","title":"copy()","text":"

Copy current output wallet.

Returns:

Type Description MoneroOutputWallet

output wallet copy.

"},{"location":"api/data_model/wallet/#monero.MoneroOutputQuery","title":"MoneroOutputQuery","text":"

Bases: MoneroOutputWallet

Configures a query to retrieve wallet outputs (i.e. outputs that the wallet has or had the ability to spend).

All outputs are returned except those that do not meet the criteria defined in this query.

"},{"location":"api/data_model/wallet/#monero.MoneroOutputQuery.max_amount","title":"max_amount: int | None instance-attribute","text":"

Filter outputs above this amount.

"},{"location":"api/data_model/wallet/#monero.MoneroOutputQuery.min_amount","title":"min_amount: int | None instance-attribute","text":"

Filter outputs below this amount.

"},{"location":"api/data_model/wallet/#monero.MoneroOutputQuery.subaddress_indices","title":"subaddress_indices: list[int] instance-attribute","text":"

Subadress indices to select (empty for all).

"},{"location":"api/data_model/wallet/#monero.MoneroOutputQuery.tx_query","title":"tx_query: MoneroTxQuery | None property","text":"

Related transaction query.

"},{"location":"api/data_model/wallet/#monero.MoneroOutputQuery.__init__","title":"__init__()","text":"

Initialize a Monero output query.

"},{"location":"api/data_model/wallet/#monero.MoneroOutputQuery.copy","title":"copy()","text":"

Copy current output query.

Returns:

Type Description MoneroOutputQuery

output query copy.

"},{"location":"api/data_model/wallet/#monero.MoneroOutputQuery.deserialize_from_block","title":"deserialize_from_block(output_query_json) staticmethod","text":"

Deserialize output query from block.

Parameters:

Name Type Description Default output_query_json str

json query block.

required

Returns:

Type Description MoneroOutputQuery

deserialized output query.

"},{"location":"api/data_model/wallet/#monero.MoneroOutputQuery.meets_criteria","title":"meets_criteria(output, query_parent=True)","text":"

Indicates if the output meets all the criteria defined within this query.

Parameters:

Name Type Description Default output MoneroOutputWallet

Output to check.

required query_parent bool

Query also parent.

True

Returns:

Type Description bool

True if output meets all the criteria defined in this query, False otherwise.

"},{"location":"api/data_model/wallet/#monero.MoneroOutputQuery.set_tx_query","title":"set_tx_query(tx_query, output_query)","text":"

Set related transaction query.

This method sets query references constitutively.

Parameters:

Name Type Description Default tx_query Optional[MoneroTxQuery]

Tx query to set.

required output_query bool

If True sets outputs query in tx_query, otherwise inputs query.

required"},{"location":"api/data_model/wallet/#monero.MoneroTxWallet","title":"MoneroTxWallet","text":"

Bases: MoneroTx

Models a Monero transaction in the context of a wallet.

"},{"location":"api/data_model/wallet/#monero.MoneroTxWallet.change_address","title":"change_address: str | None instance-attribute","text":"

Address to which the change amount of the transaction was sent.

"},{"location":"api/data_model/wallet/#monero.MoneroTxWallet.change_amount","title":"change_amount: int | None instance-attribute","text":"

Change amount of the transaction.

"},{"location":"api/data_model/wallet/#monero.MoneroTxWallet.extra_hex","title":"extra_hex: str | None instance-attribute","text":"

Extra information about the transaction in hexadecimal format.

"},{"location":"api/data_model/wallet/#monero.MoneroTxWallet.incoming_transfers","title":"incoming_transfers: list[MoneroIncomingTransfer] instance-attribute","text":"

List of incoming transfer.

"},{"location":"api/data_model/wallet/#monero.MoneroTxWallet.input_sum","title":"input_sum: int | None instance-attribute","text":"

Total input sum.

"},{"location":"api/data_model/wallet/#monero.MoneroTxWallet.is_incoming","title":"is_incoming: bool | None instance-attribute","text":"

Indicates if the transaction has incoming transfers.

"},{"location":"api/data_model/wallet/#monero.MoneroTxWallet.is_locked","title":"is_locked: bool | None instance-attribute","text":"

Indicates if the transaction is locked.

"},{"location":"api/data_model/wallet/#monero.MoneroTxWallet.is_outgoing","title":"is_outgoing: bool | None instance-attribute","text":"

Indicated if the transaction has outgoing transfer.

"},{"location":"api/data_model/wallet/#monero.MoneroTxWallet.note","title":"note: str | None instance-attribute","text":"

Transaction note.

"},{"location":"api/data_model/wallet/#monero.MoneroTxWallet.num_dummy_outputs","title":"num_dummy_outputs: int | None instance-attribute","text":"

Number of decoys of the transactions.

"},{"location":"api/data_model/wallet/#monero.MoneroTxWallet.outgoing_transfer","title":"outgoing_transfer: MoneroOutgoingTransfer | None instance-attribute","text":"

The outgoing transfer related to this transaction.

"},{"location":"api/data_model/wallet/#monero.MoneroTxWallet.output_sum","title":"output_sum: int | None instance-attribute","text":"

The total output amount sum originated from this transaction.

"},{"location":"api/data_model/wallet/#monero.MoneroTxWallet.tx_set","title":"tx_set: MoneroTxSet | None instance-attribute","text":"

Set of transactions related to current tx.

"},{"location":"api/data_model/wallet/#monero.MoneroTxWallet.__init__","title":"__init__()","text":"

Initialize a new Monero tx wallet.

"},{"location":"api/data_model/wallet/#monero.MoneroTxWallet.copy","title":"copy()","text":"

Copy current tx wallet.

Returns:

Type Description MoneroTxWallet

tx wallet copy.

"},{"location":"api/data_model/wallet/#monero.MoneroTxWallet.filter_outputs_wallet","title":"filter_outputs_wallet(query)","text":"

Get outputs filtered by query.

Parameters:

Name Type Description Default query MoneroOutputQuery

query to filter outputs with.

required

Returns:

Type Description list[MoneroOutputWallet]

outputs that meets all criteria defined in query.

"},{"location":"api/data_model/wallet/#monero.MoneroTxWallet.filter_transfers","title":"filter_transfers(query)","text":"

Get transfers filtered by query.

Parameters:

Name Type Description Default query MoneroTransferQuery

query to filter transfers with.

required

Returns:

Type Description list[MoneroTransfer]

transfers that meets all criteria defined in query.

"},{"location":"api/data_model/wallet/#monero.MoneroTxWallet.get_incoming_amount","title":"get_incoming_amount()","text":"

Get total amount received in current tx.

Returns:

Type Description int

total amount received in current wallet tx.

"},{"location":"api/data_model/wallet/#monero.MoneroTxWallet.get_inputs_wallet","title":"get_inputs_wallet(query=None)","text":"

Get wallet inputs filtered by query.

Parameters:

Name Type Description Default query MoneroOutputQuery

query to filter outputs with.

None

Returns:

Type Description list[MoneroOutputWallet]

wallet outputs filtered by query.

"},{"location":"api/data_model/wallet/#monero.MoneroTxWallet.get_outgoing_amount","title":"get_outgoing_amount()","text":"

Get total amount spent in current tx.

Returns:

Type Description int

total amount spent in current wallet tx.

"},{"location":"api/data_model/wallet/#monero.MoneroTxQuery","title":"MoneroTxQuery","text":"

Bases: MoneroTxWallet

Configures a query to retrieve transactions.

All transactions are returned except those that do not meet the criteria defined in this query.

"},{"location":"api/data_model/wallet/#monero.MoneroTxQuery.has_payment_id","title":"has_payment_id: bool | None instance-attribute","text":"

Get transactions that have a payment id.

"},{"location":"api/data_model/wallet/#monero.MoneroTxQuery.hashes","title":"hashes: list[str] instance-attribute","text":"

Get transactions by hashes.

"},{"location":"api/data_model/wallet/#monero.MoneroTxQuery.height","title":"height: int | None instance-attribute","text":"

Get transactions by height.

"},{"location":"api/data_model/wallet/#monero.MoneroTxQuery.include_outputs","title":"include_outputs: int | None instance-attribute","text":"

Include outputs in transaction data.

"},{"location":"api/data_model/wallet/#monero.MoneroTxQuery.input_query","title":"input_query: MoneroOutputQuery | None instance-attribute","text":"

Query to apply on transaction inputs.

"},{"location":"api/data_model/wallet/#monero.MoneroTxQuery.is_incoming","title":"is_incoming: bool | None instance-attribute","text":"

Include incoming transactions.

"},{"location":"api/data_model/wallet/#monero.MoneroTxQuery.is_outgoing","title":"is_outgoing: bool | None instance-attribute","text":"

Include outgoing transactions.

"},{"location":"api/data_model/wallet/#monero.MoneroTxQuery.max_height","title":"max_height: int | None instance-attribute","text":"

Get transactions below max height.

"},{"location":"api/data_model/wallet/#monero.MoneroTxQuery.min_height","title":"min_height: int | None instance-attribute","text":"

Get transactions above max height.

"},{"location":"api/data_model/wallet/#monero.MoneroTxQuery.output_query","title":"output_query: MoneroOutputQuery | None instance-attribute","text":"

Query to apply on transaction outputs.

"},{"location":"api/data_model/wallet/#monero.MoneroTxQuery.payment_ids","title":"payment_ids: list[str] instance-attribute","text":"

Get transactions with specific payment ids.

"},{"location":"api/data_model/wallet/#monero.MoneroTxQuery.transfer_query","title":"transfer_query: MoneroTransferQuery | None instance-attribute","text":"

Query to apply on transaction wallet transfer.

"},{"location":"api/data_model/wallet/#monero.MoneroTxQuery.__init__","title":"__init__()","text":"

Initiliaze a new Monero transaction query.

"},{"location":"api/data_model/wallet/#monero.MoneroTxQuery.copy","title":"copy()","text":"

Copy current transaction query.

Returns:

Type Description MoneroTxQuery

tx query copy.

"},{"location":"api/data_model/wallet/#monero.MoneroTxQuery.deserialize_from_block","title":"deserialize_from_block(tx_query_json) staticmethod","text":"

Deserialize transaction query from JSON string.

Parameters:

Name Type Description Default tx_query_json str

tx query as JSON string.

required

Returns:

Type Description MoneroTxQuery

deserialized tx query.

"},{"location":"api/data_model/wallet/#monero.MoneroTxQuery.meets_criteria","title":"meets_criteria(tx, query_children=False)","text":"

Check if transaction wallet meets all criteria defined in this query.

Parameters:

Name Type Description Default tx MoneroTxWallet

Tx to check if meets criteria defined in this query.

required query_children bool

Query child data.

False

Returns:

Type Description bool

True if tx meets all criteria defined in this query, False otherwise.

"},{"location":"api/data_model/wallet/#monero.MoneroTxSet","title":"MoneroTxSet","text":"

Bases: SerializableStruct

Groups transactions who share common hex data which is needed in order to sign and submit the transactions.

For example, multisig transactions created from create_txs() share a common hex string which is needed in order to sign and submit the multisig transactions.

"},{"location":"api/data_model/wallet/#monero.MoneroTxSet.multisig_tx_hex","title":"multisig_tx_hex: str | None instance-attribute","text":"

Multisignature transaction hex.

"},{"location":"api/data_model/wallet/#monero.MoneroTxSet.signed_tx_hex","title":"signed_tx_hex: str | None instance-attribute","text":"

Signed transaction hex.

"},{"location":"api/data_model/wallet/#monero.MoneroTxSet.txs","title":"txs: list[MoneroTxWallet] instance-attribute","text":"

List of transactions defined in this set.

"},{"location":"api/data_model/wallet/#monero.MoneroTxSet.unsigned_tx_hex","title":"unsigned_tx_hex: str | None instance-attribute","text":"

Unsigned transaction hex.

"},{"location":"api/data_model/wallet/#monero.MoneroTxSet.__init__","title":"__init__()","text":"

Initialize a Monero transaction set.

"},{"location":"api/data_model/wallet/#monero.MoneroTxSet.deserialize","title":"deserialize(tx_set_json) staticmethod","text":"

Deserialize a Monero transaction set from a JSON string.

Parameters:

Name Type Description Default tx_set_json str

tx set as JSON string.

required

Returns:

Type Description MoneroTxSet

The deseriliazed transaction set.

"},{"location":"api/data_model/wallet/#monero.MoneroIntegratedAddress","title":"MoneroIntegratedAddress","text":"

Bases: SerializableStruct

Models a Monero integrated address.

"},{"location":"api/data_model/wallet/#monero.MoneroIntegratedAddress.integrated_address","title":"integrated_address: str instance-attribute","text":"

The integrated address.

"},{"location":"api/data_model/wallet/#monero.MoneroIntegratedAddress.payment_id","title":"payment_id: str instance-attribute","text":"

The payment id related to this integrated address.

"},{"location":"api/data_model/wallet/#monero.MoneroIntegratedAddress.standard_address","title":"standard_address: str instance-attribute","text":"

The standard address related to this integrated address.

"},{"location":"api/data_model/wallet/#monero.MoneroIntegratedAddress.__init__","title":"__init__()","text":"

Initialize a Monero integrated address.

"},{"location":"api/data_model/wallet/#monero.MoneroTxPriority","title":"MoneroTxPriority","text":"

Bases: IntEnum

Enumerates Monero transaction priorities.

"},{"location":"api/data_model/wallet/#monero.MoneroTxPriority.DEFAULT","title":"DEFAULT = 0 class-attribute instance-attribute","text":"

0 Default transaction priority.

"},{"location":"api/data_model/wallet/#monero.MoneroTxPriority.ELEVATED","title":"ELEVATED = 3 class-attribute instance-attribute","text":"

3 Elevated transaction priority.

"},{"location":"api/data_model/wallet/#monero.MoneroTxPriority.NORMAL","title":"NORMAL = 2 class-attribute instance-attribute","text":"

2 Normal transaction priority.

"},{"location":"api/data_model/wallet/#monero.MoneroTxPriority.UNIMPORTANT","title":"UNIMPORTANT = 1 class-attribute instance-attribute","text":"

1 Unimportant transaction priority.

"},{"location":"api/data_model/wallet/#monero.MoneroTxConfig","title":"MoneroTxConfig","text":"

Bases: SerializableStruct

Configures a transaction to send, sweep, or create a payment URI.

"},{"location":"api/data_model/wallet/#monero.MoneroTxConfig.account_index","title":"account_index: int | None instance-attribute","text":"

Account index to send funds from.

"},{"location":"api/data_model/wallet/#monero.MoneroTxConfig.address","title":"address: str | None instance-attribute","text":"

Transaction address destination.

"},{"location":"api/data_model/wallet/#monero.MoneroTxConfig.amount","title":"amount: int | None instance-attribute","text":"

Transaction amount.

"},{"location":"api/data_model/wallet/#monero.MoneroTxConfig.below_amount","title":"below_amount: int | None instance-attribute","text":"

Ignore output amount below.

"},{"location":"api/data_model/wallet/#monero.MoneroTxConfig.can_split","title":"can_split: bool | None instance-attribute","text":"

Indicates if transaction can be splitted in multiple transactions.

"},{"location":"api/data_model/wallet/#monero.MoneroTxConfig.destinations","title":"destinations: list[MoneroDestination] instance-attribute","text":"

Transaction outgoing destinations.

"},{"location":"api/data_model/wallet/#monero.MoneroTxConfig.fee","title":"fee: int | None instance-attribute","text":"

Transaction fee.

"},{"location":"api/data_model/wallet/#monero.MoneroTxConfig.key_image","title":"key_image: str | None instance-attribute","text":"

Use a particular key image as input for transaction.

"},{"location":"api/data_model/wallet/#monero.MoneroTxConfig.note","title":"note: str | None instance-attribute","text":"

Transaction note.

"},{"location":"api/data_model/wallet/#monero.MoneroTxConfig.payment_id","title":"payment_id: str | None instance-attribute","text":"

Transaction payment id.

"},{"location":"api/data_model/wallet/#monero.MoneroTxConfig.priority","title":"priority: MoneroTxPriority | None instance-attribute","text":"

Transaction priority.

"},{"location":"api/data_model/wallet/#monero.MoneroTxConfig.recipient_name","title":"recipient_name: str | None instance-attribute","text":"

Recipient name.

"},{"location":"api/data_model/wallet/#monero.MoneroTxConfig.relay","title":"relay: bool | None instance-attribute","text":"

Indicates if transaction should be relayed (True) or not (False).

"},{"location":"api/data_model/wallet/#monero.MoneroTxConfig.ring_size","title":"ring_size: int | None instance-attribute","text":"

Transaction ring size

"},{"location":"api/data_model/wallet/#monero.MoneroTxConfig.subaddress_indices","title":"subaddress_indices: list[int] instance-attribute","text":"

Account subaddresses indices to send funds from.

"},{"location":"api/data_model/wallet/#monero.MoneroTxConfig.subtract_fee_from","title":"subtract_fee_from: list[int] instance-attribute","text":"

Subtract fee from outputs.

"},{"location":"api/data_model/wallet/#monero.MoneroTxConfig.sweep_each_subaddress","title":"sweep_each_subaddress: bool | None instance-attribute","text":"

Sweep each wallet subbaddress.

"},{"location":"api/data_model/wallet/#monero.MoneroTxConfig.copy","title":"copy()","text":"

Copy current tx config.

Returns:

Type Description MoneroTxConfig

tx config copy.

"},{"location":"api/data_model/wallet/#monero.MoneroTxConfig.deserialize","title":"deserialize(config_json) staticmethod","text":"

Deserialize tx config from JSON string.

Parameters:

Name Type Description Default config_json str

tx config in JSON format.

required

Returns:

Type Description MoneroTxConfig

deserialized tx config.

"},{"location":"api/data_model/wallet/#monero.MoneroTxConfig.get_normalized_destinations","title":"get_normalized_destinations()","text":"

Get all destinations set in current tx config.

Returns:

Type Description list[MoneroDestination]

normalized tx config destinations.

"},{"location":"api/data_model/wallet/#monero.MoneroTxConfig.set_address","title":"set_address(address)","text":"

Set the address of a single-destination configuration.

Parameters:

Name Type Description Default address str

the address to set for the single destination.

required"},{"location":"api/data_model/wallet/#monero.MoneroKeyImageImportResult","title":"MoneroKeyImageImportResult","text":"

Bases: SerializableStruct

Models results from importing key images.

"},{"location":"api/data_model/wallet/#monero.MoneroKeyImageImportResult.height","title":"height: int | None instance-attribute","text":"

Height at which the last key image was imported. Can be 0 if blockchain height is not known.

"},{"location":"api/data_model/wallet/#monero.MoneroKeyImageImportResult.spent_amount","title":"spent_amount: int | None instance-attribute","text":"

Amount (in atomic-units) spent from those key images.

"},{"location":"api/data_model/wallet/#monero.MoneroKeyImageImportResult.unspent_amount","title":"unspent_amount: int | None instance-attribute","text":"

Amount (in atomic-units) still available from those key images.

"},{"location":"api/data_model/wallet/#monero.MoneroKeyImageImportResult.__init__","title":"__init__()","text":"

Initialize a Monero key image import result.

"},{"location":"api/data_model/wallet/#monero.MoneroMessageSignatureType","title":"MoneroMessageSignatureType","text":"

Bases: IntEnum

Enumerates the type of a Monero message signature.

"},{"location":"api/data_model/wallet/#monero.MoneroMessageSignatureType.SIGN_WITH_SPEND_KEY","title":"SIGN_WITH_SPEND_KEY = 0 class-attribute instance-attribute","text":"

0 Indicates that the message verification was signed with the wallet private spend key_.

.. _private spend key: https://docs.getmonero.org/cryptography/asymmetric/private-key/#private-spend-key

"},{"location":"api/data_model/wallet/#monero.MoneroMessageSignatureType.SIGN_WITH_VIEW_KEY","title":"SIGN_WITH_VIEW_KEY = 1 class-attribute instance-attribute","text":"

1 Indicates that the message verification was signed with the wallet private view key_.

.. _private view key: https://docs.getmonero.org/cryptography/asymmetric/private-key/#private-spend-key

"},{"location":"api/data_model/wallet/#monero.MoneroMessageSignatureResult","title":"MoneroMessageSignatureResult","text":"

Bases: SerializableStruct

Models results from message verification.

"},{"location":"api/data_model/wallet/#monero.MoneroMessageSignatureResult.is_good","title":"is_good: bool instance-attribute","text":"

Indicates if the message verification was successful.

"},{"location":"api/data_model/wallet/#monero.MoneroMessageSignatureResult.is_old","title":"is_old: bool instance-attribute","text":"

Indicates if the message verification used old monero software.

"},{"location":"api/data_model/wallet/#monero.MoneroMessageSignatureResult.signature_type","title":"signature_type: MoneroMessageSignatureType instance-attribute","text":"

Signature type used in the message verification.

"},{"location":"api/data_model/wallet/#monero.MoneroMessageSignatureResult.version","title":"version: int instance-attribute","text":"

Message signature version.

"},{"location":"api/data_model/wallet/#monero.MoneroMessageSignatureResult.__init__","title":"__init__()","text":"

Initialize a Monero message signature result.

"},{"location":"api/data_model/wallet/#monero.MoneroCheck","title":"MoneroCheck","text":"

Bases: SerializableStruct

Base model for results from checking a transaction or reserve proof.

"},{"location":"api/data_model/wallet/#monero.MoneroCheck.is_good","title":"is_good: bool instance-attribute","text":"

Indicates if check was successfull.

"},{"location":"api/data_model/wallet/#monero.MoneroCheck.__init__","title":"__init__()","text":"

Initialize a Monero check.

"},{"location":"api/data_model/wallet/#monero.MoneroCheckTx","title":"MoneroCheckTx","text":"

Bases: MoneroCheck

Models the results from checking a transaction key.

"},{"location":"api/data_model/wallet/#monero.MoneroCheckTx.in_tx_pool","title":"in_tx_pool: bool | None instance-attribute","text":"

States if the transaction is in pool (True) or included in a block (False)

"},{"location":"api/data_model/wallet/#monero.MoneroCheckTx.num_confirmations","title":"num_confirmations: int | None instance-attribute","text":"

Transaction network confirmations.

"},{"location":"api/data_model/wallet/#monero.MoneroCheckTx.received_amount","title":"received_amount: int | None instance-attribute","text":"

Amount received in the transaction.

"},{"location":"api/data_model/wallet/#monero.MoneroCheckTx.__init__","title":"__init__()","text":"

Initialize a Monero transaction check.

"},{"location":"api/data_model/wallet/#monero.MoneroCheckReserve","title":"MoneroCheckReserve","text":"

Bases: MoneroCheck

Models the results from checking a reserve proof.

"},{"location":"api/data_model/wallet/#monero.MoneroCheckReserve.total_amount","title":"total_amount: int | None instance-attribute","text":"

The reserve total amount.

"},{"location":"api/data_model/wallet/#monero.MoneroCheckReserve.unconfirmed_spent_amount","title":"unconfirmed_spent_amount: int | None instance-attribute","text":"

The reserve unconfirmed spent amount.

"},{"location":"api/data_model/wallet/#monero.MoneroCheckReserve.__init__","title":"__init__()","text":"

Initialize a Monero reserve check.

"},{"location":"api/data_model/wallet/#monero.MoneroMultisigInfo","title":"MoneroMultisigInfo","text":"

Bases: SerializableStruct

Models information about a multisig wallet.

"},{"location":"api/data_model/wallet/#monero.MoneroMultisigInfo.is_multisig","title":"is_multisig: bool instance-attribute","text":"

Indicates if the wallet is multisignature (True), or not (False).

"},{"location":"api/data_model/wallet/#monero.MoneroMultisigInfo.is_ready","title":"is_ready: bool instance-attribute","text":"

Indicates if the wallet is ready to support multisignature operations (True) or not (False).

"},{"location":"api/data_model/wallet/#monero.MoneroMultisigInfo.num_participants","title":"num_participants: int instance-attribute","text":"

Number of participants of the multisignature wallet.

"},{"location":"api/data_model/wallet/#monero.MoneroMultisigInfo.threshold","title":"threshold: int instance-attribute","text":"

Number of participants need in order to sign a transaction.

"},{"location":"api/data_model/wallet/#monero.MoneroMultisigInfo.__init__","title":"__init__()","text":"

Initialize a Monero multisignature info.

"},{"location":"api/data_model/wallet/#monero.MoneroMultisigInitResult","title":"MoneroMultisigInitResult","text":"

Bases: SerializableStruct

Models the result of initializing a multisig wallet which results in the multisig wallet's address xor another multisig hex to share with participants to create the wallet.

"},{"location":"api/data_model/wallet/#monero.MoneroMultisigInitResult.address","title":"address: str | None instance-attribute","text":"

The multisignature wallet address.

"},{"location":"api/data_model/wallet/#monero.MoneroMultisigInitResult.multisig_hex","title":"multisig_hex: str | None instance-attribute","text":"

The multisignature hex to share with other participants.

"},{"location":"api/data_model/wallet/#monero.MoneroMultisigInitResult.__init__","title":"__init__()","text":"

Initialize a Monero multisignature initializing result.

"},{"location":"api/data_model/wallet/#monero.MoneroMultisigSignResult","title":"MoneroMultisigSignResult","text":"

Bases: SerializableStruct

Models the result of signing multisig tx hex.

"},{"location":"api/data_model/wallet/#monero.MoneroMultisigSignResult.signed_multisig_tx_hex","title":"signed_multisig_tx_hex: str | None instance-attribute","text":"

Multisig transaction in hex format.

"},{"location":"api/data_model/wallet/#monero.MoneroMultisigSignResult.tx_hashes","title":"tx_hashes: list[str] instance-attribute","text":"

List of transaction hash.

"},{"location":"api/data_model/wallet/#monero.MoneroMultisigSignResult.__init__","title":"__init__()","text":"

Initialize a Monero multisignature signature result.

"},{"location":"api/data_model/wallet/#monero.MoneroAddressBookEntry","title":"MoneroAddressBookEntry","text":"

Bases: SerializableStruct

Monero address book entry model.

"},{"location":"api/data_model/wallet/#monero.MoneroAddressBookEntry.address","title":"address: str | None instance-attribute","text":"

The book entry address.

"},{"location":"api/data_model/wallet/#monero.MoneroAddressBookEntry.description","title":"description: str | None instance-attribute","text":"

The book entry description.

"},{"location":"api/data_model/wallet/#monero.MoneroAddressBookEntry.index","title":"index: int | None instance-attribute","text":"

The book entry index.

"},{"location":"api/data_model/wallet/#monero.MoneroAddressBookEntry.payment_id","title":"payment_id: str | None instance-attribute","text":"

The book entry payment id.

"},{"location":"api/data_model/wallet/#monero.MoneroAddressType","title":"MoneroAddressType","text":"

Bases: IntEnum

Models a Monero public address type_.

.. _Monero public address type: https://docs.getmonero.org/public-address/

"},{"location":"api/data_model/wallet/#monero.MoneroAddressType.INTEGRATED_ADDRESS","title":"INTEGRATED_ADDRESS = 1 class-attribute instance-attribute","text":"

1 Indicates that the Monero address format is integrated_.

.. _integrated: https://docs.getmonero.org/public-address/integrated-address/

"},{"location":"api/data_model/wallet/#monero.MoneroAddressType.PRIMARY_ADDRESS","title":"PRIMARY_ADDRESS = 0 class-attribute instance-attribute","text":"

0 Indicates that the Monero address format is standard_, also known as primary.

.. _standard: https://docs.getmonero.org/public-address/standard-address/

"},{"location":"api/data_model/wallet/#monero.MoneroAddressType.SUBADDRESS","title":"SUBADDRESS = 2 class-attribute instance-attribute","text":"

2 Indicates that the Monero address format is subaddress_.

.. _subaddress: https://docs.getmonero.org/public-address/subaddress/

"},{"location":"api/data_model/wallet/#monero.MoneroDecodedAddress","title":"MoneroDecodedAddress","text":"

Bases: SerializableStruct

Maintains metadata for a decoded address.

"},{"location":"api/data_model/wallet/#monero.MoneroDecodedAddress.address","title":"address: str instance-attribute","text":"

The decoded address.

"},{"location":"api/data_model/wallet/#monero.MoneroDecodedAddress.address_type","title":"address_type: MoneroAddressType instance-attribute","text":"

Type of the decoded address.

"},{"location":"api/data_model/wallet/#monero.MoneroDecodedAddress.network_type","title":"network_type: MoneroNetworkType instance-attribute","text":"

Network type of the decoded address.

"},{"location":"api/data_model/wallet/#monero.MoneroDecodedAddress.__init__","title":"__init__(address, address_type, network_type)","text":"

Initialize a Monero decoded address.

Parameters:

Name Type Description Default address str

The decoded address.

required address_type MoneroAddressType

The type of the decoded address.

required network_type MoneroNetworkType

Network type of the decoded address.

required"},{"location":"api/data_model/wallet/#monero.MoneroAccountTag","title":"MoneroAccountTag","text":"

Bases: SerializableStruct

Models a Monero account tag.

"},{"location":"api/data_model/wallet/#monero.MoneroAccountTag.account_indices","title":"account_indices: list[int] instance-attribute","text":"

Account indices with this tag.

"},{"location":"api/data_model/wallet/#monero.MoneroAccountTag.label","title":"label: str | None instance-attribute","text":"

The account tag label.

"},{"location":"api/data_model/wallet/#monero.MoneroAccountTag.tag","title":"tag: str | None instance-attribute","text":"

The account tag.

"},{"location":"api/data_model/wallet/#monero.MoneroWalletListener","title":"MoneroWalletListener","text":"

Interface to receive wallet notifications.

"},{"location":"api/data_model/wallet/#monero.MoneroWalletListener.__init__","title":"__init__()","text":"

Initialize a wallet listener.

"},{"location":"api/data_model/wallet/#monero.MoneroWalletListener.on_balances_changed","title":"on_balances_changed(new_balance, new_unlocked_balance)","text":"

Invoked when the wallet's balances change.

Parameters:

Name Type Description Default new_balance int

new balance.

required new_unlocked_balance int

new unlocked balance.

required"},{"location":"api/data_model/wallet/#monero.MoneroWalletListener.on_new_block","title":"on_new_block(height)","text":"

Invoked when a new block is processed.

Parameters:

Name Type Description Default height int

the newly processed block.

required"},{"location":"api/data_model/wallet/#monero.MoneroWalletListener.on_output_received","title":"on_output_received(output)","text":"

Invoked when the wallet receives an output.

Parameters:

Name Type Description Default output MoneroOutputWallet

the received output.

required"},{"location":"api/data_model/wallet/#monero.MoneroWalletListener.on_output_spent","title":"on_output_spent(output)","text":"

Invoked when the wallet spends an output.

Parameters:

Name Type Description Default output MoneroOutputWallet

the spent output.

required"},{"location":"api/data_model/wallet/#monero.MoneroWalletListener.on_sync_progress","title":"on_sync_progress(height, start_height, end_height, percent_done, message)","text":"

Invoked when sync progress is made.

Parameters:

Name Type Description Default height int

height of the synced block.

required start_height int

starting height of the sync request.

required end_height int

ending height of the sync request.

required percent_done float

sync progress as a percentage.

required message str

human-readable description of the current progress.

required"},{"location":"examples/connect_to_rpc_server/","title":"Connect to RPC Server","text":"

Developers can create and establish a connection to a rpc server conveniently with a MoneroRpcConnection:

from monero import MoneroRpcConnection\n\n# connect to a monerod or wallet rpc server\nconnection = MoneroRpcConnection(\"http:://rpc_server_uri:18089\")\n\n# set connection credentials if needed\nconnection.set_credentials(\"rpc_user\", \"rpc_password\")\n\n# check rpc connection\nconnection.check_connection()\n\nif not connection.is_connected():\n    raise Exception(\"Could not connect to RPC server.\")\n\nprint(\"Connection established to RPC server.\")\n

After successfully connecting to the rpc server, developers can also invoke methods of the JSON-RPC interface directly:

# invoke JSON-RPC method `get_version`\nresult = connection.send_json_request(\"get_version\")\nprint(f\"get_version JSON-RPC response: {result}\")\n

MoneroRpcConnection also accepts an optional proxy_uri parameter in its constructor, manageable even after a connection has been created. A prime example of use is to route your traffic via TOR:

Note

Setting a proxy_uri resets MoneroRpcConnection status.

# setup TOR proxy uri by instance attribute\nconnection.proxy_uri = \"127.0.0.1:9050\"\n\n# must recall `check_connection()` manually\nconnection.check_connection()\n
"},{"location":"examples/create_local_full_wallet/","title":"Create Local Full Wallet","text":"

MoneroWalletFull is another MoneroWallet implementation that fully wraps wallet2 API. With a full wallet developers can create wallet files and manage them locally.

Creating a MoneroWalletFull is very simple:

from monero import MoneroWalletConfig, MoneroWalletFull, MoneroNetworkType\n\n# setup wallet configuration\nconfig = MoneroWalletConfig()\n\n# setup wallet path\nconfig.path = \"test_wallet_full\"\n\n# setup wallet password\nconfig.password = \"supersecretpassword123\"\n\n# setup wallet network type\nconfig.network_type = MoneroNetworkType.TESTNET\n\nwallet = MoneroWalletFull.create_wallet(config)\n

Check if a Monero wallet exists at specific path:

if MoneroWalletFull.wallet_exists(\"test_wallet_full\"):\n    wallet = MoneroWalletFull.open_wallet(\"test_wallet_full\", \"supersecretpassword123\", MoneroNetworkType.TESTNET)\n
"},{"location":"examples/interact_with_daemon/","title":"Interact with RPC Daemon","text":"

MoneroDaemonRpc offers a MoneroDaemon implementation that interacts with monero-rpc server using calls to RPC, JSON-RPC and Binary interfaces.

Creating a MoneroDaemonRpc instance is very simple:

from monero import MoneroDaemonRpc\n\n# create RPC daemon connected to `monerod-rpc` server\ndaemon = MoneroDaemonRpc(\"http://monerod_rpc_uri:18081\")\n

It can also be done using a MoneroRpcConnection instance:

from monero import MoneroRpcConnection, MoneroDaemonRpc\n\n# create rpc connection\nconnection = MoneroRpcConnection(\"http://monerod_rpc_uri:18081\")\n\n# create daemon using RPC connection\ndaemon = MoneroDaemonRpc(connection)\n

Fetch daemon info and status:

# get general daemon rpc info\ndaemon_info = daemon.get_info()\nprint(f\"Daemon info: {daemon_info.serialize()}\")\n\n# get daemon specific sync info\nsync_info = daemon.get_sync_info()\nprint(f\"Sync info: {sync_info.serialize()}\")\n\n# get peer bans\nbans = daemon.get_peer_bans()\nfor ban in bans:\n    print(f\"Banned peer: {peer.serialize()}\")\n

Query blocks and txs on blockchain:

# get last block header added to blockchain\nlast_block = daemon.get_last_block_header()\nprint(f\"Last block header: {last_block.serialize()}\")\n\n# get specific block by height\nblock = daemon.get_block_by_height(1520000)\nprint(f\"Block fetched by height: {block.serialize()}\")\n\n# get specific block by hash\nblock = daemon.get_block_by_hash(\"...block hash...\")\nprint(f\"Block fetched by hash: {block.serialize()}\")\n\n# get alternative chains seen by the daemon\nchains = daemon.get_alt_chains()\nprint(f\"Found {len(chains)} alternative chains\")\n\n# get unconfirmed txs in pool\ntx_pool = daemon.get_tx_pool()\nfor tx in tx_pool:\n    print(f\"Found tx in pool: {tx.serialize()}\")\n\n# get specific tx added to chain\ntx = daemon.get_tx(\"...tx hash...\")\nprint(f\"Fetched tx: {tx.serialize()}\")\n

Relay mined blocks and signed txs:

# submit a mined block\ndaemon.submit_block(\"...block blob...\")\n\n# submit a signed tx\ntx: Monerotx = ...\ndaemon.submit_tx(tx.full_hex)\n
"},{"location":"examples/interact_with_wallet_rpc/","title":"Interact with RPC Wallet","text":"

MoneroWalletRpc offers a MoneroWallet implementation that interacts with monero-wallet-rpc using calls to the JSON-RPC interface.

Creating a MoneroWalletRpc instance is very simple:

from monero import MoneroWalletRpc\n\n# create RPC wallet connected to `monero-wallet-rpc` server\nwallet = MoneroWalletRpc(\"http://wallet_rpc_uri:18081\")\n

It can also be done using a MoneroRpcConnection instance:

from monero import MoneroRpcConnection, MoneroWalletRpc\n\n# create rpc connection\nconnection = MoneroRpcConnection(\"http://wallet_rpc_uri:18081\")\n\n# create wallet using RPC connection\nwallet = MoneroWalletRpc(connection)\n

Let's create a new wallet file:

# build wallet configuration\nconfig: MoneroWalletConfig = ...\n\n# create new wallet file in rpc server\nwallet.create_wallet(config)\n

Or open an already existing wallet:

# open wallet with config\nwallet.open_wallet(config)\n\n# or open by path and password\nwallet.open_wallet(\"wallet_path\", \"wallet_password\")\n

And fetch some info:

# get wallet information\nprimary_address: str = wallet.get_primary_address()\nview_key: str = wallet.get_private_view_key()\nseed: str = wallet.get_seed()\nbalance: int = wallet.get_balance()\n\nprint(f\"primary address: {primary_address}\")\nprint(f\"view_key: {view_key}\")\nprint(f\"seed: {seed}\")\nprint(f\"balance: {balance}\")\n
"},{"location":"examples/query_wallet_txs_and_transfers/","title":"Query Wallet Txs and Transfers","text":"

The MoneroWallet interface offers methods for fetching transactions, transfers and outputs from wallet's cache:

  • MoneroWallet.get_txs(query: MoneroTxQuery) -> list[MoneroTxWallet]
  • MoneroWallet.get_transfers(query: MoneroTransferQuery) -> list[MoneroTransfer]
  • MoneroWallet.get_outputs(query: MoneroOutputQuery) -> list[MoneroOutputWallet]

This methods can be used with a MoneroTxQuery, MoneroTransferQuery, MoneroOutputQuery, wich will filter all records that doesn't match criteria defined in the query.

Example of fetching wallet txs with a basic MoneroTxQuery:

from monero import (\n    MoneroWallet, MoneroTxQuery,\n    MoneroTxWallet\n)\n\n# open a wallet with txs data\nwallet: MoneroWallet = ...\n\n# create and setup a new tx query to filter txs with\nquery = MoneroTxQuery()\n\n# fetch only outgoing txs\nquery.is_incoming = False\nquery.is_outgoing = True\n\n# include outputs in tx data\nquery.include_outputs = True\n\n# filter tx by height range\nquery.min_height = 150000\nquery.max_height = 300000\n\n# or get txs at specific height\nquery.height = 152000\n\n# fetch txs that meets criteria from wallet\ntxs: list[MoneroTxWallet] = wallet.get_txs(query)\n\n# print fetched txs\nfor tx in txs:\n    print(f\"Found tx: {tx.serialize()}\")\n

Example of fetching wallet transfers with a MoneroTransferQuery:

from monero import (\n    MoneroWallet, MoneroTransferQuery,\n    MoneroTransfer\n)\n\n# open a wallet with txs data\nwallet: MoneroWallet = ...\n\n# create and setup a new tx query to filter transfers with\nquery = MoneroTransferQuery()\n\n# fetch only incoming transfers\nquery.is_incoming = True\nquery.is_outgoing = False\n\n# filter by account and subaddress index\nquery.account_index = 1\nquery.subaddress_indices = [0, 1, 2, 3]\n\n# fetch transfers that meets criteria from wallet\ntransfers: list[MoneroTransferWallet] = wallet.get_transfers(query)\n\n# print fetched txs\nfor transfer in transfers:\n    print(f\"Found transfer: {transfer.serialize()}\")\n
"},{"location":"examples/sending_payments/","title":"Sending Payments","text":"

In order to send payments with a MoneroWallet, developers must setup a MoneroTxConfig:

from monero import MoneroTxConfig\n\n# create and setup transaction configuration\ntx_config = MoneroTxConfig()\n\n# specify source account index\ntx_config.account_index = 0\n\n# specify address and destination amount\ntx_config.address = \"...destination address...\"\ntx_config.amount = 1000000000\n\n# relay tx to the network\ntx_config.relay = True\n\n# create txs with configuration\ntxs: list[MoneroTxWallet] = wallet.create_txs(tx_config)\n\nfor tx in txs:\n    print(f\"Created tx: {tx.serialize()}\")\n

Is possible to setup also multiple destinations in transaction configuration:

tx_config.destinations.append(MoneroDestination(\"...destination address1...\", 1000000000))\n\n...\n\ntx_config.destinations.append(MoneroDestination(\"...destination addressN...\", 1000000000))\n\n# split into multiple txs\ntx_config.can_split = True\n
"},{"location":"examples/using_keys_only_wallet/","title":"Using Keys-Only Wallet","text":"

MoneroWalletKeys is a MoneroWallet implementation that supports only basic keys operations, without files or RPC calls.

Creating a in-memory keys-only wallet with MoneroWalletKeys is very simple:

from monero import MoneroWalletKeys, MoneroWalletConfig, MoneroNetworkType\n\n# setup wallet configuration\nconfig = MoneroWalletConfig()\nconfig.network_type = MoneroNetworkType.TESTNET\n\n# create random wallet\nwallet = MoneroWalletKeys.create_wallet_random(config)\n

Restore specific wallet from seed:

config.seed = \"...wallet seed...\"\n\n# restore wallet from seed\nwallet = MoneroWalletKeys.create_wallet_from_seed(config)\n

Or from wallet keys:

config.primary_address = \"...wallet primary address...\"\nconfig.private_view_key = \"...wallet private view key...\"\n\n# restore wallet from keys\nwallet = MoneroWalletKeys.create_wallet_from_keys(config)\n
"}]} \ No newline at end of file diff --git a/docs/mkdocs/public/sitemap.xml b/docs/mkdocs/public/sitemap.xml index 6b93591..0b8cf3d 100644 --- a/docs/mkdocs/public/sitemap.xml +++ b/docs/mkdocs/public/sitemap.xml @@ -2,127 +2,127 @@ https://everoddandeven.github.io/monero-python/ - 2026-04-27 + 2026-07-28 daily https://everoddandeven.github.io/monero-python/api/architecture/ - 2026-04-27 + 2026-07-28 daily https://everoddandeven.github.io/monero-python/api/connection/ - 2026-04-27 + 2026-07-28 daily https://everoddandeven.github.io/monero-python/api/daemon/ - 2026-04-27 + 2026-07-28 daily https://everoddandeven.github.io/monero-python/api/daemon_rpc/ - 2026-04-27 + 2026-07-28 daily https://everoddandeven.github.io/monero-python/api/serializable_struct/ - 2026-04-27 + 2026-07-28 daily https://everoddandeven.github.io/monero-python/api/utils/ - 2026-04-27 + 2026-07-28 daily https://everoddandeven.github.io/monero-python/api/wallet/ - 2026-04-27 + 2026-07-28 daily https://everoddandeven.github.io/monero-python/api/wallet_full/ - 2026-04-27 + 2026-07-28 daily https://everoddandeven.github.io/monero-python/api/wallet_keys/ - 2026-04-27 + 2026-07-28 daily https://everoddandeven.github.io/monero-python/api/wallet_rpc/ - 2026-04-27 + 2026-07-28 daily https://everoddandeven.github.io/monero-python/api/data_model/connection/ - 2026-04-27 + 2026-07-28 daily https://everoddandeven.github.io/monero-python/api/data_model/daemon/ - 2026-04-27 + 2026-07-28 daily https://everoddandeven.github.io/monero-python/api/data_model/wallet/ - 2026-04-27 + 2026-07-28 daily https://everoddandeven.github.io/monero-python/examples/connect_to_rpc_server/ - 2026-04-27 + 2026-07-28 daily https://everoddandeven.github.io/monero-python/examples/create_local_full_wallet/ - 2026-04-27 + 2026-07-28 daily https://everoddandeven.github.io/monero-python/examples/interact_with_daemon/ - 2026-04-27 + 2026-07-28 daily https://everoddandeven.github.io/monero-python/examples/interact_with_wallet_rpc/ - 2026-04-27 + 2026-07-28 daily https://everoddandeven.github.io/monero-python/examples/query_wallet_txs_and_transfers/ - 2026-04-27 + 2026-07-28 daily https://everoddandeven.github.io/monero-python/examples/sending_payments/ - 2026-04-27 + 2026-07-28 daily https://everoddandeven.github.io/monero-python/examples/using_keys_only_wallet/ - 2026-04-27 + 2026-07-28 daily diff --git a/docs/mkdocs/public/sitemap.xml.gz b/docs/mkdocs/public/sitemap.xml.gz index 06331fe0483c0b9de7abc009dbbec674972baaaa..87a7bc450bc4fbc0c86ddb138e10eb997930ecd4 100644 GIT binary patch literal 560 zcmV-00?+*)iwFn+@n>oR|8r?{Wo=<_E_iKh0Nt6*j@uv*fbaVhmhUmyRBAU-;=T0= z+B2HPlNc=qFW@@v(|7!{-89*5R8>SWxy0ZZ;QNfsMA<$bE0z2}>!i`U^gdgr32I>q zsSmsK`?s%)hx9SO+cs7?^a%xPw@XX!>kVUV+h$IBte|$8u?OZvNe#!QPPWX}>6o)Q zmcCMdWVWA%ocr~9&4#;aewWavpKH7tTFQvL&vKN8v`|wNpbNUv*+KfUdCH_=mCJ(sK?d_{0~b{*(8Dew($Qxpq31*DCwyP-&mZppbM5@#)Q$D z=8*H=P-i5;Y!!gj{7p?1fh}=ci#SXTB*APsv=Ws32~P^S^R^Lw?%Li%3g)lzQn|Ss z8zF)@YC$QS{kEDY0$bwyMyWVdjVPggJ!9u0@im}?_7%aoctR4eitxaRA5}y}>ibZ) za2QMJdJc38cX1q_mq0<>;Ss7@p?lrn+?)PI!Ko;u0p=|63Rz&A7Kww?5TJ&0ozH() zUWW_oRBECDdXOze^7+3ZKL)#{%Q#A%>u_P6zBFjN*XjJxamwW0f_8hfE()_(5X1U) ysQbSFcnw{J+Q(t^0xGP-#`Tl+Kb*MHs*CAV`U~2b&*96V&wl|K{F@$T8UO%xSQ}^n literal 560 zcmV-00?+*)iwFn+r|xM2|8r?{Wo=<_E_iKh0Nt6*j@uv*fbaVh7WbHJTD47-cyE1z z_KaA25~Ic7WpEw$={x?}Zkp^iswyIxTw?GH@O?&RqHG_Il}>(uLuJj5-KR^IfXQv4 z%wfmAfBU-l!XC1_ZR0e8Pbk>nj+Nfm8_wIdO;LHMWR0nH2ab734dhcNU#4p|=4_6o zuk;_8?S~=fe!X7v;V#SW68iLWjaNfU+dS*DkkWt_YKuaeg04(@P`+#)Q)PK&4c%GP zoiDB7Tiz#~3?b21w#Zh?)u+Ys<6`xhBBs9AsJxWs0DA||Ss|6~w)~{$HEdYwMl17_ zI3OaaJvbvhu%vXb*RmG}W^9eX|FCq%Ckgzwh5z>j^rH#Mgil+E)bU;t5H>D#A-a{GcN$Qs0KU zg~M1%*K?p-xQpZXyaWp34vw;_HQ>tz7vA + - + @@ -1906,8 +1906,8 @@ - - + + @@ -2079,7 +2079,7 @@ - + diff --git a/docs/monero-spec.pdf b/docs/monero-spec.pdf index 3fda6d693528e2e433aa40f51341285b449854a6..0329428a4ee442950ab25ce0fb52e967a305497b 100644 GIT binary patch literal 300272 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

Nf%wA_iU|!&{0sZ4XPrPLAKD5mw>AX z6ii|whHNK=kV_PQ{|Ge08r*a`a05#aSz?B$UYfvOnXqfDcoR5Lg>*&`&g5hTaHM3S zpjsm|&U0#O`@dm`$%!Q_8=))Pf^%YAf^u2RkI!e}sSEM4Rl;@Ii=UcMr^IIACDiBMLV78B z7K6@C!Z|-?@zEoBeHo#(I9CYJpRRWUN;p^;^Tujj`$>(J!sZfdc}EfS2LQo=3t^6h zjhAXBXsmld79f(MaHS_2-wqF z=AtV(RUn|~8czzMzb>K3Iau(gJE!Zz(#vFX+4(=;Q}}IcZFRoimVJMcB3{ZT9c!HLUSaf_i47tAmQ0U%6?-YS)I)sZ2B(WS5~v85Oc zWkusuPtxSoGm5M& zq%&|H?2C)47=s&9WXa0zlV!>Jkqve5k#x3GF}#$>$hhokXHZ`8f`bOZjZIx@<;5j- z_WSt`l96fRO{%PLtLz(@d6GVxS@L=-4{KtWRMjBZplTx|Hj6Z3unRQ73b;{>BPI)L zV=Qa+MJ-X8OVmd~l7bQ$l~gbFAjUZYn#Q_vI~c>mLB)@~3L>MJ*v3~V4FBhY4y3V& zKd3Q5hO;(UeX^9%7Un+EaH`X{0xGrfty#RHn6QhwZhkN!5oF63DuU+oH(HG-DJy$GJUJ|`ner9p=(m(ez08E8XrR9k0O z9z0IV#>RZIoUvlwK-a7L?Lrl;!EpqzSjh!%{h=z~yOa(-^$b`yo<>9WfjKw;;VqzE1#QKk5Z7&W#V zXe_tYpueI*Lsybc9aF*vu9kkPxm*?k)hE4S)aLN%H_G0nfBC8~F;hmj0;v+3Zi zuVpCxjBc~H{L_f8?%LrB0e_1ja;RSkwFp%3uy=dB`{SzoI%x)UA-W1OZ97&!Q;xU9 z#Rna@%1R}rKKpXxX*6`&ox&unRL5f|^5l$)L7vmS<-0JmK)pQR%XT<8@h+dkY~4p!zvaC0nb?}4veNEQy%j-4uW=EI;Ro(`1kk`hS>@MbiRNL z2b2zej66$DeZbtTRSz#&F*v3YK&sDF6y<^`8Es0~_%%V?602xnOt%bSlu~Sm9jkpY zJKdeYspRonNbEti=!80W2~)qiqJRVTNt?n*z!|=ToaIvZ7avc((#1=NToeRTN-+R? zv~e@uPUkfq2Bd;VON=}^JXMzT1m$RxYw0iQ8&MuYP6Q02VrRPDU(B{wCHy27?Yd!A z^E}EAaH5aH+P!5B>}f(cbugB zwOUsw!fIN!yW%Ap$Mc{uvR zdE~sX!QH6NjQLDv`-mwT=;lHu4U^ac7-ZU|8gTQ`>kEoi{T~vx7Yt(UWlPX+>S;&j zgZ2;wvdY6MiHs=J``T3kCi>$!EsVd6&`b99HJfB3=?N78q0tH-N`kPI8bL~t3| zAY+?^mDBUR1VzoQl`aCRgv0)(t{x{)M}!88lIkJCu=s{29G#ah6;ov7hf)L_eM`lh(yH+z7YjK*3Xc#hjiE>x;HkKc}jYnvbZS1F!M;@!1{kwF`5+ zJOxQqkIwpMTcjzYCoDoQCa%~=K4+6wSJRZ{np-94-@qo*Sc=kk8l?$Z;B-0HwWY_hBF#hR$(}^4zItkQn`F1EQjV;~}Ux9dm{8 zs!wU?ZZ^z$ZcS{aV)h;h$wPFln?gu}Pk}n&ist=34PZMl&#@6ed$=R?qM*!FeR}4Q za`{V}=A^*N9o1Mqg*FD6t7B&XKI&O<^$#U_QZVICU&rdqS?cU>#?3ffM-c*jE1^-} zE(!+kFWH_`yCv1}9)10Cn=nT1a3J(!q>clzg;#TFcVp>S(jNnSsEe_Xm1l2K?i5p& z;=q~))&%XpS7RUOMmBkHIl`rw$gEOY^3E|~rLehcHs9y;s3`EBeUQ)r4k0sp2Q7_8s=_6&F>@noHpbtR*(cNox;ek9nRf$rm%2d(jxnig8TTl%k zWa&;!((AuFvI&cNyabb(q+(Dh&z$H-7GzA<7kd!81cSrH;b61V%5cKyp|sJTBvy2M zYfy)Y+k7%+1~&HpsDd`5H=5zQb4qR=f%6p-OMeqU&06`)Mu5o9 zfOz{o74`}$6YyRm;JTT(EKgr8qw#7?;B$+nuP&h zeLt=RwD0(w$3mv#gStEDLuY=DZD?xrraG7N2pu;{k)zYwv%Vf1p#HjpqkHXB9v}+^ z5PA-;s>LK9!Ah0c;QhExk>7Ofad+d+=)erT?9S%1zxv`K5#NvLbMeLR#vK##wk<&z zk+WKOyt}@2Rerer2<{sp@8*7cJoY65u;OMmT!|#;G$1B*y-N%?iE-ktUwqdwP&?o@XJAlN&gX8v& zkK6j@*H45t0GFgSx_y1SgI#0`&&Kfw=A&4mk$S>W3+@DI91z zn>1S2hb1XQ=g^0_yP>Cy&IuEBoGoA|u_T8$Ghj|mQA@qB!<>(HaW?r$CPwf65+siD z5vGdBR+{F&MHoL@M~H=?jSP*!0D6SX;mF#u{%jU-wSidw$b!iA;*3;9@IDJ?ArPnu zB45kP1|~e`VY~lp8WbRj(fQ-OX+%n>L`sOWV)(m3M^+;$V~~c}2>0TQVo_TvNXxIr zhR})6egX&^c7w!zV8Vvy)6e4zV7%Ee1JAR_G|W>K8zf>5P?nSbH9_&=HDH#P3c*bO z4`P5^Y~e5!h73xVJ)l}_FUcRRPlGt1Vij>~WKWU+r@zC@V03S71yRma*o`UrceI9r z0C8W4GyTOG=$S4zILoE*%Lp%O;{^ zuBe|iA%~#ZUFq}4g{dc2r;Tvcg&eOjaaSbNJAi5K|217nSc=#fHcACra6l6z&S+0j_h9-vvB}$o@;S09Q3Q?)Q4L~ z@3P7{>4kU|yI|)~u2TqgDVs6%8qtb3oP4>3`xRgAW9jkJ<0ybzFtp`h(;GbHaL)Cq z@~AroRrV)xf}7M-$?k)K=#2S(!jgQ>yaW}FS4711^1&=%IX`I01t>$`yai`FQyv=v znoN0*t=K~WTG(>zC2c?Z966+;Y-`C{okoPs)`!R)l{14zDC)*Skvuk&8E`yQQ6){F z9kKDZ81*md0@Y8=&nBILm+i!@wTE=gy$`SZR~>#vcwrCRr6?MAAG-YZcWM~J!k-zQ z3`2Ye&~^h7*BgD%dWu3ckzZOJ(ltaP(CrVYeyt<6O%m67^TF7`B+9rz!5SeX@)~>4 zMxVwS0sa@1;SBu{5Q3B8<$m*NWh4+%fA-3-9Rdmih6Doc(wJq#`(owGkQivrX|hEM za5FuYMs02@H~0K;^hQ!y?fVUh&Tiun!)n-k8P|~3=xeE)LN>1iz3X`a3#w163dtO^ z8id$0j9mP}M-*iX=m|K7B7%|CZ$b4rJFec%ku7WYNvIq*Hdz3OqPf)fhs(nc7MgutX8Si}-S$q@>#afJL7HTG?ve+mlu49bMf< zq;~K$=h)b4p;cQIfi};iD(s8~PPZOv+LBy9|3qhME`zyJc1fQmNt?SE2K zdhgI2smHoQk6t+g3d7$d>6cw`&yYf~S9QCSSQlp>1QtY@nmUxD0a+1kMvg*bH#4R3 z=M-rY-f1IjcM59ey{lFyefpbhwcQd+X~Osh8iHe>BLdyF-lO`iAe1b9u;+E!vHOun zmC{QhaSP)^RTWV?JUH?V=?x59(f2lrT4q9Zli_=sx=l!bJ=GP?3UYPc+fhKuA7O0h z=Q(&aJ>^Nj^Gx=yXaB-p28}l2L?Kj|cuT*z3)y!0?Q< zT@-twi?oE=_b{|tLDnqpMK})0%y%q(u|~QUVt=b8x|R^75lj(IqsEoJt6PKTGZ`RHeZJ_P0<_U91=i%(ISdmvFUG!(VEN2Z@thZE2SuJi8n2Iwag_D*LwE zuKTrFhjyo`C+qPT6~CUO!t608eZP&5t<_~)TVdeH%(|~LB2$L=X+uQF{Gso_L}gVyMgEL5M&R%*A&k$VmhQ7b zW^gC+BQq8DF}+e!AMX10}lR ztac`7Py38KnUeNw9Zg-s$dp2nx+jvZNQwfsudJhS<@MFmXPOXmq7I4s+(AC*{z9*d zdiOrv-2o~G+}$oM!zxb#_C@vFpcOiWfM-BWB8aig%E~F~PEiWbMjqUhO~z#E_+X3_71in*pR^4T(Rvdq*6{hTd0*1ql6U5PVm z8isp*-9C@;9ITU^G?Y%Rj(?^R?67u>9m)VRfu`uq-6WwexqnRN9~D6oB5VbgW}=-Q ze!x@CQLYAp$e!1ur;OLNS`8fd=*b&<9CYWSCcnAqq0#a9vkA+a{#spKx2|L%@&iM! z2)p*6LH0E6B~^FE-y2=np@%rvfEc7mA7+5FaVyym;$|)WhmLJSGsbcLTbq#=1yv~J z96dEO*Rku%9A|4AE_g3^EnInt(=ziwoSk*j$>twvHTdt4(e|c1%co1%*Qa$r>u;AM z-V3co(Y%YXoEsY1gRc3*m*CjY(fROo1f1oJq%F4@f!BKKfT^mH5av4e;LZ3yv9qdk zzXB?NH*;H*CZ0$;1id1MpHmE4<|f)b7IA*BCKCVr80Q_F= z#_xFRTJ!jNL`YXa3X63=fX$Kob#ez%05`Az)fu%r910%r00rtyN1L4ere1`N)4XZT zqZ>~P=_2MeYE2|9m%@gjjc@R<3~|#I|H6k3^XQkXCO_DeR5qXU4+-hHNV{NbZzt#4 zLar+*FwP3+Fqu=^#|qXaksLHeId*PQY==qso|#GFVt|N_RjSaT{a_%qAL<+y4#%xH z^g(&KDr<+aY^0g~kJDwp7ovJQj4mLrdW%axkF7o-!4xIFk?Z7`1?IHp)g zzlJ-om06Q<&feN8^-|^p_W8s88OfoPu7-@0y+8B^i77aw2_OtDx6GEaQ(3$}KL53| zH{SZ_KtX=6_=kqFs)nM1KG(0kf4Q5^ftO6nY*<2HxV3~&u5kI&g1d}z8g7}P$_9Rs zqF(bz5exi2f^P0kwAGJjm9L){^~X?$^5_stxAEH;nla@vCVy|L;ImK9Q!CN%P;q== zG9&Q4qBMtv{dthyyFam;&N*#psCS2oDmiK-TQepl5n)6VmQ^4ddsUN^75PRQ4XvK4 zJo*Rz1$*wXwf%ybtmJ!D2DiF|JK*%!L9)M8ueKYt^6lyc+VFzBeJbnZsYv_%pN=t* z1N_VDkDRCl}}g`fpXl|DQXSSHZJZNMy9Cr=JQj19hhq$3hbC!r*QW4AGKs0l0MOd6sISk%EJ{F4PJ4x` z72oHgKN7+;2`oe(B-(Rb$MsbQy|&C>SRo{F8mj_!*h5#$R4WjBDk6F79BDI32I36% z0}!zY%A_%MLi;!V5T-KwJ_gQPGC%}G0W<#i1`Q#ZAz%e(NSJD;wHE4jUJ0K`cs84q z5!U^EMf=l=Eu$i*nZKJ=ulk3~Zqrer&2%!kKLQ`2KdVPTjjQ4kd30N}4ipP%#|*EMODP4zX~lE2nIe<0 z^iDz0Y!wdZMj*jj3Rx??gc67@>F%10!izE>s&Em^9iZ1J1HB4`^xR#%pyZsF(Y|y9 z9RmB!(szII3RYh0N!kw0SkczzZsVVsbihH$zU-+}SstD8TNM{WBO3KHII}FN5j#95 zbPthsxDyxaBZ%1@zX%8DS=tnL6%jeeVbC21tUv z_$p6rYQ)I7y^SvX;K(dt*-gMHR36qWyCld=7&xx9$i~c#;I{3(>zza9@*C?W&rssf zDV!_hs24aFsZcLl8kmWjcyyc{TdZ-ii2`%@53)QScS`8&1{A($ZM(hMt@KE=rCjAQ zQo5WlZPJ?JcJeG~k(@zq0CwRB5TTLjZ73#c8KR_qUK{3MjGq~jg%!J?=((SN1+vIc zr=Y_@0K zk*=_`SoDP53RAAk`$V`VrZX)bNx~{XSE1ItNvV&cfv_=N+fX)rBqLoYYHvqJ3dTqaLji`9D!WmiV^cx ze|KO6SK!@{6lnxUe0Q6elNlBbDF)WZ-OWQB1(Z5hSd^7--V~46&qD;@B{Jazo#QyF zkfwIS2}X^RR z8GgPAv}naR`6fb3i3WA*ECmo^7B~;y(I#Aa< zukfqLWuXNQn4a?SU8uJSA;8DT6!vloJMzR(_#T}Cz2M;F@}s5qE-YdFt)9_*D`vb= zp02<_>GAUZT9JYyz9d8Avcq-Q>))ZIF7Laj@?1m}|P#pZS!R6{=--Lb72c5ow{z0XUXmhT&n8t~`vwYeJ7^$gA0eNx7cQau#D ze`|b&<{XsfHV9?tlUTR%Nirqf#u~KAhx-t;=^`?;o>vuf3hAA_5Ua=0Ig;bW6`vaR zlxI1EtH=6re?83^Ndxa`KXSR3BIwk4=B`DhWZhqX;PdFui=*DIQ-8lu*Sx%fd1Jp+ zqwZ;wO^<|F@)YyK0Bi#fRzFVDbfSwgx2QbVL}jw>gZba3mH8p|VPf)Xh&!~YOvCrp zk!i!hS6A-cKRyQn6`6;@vt{LW~j+b~iqzXPLC zy>^0YdtO_2I>DFM>@^X}=7_}9p7blTkgy3U)$tO$=doO(7=p~azew7y0_O;J>=>)P z(R;4Hz&{4){u^bRnd5)C*2%=l`JZ`X+dngTWS?ia`e2oj0UP?cD?@Lkx*mzN@sQF%l|oB>HBfJes%3P3Dpu5dl-PYmxex>hxAGVeY8W%}#p3PTf2ghYK`%6SHY1Zr?Sh|)~c6X&smZ9r1 z&!=S)0aRVAt=9cR%+XStz$E~vve5FynS7RGw~2RGP-GPx_X_F~IwZHRZg$tSwvn6& z3?PSx;M&Q0mAjISDBvt8+H=Souc-Asn@u1Aoprnm{^{+x_Zfpw@hp$GN|2 zK^R`AID&{MilcAGcZPmG4ThKr6q_465s%BH0E=ViX1h>|alZbSTn2Wf6tD@sfGT9k zgpk?mdI`vg`Tlx+USH36*Zumqp2^Aa`P|N#y4-&s5kJ1#)OK`TKB%eF1w_9~k%U2a zMSxzVa=8IsVuuk;&Vz?QB7*aYV=b0u3T|P2Y!&A|)|Nb1SkH8fgu@9K!MBV9j^7$)%}B6gE;cUni|WeEJ}0v@gH2u!Yg)-XG2p3=H6>%PtkAb}8?_{k=ouuO!O=xlD6S?7Gys(%CYow{{B5@vn-~tAD65ZJq2(G+AN03 z5>{f2ZBJRpDoAKdWyTEy zXagCWEQ-}q85SDdi0mSDW}Y^4XwRflTJdz{TuPa!kRNux&=qa+iK_(fXs!vht;R*n zA08RE>O}0jCw{2!aa7C> z3Kt%$N#3>uQ&(4Ng3r{%`(A`0xkwArTH}N?aiz5oH~zPJJ2OTKw{G>D$>~NcIf{HP zWSj%BYMb;?i~<7D(oy`0rD{A}n5d;+-erWfkGzMsUh|@CbN0F#8{?G` z&gJxaM4bp+>5SRRpC3+hjajK|;9sq{{CtkTxt{hdTa=fwI!tFcj`2z);=C5rxYx6~ zjDci)i#l7A+nU5NB1GX26%VMQpqPV61_VjXrMB@PKH-;%iAEVSucoD$Zb9VH2A3AKoSEF~4dbOE0?| zV6P+TTd>-B`fSQ9WD{v&E8@ff3G)x!z87g*4@%)Mih|Aj#jle=FbQurk90!U!#0sX z@8AqoE$||%*kjOQ{o2<1n5huOBY(a~HdfP7!s7wZpgCpd>tM}A#0q>es9Zb6 z8E9TwL?5Hiu;dtmjUNfPtE$vJQGp_dq4tq31g9@Z{)3m}8eUclQ`PvFuqd zZM@V%Z+rutM4GfVqWs=3N}W1bblZ%(Jd`2|t`d1e`H0ypWwXg1Z?TpuKS z%OmNH0ah5Se&;?@tlzZxs|mV^TK#wn*DEG`b6($dq{#*n65th>j+v=MjT=TsG1CT0 zEU)ZY%(L)M4rlt)PyaE1>aphQz5){o>m=0xj09`me%R-VCD=rMWQT}CR(-XH&h>V@ z)WL<)bOy>{E09Dd3~4?w6O=f$Isw)hV(JtzBC#v65z(MTk^yoM0ywc9*=zG{cac@e zRILUskzCw*#U}Lb-fY<|oy94)6Zs}ryCRXF`tbY+LHbS!FN{p9ls21;>Jor;A0Qdn zdl6=G&}8fTr9okrmM4omK>XqZ>^jV;nphEV!X@dHW;2#l1#r(h%Z|mc5yePo z7D|>?T7toh7HjYNFs7YpIsBMw)y=Ze?#W=g-tO6nyu;-e#ik;pH;P~6M6&NpnhL(F zqI&unAQR1r?G;rOWssAF97tmCVfF$_#JU1vaF4Vkm*v+kP?xo5QSb2w2mV>J!fFr9 zqHKLw^v@D2!GHE=C*C{%`Yg0o@>E)q)4xPrlG~-p>W>SC!W3kgjSfyF55FM4q*&L4 zvc?M^`1LExZne6dbDO$>^1i8y@DT3Wj?hGQ?Z{<-#vUf9+>vfoCGF?*SC08lvaiQY zDk6`0>Mc^h6_6v0g-%jh5xg$=ndra)6v3FA?0Mvu=tRi2t1p6Tw{pQS<#w@f2{s_g47UEPG3 zrsbE%TQA$M&8?2M>=4IK-i6QTO=idJf4uC@ho{kpmWVCpH^|ML*Wl+$Ux)cIvB6Es zxx8BzmlF+|RrVND(b?-3SM!-EV(Rh|j|+GOmzM1tEy~(gBfy?xci9+Ab0JOgZ6|I1 zV#nGX5KG;G*}6H;o2)yHf)Fgt531ua5^)f?FIAq$Vp#Ylm zRgO|~wuFW9%)*vj3-7dUR&?s7U0G{J-XxhRR2S}bG;GO%=jb})#?mS9hb-g12;JQD zyb}2=wo$x3=98MbPwl2I1udHgTS=|IZl%HUTt?|@(3y|Eifc_DBR6|Ox^b0V>l9M3_ap+sA7X2 z6cceSzuWHL1Lw%PwEaG{qtiUNPj4{FXsB#ibIT0uz9qUy1MGa7ybPRubHe05{g*Zp z3&a0X{xfs3GyTUfTC)bH1<7Z*X5|rdj7()B!iQ`S%4y}Rm6##+D z_uIske9!q;-MclpK&5w2$v^fz#{^xz>(U8dpSL_5nD4jqt0{zkpO4$z7hycFbn(|v zi^sPa+?U%p;U!h;8Qh@Y<9Ug5A?;t!kb0fg>1a(5~I zK^u7AKNY~{*fwsD&JCX8pKb3g4Db&54#W-fzuwR0&z9dd3^5$2Z~hbuF%K`5-gmdN zCR%*UK1#Ry^9uw-ze`HKQK45NVqtA5K-y!sXWMe-dSYz(ueLtwJl~(De&hRmYlm)j zxNiGA*LvRj8;C;@8vTXd9MN@UfkJd9f<2g(7C%Y48}$C@^o*c*seXTX)&_y2@&CDK zgx}Q`Dd`;s9DoZcxTY4XxND%hOAtg+>U5Fk9qcD23hniZb?5V4#Sx78%8}?e%)AlW z9Y9DbL{5r!vuT!g&h{MJ#Ryt* z2fpZHBF>vyY8Ah0!B|ruZ48otp@G~~k%z9`KIc%#JENB`uUepC3c4(31s?%R!^+U` z>#H5HL|PvPb50&ngSznW3E(aGVIXh?^kOdcIadxf37;J5^A7vJJ8i&Io%+`Gpf!H-IT2 zsd>Y`28map=vtnQJW}uoAo3o<*P6t;@b{7Y~SjbQ28`W&vu*I~u4+9F-sqFW-=CA@qdF!7zk1z^!_R3_ zyN0(OK4iWuL1TBCQHH)|fQAK;kl2bE6SwYDckJWnp+h7J{H60**0N1{1g;u_%(rf2 z90r`9K%Q2w`wFo~%?fGBhS*|exfkN`XvQC zlch#mP%Zu%`KnK(dnm9Fw7_QG()XA5<{aBe7!-O)=_;8vB(n1#SfM8tJIANk(kH9+ zatN(P= z%?x-eEv=emk5Yn{Dh__^B{lm(w*_eYHSs1&AsY*GG7FHGPtJ`nD?Br zhw~0Lj{XfwoJ;#@_y^)uA1R(PmNpVvyU2UtVJ64fgLFls`@+HNB-M5dz1+kye`3xo zZgg}VWpY!6fG`}(oypuj2rEs3xW+VVnh!%w!(b8&~Nxa0hg2K2D=Fb zh16oBsu91X-vWlMph=C0PBU{MkH96_t(QnCG-Pvi^U#JUokgaHWJ>VHGpmr%cxXG^ z`ohcc&TnN97TwHP>2l5)tJ;dtR7B$980>%?8W#lPt8_IPCCVYCfD@9oTmnMQYNNW! zWS5xfK6+0B2wGc3dFNf)iCiFHFGYh!0!`XGlF*+>;(4J*S{mzHZ!V zE}-uYMWuUCF;q}G#5JHJ$p5B(EDYq5HO-xI7GWz}(Uv4H_$W}v+GBt2Fknhj6y(X` ze`CEFaDS;-N3asVUHP>`FH4MyCntFxi|CS_;vvtBdrI3t*6I=u3xt z0zi0uNW z{Tx~i*9xWr{l*g_wL13n0BCw|jNrvFS5j@?LC<8~Dwvxc%C$s0cC zfd4n|5v^Yt&UU8kPG|(j-RIyqRz<-#&+N4Y9Y!%scO)Gp{O9TpFLO_MRus>K^a4wi z3yfAW_Php2+8B(-2`kUg`1ZTl@R8GUe* zs&9f?0qSO1bo(RHJ8`peZY30FWL?)zbx)8oOP>o=>_aP$F8yT?fZLOLrFOHnOWz8G z3M2x96a1OU$6igS5i2m`*(YAD-e!iwpxu982F=uLom8^sX;xF;Wi_rof3j5=y(PY$ ziZDnvQN;x0@Ia(y5ZRq_t$da4-a4h2aCsp%^0n0kwP#vqD#;Fk99zlQt0?i)rb0zd zI?of-ZksFNLp|P5u3#WqP2*g8#T`X*TK9@9D9hSp!G_^2{PR=8+*SMq`I?|uhFlv` zmo%uAu^X%?a>9^~aGATFDNs`_Yo=lMocg9I^LvsL_;LDFih(L`P*!h{eI@GuVeh@8 zn)q0j_s2WmckgpB92tA=x)Z+h&lC6XzxDdG^@eBnz_-W){7_>AcIJ*1l!3Hhb@8M|!JM-olr}Utpf# zC^Rpe=c>zx-*>}SUU!!;(GJZShCAH}>HfGX^8Wb_-#O3LB6zsTwz+(xNzp)MtH-Y! zc2qWGq4#C6QlAzA>(bvI^A$?3P(G+8iAIO}j2$i{V~k|_SWOVOZfA9?7Ve`0y9Dx7 z1|(1(-Sog|mG6)2@C>A_UxVVVdeoAb2zg?zTjH3QQ%bX+hQsMr)WR=&V)+~CFFMyAy z1!#;hsE5_54R3BQQfoLGy!X_US0M>p6#XibNOtPo^Ie=WCB5_GQ9U}K+FlAPJm4QO zD|W(cdO-xrYTWiVQjS^Mb$2DKcUNXsORnhu)U@>}wEh6=myR~=V$eeRa^^6# zDA+IVdb;dBWUbpndnS594ELL>A;p)3q(#pM{gZ^kkIzWWzwS z+8^p-Up)7U90txDH@f8eQg-eg+k}y7zN%&ST9&U(X+>6itOlQDn(Ns)-nv``*M;tS zq3X7)brK9tgF^7V8Wz;cL#YgMR7A;doi*R&*MWx3wVov$%iGUSEDGc*uO;vnbe@h#?Ut>D`H9vv7nCrm%0txJ7XhMY&rRH)r4AH)*t7h?-BWH; zKcDaI@&nWM{^j;Zf|0AIs)2%&r*>ImpH$6~WtCXsreE4b*PY!m^Oqtx@wbc8 zL_XTVE{aXv7rFEV_2qS{^_D~8VH9z6?`EpR4-J;<`Oj_6_En;Ku1%KDWiPj`Kd0sx zTXekI<$hI6H3+3(&)4}-?nGb~jKuvA>wpzKvOOM$`$ z%2b>O^tE>KquSnj0j)E`0S8`CHDjdx;=ANWFj1KOd6sMwZ@$exUen2A8fyO_J@b+oxsQ0Y4Yah#kiNQKi-A?`DIMnfXw6gsEoz(OuRkFJ_IY4#F-Lb zK(X>Owelyh7>iUY3agiSc0f)P{%nV?9?xM$DXoYD;vpUrZc}dZOrz|V)8FKKkE~`# zDXJO^MsI>#Z#mxz!rp31F#G0{5{t;jBc^EsE@}a`^eCNine-{UcJdat<73U{f<0cp z<+O8d<6m~|`G35+;BNQ*;x!4*+1$;7DcruxrCt83bm8@c#RBg7kD``QZe5CJASk^Y zg;ejKP_OKWd^WM)`-fAy+Nl-9xa%16;-`JjFP1@ zOXiJ`3wW=^j`&`E z@@QY0aXK&LyI&WbCvJ=>+Vl3!?{Nn|UhW|V7A8FYE}R$t&xZ4ovj5AMT{si3bP$q17)kE zDfyHe_4B)z*BhK2KimjiQr>0tjH1&Df?rd6pE^ZuCg;l@zBurYqC=YX+wZPc^Ib|4 z5xjKoako6C81ABvU8rkNz6)M4`eV$&t1`CA@iXS06VZiIe)0PHjj@rNXV2NpyIkV+ z8*Y44&|GR#-YZhXgmC2IQV2Xb94+M-4I~^Mt#%Ga*hVqR>GUk+_H_3OuDLOA*id;N zU3vpM!))PT3OA9L>D;i|-6?%~_OT@xSNmsyyC=j`**Szl^(|-h9;2P);h2=4PV^d; zFK@21dF-wC2|pFv;YD`xggWQH%5|;n!**LSBX9Z;G~Yl2$UiBUNO60dA6?ZRr-V(5 zCe*D>mY~l*;(u&)=3X(=^`?4loB}%2)E|w^R%&bca(|m^sBn(2EMi{3A&22-L~W-T z`T>W55=Z>?`BGbFkiUEypdqH##A}2t}v>#&~u5e z-+*_^ajxY00VB^x-(cU%8uDL1`$JXWT~%f-?Kzo20rV_)gl72Pm8LO#3(cx}=yz~C zg!WTb8*KywpYr+j*Jc^5I(I@Ihi6Un_%er9w>aoI$vYe94G)G#I_;%*8c!L`tVeY? zbKmPy>e#z}zuZ7$#;a-FjL#<~Bf$CRjatRoGM8Sr$+@@LGD&ZMBcQ=Aro)nNR#H{J znH^2Kz0`l~0i3W?BYv$r>Y+RS>}~chA7aCHiYc^jy*>G!fqX-;o910F`>;xGT zYT!~!nmD+UvSlgGV-dO(sHOtz75`{6ys?rjT$Q|W4&(%oSo+n(bnm!~bijm>zZZCj zp98*8JJa2*efo`BKe#{KXCv-pERZl}?Ur1b+;8`>(^p{C#zyITlhF7`qYJ2W&TwKk zJ?gH@&pqsi>o5C!F*ecnoSL%lalD0f51e7=6sQ#%6CPL-${WWY8(wR$ccbl7-Q=J> zFLv&N-rH!y%9NX4xVK9k!A$NUp}b1l((GSnU+GIMamZM&N zxiT8hC=;Iwo2}^ z-gn~JgJt=83?{}_pS|y*4UH!{%bZV?nTxpkdOqUWg_EKZ`EQd6PScjlBGox9@#UWn z#JGi|UffhBu4dlPprZ~F49yJQ0Xa|VxILe$**!a+gH!BLLdH{f<@M$&z{QV z;q|Y@*ash>tjWx-kuuI^w<1ss2j;a9DgS!mYr5KuQjhJPF2JFW+#=XhWGk*s@2z zRyS4*=$g~BMaV76!#Bl$wB5%&qVm+i3{@2fRf{>K`E%2=Wn`k+9!xfQZ&b-rzFUiy zDV~tHeo&iT8mS(rxgNahrs(d6w-yloBT?KmFhcsFIb%mCFU|qgMNC&| zjXisdj&YVY#Mb(NM=!!v(e zb2w;{6=xnV+>DvK2<-piaK2#iSzd4HcK$1e9W$2kA8wH=qb5t+7na=FVE#%mECNvv zwdQ%`xgNxgTTa+U(d5VW_fczLwoS^NANbkLV*z0G#{Y(FiQ$wtW|2#88P9TA_li|SC!3d* z{~Y^xbwuJyd=uyQ3zKCveLw3!LY5)rCtL;rRkn5G!>jbXLf`iy&87pij_&S-|5CpD z=aTGi1$TvJwd*_H?brtHi-@4=|Q>O!wCpA*&7Cp|xRF{9T~mW9fN-~9Xl z(MOWdy@G1G=K_E8Qf{F38oeIr?bRUOBP9=Cv5{?G?yYykvgk6@Hkjwui4?6ntYNTi zJO??G+AmM3px1W=Tm8H7MwCq6vp8rxTPCM6+>HjzB(UmxC*G1G51#V1V9e)=&ZzH| zus#(50i7kpv$G>tZgol+pV5iBbKCCo+4#n@x4wx|#Fw5OYPIsoY@935S$*ejlyFDl z82;;Clh@v4ONM00ONbGo%SEG?P(voZ3 zj9kyBAg*GCk-68hJf&%xUewf2ztd0%90lrGo8|9oK|9*Z6@5ovtQ)V+U0PF8Vs$ z>;0LhiLy9)LMDa_eg=*|ieL*`ZCK4^kLfcFtNZje@v~nY12b>p{14$WL{<`Oqt4Dy ztj?O$w8FV3!kV?)iRnvUso16Ll7qw=a;K~PpO?grNQ}N{Fs|;V&nV-*Xx#|)Ed8!O%@0TF@@Ab296BydcbsK&O@3}$$R5bX z-7ED#??qlpbsGgNhnOX1A@wHW@mcck;OjLtP60j{tyXo2WlL-M6%yDiF<8NgCGR-! z31Y*7@sE+oR^|4&!7IN;A3n7$DzZJU&a`5NRcQ{~8@J#dzsp;&)?Is(Hof*DJ52cg z_vcx>{yHej^e5l$$e9#R&~pa%r7OK)Nwd58I%N#0aE&?qrF*nM#@>C`B?^^hhnwk$ z`k*81;!1%L%4Isk+HBU+bkcgN(Xu%qPl?bwzmnTGp{w zfkt3|;q;l${4}%euUFDE!fy*-srb@Eh)v1HM+UUn@Xo8gHxj#h)A`|QlX&M%9!%gV z@z_r1Qj4RZH^f9ix+C3qJ(N-AP?&l-3UPky=Ix)bC+Q~TYg6wvl3fKf+iETe=PfC1 zyL7Vlm-jV*pVWb#ynJ*1^4U-P_0db@zl)W46o(MmHT#=LVqHDTT4lN=Pyk^Hd?m< z2eYeed^^A5%J&dpJ^mBIS=w^{awT-`R^jWCokPz+z>I) zwsd%5hi+H>xK-S$bY!wKtdKG_CME( z)9xdAzg(gulC>ueqD6~rH8#8Pf^>p=@jUTA^LL9}cU|7FEa3eH>iQ=M zi#A;e#-JPT!)@#P-cNX1NL4XM!xbKTk>`~%Xju|d?UyLsCGQP}`AlZgR}?1L;ddjm zPxxt8V98}eFct1MIWsB3m2>;X$(kh(a!}frrxay%Y}-QfY}k*Lt~2&}edMfJY;$q| zvl9cemq^%PITk)4$Y3AMtesyz{d%oDn~k1e|I#AM!vpOLLn)#bg(=|*7ggIOOzb+> z>qOHGBOfWEZq*|^vVMlrYV=6rgJsw=mzD3j^oETOsY@OoJ?JOKQF`;i3>@-5GIjKC z!PtJe2MGVjf0o_f%m4OoNyHENw5I3gnvy~rg$v_~-7WtpfkVqI%D>U*7vx1k^y95zo6CdZC~y^#>D zAJ;#HUX+539R6OZ9GYRjmgaA`(|WL%`RyMp!7XUd#=;L)q!KSf94tSdQw6>8_I{DW zOW6SGS-#eKFrR=)}SuQM;MoDx@bbFck{XUmfPn={&w>ni(~o}gMx4VUy2@B zwV_G|>H8s~U?iB5slXpD{(szb8m-uPLVHt6C~=rh)}kG$ocxW|gi{MlY&Q`Dj_8H; z_<(6oida3`!ogvp(Sr4I>FUQ34VFttOiJpyI`h81;Cv{f2Au`FzL&R50-nkDYabXP z0hveut(89OqUA`u+$M=$T5-F*%)RmUqXx;wp;{0+W>yl*A|)gcYH!>>Jo98gagtRf ziO@6Tq>n7a81nEt8R(uLtj#WJFU&>M3Wf_Gr4^2&K^BNAWv#KY+>80{5A`GTpkz0F z29q6Wy$Ta(8_6Loz03m21Dkt`zEFT9&7iN=&%5T^G$8+$Fz7QllfOQ(039nN>m4?K zWoKOZSoXn5&k)Xkg$|3<(^qrhLEXtksZ`=%#FBrC+cfd)>l_?MFG=S5H3h=hFtCQt zGDNrvgelrWudk%(Ce61Y!3}u!Bts;Q%9&zMXMOXvL$w5}Z6W^E2Y;4Do9 zE`ya!_T_|UhZQCU&5d9sL8fy)q3$#}X_J+K&t8A4)`XArA)h%A1P{9{uU{ z^LFLaSA&ZcTM(b@WT!l0!Uil0JjV^|@$T9-)=S3;f-qM{%HX$O_QP@_=9}>G#hWXI zAC4qUr_!*jNHYfD*rJ3+yZnBY9aDex5#PO`F2c3ajh=ZrtVlSd7^QA1Ik?30QbZoS z+TibCO^VV#u<;0+XKQC4(FTj8+T&vzlQNNeCh`z*#J8dVi8|$-cNUDR1xU6YNq@Cz z4Q=c(I+Hy`ac;ON#hB;lYgzc79`>EhKO_(7YHrEN@d;%KTeF0$@L}1-{Pl&rcb@br zHemIx22EL*GdC0jO|Uc=MAt*hA4N^GYGm9S-ks*tw!nKw1Vh&{_no!>m#G11_rm%| zIjQ-+1pKOz|MG75QyR#zW69*p5LQoq(|PCeBQs!wX~%{=ZofnLS&j>`_)?DVS6zPX zy~djVN}$N1h4#<}ONo^EP)r(quk|X@M00JxwmjI0O+`9=Ym}zk1R5=P-uJ7GIF=S6 z&6bHB0XL+M<@H)qjthso$jp>7SvMfr^)GI`?XgC(kX(fC#g%CIK)z_8u+-%y3{!4x zX53vqUJ3&%iH%fhc&K!fymF7rLN+PRz$ zsuGUj<<~5;uDi!)-^Oke3f?op>Lpu81OFk1>hHZzmuy8Y>?Hs50IV-e;dyi*5-Ihu zRaat2yf(16o`i<)^0OprCn6s5)JK}W`58*B(WBG-dq;ltxZ$`51v5~1PGSvP;`8T` zV__G9r~nNM2gR$KE7AyYizDkJ{ma>DOJPeeyRspMDh6R(1sYR?BVa=p;ug#vzj4WC z%a-^r2X>c*7!tl0tbe&}>BFcdvZfH##^+ia90tGXJ#hNuy+(a#v;-K59kPIadmvf1N=MG+i9@Mn;71t&Wxx4U_g?`lbE5VL zpx*%XGTxHg$o29jM9O~5`=p!Y(LqhoYryCHKKdnKmgHovYZ}w&dSbMyo~+i>M_m7W z1Mp&Zyw@^o6*-dQM|n3VNF(*ke7X`|h=$v0fcqH8*}%WiOU<{i*L6~jsX~WF4lzvO z&~(gzLu%H!5qVM(41FoT)4c9lB4}|FqVoSexE+Xp{Q$5rB?YTD#@!;x*T=B|Em1wO zY)1}7xd{USy!{(nKsO>N29uRsYx%3V*55H|=t{KJc|kLBc`{S(g%Qudtj;#gWDfaP zibx4Td(JNo08w|ipUuwYeHzhdT6}nb?rMMYSQ!Yyo2~&w^#Aq1>Vdf9i!xvKayZu8 z#||e7bZw7Cs-lIimDv8~rjzIg+U;`5<|S&*I~yJ$<&XMgd+31 zBl`9DA)+-W+$sf61&YBOPS|vs6t)Y@83Q?JIg~4@GhWy}u zutxUsjs<=Q%J^fQM1!|uu=%8#DU*!16=jSPe$K3!#FSH@g^-zJKuR17|W@(<6TgYqr7U zTcITy8>xNft6oEN1#0;tzRT>C=Kvid;vbE-=@QNtdwkv~X%h0Wb!7PytJVit2@vK` z(*YS2Gd%lpPpk>dD*Ix!aGj%aNXg)1!StIchPXUOhRcA4!Yn}s(s&w@zdhh_GVvG< zr8X+ac_ssV*Q;4$^y)1?+&-e;F;`l}M=Uy0d8~dOP0LuVrCQ?l*4iN`2`#3x)x1v5 z{s#+z4L%kywi?St(fDS*x~BC&xbTBLEH>V{L7jnLEp>^pLa&xw232I*xOYY({f)6M z?_lx`0jy8LRjpXbeh!-gH?l<>oNMysSsR&4b-9o7#qR4O*KdoZ->}b?{-HHPYUd-~ ztKFsg;davl8V$30oeP?HYAJJn;DKv$MjJ6g^Z2FPB5m@_gLx!-$~P(~w7RIn?R9SC zwCLTi6Q(r$?(d&0qV17gV2F4$EfVRZA2~w>WofeTp*!G~T3&3;;5QFv`Jmxo&CUV> zkE5B}X_0*X?Q54e6rBcoL+)y~F!0|@8tRhdQ&TTD0f)1IH1Xl%0+WcpC-|0Fe|P6< z8y`5VEQP`8EW@73RldTc-j;C6hs-QNH*)w5nfYRPSM_s}%(5Tvg;A;mv4uld79`4M zls<1 zfyN;Nj$Vsg->UFsT>7v{)@e6MFz&gZQxKaA#Wn@DvRybFZ=l9^9UwlxjeznS6>JzAouc2ThHi>}Cs`d4+0nREh~CN3d^vo_DywE*}Qc zRNq*jZ+2_xorYwoHj`BteV=+jXreQfk$m8TopWX~zil_!`*?BWkKqls>rzAh7jk5L zpDGWa*4b-Q5{s6l*Xkfs7YEJMuF4xKqR@m(P(-!kZyQ5&KCWzW#7hN+;IY8l5d-UY zR6)dXba0w|T`Igi(`b-Uj2IT$pR>2S{GIy)-nN0-C4a%;m@&XbQ@R7s#{4K|q_;p2 z@!-D}5OZQtfnbon$Bhkj#k@GDLqL~{yWIp7%%*zM<`H({%f2&EMVU;1tMiX8d57rjMplkk*K%EwnPFNwn@;Wd6D0>^H&W})o|B87Raz} zw*|~VFbkkv{q^eud$p(ESGfWOm{~MlPYxU23#fBSe%;juJlg9h6V=G+h}+k`&|$J% z;DuyF0hWhaD;LnJK(bn1@#Wo-=5^HdHw^>Y%ODN~z=ANOs{tCdVPGKuzT;CIG@&Sa z(Kin@0F?>^jNLVv4}doH&FelO%&!}qR3rW|p>L=6k$O`?A6*;!|BwH}^3O;|fHv?B4BL^>?gOa|2~O{xvUqjIu64 z_SMRR<$SKC|K*&FDVYG3B!*`I>vH_>IOMI|8zvArf^p0y=TdX171f`VUf}oml2Q-V zrIb#AmBjsE)gqQO>^n25iI-W6v!xZLfgo;i*daNr@yrme9+28sAW98B&wu_YJ$=5K zLtQqfsWq#%2M42!{D3uCD)2h>2Jw3JJR7%Vb+kFTlGoI6Uz0`qiQeszfaw4<8Q^Eh z5#wFnG^k$~(u<(sYZ&kqGWG5`)t%e3g9gcYA=V^7R@Wkd;6J}3kLmjqhKO_v2>6_%O}iYH5nn!KAj+B-NxNA zAEBVeCeOC<88zWJgt-`$)l8oTRL1T6^vh#u5fpK_8e(^C(<35%Kg~)*S>y&PD%=-L zpRz?GdK5H)iTbCWgopqfn_1j%s!FT6B2Wz*^14j0%fR5%a_c|6K*9+~$oliJ^u1p| zBPUJOJbqKvL$&p>$P~pKRZ}3*x)KIcx|`Ub?h(L)4Q5&5lQ#it*pPs96p%pu#3p`b z-C*N3c0CM4qm`A0_eu~-Ig;?7-%D}IGVS_j09eZ6q9Wbj4{_tEw~nOdc;h%k!{@7c zT}T$lElG&6tPRkrj%a#$F&e)SexBV*J|qHw&i;C0n*e zqFq^V?V})bkI{}+z;Z@Qut>BDXSi8UJy0EO2?K0CyVDKyWA5Zhh6kbPLCI=Gz32+EDpx<-vK?7$~ z(R>T7Ka8S25ZKM1vZRhloo`yI^Ut1oKm8Qo8+kqo6NSK0BFrn#OmoK+Z!F*MqPlro z*6lSH%PV2-=2bXf{Xi+-OA&u`rd>^rZ^Ct%`!TdiNlZ9zMHZ7~{kTRpd4285iGDyC zrDt_gWpzhv)}tcP_#)`^yUZf~U+YUIU>dDHtFwIz?Y>jJ5A=_RL7NYIhgsHr@PK~e zUlKdBv@_GNVf#1a5EKofqsqt~^~{V-WKwW4Gm8mjH@}_)9?b{i8>uT}zh*&>^aiv0 zlZljKV7_|lMD2W=B@@kLSh1%CM7)i}vZ^kLC!Nq(s>8e(g;21bzJ^rM6obV!2kTHG z|44$}67hhkBR+YF-9RBF^`kGuLj23mu;H%rC)&k={e35!+;0TL`XOb3;t-Whhc;`= z4EmxEm-bNx`q>{3aEcf8EVCWWkE|WSr-wta9dc~XczM?pzn~weY+?{M@;e@kw(MYs z7@CS`<08Fi?yRks0# z0opEjD{}w$i8y#%X-f3kwLz=dw(p(#db&B8^reH^V8+rc(65lq?s#iT?{;fzSWG0n zAh($&G}>RdQA;sFvhg+2j;UEh56L*h823R;o=>4{-!%3#qcW*M&~oZ{;a%Q!0XM#C}LT67K;QH-x|Zj zU#1i;n_n(~R3QbVs|x@tzNb`BEBt2r%hX1<@41p{UVHa0??GIef3X$rcBj zwt?q!XmTh209-Jm0`*#DQXpi(_`^FWpR2@whXe#2C3;|E9z=7h2fFJkD6S?2wftz1 zhR+j-RYnS#(XonVnzH)ymPqWxk6y2wWy-j^eP_h#6I%T)RB3*?pobWC-uaJheLp@J zYYb$2y+4Nv&iCr;{ba36w%(E2m6);vQi^DxIY#bj+h63^-mLm1JgUZ=IMkq?*;Y0b zMTbY@A!tLs9W@Lna%Gr5ep^DvK zFRT>c?T!It$TI|!W$qZQvd=6QP(bepFlh87Z`sz3-6zI#Y2twOQcTAP66gA9pLyRD zD)a>kVitwhSV%%_cR!&9a+U$FjvTS;n}@h3*ZNrtsC=Q31)@R_pxb4^l4eiOUor@I zO=LF`8Xu#|Z!jELmOK4)=W=+S4eYSOcr6RA9+STbEIs#6Tmor(iK<8rsL1`zYGBqE zds~|9fVyN(LKiz$s!fzUUnodo*IyiNx`gDz2J6Sdm%NPo#G9sbFu z;#Dp(JiQ~!=48+hOl~Z5G#5*LFnG_d{-aiHk+s8=n{sB!U@HlljDYfh+2#3Qlo~7j zUMd-G`q&|$etXZTAcPnvN=7QHOZvl-sS}5Cmc!*{(8xmXcG{QKS~Ms879?<3yd6GS zlu@Wqb&%1!%>=Bs8qTuglyPBSyN#ehC(yqnX2EWt8ZB~Tm2|rz(|7ZumjTefx-`df* zIfM(RL?udgg#AvT2m)G39`NXIrpf@kXaO<3v`(Sb(+7_0M~2s4yvG8xg*c|)nqL9j zj6FTM;%|c4oGpdd>aE2M2QIR`wmpjn`c+uMjGG*10X~cv_Ip@KDFabSf<4k;pH<$1 zy=n&9QnF)<051lR$ujoRH$D^vHcLpL?M=n_d?sz5?=nQ|vd11e5)eqvXLGFm7k&>h zn22AyWB-P}RpJbg(D)XqjGl(L1LD~3(0KFLne^0;8hklmMt2@RJ|$ee*t^TWG~0CuSflTVmXt zKr^IgfglZRFsNkyrRlwhRL!4n{gA{E6=@~x!z*(PKO9z=cMV}91A3VQ#tkS~=#CUI~ft>R97Fu=Pih$Pm2UhGe zCWuetAfRixpJTelQ3zVAg?ZKPBK03Xy^S5kYw7 z44TXMLwKg)X!4ReE{xcU&ZSNi>Ng+(ohSN@1OMBPnzS*lQfkx!ObKMLM*RZx{dt^{ zIN#;4wNdk>#A-_!x3Pv9Pi!z%)nF9$B}8jRE!r@@$TcO@d7qtGnNS?Web(jDvOYa|qA8RYtoUMw!m7 zn=FTwnfM63H$BghY^|&??nbMB*~7ct7SHawsV)+_UT)|n$Ho-`6)@wfSh zR>{`l>>QsQVL)mHYX@kr(}pkxRin%t#65ZaN0?$`NhzJth zbI|hzzWe(_D@yNZTBwxhwP<_uzgpE!sz6Fq-Uk#a~k*X5;kj1-w5M8 zKSEW~HAFzPf|!W^F=&O`?>$bsI&19D12s63H_l+^C=US_AlZRb<_M`PeiPv4zG+X+X<+ZgGgEb z6}16|zZen8^D~bP8Jd7=A1?gDbJxJ*cHtM-6I-GNgS&83EU1{kh1QB@9RDkf12U|u zW|nU}m%~673kPoA4o+Pc64QarLldOuWahs}0NlLeu$98N2EINb(9h#|vr0kqdUPx3 zxkJ#X689ZfHEauQvNg78a$0oP7U=T7VnBQ((v2kBGo=Fk;) zJInXnL!?If2jO260c^0)P6}!080dkb@|ToyJKGdH-x91qKo!7O=c!%$|M(y(Ke^**EskLTLF!G#JGZ=_~Z@-pq8@4 z?q`mOhHecv)<3N%;!>FcEu-#v=XZi^-Ykm%@gC)gBkXnQpW%{JlfA1ed{Dr(l#u5W zJ1x-EQ*(`(SuqDfN?nH6K6mO!Ly!5jGnU07uUQ@g&D>ipB=)%9MK8UJZ1m;B>!AaR zFIQkO&>uk6=M6fTW`8u9%B-iz2-2`3Hl&FpVfAeNVV2>^BxNtgdu5n!phE}Ksn6q2 zV?Med@!FYkgI3HEK!qpU@pmv0!q=+5yYj3D?a$yHmy6gLO5uu2=E=tZ9p+4HrGHN< zR#~0eGMdKQq2CKZysQ;%D|PW_Ug;nvHd9&MdND@ zc5Q{>fiqlL@ER*Mkx+G@y(2F8%7L?QHn_F$+K&f{r>PT6E<7zccOGaAxn}2%^8sqQ z>8bxR)8xaJ%7%(B2A#GWP?dTz?gh)UeU|v3v5B$1F~Pc_-if}gS^j_Cu)}|Dw^&{T z`Hbduv!{QzX-@Y4>83fEf46DwuiyW7o96U1Ej%58{dK3C=>Feqp_3B(pHJ;spX!e> z8MVNj92qe@(0%wk8)TS}r=}G@Ssr|s?p*(;{6tr9t(((_><4diK?64Gqj|&Ge4nTv zQn21hHEwxmgn_;sRB`8Kz|1q1aqkR_Dr88gM81Egcb(H;jVVInB)#H*RMND+7$PE^ zp2gI>{mYRE(`}Dtr15!>_jXblDIgVRiSoA@==8;S3DW0s3 z@N@qh?H-<^`H>b-({tljGl767#O)%sC&-wFBeqhJZ)5XoR&j$&T3U)SO@~AH$^Lb2 z5*FWNt8l`tcubh%s2CR_qG%~ZubyZX0*`hH+OY_ve`r`-`c))wim-&AZ!k;kvAHYV z40(Cd9an?77ql1&P#n0g&lW9AVQztv6`K{PTH8o9m8m|V_ce<`>n~#34}Y=@`eu$D zZAWIT8r3Kqi4sww6n%AvLWQ-<<2k$J%?52(GdO%_N@VJIzI~mWFf+g2na|c-9<+D3 zU!{r2qNiB7XvS%^u|Mli9$yy}Su@6^k_C<{Vl;6lEBnI;YnL-EuO{J>I08+LhAYF= z6v3Aj7j*3VXXK>U#Vo*mk>5yKQ7%K_E=3FHiQ>Yh0w;<^u6Dw6b!9t^J0sKdm?%QJ z|Fx41vyz~oMd<)U6=()6Dgwayn^s?Bylf|=L~lDBKC2J!&Nf5 zfP{TOvGnt26ycv0A$PNU6M?Xg zB5wot587U&aBw?`fudx^H%mk|fj53ks@NVi3#x9Yav@i~#6+B@=x!jYD3m(?L}aWC zg}mdI;6f}sRrZB5ZU1N=JjficBlWt#y?!zMI{WIRZa18?9}%b}qQHvidup?5_OUg)`Dklhe`j)TJIOG_g;Zql4%NN=2Y}ct*R+*zq&;3yKUvuxck%tFg;s{HX2xgsj2X|vOL?@nb6|)yPL zVEs<|vC9#JvU7zmYZMcK(_<951?gYm>QBBTHy&A_f=u1n%;Y&&%{!43pL^*&NYmWE>kLtc+v~YqHIZ~Ln+VWQsY@n)fHg4}@ zpEFl;j!K_5?RL!fL@bhLC+CjX?(1?)kHgGea;&N)#Kpf}wXk4N^I{!$-vNp-nx8aM+A%Cf_dE2laYZm+?v zz8pZGWxT7{Nt#pK^PN;PEWvY9>!crX7ah*_e$nn#yoSjGGgjg?sde5SaaSEDkz<~N z?WYJOaughZ?q3@zATR$x1bPB+GBFoakcmCG&y;1JL8}#HQmIWv3OD9PVa~w8b*0k$ zO~t!S_!IcJx^6_%(H5R)J6OZ1#O;C$DB#}deuk8DhGWy=cH52;0tOQ0G_NU>p4G-I^>5g#5W6^NlnEW+P;TP zlXe0v^F*|va+UZJTDLbxF$_VQMZ0Fz^=?9NTXo&`0bl->pdQ42+rr`>mQ_I4P3R&M zZwG~(U4v`~yheV$6_j>%Qfi#INJY%d%AHAS);l9rUD{Z7IHiQ)zg3tzAT20r`fvJe zjqr7KH*%r0@xv37Wuq%sGmKDyhew^#HWkkaXXA4>)NxfUZvd0^tFC!rlO@#`~*?JQOIUG|@kC+4+haZ46on0}fe&$|p6y3a0BRO_E^J){?)7nFR?v zJ?5kSEIv-8)n7zK;ariIg@U*#6UOTHXYrGSP7xUH{p|v0<8SE z3lFEj(6FTDir_QJgne$-co0M=$dmHnM3W#P=QXnO$?^%uty2p#=u7Yugc^Rq-??zv z7B1UJTne35I^o!be}YJo65-_h;->!1F**@A&4? z;IhLzAn4P?=BePQai@J?>3ra`NhP4dq5*07z9OtI20w0wxtrEAn-l{YHaTvl@h?9a zb|oKice-*xKR4q`n7oAHy=nvJHE=|wh*{|hER&@+di^8mQ2*|!?K!kSd?!U1v2ri+991$XB0(MLhE1~*_MKI_N za7BdpnSx_NKSp~RE(zyQLmCPZt6M(xD7M#dXJ{AWpWc8v)ZpnUd0EN(U}#1n+}7Od z4{ExQW)9a3DjXarWsK_D@RbJKv%?w@=t?C%jnYc&_`RUy_{2Z`<4XCBv76@ z=All)A=@43?Ogmjs=eg&molV>8b~?;;;s9Pf6N98Y4QOMMf4+cnbk2GqJ9(lrdxw( z5Hvs?qa|v7$`61^2jo-H8meobhr4w(7Z90R&mhOe<7WhxL{P%>ri| zr}B{PHk93NnT_E)MAj2T3R6dh8yuetQP#YoSU_z1a;ORnTQ2)Dyk#NZ218ln;XPS5 zwl^OmpJ*;iGpb)AUj;*la-sB{v|e;-R?Z2QCAmcqLmnLq+=fh53jH~2_< zP~>f4;`jUC=1Wv(%}}7ik%7|dR8D5{3bFxSr{Y9&3;MYVZ$#6S%6;;0FR_3h`nduB zj)oYCa6#sNh=*@y@o&3oA|*c$Y;t)ClM5Fog$mJj?uLzM@x!a~Bhc&#=firnHsDUA&=mTiEZ=e(`#81MiA-(LDN0}2Zl1)KS2ZQ6D&_}aoZ~qbs z*%`O(-rPNflOp4qL_ej}D~d4xG4)>ameHq4U2&mXmY%QVJ7-TDgd!Z%^y0S4?+i}_ve?5+qQx3f* zxMWC}KX?}R7h?XJ--bW!CqzDcKo~oC*8bNu7sk$npmP~-QAY}n&8H-(6d%>HPXK5y zJtwprjO(6aAz7TruD{Rf#Si}#;4=Q#JoWDPMVA0L@1{Fq{Ci7I(S|P6wAGfEX7O%& zP9uuePf5a-NTI*g0b~9b73YaHJEyCWF#dh+d-H4I4sE|&ZvY!`Vdcm*{hTQP`;52T zn`(}KVJ}-E3t(?&LU1ZDM3|)*Al2=N?vOtK?EVjjty;t1PapNd@x|#vpbrZ#jEtOK z$a8Qsjt&HFuM~#ohE&y_VnrOC1+W?@6?+*=VfyTH>~-d*|1cxd?)nJS|KfY4uehzb(s+k-}GCYz^AV&p9k+}fal8DMxy zSh}LibPB2xE)RfO*%&C547sdWvoQ1*-<0Sno<2bDxWvY9HljM+f8zA*5C1pj-a0DE zuU!}(KoAi`K%}IUkS-BWLZmx~L8KK)32CHLLPAP92MH+!L==!NsewVd6lG{|B!+tT zjn8w=^IP9p@A}R^-}?UHo_+1Odhcsrd*9qEPXW_lc0-e@AGKeF=bR1T;1>%9m_-TP zmZOxZP(c5NC=jjuppdAFU6!U;EkHwiDX%V|<;MmT+)H0b?2Hl`xp%9`QsOZwo<8Zy={T|-B zXOLOEeE$qc+T9tGnn~FaXH`vI3$$tLKrIUB3{h+TafQ>LL#?6)Qp)#|8o(!`5l-q2 z?>51MXM~WF>E#F^kqn_WC9EQuyI=9R0`$5w$-u74nsU_CO+CDfJ1BrsQ{zuOX=FfSz>LE;Ww$1>(Q7QJWmg3Po8Il!Zl)IS~ zFlql_KZr)1A@Y+aoPoR7I$*wKH+95K2hw99 zQc?6+Kz|C~@#IL^zBhw`9AqZ?nsUG)&?Lw?UmTT;LtAMuL;$;f3utO^^Z4gT&b|eM zfjjUbwO)g+e*+WuRTzxX5KtA~4*_|OcSa)ig&2%QAy!wK(;@FM!ldR%x5rJ)mpVW? z$${Snq@q=uk3eMA8E)tYi3(TJ1mst4j5~hwaGT(Ed+9VFYSbMLvATrXl$nWQu3|M< zh3MZXbqAv2N%cR)7#szXRYyUry6bd6qI!cpm&>zVAUd=HrtXwcM|WV7c3CK%z>4;` zv3q6y5dMd7$RXTSD`5?kGDZYXNg@1WPNaYPljKruyNXULzJts!OA&GtQ8g#LNg5gb zwx^O%Qv-WRsOfv`)m*=AIneY>ffI_5r9w@OuFB|yI66R0)5Yo_uFQNWhKlxG=-qCd zaaBkGadnJ}4!qqFHjtv|MxYfOk_N9lG6$I_ z2F-{nd$)grQEPR5Xoh0;@rRZem@QW%;XZH*@Qxyx{*a1YcsFdvqdqZoqF9pvCst%&o2)%sSQ zXuN;)XZ+f(Yek1R|Gv_QSBlC|;b>ex(a-%Rl^Xi7F(crq8mntgz5Pf}V;4>Z2JNo5 zYyAgMjw6LA%LN_phqlBZzi=;h6{WA0{Z!{AyY;r51$j7*y8)E+2Gcal$#QX#IrKy>uUm$u&KGkHi4cVa1PM_`gc3RUHB*D9)4dW^XqhA z@{cS_wqnZA|LmU@iL?}{FnD5CYw9CBq<>VbpW;`0iAs&|iE(*blU*a$F1KV~r-b*= zPJ<&Qs<+-K(GTr|LEqEcF3^1d6t2!o{mP|Q`mpp5sw}8zQ3?5Ot<2!HVU)FTEnxJ& zyO;8Dqy*C;o>o^H2{h8%u=#7Q0Gbmbk;W98VrPgR=TszRTl8^P6cixuMHQR;LsPq1bcR>>#mPVtdg4#OBRs1Fp zj6&6;ww-XLe+^0@!wP?5=HAt=t3-#Gsjj@k-N*vsDlh#sKQtGWTDi5cdvDW9F*bOf zW&691)h_&-I&bZ37qsYMX#whDa7cTcQt|{sO0arVwG&RhRu-!&KzxZ(h6xP%r>z~8 zPKP+I`p2LQRBAld#(z5h4%)P6T`;y*CY@$z#QMEdYZvZ`^gMSM%^YL&zS8H3rEN(} zS@r~CCV7@(O~7B!uD@v|ClVPB27O=Iz|(kR-0aAFG~JKd!V)tSQ$~DP`U!P6__%{y zv3vr-#gTHUyI!^W9}OQ{+Rnw4vHYXq1CEs4$HrFwLUY5Pn|q)sN~F3b!-d+~%-zUG zqY81Pte@!z$EQ;3gtM-dX{uFT*o|V2jCx;5Vqy7G@_Xs!UHBX1w{y=s;^aFf5KDs9 ziWx5OONXT+DEr{XMWy`3wX*!zhBv;}b4U51Z84%PrrS4kTz28M>Th+djFW*dYOv|% zmHP?B;)kX8IL4HPD@Y#y12+d%87`(wcmk1?VoJ3}Ekg-tqwZ@j75`pp_!oKe4S%MU zfhO*>NVrueyl1VfLd}U};{|hg10d7d5}x7$2ZOJoGJ@|eM&xa*mF=V%0xwJ+Y+7l+ z7R|@*TNK|tw7abSmPELMsO2BPo9b_6t&PdT{LtZ5ckf@g zUW057w2Mh77Cp2xRDauIWlR?RuRi|Ar6X%)Eke~qNiL$|z>JV$gr4o>ax)VMxyP1} zJHGe_#YDaB+>+nza{mDg?`!A2{oStqFVOMRpPmSi8~jU4$P-KI*Dj(qyKr)3DxoXb zKtd-IM}k0cqHY`pI&=s*YqLMvJ`V&x`2F!ZVjIo!gX2+^#mAJ9j3cCyOs_iZw;`k+ zo1t6Ufp?;T0P?W!%pF1EV>?mXa~CeE{?@z`F1l96q$+Un_SHkX!`_SAZQ4MI8tQL> zmumd0<_HHTpFkuFRr?Iom&W*^ zIi^eq6#g4_fy%x=rYzxKFpv*4lcJTm;BIa9G9t3}Str_S9FgUTYk}nAv%oX*TkGeb zT;l|yz|yij-bIuf*rCRtjD*ylm(PQ$>T$%B49@4wb3|`*jOo%L9z8O1pWI#gwO)2# z9prOm$f1$rBhiB2?Lybe2JX7D0qVAXO+5$XaZ;@Uk9PSN<9|u!qgoA&DI5L=OoYlF zIJD4zvsOIj_s26}&l3}HvCZ6ay{F!;cuec-zr+C^Mtf+aTB`Ihb_ClTZ6R3gAyPq) z!;WYPm^37vcn)9qD^N1<0K3MFj0_F~um-uHr{CoGH+=kPYi7Fykz(NOk(j@9|TQvK~uMd9k0vhWQMLL`rI{nen2K8Q=~DsYij#-cTwAmXUe zgbWSX+as{uFmR>T;{9HlcleU$P<0g;_g5%^4pb@D3IY#N#8SI(1^wA})Tr@&9ON$} zJOa=;;=ylir|%%RF>p=RfCdNwaVHWzc{2R%4Z>7e;Ns7^054xC1EZ`zZ3E&pw6Q2v zU%lP(5JYq>$W%T(-2&Pd6!Y6m!yIsa2UB0?XNU#v*N`|gKp2Tcr)LK|!_A5SdZ&M2 zL$-fwdqR`km$JdrDfHP2v0@I4avQ=j+6!SZ$~pZ|whL#i3)qT)q`8aEQ-2#Cd?vAS z2-Ol)1Bn}ZRDCwhmtLSM%j<@W033o%AdEg@4jw`E)~A1Zp`@!fH21KAHrbrOB(=}1 z*bW>)FQTAw*KIx`Zj?R19d&zS{W-IIf~pV1Gpv)?N3d~Gs{0xihTTAVpa zt%v_R(TskekExQw>w$F{oetzTmI*217;NxW%S3@WpHcLDaGxjp zQ(u!&P9%D$_l&I%5aVGWQ|n|#Z3RXE<9|8}@_>0kCW5;Ljc;>u7_tjjaXjf*JwpM1 z2vDS?Lnx%qbnX6Iz*Gw?*!2g)CC#T(&5>tp8$AXLoJ|MWQh%l?@^eQHkRr;3xYN#lnZBH^3;*p~*@c zN*@^29ozt4x&@;MH2b4XKnw?1^EfjcU#Ob3*&og#V_5^FqM2q$c8vQa1LjWoN}!P9BV-ll*h?>A6U>Ay9#=Nf4?@Y$HO^-F`XP5m`ywn1G6uC;kmo+^;)H_P{s8$l zZ<+kOp=!(+>9!~Tu*cEe46QgFG%qI{#979Rz~^SkQ7Q;*v$gaaa%}O2B_Ul zrun;9xeuaNvA1Ufg9Lq5CCT1|nMusqu)QGk9h-+HULrh`%OxUlVs! zr09J)$oA90bRd1YujnJ|96#Yu=lcEO2}P^N`%2YEmM?qnL9=~0FtR292UknL?xX$3 zXvp>m*gnC7)ZZr1Za@N)_ZM%wtPajO0`ymUo46Ar;f=CqlEUs5VAj7Za5%}VII%j2 z9hMq$7<7b710jhzoIIXF$O%dX@cJ7;1cAU9NdnRPQ)7@>?QBEE2{u&J1MQ{ijF7f< zksk{7AAzdOg8)0HqggCCw@lOnoBrH1LqhsCh@~p96}C;( zBkzpU0Q+`1YfEY?Ho(7bBG^sC_oK6?dYeiEBjGQ$AxDh(S?SJH{Pzw~$DkJB1j1dg zdJ#&J@Gwq;wF1;Y-M)6AC%P7uii6k6>|PtnK7u523A6SHaz3>n>ZL&~>IsCXQ1x|1 zaj2(}&yA{v{e_Ynho!2w4%* zH>0r+V^zgIMJWJUau_H<#Gg<7uS`g3MkM;qce|D*a6Iu1Z#A9w{@PGY zsA8k53DpGBLQkWZ-^l(AhvQw`VTY=RDW>OYxcoDTviw9fImYs0%0ea(lOM3xb2YZV z-&$TP8y2pOJ}%uu_d#m|-?RPB1Gvr@F<;th#aqEE=^OhpL~DX8yR# zGEYMKnil=JK~#vwt?{g<_#a@}7G+k!Ibd=4G5F+FGivVvCs=CrCBQmsFxpUgGI)Ao zwr%fyZvydM=wKriIuAn1XzzfOl>TkdrVg|*>;>mZB8PU8sIHgS#}Ry`PXH%;?O8(Bj5_7!`)i&V@Yw86?l=(VpD#`HAECT64hzA~g3CW`|9};NOEgeI z<*c0{4n_$!m?iNLtfz_oJ$6dd6h{idc%f((WK$kN8E>^5Sy?ks*p%aK+ji8+r$gWVRf>Qxe2-O@7A244dlL2qk z9ZmEZSO(3HDCsDU48{w=;pbk>FoV_Zl07blpX>tU*DPY*l3^ z%dvroBt}H-*IHTLxCj8|{S$~c0k(?hz;VQ*c>glGLToki;V!z$7Z-+YzL;We1{XM1 z7175es(k>*f=PbxMl4T%Ad*~w5uDlS?ZVGauTrF&-MX8CHNoVp);vgRiX$GOJ|wwg zWd`Rx7S;>FauxA_b3iby8-i0YN=%44=ijl)uo>!7DC;!Mal{Z8m`gEYX{Cj6BJ1zZ zhE4{jZ?!5pHj~z7vTxSPxRGX$xRazuYrdXg`lHg^Hp=B!VVedHBHvZ6B>G2`7~pJ1 zIQ}B$IL6m|kHr*e{6(yeBP@D`A<(q{i#QQGrFM+6&K&!Tm;>`6RY#fGb<*MtlU<>i zN#}Jxlx@V>(4`6f?sN%Qi#LRS$CAT=Tqo*R*44kAFJbmlhE8$_ zd60V6nLFO!maYWbV$FBfnZ5zb&{vF%lPNpn5uJ-PLv->V6IR_hBb&?!=T1mvUwlTT zs4>Qq8tf<+&LoX?M$Wx}MVS$lRYB51-$R<|?=xb^gOT8Dlk3p# z1cQ(Vsg|MG-VP}ZipC4*SgUgPFd{CnHbbEe+q#__ZJH!y>Q zuyobtv>|=mL%hHuloJOp>+wg}mxZ%4_~VX${o*?whJBGmZL+<+d5nR5IY9}qz2!gt z^RHj*$9Q;OOferQjN(sXVDquqGU9dR02P?C5)K|ZRw%;(8^2Xitc6R&H(x^uu+|71 z!|?!F;)P0p zFKm?SxJlL!M|CduHYSxUD*og$Ua=BRBSg2bSpl|^04`#%UO+@2l27j7(UxK_5-F$!`=@?F!r6hAyq|KCDMD5s7fl**~RA4&$yK`OeI}lA;QcLU1=;Eee}Q+c9iB}^X=!) zpZ1lFyDjIL3!5Ea!qWTmA>T}&_Y0WHe)4GMg(=!>&%GOQqR_v2>_QNq z%||<{mCe~Fy?D!Q;K#{Mp8x}5sCLGQEO3SIWYJ z)Z7?lCJFOXZoVye2NTB>=!l%7qb=z$OLfMekXT08y}SG-4K@20hfxBgF_Rmq#P`Mc4C4^%Yu`-7(9)TBiSUcuZY2vpR}mP`Yeq>4~9L@*7c8L9aN%teC0Hsl+!AE^(<6$(%XRzp{} zI8lg;U%ZfJuv|IJMIv)v2BJGZ z@X-x}T6`l^2(GS)f7&B}sXaK_8-Xsjar-IYk$%+*z>SE_dbL#=LwBMe)HL@q94LBl-Pi=|}x`W)j9TLw;9qh>u|QYv$wzT9+hbZo++)G!yxbICCbG_(oWu=7I^Sd)vuOMen9tK$3#75V%K zLA>bq9{;uBmwCU{hjWw1-!ONn=j)am!F5Yu+Zcwq{csn;D>waQ@!#@;TaeQTT<|$V z1>D9tad}+&Iq_-Frr%kqX8zvbM&}2PdwQ5pRP!uz`<-F{yjkd^8i+(zY61OjDhE`^q_Uy57^^|=5M-;if$c@_);-%t}b0B$m4qw%is`)R?dqOhxYYXW{^u&N5I8vb-b6FJOA4+jsb zR-40vxv?L&exXG+KmY5lyeNPcTsxEmli?oOJzX4i@MK}LElf4RKOvV0vq>9Bi8SM+ zEyPA#{32KgZoh?NQ%L~BbNn|ExYfV&UlRMV0zR;l_e3g~&A*fB@?j>(PZ zI1EqF6x9mSaX3F2(tKT7>rMuJgQpl z^cOkIjbBP^CG|v$7S^q{nP8!I`sO^0RMDp{=_d3>igr2nE5-nK+5m$cDr*&n6rMT} z{QvWnAXxlf0A3n#smTBE!q?e*SWcF9B$ARO0{^eRlJD3>M0U+6QCml!9Q(BYFK zIJe(#+dOvN!okUeBBIn^X^QxU(K^Yrc+;Kr$2Vfkn`V^)rsO6nscUI<6>p~ z*O)cg==oD?AO8GdSC~d<#?K6n53$jnX~f??!_E2|yEG-DnO5^1-C{6Ru_q7X)qkHa ztGxDp|M9RQ=N84Aa=WVme1(jS9@j%BbSGWVEf-~9QZasrj87?NNU!!8(-A7uv1c#) z^f@}7C^GgiGJfnuY}bqUl|bof79vMp_1z`Tva=M7)I*H?zyyR;n%9fof zSXv9D!o4?d@7;eMq8YusS#f#t=Tnq&bDUX(U6LYB3QL%QB-^>0JQMCdY-Z+Dwk$)D zP$TQ8H}N!+dy|j*Q@P$!qk`23@6ylTxJ3^$7yv~oVfR?g<1vix`#b8=m8SnL;%A9nE4aKNQ^E_6Ry zA0m#bUY>A|4AB-w++LV4eiYB78!ysxzOj%cKv}x}K1u%X7P1DGJIuzOcK(<99wDZk zUz|vX(0y7g(!kQt_hym%gMXcM8EN7_{44=sn`&13@CSTy=~Dky@0sGIOPepRdS_MC zt7UNVzTw#zU1Y25l-RSYe%bWW)U9`T_Bn?pLNfOweaa*?xlMUE(xXFeveZJtWIMM= z(-2fGOW`uI;+b*t7VDA{cBNUIw?r@-11wrLOZ<5`;=j0_PP5-KY;~Qa6&c3Ot9)8^ z^2Co`RwyziyCrKZ@yqs)nPO_@@8C&2w;qYgVkresc+~(E1WFsCD_jSn?KbicSw&6j zVo##F9=**4FNb}7EpAGYA5W0-otm{* z++4zxqVNS&kd69V2!#q3Bxi-9z`uppEm5Y|jZ*xH`fTn7p~ycnJmu8J5u{jCT}V1+ zRUj9+Y)8$A_rW_kUAxDuba#U~?^$yQ(p$4?l+Uf-H5lobSGGaP>mK&4ja@!EHi$vr z^Fr!At0~%~mAzt%DgPT0rP-?}Q+j2|wofspbjp&JiwGHImZ$iZ^`Yn9aj=A|DYM$* zFRrj~v1!~ZWG;-qg*SZ65>|LY8T;ZI{xO~@rW>1;! z>vyjD)E~;yI}HzSC6@gvOxU7q*kG|;%P&~qY>O;RsFI^?WOGiakSo5cd>zANJ1$>I zY+Sf{*@rGx9@R+6DaD!KHmI*8K??w&i#4ZjLsy$x}!&(eSO zvYx?_Gj;jJz9mH?{T94*?txy@^)!7#Ue7@l4s>WFhVqpP{EO~i*b>jX$k<4&&(oTB zB1sH;5rv7xfmXOEH%bk2uFY4P`S_dCK78|^#mi z_$+(gEkaWnW3~IM%k}%YpVjW$l6>aRNz_iiUJY)H24JSk;W75dQ0kiw)w*_+bJTq?fxj0&nM{*N`D$0xnIHPmsQ zi#?J&t}Q{&?Qy0;B|bJfHs<{@JkWnQVLNrMleOfE*wD+=c>O3ms%=@_MS==73g!%` zo-4cfw!eZd7g1IFd6h`=dVU38uj8mf-S&uW`B$n!xd54}?-zH_gNoTXYd>&Rx4lcq zhdS3Ril(%H2CpJA_GQ{WOZD>j>qv6S=>IPYAI;QExi-G}S2ZNdIUlUOf)GR{`V~ z-yPu-D)8e!R7*}D%9d0p1*uWP*CsGt`_*p5J`3{JcAl*AeU-@&`cR-{sp2ncs>3=i z6pfTydT#p0H@9ACrtfSx)Ww-z+;?PVq^2SHT$ot&`EEve!8iP-he}EvVfX@=A6%Q< z<_TJE>b^fC#b2rHh)<{C3-qvYZw@?}T1E#})(s17r_CAONW0QpzAK9t{a84;^2u+g z<|n8L!@pWm$Zf`Do}ga3lYD{qmC7wYQIQ~p+mS_;PiAS^GkBe%{a=`p@AKYaYD&ya zRDOq@4!uxPn9iT3GStKVz=vO!GuZ+2@m!WV8I5<{3*08sjh;yN&`33WL zZWxBDN%*=yIT!8B6;U}LiMm(st0iLmSxMkhxtjOh_cneXcbgghJ4B8y7qZMRRA!s) zXNd+c;Y?~bV_sk8UU%+EBN51>M0i?rf0pkvp2;fNqU3RR_xzcrW6ADoh~=R+#Ya|b zoGj5Pv}WcvpUm0jQE|BcKKhCmEqD-z;8&sG#7#9vsOg?l@fBTZ6_}u8o2eYz6)I4U zpMD?7e65ODr+vE@FPcT+S|upxc5bUi$6qGAb$+mh_=5I**R8LlR}*>6cUM9P!1Jfq zQl1_D55E)~=Lh06LtI8k&PRprc91zea-e85s(C_j+%NNkw$Zp|iT1cdrZeV3BKPCE zA8p1LLoZ~hrtux*61Ikt*!gGL1_|c9N@un{g^_>>-_)Cz7@E?spn#R>_suS%cW2G*yen-{d~a>Us6E2j}%R)N_k_b_dlziUhsm zn3DNzKN!P*AaG|czrAm{mv4VqHRJ^3)#SOmn(9drh#^%Ggs7wu}9`{&-a&ha}e8>Hlsi~QE4rHdq+dHp} z>_0J&dU?y%*3OXYx|wRbKJy2DY}s2IcjD8G;d z^$6jfXH7oDM(Mr!u)OL1Ow(|>ymkcr^+NQasAogEgoR7CK1fQQ!V23-ji=f<8X2=;#1pQ z#dW@oVCS*@tT_80%SY^Do198Yj{YIn7(X76&Dz_Tj%*4YDKa;@<9>?u3{Mp~om_ms zp+UvetkZ7y8in4xQk{-;bB{B@=0wtdS{A6h9A&5>?C#D9pS@bLHrr1gQuAgZ=fErT zwzB;#X(q5ocrH|Kg{48zK8-K3@s(5!ye01?IWQ4TY5?ZqdGgl_YG@ z#=uJAwrJyFB`>#VlVBy$TeRcT#VQJyS|2%wQ#UdZ6b^-bBp#HsxON0t~ZgRLpBp%s**fs)sU*d=rGl&o}j%hhX}jgFfmtr zU6ij?lqg&vh}H!ftw$GA!DjLQd* z`hJK!;n@GNE`@tOFJd+GII~*VrLNbyAU3(ZXM+2N``c@y<*(9LsX40L>s0NRVyM?@ zqE3kFTO?hZ%MZ|B7#EkC4&aoE1$tigUMoG&i$K~@LvF|Q1)s5eF8St6o zHr&p%TBn{%bfp$}06%K@<4@h#kmS@JpKz$qV93;i6{WUPWhm1cwN{_2@v< z%zk)wsq^<3^)!uyqcQPg2dnIw%+l8bQ$@v7*UvMY*L&!p(B7Rlg3qSBLrcLB`q1Mr z^q|{T;C8oV^(;rJJ>v&^k%-6dr`K9Te$-Em-|n{mILmZD_Tig0558MBTP!EmIn<}g zKRIIVDOmjM)9|GI)9xu7mC1-KB86U2m zT#x_C=MCSbK04WBUOzp0Scc5~-=_v)^F;x8#vAPv|5N%@=s*5nmZGhLo7FQG0YwK3 zH!FFoM^2BeNCeca9If4KScC<|g#Ve`GsbY(=6{-V4pi&#r*0|%M3~0_SK;N zPgG9C9>HR#%=cC9_(_Po+wwIU8lQqSIU;`#ooc9mVRO;dSoYrJbqX0}SjhI#Pt@X(mYBz<(CGj$L(}1%j{2ZJeZ-vKT!jBhsyR zlm8QbKx|KjZ$R4NZ9kvJ-CQqg-HEY;$BF-TJX(qq>+Ac}l4Ep1UHw)gwoj3a|Ba0i+eVZEtAAQI4UZ;V-|&3bY~!~r7U$I^AWM#C;6^- zdEj%ywJbfNuL+4t1j%+|bvS`rL+fm8Hw#!1cHKrVf2D0lhlqQ6)&=WT@*_m!Hm)_(8Y=4G%EQ9n!FzfM=cmwK$w|?Ctsi#w~|urX=Ewj>#SPMjj&T`T!HmL%Cyov25=)n95o5`~N2_4rkt zzJ0i}-rf6k1`+4^{PZZS+>o%x-=F)~sopyEnHINxk&n+8A9?)lj*OY5(bHB+lbs*# z)i3*O4_?PT)@zcUeV_h0v;MBs?~f5PEhgm~id+5i$v-G&jEon#_m-X$&RWko4U%6C z?Izw``|-Y9wVk?n%&tV4h;wlF!KBn_nO(!Nr$~Usm`gf7T(+tk_Np+hyy)d;4Sb_C zJt}%QUF!-uUHhvl4Yy5E`m89S1KRyXS$a*Adcr-xxAVY z@O=DYqa6#W9@cM}zb7UWLu_=U=R>b)D;gWf6Oz2wmky2-woynR(BwMLUVrVf2HlX$ zkhNUEm5XXpf?>QjWtB7&WDOK#zBALkP9e~f8}Fqw6OyQ!zVy(V zT>t*#&rkE*K-`wDSG%w_%j(6-)k=bLEF8#)d-g zWMmC)t&?Yvc^$gib}XNqdpPVXzJB`$vu3C4t2PRHVsn|hjtuxVF>|p$snp0L_9Od0 zxt`4I#Pxi-U;E~6%ShHdMsv%J)2o3>a^^zz#<_sEcUz|Z*ykN{ZEfq1z}g~e`+XQv zYCS47m~2Mc>W|Db)~03$5^2hF^4LAqdyjvYA2j|9+HjJ|Q9tmD9RAFqIAzI1nXmXo zU$WKdnUAc}w--MWYUGma<;S}DZ|EvsQ5aoSu4A=R&|ejP=hZW^dUahaK|$vNVKlWmymshW+$RF%Kc<`2+A=~tZiMy6ToYJ|r#DuM{ z)YrM1`!lES@vUCR^Ra{bqSp&97Z>M8L$K*oQ{?Cg_fr3k*>L*9$p0b45Ei;6 z{vScc-*`d@1QZfN!XyI!x0pld)@{*$1|2VbFPiIhB`-^e?5Q@Su$%OxI83ClKR8iK z;ZJ#bl<3}47yliG?@*-?`c#ls?#u1lp<24?1n1N#Geg-~3&ZNz$PQSE*$Z!VOg%}g zQz6k9@%X*W?~qY6b^A)4K>t*dd9xToIEQV0is#v;??9%6>(8%gt^+Xy#4sOPJQ5RE zntjy|Z+%Ozz;a-L6;}2Q=a)ZCXTbL7V9w7b!Y!1Jzpb1S=h73fq)-zy+K2mZMB&*e z!A516wGa2G^}1U8fmtKZl-v6>MWZSuGp_!$P9dpOeQ5_lMdvxaTa!NkWrDjztW z`u%who36y$YQJ|nwDm)L?fe&B1DPtvgD*ds`3}zA`^^hGAe1AeXE8sQnR$-HVNEBK zoNtR|>)yR{%xdga4iLZvc=OCM(2id-EHA-&|4aC*=#i7i{*lBfBS7u}3MUwZH~MnqMBZCF^e zB~pKWUNGalGi>h^btyjg3U@ALY2MY9T)d6IiOWG(4bNrF3w{=tD4BmYMKCk)u z;ze@`x2`;nfJ5?tK8{qsAg6#$m(vh40Z9Ux(7C)zn_Y)0&lWwSGV|{)U-Ajg&i%G5 zS|PptJjbl9S>%u21APWK1AGp3nQYi$)Yx2RK^Y}Bu4R4vYOZp9q zrthmo>s)n7j;>MO?Y`(8^K^mrChQ_s3X@3Z`J}wo&n_Uw_Z*pC2n+nQZ5SW6hmVct z7T3rQ=_n)_sH&U3ET7cCy4*xd{z~;=`{O9hUt&0l}PBaXAnlB9cH<{@Y zR=PNNeBaN8OVLE=z-7hkJuk-I++E@5Baf7u%68)_Ez>&|o&*ED5kAlR%)DVsRhJqpXmPpB zW3Bkh;kAP2E++5f$(Ilm1<|m*zGQkcgii2WpSi@_FebuYJofp0U58kP{hw{mmc#xy zi@CKmoRT|8VcTF1!R|xn8>=Y8TkyiFNTa^sAz8TG#IM9i%?DNmw-H>j39hXo{X8E? z=PWi&7W+_;l=>LjMEu)=sOBEk*D#6sKxx7zhHHXvhq^mID(3l$ zisv#L9JQSU1!M#;Y<&L^M0cBOa|&5Rue-n$s8ZKFy_0Q-l}Y$`dO-DU*qPEa69g*d(l7-%`Z5Pf%3I$faB44rbrBvM z789NOv?Cpwc_bKX*7fKcMa3i3wEc2@c)-gmlc$v2HK&N;aevVtb)KdZK4G*KUmH>0 zR-4I>5MJw>(%p5ZyJD=L7Q}9zay+g+?Lx*MPa~sKD~$7Z*aH-nb#Km`I0Z$QpEBi^ z(;6)=3&@w4?^gf&pfu<*2m|Wakk`B zZn6op3r)g%$tQ@qrf18^k1C7LYhIJ4xGPJ>>AZHA_V5yYQwV)qUrTD`XLTjZM?#d* zFS`c1iZ>0nXeEv;*A#?L77u75H^b&H{uuf#elmUVt9!cOc^u{3@JWGnoF>y!_MO-E zao5^Uj=el&HpnN|PHP1Eo80GS{Spt0u`iB@>AcUK-;G^kfArkNck`g}@kU4%`L2wz zXE?`tgvb2u;hTwwh~V8k<)+4fr{#W6i>I@LFy#gTK4p_y58-a8S?Zn-o{Br`o?%53 zG@haBjCr=ZNxFJGaW%<2$nxVWWVe)ilD!juzmTl_EX+38$3vQx`0)Dpm1pB^dCv~t zYJWU7Bo+v-2<=uT=0pB8xIu5!p)1EDYol=Q)6C^tZuE8Z;vp^8ukDw`)gm%B4MG z%2N`1`D=}6mnuz7M}xz9e|0wDQ=v3=#j74DszdA58(VK2QA@8ITT=O6&tG@Cs z^RDTe!Xc?2L_{*TB!4LGZTZkXBPaVlG$cq$MovyfzVIq9Zy}G>Kr+%O2ADqH$ei%JJvV$Mo7&Ey zI7dS6(iowgeQ6o@8$^;;qVFuFmW8apX$4Q0t(KN(6j7sQ2Aj<&cXq+KmXT!=cL~b_ z6CwUN>Px9rpUb8w`Zk-8xja9YJ=*VoXluV_Lh|~%hw{fMiig`0$`Y5j<^tu1buQMj zGbt7HQ9OUsvLybJ@%N;0?6@3Rg@@AGyI0xeg&%#{3+$b1?`E+xMHC46S%usPH;L^u zv}x-d?yLx>Bxm}@f&R3T%9-pn@Aax~7GBA>eedm%sPnaptJ*5@t(`01&)vE+_B7_F zsK;LW_1}~948mChyOdgb>YH}jrMafEbb9EnQ4&=p<{ON=;<3*=m6#>@T2cI-&*IA7 z99GoPt~&~B$DlfghtFFodcN&OU*?%SlJ$vviHCR?#Cw22&K~$c*~}~7ap;7$O(=- zYP5S%vigX-Q}0b8neU)2T}p~qW_5!1)9ud$DNnLt6Tcke68H^7q~VVotwe9=iHfCr ze#~Ug{z>?>K#0GxqzgSxlep*BrI^xrZKiBozrOwTNuv52`_ad4`UjKL|A(=2iV-c? zwrJb7ZQHhO+qP}nINg2PJZ;;yZQH#4dy|{I_qQv%zG@|vT9{*Mi2t6~(<7&mkDttt z*48?~@KFOh_c~6M64Qa3nL#rndDN(#zdKQyo38ejQkUbp;n%i$#sl$bmbFEqjMg{lBjeh#azt`ivgL8 zpg2_BC{#|Ybas+mjc>NUJjkW*w*x1;{@%=|2%qV%}#}!A-o3xWucZ0oa zn@+?78JN&*%=V^sHfc#ciLm}P?Uohmj1`Wo^cbe2x{x6V#GbN@21GRKSj?$QGs_Ls zi&st&aSA@X@p$Q`&1vfOrrhUN=a{av7L}@hvQJvJ(%UkhOoPm9>@qd?IpqwF9nr6| z+;xU^p}E%ePyul|wASSiNS<_=H{wtBYdmdhxd2RxQ|gq|Mw#H!3^R^fatW|N`5sg; z4MfV1Qh-Q%E?I(6bWkzXGz#-qHzAw((c&r@p|bDTM@)|$B$iZX;P z5sw*zSj5$@U?JrwNBr3`*~&^PBWLD zN3N@eAJsT*lKov*YDtl??zpviD?HAO!`v{}G3cTnelVfK1b~v`M2(OEgCGSkhuh;M z;S&MTce!PH_nEU)l4@J%#NZ!(2!{u*j{x)or2_!1z5Me5I2N_b>pBu0dmdPpmZ51B>$MG)%S%3$oxk?0_gp1Y{_KPlyw^ zkgP7xbczB2HmCk3*XWdm;wnCMD$euz6xprv{oA#bVIoS#cck;<|0@6pGn)9^+0BFG zMCVfDFdv#p%_QlqrH{2I)7sa%Ai;L#b`imb*@U(Ece|Pl`&3SfBgjgFI=&cBj6z6OUr>7Gd$_g%VS?l0W~ zl6qWThH^t>Ph*@z%^J5{%_*;=zw^U$a%CF+j^7D&s597rJKPK{O;$&Z<#KzQ-TjQc z?C04V_q7Myl>HCTLSA{Tzu7)~kH_|H&$oc=6z~t+?+A|$Qx87W9`^m^ z6Hd*{YN8-pbP?(-)$mg$H&Y}PGPI4gX>5)@P8w^gdT`c0 z;=+2$-sjaD38}sck)KTa<=UI!>>zEhKul-)g*qH3xr+`l-{#= zk)kqcwq_6ix$-L0>2$;dKLt;u|JRYLk7p3-c@Wn*{S?`;N|)3X%ga0d$8kYoTN`Zd z5^Apd>tbnW=D?2Dmb*#a@(x$s+cqoo!q`ytg}&e6wzoTNm9CEYOpR?V<93^~r|a4L zKhg%Vu$yb$?!wx0fb6f--vFxl@gEA2;v^S?PqnTwSrJ~H^Rb@&sXR54(w2ZHq^-eQ zsf%ttd_06XnZ3Upwy7^dk(QU&OO;M?*}KBbNLS38%lO9^++gyjjh_{DdAz$**wcgt z{-HwLr@6@}i8zvkQLNbfBs|$>=mIyc{*kcqEg&-k_Pjo%?zJdgR<(PgI7T>K8ub@h zMfaqu_86S~53Cd;wSv553{FznTM;qW;~6^1q#Dz!#(&~$DsZ?qZw=vF>L#ZVy}o&} z!`N7QtPxpQSN;iHZw$5;O7_=RrW;Rr10N?a4O(Gh$-*MHmsp052!CrIvnEQDT|f zony>v0}fj=zlk`yN`5C%j;%DdByozeh|YKk7e^R^IG{T;o;Q^sz=!2Av@h+Q)AWC8Fq_`3MBeyM>KK{pM&gOCQABB;)RK> z6kp_eiN#|ZDgKeelo@8;BCD@*@0+h_Ue)fl32LiCLGz_vX6vxHXLXL?IRS&C+&ur8 zste1kCYB7-ay>-Lt6V!5Q&t$-oQ<7Rhmhr|Z2nn;fi2wl+UiQ}2ak`-*ywRkIsFz3 z)hXN;`pOEu=C8PO)o7qG9i_Lz*u&}j=06jtHq`WX(B55p%@;fO?rfdM9zrUNbacz!>t22dl_iQucaIwP_PJ{JjKzeu~fyI z_9anb-+S<9=gud5AEnMG0EV1AW1(#)0-%+8pnmuIrbS~&C81=}7^~Lo1bKO%>TCA( zA?`#K0UQz`FbHuR0EA`h73-CSRFNzso_I#Xor-Q`cyALRP)hOjCQ7WT5e1XlACUrfwCMilyT$O+aAu>IL>=vRg(K_igmpm4$Psu&6l+UZr!Kq^D~r z6Zfe>At58loA}yz-`nFCwa6O&UVpbWdpf(HzS(XD^Yho)9ns7iVZw1AO17G4neI^F zSZyuohr-qPx6k%kP#bM7$~4!o7)VszH-*h=w7D1;Ff}~BKAxnl8pv87*YN~OGT&rB z{U`#^kJ_>yJDyCs?84)0#x|10)s7Cj+Tf3qRNGpqptYA)1^=x!kBhmL7&@+3u=HC` zV)Y|46MpVXh^d2dra7_&b1=;&1Y&X$DfbUq>1v=vKgCTTKjut<+VFGJ!FQ}j6S71 zSz6H-pJD5F$=hwZnSFhNFVnd2rSjjtuEEa8%XGIo+%bj_{{(Jp?nv5d{LB8(HraWr z*7pAviT0j8$8mWD2?=77N#oV>UE#Q zqihcoyj?&}{Lc7A`lZTSx}t0xJ~??+W3rwfGiFH)7PXid7RSO#o3xxde8vr{ate|u z9A_+MSx!&IgeMN}8_bSwM8Vy9vfIWtC|kth3AjCvF$olrskdT>JDI!)qv#3@S6 zF87Jvt=#rLwupT2j5)Vn)m7AZS3aXN(Zi_%US@%X-vjGWmI5s*w-4b!bh2ww6OFwG z=d8{NE6%+iQ*0$5#VwfWYC4a~^%;eHf2ny-?6=W0SxOM6D*9@>ONht$7D?o@88=o) z$(!Tjb$>p=WvnrBSs$JgevWt5+JHxz1M)>CPw^om4INf)wBT z4hh(EMtZojbt@XU$~CxUMEZbts3X$-wmtpAXo*%2NqlF5VfgMLkz*K)UiN92(dLDz z6W^P)>S#o-JzTJEc|gyuy>l1X)S*fg2fFr&2$iAm>(fw$T=)mhoRBVbYvG*Zr>laC!2AEE;|aEyW&)JRk@cZG@s>u`;W46v?lzWG6z2DZxjy45@#tSnu9zzsRM*YEz4xH> z@jt33W05m?ewO?8^i5l?KyO7eME;*O_|vQJU9|dd-^;r()wQ;3es0pRo)2e{Ju$VN zZHQH`+k@mg>t25PB;A@g7P=n0U9UBNG_brRf}ie#ia_wC2ZHw>h$IU!8#9#n)^c*v zWeSAZG{jA)$JJz1-2=oHN3kjtUDuU;%bk_Em0L>g!xo*(lgm|dsi21)tSY#QmH$|k zNTMznM($rQ8yb1Vz~b695$Ht07RX`1qi*5@XUo}UX?UegcHDHlEXU$=GW`R-@qZ`q z{izYYz^>8XZ2^7nS?+S4d3wPE4LLm&-}Ha@AcW{iT)D0t2;=f80drT|eYSk{AjESm zT+Tdm;fCjGbK6kFUNau#wc3j8RKBl)}8ZxTGI`HnO1; zQ)NUuaeAMo13ZCVCHT{O7{J+*p345PUy(6@=1Ofnb>mDf1Q12fess1?M(VZibU5tl zhilkvADEu+#GY})KuT}9#`CfhYmELZ@56Q11Es&DPVem^dNDv<5p>bLt?E3JRim)i z`EO-q>t`!*&2ncUoqn_4;4IFwW_Jr-+{|WU*1Htjz41mLnd3`o`!No)t$BSqGZvcq zftIVI!)yCoVP?A{D*D(yisLIWibnm4N8dqDv}Vk}UA?6W*rfDyQ_>H+?2gw{3E_66 z|D(SYh?m$Pd6v!w$qia3HXz6Vb(9~{P(|hKWpF)6+tGo3zP`bEP=rd=U$NQsd(YIWTiszrw%_~$m?5kH*ac8oqD{b);>T1p5*+nJ=#Q_7Rcah*!R)u z!xPAY27Vtbk`$Qi=J969C6~{a-8Svp-2-xFYv^mhUZ26=%Djvh z_bx|V74v)H?eZ=nwGAdF=;rF?%7oZI3160Mj2jP^M{X7M2jS21mxFoL)4fJjVpIg* zfc&CHVLTMz6+oW|e1Jg;b;SVTv>UX8g>)1O+GT`Ae_Q{yhbYNHew&Z^rza#q>+zfn zG3)Uh|FS7IFNSFKE?@SI=%=5EGB36+c#n(q*0NCDJV@yoJrr;6iN57ND<$M2?IU_n zC{bC%qz1$W=mwC(7Qj^N1=Gl@-wX$M=MUy43k3grC!C07xE=MwEDN^0naFi5k5$&(ykM@NVG@{ z!$QW8YC7rm#F4(UL+qs~C;yHquub=iDrNlw1V zn$MfY)=O4b&9}_)sD!CPBRZOle?P31Qvr&37u)Hqr1u(NEv1t?GeJlYU2dP*V_yzE z#*l9!NA&)_UbtTUw02XgttClqIsWgolFY4&v)ZZ++;qM2U!^Y(UQV6(r>g$MD=6+0 zRIQ3*NTIMEW>nvDZ)HiV3c@5puP?+pfm0m)~b6`&Goel9?ohIhI`n zlX;>hlwc>Xi5(-hGVS+#)S1~)Mj%S-W8}>%Bj_NHBU968(PsnrpLUvN4e$nm-=1aa%_86 z=jkfuSWxF*VxCVpFPR6(+oL>ja270?3n!{6O^Y0O5Olb7_9wF%>vN0CL$B?=_r%k~ zJ+N-K14Z?-?6wOm^<$xK&B%W%ll!?FUd)qACZA>I2b-Kt$gjnNs+h{;pay8(>VR>N zh=+WnAY=+9nRHnlv6QQDf{!>9_|)Vsk2o~r4vx~tBU$N2nGE$> z^(z8MN#kv6WS=QrBmQ&P!%Syf`-o+i7?1k)I&!%oZAFMT9bz>WrS&mNFw{Wx8NH-*>pYj{&C(2TsIQn$4>2~Sl8_ng}wP~rj z$@sEfr+WAF#ya*hV+Zv0kDqH^(Fl?S-hbyqQF^^Rx5*IMi}&hzbj0Qm>o-^n1}1B$ zf;68|WE@4AF5{}>y5geYruRk>aI*lXB91$clful&eAAO~S8`U$Sh4sDTUMhPxKNkw z8zev)c4NOke1gx?zaksLD5#36BEbKp0C2cp5CWH&jQcipG-Jv^Hg$cpx8$ADPvy=n zchq>@4RqCCtA4e2uXQ<*jYaaYYP8&6AHI91tI+y<=Ehog`|4NnSG&xGf%%S5`QIqZ zkfF)>iPVyq7)5uMv6_3rol)qjN>$WBN{T8`L_*}GZVX->bEK{pZvWXXKUNZQV!UM4 zWkghdi!e^p4XvPu2v`Hr(ib5X(hK>u#;{~4gAmx4h^sE5Oef76QG;ZRnpTp|>Y0o- z9se{>W=T&^Gd7wpRl}fFKgPu0cKVw_kZ1Dn15}Wr^P|sR@*TG{zSz@P53J0XtKvc< z>+}%?`nlYc668>=Eis-v&g>wN`LS)z28XLvG3l%G@z>dz0Q%mb>GH~<+9@&aQg!Wb zDqX3_0trNBgGmSMh>Zm`##peX8!=XK&|T02Xk!3nMv9HPM$sN&Qu+ut5nAHZdn_}8 zaVq>)3~)<6ec#D(4hHgcI4tzObIq`d`a=8Ydw7*TJD3_y>&JN$cgu*ETi5)}M~&fS zV3H~A63%!2a#xqCbU!I+bhb}MET;UYkGJebpF4YLJl_xN2CjBGP!Mdu;yr($%xhRx zu_UGB_uqFCx%9!bH!4{tjsb!~y~Zev{lGtwtG0X_I@+bSmA18439`0zptjn!BR1x? z=(g%M=UH+an%I#mirJlY-5M+iHr7_lc|PhCHj$1*wpFj=KMd1YoO2M_9<%@593snWSgB1qvzTE>%Y^!6 zKc76N&SafZzu4DkZeOaEyD4ugsc6so@+aR#iatWEz%2Yh+)f|JE{&BVmWdm?=dzL2 z%ah@%P*+X%(GryGhK$ak_^Y|VR(vIQpu!ey8*Ez|i|j+##v(p{p!OxoJ2!)+7^-2T zoR^-4di=Jo83rRW?l75Tp6J|wV8&?{I~6sxPlRs1_ezt)4J~eln;L|Yrrm3z8 z#VQ(>bB5Sqk%7pl9U{>N^`Kf7BmY2quKS@^eTJW@ zqjp1!y(N6 zdyJB{#I-FIk7rVD^qlR2d3uQ|oqyd?dwl0Fnt1NWc5T(?tMYRLS>JKGiberAaEm6W zW;0P?Afc-09HH*Ec2E(vG{-k%VF0HTao_Gt6wtW8RR9i>gCGWCu*RcaJryc25Zn2_ z{}+Xx!R}zD5zxybiBL3Ylfy(AduK2^1uRsw)B15ZmfU#|ivH~uS=s#z29WuAHdqK^ zYI&NDuU<+XZRlDchFzjFnv(-#fHno!U~{}^=G^W&8P&&OKL%R)c}?GcQk`C9LLaRr zS~Y0Uq|IIZwJb@^Z^m22ke@x#d*?9gHR-kNH9fBT&uEg%j@Q0e@IuGBG?lBWRlU5> zVCb7#jc4Y4)tdBcxocT?*%&4}6}H{<`tw$lnrV`e`bksMdzs82b%J^Tcp32`gVpQ^ z1JPtYN^LC_AFp9whgwc6QMEyjUemJ!l@^SV$VBe$%1L34J@~rM^iMt3y7Ex^OQCQ?p%1_q(y`FUJD+x!M%v z-Yaj2wCjp@TWMxhJdi_*KX#*otX*6Bt{JSI!hw)sXr1yZy@S+d7w)?O^6cKeWKr!iq&bXd3;n|@FoKun9zsbm{=`QN7 zL0NyeA{Q_`b|-sTJQy<6LZw&7jS5CvRZpCm$&2T2UPP(CaxY?3#eQOoxMGABBdtt} z3-kr3WO>@Z4kbHpA0o*z(AI@TPshrWYL*YUf-ePSv z0eo}Z`t8C4dXWWy1GSO|_y)=X)^h~N0=j_zibfXzz9|E4z;CMoy4{c=(822{6i^8= z0a1WnllehwKqd4I+;;_bmwMxYKlcHqyCD(9``d}wx!UOiPT^R<(ZJQfIlKWlmxuC! z4mEad0xltUmwRoO)&cl9$7V;9Js1PbfjnXgI57ycF&Qg?P3!=yfifxsz9}7$PYDK^ z*af_RR&ja>grma(cm?(aw1K>VX27RGTK$TBJ1bSqfnt6ce1TH%9P9y^fStowx`qcH z(Q{F}fxb2oF)HJrx5mr6Z@r-aTUfnIfHcZjm_Qn?WDbN5v;y$p4jHVG@v*}l#=g4H zv&1kNsP>Q!_~5rb0FvqkG!7gLc)Q173Q&LO0|-h%6q1$kC{d~_B6MXKUtMG>q@;uI zU~vvUoOwVzI)41UJ$9i-_*%f>?8>h{g?<+W;eD@pC)!R$EPh{NipJC0?mTFx&*sVv z`ga-&pZfK*N)k_7oL%QNm^JB{kheHUQWjpO&Mlp$_Gq%Tv5%tgD5DTme&=S znWWV(Qyt$3x(N$9^yQxNs{uJHAr}=H12_rOt zIb+gMqzULr!~x+3NDwG70Y=99RJ+5_vkC#kpc)LOkQ&Lt2Qr?FxkE0fwR5CoBz*XH zt5@loK>qo-G4PF4)m5xz8UXCz`HJlRs$~b2w4gs0Wp{#PJT%k8Q-HjOy>&VbWB)b; z!y1~+6JgVG(dx$b6dpy<>RUD>liPJ=-R8eiX0;EXKs6M& znP?{vfD}ZO_R{ny@YIy$ z8e4Pn^S9Q9ca&glj&##gMW~@fv#9CeDykYYkK?(YZq6&cu9-aJdIxZ3u3W(j3Q>1T z%?9RF0F=y_gS7mebIu^VAJ;cMf6YxUdL0$r zV04Ij5DN)0M-Tc?;qekPb~>0%X5cl#ff<$7Y!GHf>NWIRRbUj570!ldHIV*TS)bh>YEmOY8*2Q?3|0eL zna0q%UQz{nzd8B`*IkGhBbD0Zdxm--q{EVp4@dt!g(!W$CQd~Ys)>xU!*1>oMk}4! z+RRl;OIBCaYHJ@WJBx4XA$7uSrsJEf0lVV2T~gX=mH}5gR(<&lbjEJadc(S~gf>~( zyD!6%Uf`rEm7SX@>y)iS2Qd+cLKzxUj3XCWJeyL1XseuLGX+OZ>e)XDPY#E@-d-_W zIVypwMu{gX=*XcFYJ^(i@md%G?Bq!EVnsJL=# zN~lc~d^!ILJ99srs-Dq)&E*R3Jl+wLA3uLz4>e4F$H>mEc!4Q zggM`6@Q-&$W3$!hxjR^YEm=$Fh-q`~vYe_eQmb-;y&=|dna?v7C^8~mWqd>YLRN?Mtdq3clxG~! zysUCls^la2X!LG6tU`OSg101ZQqg7zDu`}VcY-{OYE!yi(veHXjvmQ20#%0|H35Vp zc^1OmfL2B9ARWqq2`i6{SFFrvX20I1O6MrD$cd`lLbA?=!om3Wj(_E=^Yrwl+<}kz zemOLA<7YfEHnYmH1n{U_gC$b0kykT_0#BeO05K}J3jcTAAv}=BvX^gwY`_kfwlp^7 z6Ipa!`lbM0p~9R!lf#YhkDNISF$54}M4|R35t5utY!B8Tnqx<+ypOJr{GtxRomt)t zN+Pl%u~NT+jMbQtP*mh{ilvg?RLM{YZ%J@TiwwF2q*s}SxB#6lGGNW?95$gglK+ufwrl<&H+B z+NM(W$tV079cNzimnh4{QmIIns@@K1)O~fEL9m0&oE^+&h5P^ll2_J#QUfZ(jJ$NF zzjU$G(6{k3VWaLze`G|H@W>iB7k5Wfbwr2Fxi7C}sdfxXPG7-HC zGg2yMkyO1Nv4|24Cb|zQ*y>$IOE>WtcqlkQhUeYy`@-8i>_f$~xibhQKO|Ix_q*(a z=Y4Glm-oC40C)Ft&;TsIH>eXJ>%& z<}o1y7L6v~5$1sZ9)3WF_nZl~_qdG!$5$m#_h9oFU9@n*q;ay5xu-`e;wk`Oet-71 z2reBGrYd>A`Uu$@d?^7F59i&`bRBKz7k0*s7!u|)6Mmf)e)f#>7?p#6rUbSyXhOwv zGR~Osknp}^6@dj)H>_vW*%ykwZz9mr zQL$I6!D}zFdp1-rEU_!_*^a;L+=~26dN}WKhWc(pzSRcocCci;&XJ=%-RRp&{T^g| z-sSo&p8l}QI=REOAM{XsjQ9on|8!!dKAdYaZGPu>l`&c+fe=b27jioK?VFS9DPAmD z#fr^FRIL2Gu{M=0Td-g?3Hq{$b!TIay}U~C{Q9x1-0W7=axa|YdV;>Sxvk0g`EO-0 zE~Fid&or%=Cq&!0O9TJ$Kdcax_M;4cLEMzQC7fDeF-ZpNsqj(}Wh=WSe8ozT4OmFN zmL$@YY|R`%fwSbY8`OOTak4xIUyQFTmr4$?ibDoTG>2{pL-z;_QlptyvxF>_T}slo z;$QSDEUvZwMQvbSQPOVJh^DgXW6#&jUN6?yvp3>ffx<=u`;l+qEi>U?R8*l-Ks81s zkyLQ=auUJoe+qj9!+E>>_QPShs%8yq;ApuHkzPEvm-brW=fSr^4=wAbqj&+cqeCZ z&}IR*zqlSskK9WatG{yz_m)APwVqLFW|n6*lUb8@Kw!5$h9mp-&hb9pI+ z6Sp&N8RFtD8>Yi)yHH%z$%MnUchrE*0YDNjU-9S0!kw$GZc zh&eTfUi6)iy3lEv{wmHsL66>?qmPE(3UK zTXbO%XG!ZcXrWiQ$iHp(`{5ln28rzp@sj;{?jWuQZ)8~z;OFFNhD&SxeZF*?sa}68 zMZdm7mxnnz4;Vuu5O@fV{JX;YDt%5V8?oj>8X7jh=4CLdR_D*i29m&Sb`=sRGy>B(iIWGH#q~iVCK=u963qJ4$~^+ZHJxbB(>Z-&Po0->|aU9$Oahz{U8uz2)+e*0m+0B9BmQK zgPg}W?oNEElbOG+Uf5 zeVo~q(u8}{ucd8xB3WG@W@2(CIi+xZR6y?3iXLh{+oaj2$I9LQN({Gkd=5u~9^jL# zU7dxLtkoxPe|*o^KCL*MgHvqPO--fh`_nZP5z|&wYqH|4(5i>;ISj zz|6$@U+@RrqzSuV1_aTUZz%d?Q4`})X(5S7WD+#rG8TM+%RnuvVW#Pzp4!`4m2;rk zwn-TAn9M4=RMx6kuw7uWd#+~triPuT6%xEi~9J!CchoR2U(n?E@ypi8qzWcpYy>yHAOHXABf zHVlUAnB3%5S8Ph9!k|Ke>2!`{gZ zc1>b4qUDVY!`fYE)#4kkmBsw;fH3_Jr7R;W0~5>tp_FA{Wn=!Y2&H<%8mJ64{ct+p zY;AR9Uy9eaNv;XZrIz-WHz6k%wcvu zW;aI{0GJ)XV3^%lJVs>a|9sT}*aQdYl3sa)b#!h82e`EdxZR(JEo$EV=wk#}x&Scg zyDvbs7Tb0i1^7o3kflAx&ICfX3%IKcz)+*n<@lEOh3*Gv5C`bM%UM@d`!gRd{{&z_ z4}by-LvyhZU#SFGhXXJVz8tg7=gIRt0x*dH5Lbhzv);1XTet(5K-~Dl>e~YEC~x5h z0iX`h+uUqF#YC?ELMBVi2DzDc&_Ghr_ikKy%856l>9= zP$BJW3n-{y8&ob$dd!MO-S&q3`dp31R(t3 zz$S%$a(@eoT7QML&mR0Ye}3^^vHtw_3i%8FCryxQ9TZ*&_}+@e5I*w5if@K+Rj_Ma zwmIJq&Rdz33Teg364p}-E7g?nr}Sfy_WO~143`-00^);|joBspqgI#N&C17<{Minp z&wxW;hVf^jBtvyH^U%|97t)K=XVt6bUG<@IS!Nyx<(vMDdzL@BCsbCEC$nz@aa}5I zAeS2m&n1M$k3AA#tA0TI2k2$QvAd6GKKrbSyy$oZlEsN#81DE7dR=e_=J+Z+fn%0@ zm$ez`&%j`ufal}Zq#wZ5qih}!_>}m^4sP|1?8Et5UGA5_+X{|v3v&t^(926%8C*884Ws4KW>u(PX!f<-#!vgx;|KnO`Tzk;pO^+XwIL`>FU2YWa+(m@ssKnWlNokn zKhr5V_98WtQ!m(qAuUZPPhFpm25e=YTW$zqaU+aaiXJ*p4MRmt;ut|(NCHGwd=KOYw`vZWSyetcI&)UA505i$l039 z7IWk2PrLcIW7Mm=j2O8OT)vL_ow5hA9}rVccOEt~1GFjt1~~dIQs=X)5+i1{M{*J` zxcQ!{$G7z>#3w{;{|y7?@Gga(s)gz;9oQ_Sd>=+txUL5%dm%1dpg#9q4d@d&!*WC-XHR!B|{8T|4O)NMfe*5*{>RPr=X_>g@T z@CR}y9BVp+AIJkUOA!_V@5mEEvm9@E zd4R#7N}VB*c{Tj0Q zO#Tts0C^sFHqQn>CZFSB72C3XhKL~3?gV{X)%;ymo8Os-R+vB1RnkEy6t&F$p<*>^ z91%_vZfe{!9xm7T+)7@Nd7K{4xNM7?n&InG6`1n=uoCL z_i~{NU;Mfg=}=20ej+_}N=wA4FtEyz#y$$oc1Erwil{=BoIcnL0mj|1eh@ z{_6*GEqETUQ^oofeG66|8{Z6`#t~EBTflVJmoKgh_8WIi*p8|W35S*48rqKj4h>6n zpTZpneyNvV)ZPHx1)S3jFPQZ$9!>j%KlXw?P-#To@V&bLrxxz;V94d12Giygxm*541mJfKxN!2E$-wP=$ePC|FHQ-bve*Tl$sL@{R4RCt2EB zO8sMFFV;xTuFsNCUl=E2igZ*;+p)~Ok#Ao9xLW4&FL<)|+dL5$lsRQ6C>Wr?;(`zY z7h2_tEEz!C=86<6@9)=+MH>@}LCYSp#;mVX6HXq-=7TsQ55BJ=NRf41Arc@piik z@@&91`B$xcox8O}@Y3Qsjx-h1@1DCN54mZ!*XWbdC6O>QxNdF22ctWXmhGR^E7uKTjSLQ{x^_RY-9#N^#`4pwq~# z5TO#2ZsIsxNHn+XJKEK&mcUKYy`fzda*~Gf^a4e;oih5*POzIpJ4fW8K z*SVQ936svem1x#NmMJS1%%@g*#A<~)!URHCy1aMOG*+XR>B@P2;cU4!XP&I}=Bnm+ezAY?wWGohBD9yRCX~ zT0f>N)vY+zKv#^Q{kz)u-PFAPHxMg3rmI7eTBB0XE1%i5a8&0F1W+DG%IOtIpR79wS3 zg=rJfd~*^UuG>19lU&RWzhww%*L8-Uxc?4qF4MwFYBuxqVqCm^x~v`Ngd(x|mLnl0 zd#PJy&Oupu>XwR?@P!ON>`J>xrZX09^WBW#u-?dGDZA2pAxi4PE9Y$0&fX0!{tLIw z_uckg_t@*l9{m(bu+A4QI@!Z(EHum9b+E6Z& zrtLy`dzb@wfMHD-2ArseiU-N`Xaqiftmm9t+@ky|m%)n)QX+GumPb~z=EnC1_9 z^cEwYd3~x!JBnWRB*)21ZR1#uwA!573VVVkx-FBP3e?@>Rz`~;Hrbnw$=T=&TveD_AzH0n**>RflN>p#9j zg1~HzGZRyp1Pu25fiF!m5+3^6?k9}I0axA6(*q!qt~Z@EkuIIJ#Sa<37CU7jN|cFc zHjM(LO>TH(SfM*kGC&y0R+^!IQqtv!C|IUgU=7bmB4=Y3Sb(I-*C1q-ELe_?7s+5b zu*!aFnx2$DY_72|ZmtTgaX>OTO!q}FaZ?G9#g9OcRAZ`KX|l;La2_bSqUI}!Tu_TE zaUV=j7}!tZ9F40F9{%bm5DBpY{LQ}r09#C858S2XuQFRG8H7ZAu|EpOOkyML2N52_ zA;nj##8DrICocYwaZ6sXt6xFTroep(1#69?&#N(%2kf7oolzY2nHA1L87Vh%iSO6b zj$scQ9K2TlVgTdu&k~Z~Jx{q~W!$-7xrkg>97ExfaZ7=v%p4mr^In+Jp5v?avNb3e z_*d7&iu_>tSdEEKoNKc3BcM3&0J2N|N~9uNFp_)|OW#P&f(*;&c7{ZdF<_5O{=&tu z%L^v+T8L5_Dzqb0>krqJKjixz z8u#4JiY2}vlx-q=0@aEY=g4d-13YlsX+~=Z%MnqUD5ye7u>Lo;np^~Z;9rbXai5|@ zPzB|`ad#<}A;ZX#s|QaYzJrw0u@@nNUFyc{R-uZ~kZKGF-e}*lq4S1G`JK-%e0uhL z&=4+w<>{+X7K$`8Yp~?xtF!keuwYw?G7y9*uP(d6s^(aVFBRE0o|0CiN01VqJjw&? zLUXE}3+k#vC}^EHmeh64vDZPBB!lG!EAL-7j?X!9JMGzqR_-$RFGX$6`^l?|!wqWm z?Yq%0V#>p8e*L#1UF`4`N!~4A-{EHP6*W{k|1$HlzANmo<*Ba(y|jM(2F=Z1(#(@m zu(hq&9nFS;-*DCErzU0$n;!y|OR$z?zCtan6kaClM8?7)*DeuVx-p5kEzX`zyWUoU z+;Z-$qh9V`?1ihj+&M=s+;kXKK6!)HG8r<1DC#?z)ITGzNvAFOg)xvCcOw*4wJ3=6nl_8^5ba?8edNJk(0J>DjZ77 zyC!WnruQGl&M`)p=v(vc)3$Bf=4souZQHha+Bm0e+qP|Yzis#JnPifCC;v<)sSmYN zsY+E=)!w_-{;lUZoH>J`)hdDV#ayU+4Cl*6sG*Vi(_^<+Shp;*x&6L+j{H3u3^&#W zC))6?uCkR<^4*)UrO<9+XHmCu2cW!Z7Zrn6n`7pb=XqyBwROH9WsQe^N_?k4SQ? zH_nPvNU%sMR8m3pD4GWF;-frgiiTP0IVbLX;q&vLYqC$mjoCg>8VZt8k1^O+lkpY%+icCSc0IniO{_ksT;J=CjORq6zEmSsi5R)y@cL23qC=4 z)C5=&DUKqdL$yF{7WE^96!nLL(9BAP`MdtrBiUu3x(NqC+3S|=os_`2QwR2^+EoPZ zVc0DK*`_zZqw}Locn|Rf(Ina=Pv8O}hb~8U*wF{`k!~eSPzU!B>J1OMfi}qwmUAj)B!q&#CjRX|LDeEIHHy7dB1 zhgqdJxMCZt3;^{<<;NJ+2I;2Wbq47d0wzFpP+28UAOm5Cp@hB%OR64C+a?FmL%sC{ z)<@b#9yJ91gX$0;;68`GN==I-5gQ=d2+B%r+(xK_JZeuR;3v*Wn-C7ZNw`Uq;5Qxz zE*vYU1Co_0IsGa>9^Zp@YYu|1*w`9dZ`?5}zxDwViGmm?)j^sN93*oT1C0P9!;&gg z!n6?*9!kstPv4RT{o`2A4voC zQu-Ug3xqGwfDjQ9cA=5J^;+v3N+&(cUV??UkAVrII}3ol0msG%+#<~Q)l9L=o@(Q6 z@7`m?>(~z|ur*C43iGPRV{CqDal#ZoHp^l)JYC&(e;)20woL?PPvr2}m+?CpUeQ`A zW-T&)SI~l>y2qLNA9+Nb5hM>UQcHZQLgi0SY79txR8_wCof|b-V zpUI6$<4I#yx(MUgPQg<(DQd2KKiF!RmrwNJr^^Hx7=A9j>q<-j&WglOg{l?CEo=2c zaedsptx8TOXnn&D%NuN6Sq|H-?*9BWG3__^cxr&gMHS93-~`js^jI;AA& z&CvxUAs)lrf`+Lw45Ipwyw@XXSW@ZUrgX335UtKjwJ#7I!6Uj!Y?Qf5SdEMo zAAyd<5dD%FAsLfTgv`_9>Hp;3<{t!`)0>Jna;UPEpx$g)l9=$}b6WSzAqSiV= zmn?pD1n91RBuF$zwn_~W9`%EifCfjT|NgoB1TjAqajHCosLh}2AT+?71O|mDuP{&l z7SdiL$uhB6Sch_Pt`0g|BEEis@h~WH?mQ(P2Rjws`EMO0bVY8Lz_{~b3HZnt#w)a6 zqLoN&JXI#<6vuEieDlnh(&Nz&C;qPT50#S8!>oE z_a{3ee|wiBk9h(LCFG(#6b7m5BsYnf3DMs7N z8#!{I++4Pb;ws#S!>1y@$l@FOjq}BPHKA91GTgq)xW!P2scv*fWw3nJoDCfn6&?AOjbmDbCob<90HgH8bac{ zfw=3yzrlf-X8e4>9h#e>;iuknQ1B>^QR?#puh(vIFSSp4m6rrN9sGc7L!)6WZwe~yR|JY;>=1gkkrTe%cu z=Gr2Au!I;(eacj%Ilpl+W#;OWV7|EcPeJ?!UWSUs+GCwZ?%ikT!dcN@Uy{>!h{MlK z{*#>;1Yzq^!v?MYYCItN&Cdk!^vREp`5eI38_iWBGxF^ zB?HtLS-*I%fT;~q^gIgvb~b~sFd=v>GXphVjn63>yeq$j6Qc(fvSeGSqOrxL+@&(5 zAyto-EN@5;2Aft5rq1M-Z6&(}Ga49p9LhdbFULHL)S#f^`{0}|OX`iPS|d;Xq;wVG zyHOK9TK=Dr50dC5+wV0qXGK}(?aMnArN%yjkK^&zv@ZYEjoWy*R_pWA;lue?O^CR6 z)tEYyA<*16I0jwMQ<_RH$to_arsIQ6HAW$5SV_2qicPv$nN1_Sj2MXIrQb58)Vj%W zr%K^UiS3cW6*9yNw#HqwhOwlWGPp9ENgkAmvMFHRzDC55eORriO-_eC2(UOim}=K$ z59`WFH?A9w>#O5KVIx?{4Ri&@1vlZ_L=??k?Y7lrwz_QFSY8J2xdq;UYR|qXl_ZZx zV>|1$tWRHAcZM1^z0}MGnm3WI<)qL61@x~JWk>Gom5Bzp*!A)Vds77P9O4ZVD5Y2cq;G8F{(6)7Zf|islQRuCQG*NV##*f7-@gQ>3$* zNx-XrC^_7&fwnDu$LNXC185j(sICq&Cr?h>qd}E89{fLHIMsk z(D|wZxTBVuvx+GT|HD|GVg0T$Ci;i&+D{x9b(KlvjvJc{_m!|CIJ?b__ZNlG*26&j zcyq%@S4aIbkeaD{`6>Dd&ZG1PkHs>eQjD#G)wTMHnpPdEZy!?H*8=DFa!Cy z4FrIc_M#VQrQXQ?E;YJqW%kzKwaIgXPG($FZS5jeE)SmqJg}&S0_|{sg5sx4d4@=z;bJcpmPFBhEMDH|b2}zGGJ3WU~9Kya(|; zg-6nK%l+pE<<9}#V*syhxcvPKV|=t{<=$L>hiCuYOVxzRBGMOKp5~-6a6C7D{5>UL zs*yXFVK)=zhX>BtO^l1XJamk3TboHfQ-sqw27tsn7kr>hTQ1Xc!k^PYK6JSWiJCVQJB#gJ~jqRjegDjSorAZq@E;MoBDG+1Ax6{-=07KRAR3Zj^yu)ie5s21(4O{o$#!_6Q zLk3<%{ z7_YJ*pdNqN%e{Eg5m8Cz z4rTD_6^+w)L{49z9mq6VdK8^yMDm(>jr?}YO5m8{NOW1CMv@++Piz&HK?fKk>7zJy zw<>KCeMy*1{5~9_P0TqK)oD~7j3uToTSC2Pv%u?i(;W0i52At6~bO_6?TU>#Q;)Qks1VXt0w02u)hV zjUmOvE_{S(gXs&LR9vJTWQNE|);Jwn-hiCw)tmf#UVHgcb5c!n{NkELeDKR*0T+6@8f}74sid$~IvV%tM zJa4Lp+*y*-G`I#ACaoX$^!V7Lydm&#G)^oO6qJ9`a{{4u!v{Lobo4aY$%hj&ksVHH zKf_~TBUewcL7;%@Us_30|8DGb6*bk=^O|hs>yDxjCM6k7{I3)|V+>)U#ojoKyW|(l z)-kD-uHyec#nxr%|Q{VLj*&mdPWJ>8-sR=57GBor?B zFDTPMLl;XNm*Jf+7EId*<2#UWHsyT4tXXD(G82N*-H!{+wwwNk|LJxz0+ne>FYai@ zjN!#0hW)j@TTii^_V)mfs(JBna&mJ~JKa*%8UE8s-cDN7OIK6TTr_KK%Wb58yF)u? z6g{0S63R~Cq_K$J05U;rO}Kz* zwB}n!r4iNADF-I)S1GEDB+7Z~3whOCIhz!EqefCzIeIxriZLFa^6+ztgLAjL*Yt{< zooY}b2&ddk!g7@WUh>C=U%TazJICZo_!s8F1{d$``|(m8r?hqpVC4Atm%Q!v*D)x^ z)Y*nxa<}c7Jh||}#G5gWTV-X`CeEsM>k3h>mgab~liW8K&w9zjq?b29fywJ!?sVof zQa#>_#)N}x2#fT zVMuE9#&h0!>shS$dT6KDA9fL1so~soTiNXS2;-${c5k=mPiYbFd3(QrYJ#5Jy zmGeoOA}|@dPrmA9&5Cq2y`qFL+exoHCD1Dcx~F!Ut({(1?~6p$F-Xz2bn5a)Vth6? zm%dr|?I`6)UW(1C+T2#`-ERCZuIHsQc@;EnGG%VrnP=bWA`t%FO1yKUS7r zEDi|oyyS1Hk*81!xD`5XKl!(!S&YntgbYNX@P@hcfSVA0ul>lyHy(6v(COCA7ucQ4 zj2*`88XIHw9#)+;C&M_kN8Sl6+t=o}^ptE13!;rF_CN%y0^Pfk3z&}+-qQk_ab*sb zaB6`O)#Y3Xu4Lg(s*EICN=vC0oD=pT3i4aJe5Jrp>Mc&!&$~O%YHdSI;HL7+b0=E* zcE>KLNPg_}mJ6mnljY=>%!`Walm-8ig zZ?3Q-NGm99=jVxmOeJkMMQzLTSp&C?&dFI}_XFxNes>|M$Mv+7`Qj8!8gDK9m-JZo zJfGULG&HE8ZW-4%-7EF4+Pzr|s{8G`cddnbo|_9Um(^`{_>iwJbpLW6@6s^x3P>&i zPt8yfYThzow3_^$;LgcpI^L%{iz5IF{)k5u?aVE$xdBQ(T%ca}KSnPZtQ{CwglJ`> zLvL=YzO4-0H^k(%e`WIeW~=iPHNf+JYmb{3`N8&5XH)?Vh!~dY7EooPRS-?(3%B%? zAOe@*X}@w6%PR5tOZCd49|sGw0DlY{2!Faj4=EY`B@F|A& zYZ_R96ho&N0wdeH?NydK8`>pfA1^cCO8KQ68+WFLSU}jOhN!QRs%oLV)bIGhHfy13 zSC>=eQe=cCPD-Kj(|LBPHCS)z24wCEHqWjA-!ePo36YmK|-lj*^Exx;#73K5i8$lDClD1C{s%I9~Z=u zENu-*&d+vF|D!{qcVAdP{})c2W%9m8?jX3sR2w!UO%KN!^xb(-7|faDo%1W#M8b1y zI$G|Ug<@$UQzIs}no*R+OIF6$rv7iH6&ZVbX{pabv}9cYa^b5N+H4yON9H{`>f8GG z6~|9O%Sa2|+VQliwfWyt^eF@(G(bqmk;AMCVt-$|t_$s@FtN6NbyxY@~)b$=G zzOjkl=WRN+?5Vj$!09~h4?j)Mrn`U3Pt~RX-ptc1u^Yz*$e99Ipm72^KSPN{eqxbo z2aU6xwVR^1B(>y*iMwEMyhlEr!S zAF|9(5iBm$8rhWT*lS&y(aQLvOq;QxuB44jW)FJ-E#pexKYm4k{O9gDYV7vn&q!Zo zgObwMZLEO(B{46yucg%*IV%l97v*Q&EHEK8aw^}vw4jmB-d9t(KrUErQ7vd6sv}ek z{h*RRU4w?gDKGt2)8I&nQ?-_7la!ll$J$H@%!vJpoHCk@`~nRIGPk;-Lb#7ySRnW8 z0(QAhOkYaG_;w#^QOOb|z2qt5;!a-5T@i)Q(XN8)VV z3@33^B#+>B-O)AlqJRD%?C<99uQm`B74|F4y3S|sSTt{Oy@_smldD22mux39*It$t zv;N{24>pI};rhigeNO70^wR5iE>{BzteE=%grEfccP4M|RN(KZ#0X^Hh)AfcIh*D4 z&zP*eR&w%DSY}v~Hm7q0=FveXS?VgOB1J5j#Asnv)S&_j2a>{x=k_*Mb)q5Xp>8n! zpn>0Y@`{c@_<*sg=WCBfWq#McomOg3l|gf@S3IK}deEVI?Qder!D5e2k#8QJ<%NmX8&m=`v7^dL5>G7ZM)YN6}*f zrprMUuOTW(0dEt*P|un7$28YC$%%%HE>K)yd&j)a+B?2@^vw_F0g?q80Zw4Fg8PFZ zSPyuVT&LA|7;VO zyr*@_U-vG~$fsx!wi2Y}^YiwoUrv{_hN{kX>1zY48Ggi~LR9Y|LNnWRF78STXip(s zJm7NKf!Fk^9Tb&an(v?_nDSgy(tq@Y5T2b#9$XBnX!Rf8$e1CQug} z=Vy@QCdviQ^C~2PjT4hzPSi4pn#PTz&fFO@cC?Lu@$xe-38C-FC>E&aAQy~bhC|Ut zp>7#64XXgqe+`gfA-|0o(RLfeQPA?+H_wiGg? zv2V*}+x56u->_fxd@lQ3@5t6~kc)i_s2dy%Ub)?XTmG2Ku&|u4olF7|0%00JV`5sI z-M&8Ccv;~9@dE>aUbMi))$z3IgC@WL-M+o)Cim|WXw869ZvP?_#TjO|%k~%{0zQ=n zPT3spi)0!FVgu3v1@b#s-on|A`x#93W$=;4*T`Ef~pFn z0SYuNyFq^A`BHcX2Xu@Nl(Wg*?swbMGn@*%>krzyV~f*i9)qL)jrhOr#PEH$dGF)m zF&?OPg>riJbkJlUBnPb5W}Uy;*yECdVHqBz+!II*2na$&uoo;t0tnRQ%F!lVjuQwM zakuZ+Kj78W@f#peFwB6#UqF%e%31Cnh=Q6NEztdcr8%}UHwv?Yh$K4TNa*7OOTS;# zoB`v0##7-2%42XC4amw5?^g%^Zijg|@YQ82oB~E0r1@drWqn{dfv)Xafes5*zx1X) zNNfnHsN*cqXo-HyYIv$f=heT(F%m*Lgn64+?+jJ+VSi16^u_wb+hG{LX*!&Mr}Ns$XK*KY9{%HvhCqq0K%G)kj;#V` zRr97AE9uwaD$>4l77q6s<}(0gTm`s!34e`O%2XkLgbm>JZ@0SdM4jpl0t2!`3;;)i zQ~(lH05Mg7mnMQm(txj;g$ibbC1HecAF$(0mKg1%1Y$@LJhRQfV}!ggB(Vv_lbjr^ z`Hph$;!W>4CtAq|m~p+F0B#XKJREapOC*%ZQZ9PyF>dSQiE7Q^M zz%e_Q&(@GzVkpQ2J9RU4t`Gp=?N^cU65|Z6Kl3kH90!l4@m?01B7#|oV#Gb#Xq2nvVGt2;G zOrPB+$`9Y0z&RAEL|-$7-k~imr#JDXPnE_h5@2mFFK+DD*HzXppBzV zzwdLCUm|$x?&K;<9o(!HhfwIbQuL4W*0(m^*M$81%>eiddrm0JEqzWfL%*{FGJK!m z3vNzeIyz$;hhjkVt*=MowU+}lejAIZ9YJZYwFA0aucrsTTyHYtqd9(jOG30O) zIMx9c0)PQ@h*XN7Hvn(b&(K?A$iXYaK7h4~5HCVv-haX%OhXOaN8z6*s`kOF*Byvq zPv{RSE+7Ul{-|BDeHR(DefJ%--thi>aNY0V_wv1YY*^Xpp6+A&%JQgsTwiUfu!erL z-=1mueA^*rKjeH>R6>%=aP(1|r!{VI8qTB)(htfm=t`Am{r zjS&zzm_ZgGiTty7_Gh2xTgABJh3~`8y4!Y_$9O064W48gb~0v)ktI^P(2IPCfXR>K z0ggGC>V$#QhQ$IEM-Q+O!w|05{l#2_pD;{%m*FCoL~3?^5$~Iu^Vn@RIw@TfHnAGgAA#dS+}MugmN9sj;6S%$s%d4EcRq79{$u+2DWfBtt6{(>8ge#o>15zP*le%e&pt$I zV}H|GfBzL{*rE2{smu>S9+@iYv@nn@kWLK<(iulsR-{ns6uHVQSP zVQ6zlQe)9LL{Fn3XBr7wB}?l#$YzV;&1PC9J06@qn#2nvW;CH_fvSm+Vft}iTKyOcN4|)i73cldAy1PbG9>B7w1SK8yT18NB~?X zw6n83Tuf~X(gZT-y*zu5<3o})I)hLd`EZmR^XzX-d$K{~R5rv=qBkM#M#$vkU1J2$ zx%q+&qo*i5@8q)=q1};^IT-R^Q^t(<;CfKmAi8r|c~Suj=cK!8*EJ0KYdBLD0-@x+nBj#~6zW$fn@ z+P=2l437UN6Y_6r4iM0e#S zE)Z%yJT)U7*kIlMT?lPG#w0p5Xu zcHkPjQ6|>bW^p43@95~#%+j+nk)$yiG;ZvYe(xWVbb2f7v?$zI*`#!(*rpv^3O8$s z6i$pA#8Lq;s9(4ZD|X?q(;}$!Un2QK5hTove0YwKiD!XleVK!c+~K`Er88$P3&ygb zL10yU$nevo-JXNgqWIUTFM+ZeY(1+I-ZE0Q+6yE|>c3Z6DVgXa9Yb-SO4K?k+=0s; zXV`*^VWpwRl{<3jKSpC9FQTF^=T)@j>*;&BFFX-_xAh`nXVau%=qz;`O|1%!%$|Y6 zyILui=UC|Ks*j1p7a~aUu~JHxCHr^HsG)x`VDZSk+T1B%RD}c+ABI-sdUvcx|gLAo+SeFO_573vNZTIUnzyPw8~Y`Ar z)mJ9L)3nIKw~+an<~ub$c0vRWE;&nsT}%LLfON&8t|4D1W_*;M{xryqTi3kACw)SZWRriWp}tTy%IQ@p z$&7rGq(YxMD^e*_GuZAC=?sMw>B@y|MY>EzrAsY&wofLCET!61Aa*K5Lu()%s$L>o zVA<-3AHQr*GOp+fEsjx6Wue+1=&)#Y(?s!SpP0Cg-q6n=(z$|Cxd=u!Mmj+wU5dEc zK?Ool&rBf~!wYvHPH%)<2wB_vbe+=Mgnoua|XFd)S+Watt>EhLLjC94}Qc@^gFM>Zq_DLYfs03CgSV8Q_v z7{-uC7E-7K3rV0L@MrfKG;_=pV;Lyvkx6?9TT^h!LxA30 zA3LNfRq&ON$)1@*KmZ;F%Qx{ObK)?jB>)fJIP&l@Jv$C?nJ3n}tC170+qMw^7c=8Z zBm>?^`Z0I>f}*aoe?MmDFK$XiI;|2_$;I~Ms0FcDS&<)bWL>!&Sbul;{WSX9ja@?x z+A%#)k^8)MUJ*;MW;p9)Y#k-$%$s)yA;o!#}$m>0^*s_UlYXdqA}+64vZJLsVT)3qakWAcD!c~fa;G@yi$stx6BvL8x8*n*uky8ES)YBzd@ z{FO-HbcW2*EL2Gd_H>kn=t%lp!W3`hWE`W}C=5o>%<=h4Z)T-|FK$_2(ZywTWna z-;=S&z6XKNYNMSF{d2F%w?$eaY{|Gf{gW*gHQ#p-izoF z(Cyhu0$+ej55slvC`Y4R7{%{@fIGI+`(=;UQ=+(Muh*4VX>!=X3Z2Ueof4Yf)zqW5 zR>0jR#*e<^8bU44vt;w(c<7E#4uCY*TXG-U8=(auYInov%Wg&lza9r4#Hq%5UDQp3 zpf+i#bc(z_YiANg&3u{56_zLY<#U26jglw1^(|^0)ifHjJxapMEd@!5RuQ6?M@uEe zaP?ZyXEG38T=Li=tXwYI3>B@7VwJ`UjID;;itSLYxY-Q;$DwI*QN|4U7=srF`epy4 zl1d_-59d~qujmfpjxU8A2#831h(oVD6%1Tz#P??v} z!69<+%G;?r52OC&Ztnol(Zhjv|Ge2Sd0~gLCHfDc3Lb%NHCXh4w3XN~c5BoZADR%7 z#!yUV1BC~fB>D0EVk|F-gv{h*9#mTLOJ;vZG`J7dm5wc=umTH0nKd+M9k$dW-AO}| z6|3BlXr!2lK8%XM^>!oMcFG(#DVQ@0Z%T703$ex59x!L5q_c^I zYNLu`$H6LBY??-o8AElN4VMLSdQXnUVGW(76eRSAArJY`{MD1EFcRW3)idJWhsB7# zp;ut7bX+>YuWZ~WrHXngM>^$x2j-G29U>3Ait2i`3HLLX?ddj<0Dl#*`4n|q+O=dI zhJD>JyV}K<^0m9YE=$9!$#$W<@!W`Z%oh7Q`&zS$l%q5D-N$m~lP3H6>fb{BFj-yT zd0)-79kdjF3PCI2ot&ZNe*<(-RXMt;4foK^YBipg`f*8KZ|q*r?+-DA|Y+D*!H(sRA~ z-sADJbA@)xSUb+`Q1ZDn2V~|u0I(KtNmY@y{SiAd*E{K)S)!F)O>2nj3DG&WB4ww# z)}{Y3*NyV+#H+>huu5~Y-EiZ*kXwNf;~M;{J-+ALCOR23gsZ)lruepnR)N}WPT>lb2rFZizNei{U|BB3-|%m#F+tLj)trchVrQ`n;J1r4kF4&jdS=zi%MOH=f4cHy8>dUuSflI5_w{-iCLa-^&SP zeR5id@9wzH(udeYHc4Cl7(-79v0$;}_x0X#^EF?*dn9L`$Ua!^A$jCcl)W~5h~`lp zjd<)IB%Um+HSt4Wp&)RVbpJ6=`6R5bqBYdaNKgI~MVZ1H6Z%PpPe6d6uw&)808IPm zv8ogm*6d~9S<+8C8;r*23{}QkOw0|_#OHEsKS#8d&P9`Ictv0 zkeEnWAnRXlRTGYTM3H93Q>_aZh?U#!C1XwHABrU!=LoLiNq|!(oAq-pr10rXK)n_uw*b_TAq8!xyLMw3b zJT;!wd9}yikzcp5%On;qYtL3`FR@F0CyyYn;%jQzx zbNOkj=2F-2qrI-s`Q)#xxc63Q?z>le4|kK(^@!O{7U))Wds9=}@~i_bA{>Mh%ioS0 zZN58?KP}~^-oE)RqMpqpi+JT4#|)FB<>y;HUj%-lRqhZ0+7nlxWHv}RLVYx&s^EGm zyD9rIK`*GE(1oYw;+pgQdWKN{44?>`jS1j{F~cZe4@e|14c@uJcIjLJ3$6QU)ftR} zY^FKbzkPDBYl6>Pk~Ba2-1##mrcDu!>w8{T$G?s%$^u3KB1|37zfS{L}xXY zw-roT>6Xwl#kI|yh_!6YY4t}p{nNrK0vBfGPV=?dOhGQ**rY2^qD*CrMKq~XBDg4= zGxU2+ijo?kv&SKBAs!40O%N(DIkaHftttOq64-GTs;Mof5#e4}?l8CZp5`yZxu1b; zn^u8JjgFxU<~Ywk+poB)zGmIrqc(1noJ_J~wyohH2f{MDgS-AhRqYGgEpX>wbYy1f z$)>jxwA4zW~om)u)pUf6*=^)*~GY}(ZPX*FcGVvdoVPFC~4wu3x_d}bgMLrR46rlXgGQ$aR(e{ z|2Fwpi6?t@SqLN(V3;buf%wxt<;+0Q9_NSCZ;iw{nMEi{vZap3&m@8=ON|ROZ{9HO&Bb zcRJ7K#v~=#_s{&WU|GoDef%?BP~ZwM{xne?%m`*lQ}mb2@Hp<+nFfl^NC1nuA|bfs zArH*3=OfcYBX2uehOM0R^t_+VZnEL%^-k=b{@BqoMS1!m$3jo9+zX4s3RZDCEjuj{ z-jhEskgUpUdkZ=(Z`&k?J39#<7F;;cbJ`<$Lp+x!cV^;Whq8rVMJ1|f-W+0p_AbVc zveZ1NtBk2tK!K#Dk}eFTc5+^3y`oT?N9AMpG;!1Py7NxvqqiIsu40Ais^6YSs$NlV zdL#BU)`dzLJFAF;!A40GE5%e9uAj6mb!aTg!T$a`AQU7zivrjtiza9b zI51SQDmA@1t9nu{tcST)G~aE!hOc7Ln~W6}39%PeBVn?p*`f0^rEnOgp8A0GN8S!Z zP6z~CopyF~ncV3ZJFYg%(=*$?YKBhNnI{H&I&)O3Axq&LIP3H@JA512k?(PMGXf9R zvdV2N>g!naUoCumAFN60E9$n~%eluj<&!z=JTh>>1)DiX-Yaum*|`^Hzt&O}z^`tt z0eMG#OMO#9!$-YS=$kcz1|rU&YpQX&-~-^lpfTm~t?C=<`PO7emlX5@uh5u83f2rL zSuvqud?9dIbeI#+v5#ER-1b!{sIx@lu!#p8mnNi~nbMu;R}}R61S@7Tu&GR#jjQDJ zgx2hoE()PT+pF1FWVfJ~wa2j@JWo_v$@nOp)80m3T5Se-OmwdtFzz5kM!xg^r96-M zGGW~;8XghHYbj=uO$e&(1q3S2D_H2sMUxr{`jGN(=~ui*S)M4kcuRB5oNycsyD?XMq9zEyfzMGhc44uBAM@t=5-aswFwJd8i z{4Mi-6~kGH6uEWYE7u8m@TWeV>Pvuw(TbO{G?y2 zxyjw1x04FWMtHk~J$!?A&p$sr9@Wkj?}1iXuVo#2SqkM+a}#A3$yNR-N;YiRH8K4y zG1RzJ!#rLvj{YkDYW#}ITe{HAOh^Xb;>t)3zT&F0`Nzexku{~=&`?!4jNEi=B2p@J zVZh~^mO59Gsm4+ATgr-bb%y{eApIC2QKx(Z`mr=fV_~eh^hGIE?Y#hi1GXUYrnmF8^HZ2q3o_*A2F6E%w=%zVwx6k#ucqvx%2~V5mqj$Tt<|5m#<$A1 zLhb^!1W4jC1)~n;;h!S91CO)=2#p*ghK7(59Rsu+#j#SMU&8YCGdD{fsO9Hwc;V61uXY%T6f8%$6 zbXYH#nA|XesRx1K%UUOJE%#=JUt1S8HLr=&cTq$7+ysMUU}s??cnRTwd($%c*)<}71xZYfTN2HX)G>syCM+-Fz01ArTg91O3apO62fkv>Wx8LJEPEqr5p zps4FFV;8~yRfeh}!e%8RSvL0mESv+z{wOhB)kDAkHTfkN@cawJO5kfQ{?{kx{>~MJ zpZ|*qrg;A<*6@b|sm!8bCyfu|ht?7{!nmb6D3;Li1G8{pID)sq1VI$j|D%F_CJbPLNdS3Zg2_P(tB52<6hmcbGVn47@`VEfy-H+^V;=}s%GE&M8Z(iaA>=TCZlR?fU`U_OVysu32Gn)lK@?wEWNddX|6QJ@8;;H5zVyIBMYb{xj^PJ&<5tPl;hCEy^5dd@O@OjT;rT#}qQN zs$ap%{PaF7oo7TAva4>VZ_$TU_CAjudB;e~2E3Y&RF&PRowM-sZ+~MTp(nr4?&sDD z1k2B`e0B#gASSt!D-%AP{YHDYb4``ZI_z|<`z2Gl*Wx+&#p%)Yw8(v&Mj%ttfdmHw zG6rBxnkrMtUcp!OYDZ~afV6j6bqYq5LN&R&d@zw&FsC4j5;-tq zA*{L}@Q!gBI2D?qeX`cdIZ!trw9ourEd=4g(C^>n-lcivJR|+n(wQ;Fw4<9-VWQXE ztWVl(wO?7ikFi9GDjfE)FU-}2$-xW+VYPiZ&(>~;j(Ineok_!Mu}-Chs?fpV4K*#% zn@zfMUCE*YX(z|22`C9@D8MHkSmWn5v=&|p)lyBrj(d4{`2XNj={L9^n$PEqs}lNx_r zi3LI!*>c>z#_WcMDh%mIY~}6hk?t1kmYy~@N&59_%17Y35Np)1jOdC^NRt6x)_X`t zQ#F*f-eO&|$gB|E)b#jjiZkw(ibrcafhqeY1XpTZtBbO5KB-kD_iyRUM(YoIaaXyo zwzufN*{HVZ@-!-G^WKH5fwGJk?jkYkDvgw7FyR&zGWzhyLhTXjrhW5)-!TO3E>H)O zII_%Z7qa+qT$An!xh8*Y4U|rlvpm(*Qy9i5@U!M>sjCV)04Vm<39o9TLcN(>e}F^|-x< zGSIkc!QF!tEthL9t8F0CESqVvq)fu(SiQ!DpWAhgEpidVEul-x>dxx4lyZj~a)ChV z>|@{4;{;oI2+((RD{jp-grdzFE#AHj$P%>7d zW|Jxr`?vP*cQ$frTBV9?w%*t%Mf-52+HuK0@*FMW3_l|fScW>-sGw-R3JLlS$w3oZA4`{6m&751XTpAG@*n^C@Q0<+IsKeZ#O zDe7s%rD3>SVP|r#w_Sp-+uc~cW9sCx-;&>ykJW>;9XVA&Ad?t$*3Qkx3GJJzZG+~p zSlTh(vEs2gK7U?AmQlgsb4{QuNs~;+TJ z>(1f=H~e!alu~jabNJk1zFV~Y>vu{n2d^zg)>Eai8ev$Lx5B!9fdRr zZL}#0^Euc$7+H{o^m~tKImfM;zm8>;J(kWQR1P z^}?mM;3R-H2#LSE9xxR!vZ(Z{0XeZtCWTzsm_tuEp0d*6CdEjN^*XhSt?CU^Xi}{D zp8nnX!Pt{FY#4Rftv3vX{Z`Ca9m#r1K0@Qv&0?24PlHd#7aNLFi}QvYR)1+EJ9W(e zM%n1@wzOS4*xEIsUg=x~UM1QrT|RMN_b1~0_Q>Gr&iV1c-RtM`xY3!hrWjZ)SZbrq0p*({JhqM}NQS`!>DZNhlD z02wg@6YeIwRDtIuhWD5a?Bs6i4@88gz1&KCqI!p7Rix?`a3zo#xMp+1}RcZ5G}~U*PqGqxW23 zDRf#WO*5v}J6!61;g)Rn8PHVbog7#ny^Iz1~ zCT|e=J`oHEqoC*-q<;>au$<|PM=)SMtJb`Dvq2oha2JZfQc%pWn)y?2f>F*wM5{7F$viO@~;)o z@3I}UoyuCjWz}!=DJd!`Eu1Y=+RIs#+E51KN3_eNAVqP)7M<~wk>-P(Ax(+BZGl~f z_{LytXvNy8kA7Js5`3rPZsDQ2Sk_SPMJXzBDP=q{m3Pzha8brEm?FUVvVoF__`X#^C+nn;eZrEf^G zrK$b@U9rjWABxTYr;wJJ{{IrvPDT7U&-z`vN8qdrNqpD}1TCrF)bUlVL)O_l1+#>t z;d#9eW3CV2q4e03y^dhUryeUl$3)6;RY2p|dTy$xjdZH?+0H&@xbxb29I6hqVp$9d z>*iFtJJ2U};A&(z(Dvk=|1mY~;b7f|ZISj`fv~FO>S;d$q=cW@Ow#?%!%d~0a08`5 ze$}$xItOm+YtUKsbLq}>UGDNQ_L_lci@k`C#==gMuI^jv08NpkFdkVbAdiUhxB2pZ zUTV;)^s$IM6&O*X@J=Vh4M!rGA?`r9j1LGq5pEK@Gc2Mf;6xY}HZ34lapM6y1ItvXQIT>CZ&6w|^uOkZmHt2S z^FNAOMmC23ucDTNmEr$PSd2$6AAxlmRs#Giw744E@L*kk9Wl zFyIgjt_CA|FhQhsjJpk#KfCe#ZL=Y9kmff>4d$%*Yyq=L%+~u`GH);Q%ubmlmt^Ky zw3jZuL$KE7Hnw4hou)>}W}Tg`M(2|p$9$&KuQR@1_r0QiK>C3Sd2t%;WSZZ>hp|;a zePX}_jkiZ%gl|+eAVA;0f&Q>X}y5+O5Gx9Z~>Ep=-!~qPn-P8X4MA)Nh2I4mZMBpa%J(U^Yuuu!s z<_dgsF}pJsbNcSzOk?sWw9W=wKDzX63$#lDvqhGZ`Y9$L|;5BXj-N`zsm-I4WNoTl+TdU&)xBK65a`X52Nq zBD*wfTlAaso9rBSj|RA4t{>XH^=KQ=aBm!cO2I0my%e}mLxGBR=UH?U3a_UP?#6V% zFaxFk+V6BwS(2?)mML`p*#eD;&2n(!|iCo z?fizE9R#-80irbh*I8SpCy2F6!Q+c>mGipIxDNTvV|Ra^7p@1X^YNS){;p=WCz==j zt;;Ky6MV>I=aF46T)S{iH(0%}&fWJ(74&-TKi~@w9R=xsvmJ=#!pD>tpg_NrQ6YyNs#$)M}jnyq3yFkk$=Hh2gusM zA)Lwx7Wr>%pU}GsMgeudZ2YqAkRJx0zR^4=eh(mQ|ui(bt2cUV#}q5|H`NiVqJ%YCWKBM zm~2M__O}vl8(v@~KQ>|N(Zu^=od7DZ?zPv0*B601?{-Q*l<@PtA~NR(VP4AD@y69^ z@V4+xr+fG9e)!7F4J|i_$qv=)w*GB1lgg{0sMm!3uDlFbg^}@bz7^o@ken z&A_P*0oQN%{Yx7O&mVoqQ;mo87u%qY9YPO8Zy)CiFc91TzPz934huVsZy#sdk*%|c z6;Pc<@1~c?DVJRoj^E({HxT!Tg?N(q4JEg~H&7es+V0LFCf!@5>~sGnP#r`|Uv(Xw z-VmGb6CHuJ1IP>=C$w~z%R|GdWxi|F9>@l zayGUXhye1`!0Zs$4PqxL?UfY^IA7%32b{y1M^<__Qwbw$Kqr;n{g>Fc-3$D|GkOKc zjGo&eh{mh^+x{_MNi%-ory+{IVurM=30WxFC>bo-yO^0j{M>CVG7QM|=$6*|#7d{- zE{}GSm+eFMh3CV?L)+SYj=qgA{OOu&IU7MV|87+)D~rZU<%}`gci;Y3r+Q_E7Z6j~)s_>qVV3^w{?E_!Wc^mKK3O%*wO>bRqzzhJ9S!+MoTA~^;u zx7aU1=gf_qUnUbw8a3KWO;{pm>ftZ8%o0ct`OpZym{y?)B~ zac9QjNdb}i3Np@hGH@o_X32r3^`rd8EGAucanJNFI*wQU3c9X`tlyxm?%0sM*xt*Y?kju8?{` zLP4oMtx&_ZKEfL%R(7mwe&)}AxGo`xe-cwi7VXf4nX=6P>S+zV3NX=b% zeI;g?2qooc`<9Cvj^ciu1CV|)k%rVg{Lyc{bnrC!{&L}1>EUba{l0iOf#4t?f0xss zeh*z^?EmqiKzVv~hu6I{)l}f%;`%0I#v2W!F#+4-4Y)xjJ2d46~$bB>umuGnHRfN!w;lVfU)HNa-O=#@5LpLh zfjU-EJ}p?*c@S$NZl>S<3*8!=L?a z>we%CUf))qiLXfy(fysN1iO?VhDZmH24UGOL4!IYnY$8FjmEB^pY;mX5YDCw0cYT5xF5G*4*4j+3T%WU_NP%okVm>=NO$s!*jQ)cdNJ zra1zimJ{ZNyENhhs8F1IRiw$}-NJU7k2Sem%fl@okj|6G1C}0*>&McwPq|3C2&3*c z6_RWs2cjODFVPR-qJoYJsr!h-J?{9g&aiD%`_QmV5p5bGh+$0yREj?xA`LfLVWvZB zB8-%HXcB?!1Xl>bycGZKY}XR;K!fNko`4uCJWo_2LKGer3!K;h zZ3PGWGU}JuMj!@0O^!%{BX3sjORN$**Ry!g`Ok_1{-uf4j+VP( zf8oTK=sx2rGx5i69BOri{!*1J!pH1Eht9HE44>C_-8|qn*|qLPYg_QUmwR)r`K9=o7dVKt z9hIa!_7sa{>)`U?$-_Kxk>XLZsaoF}Si|PJ9@zpMV6@Qp7+T~91||UoUD5X|0G5ES zu1A@Zr5GM|z8s}QvBoVRmTi(0^;U83p)DLX)oH7#tAyXK`4VsIUWc{o`bgD@V(^*A z>w`*1@8zI770uO|`;)F+&-Yxb{r=hu9HC~aJEU{xk37(n>5$kiV$NSO5_V=hk|f3+ zM_z*$#_!3zHYsirMTUJWhv<$nn1XWkvptfMf^xOw^6`$fx^>a0Td)!ABZu1%_xd-* zfKI^)m#R~pbJ}F7&Fb5|kcfeflKvjl;N>KzDc3h`S-mzl-NMp}^y)QeZb?QGXp}b< zwp~kit3%hD&R66Q%pAUfLf)DI=k7J~STHv$oMXBh;lt1ug`9?e=o!i~kc<8FG%nWJrj4QOB#}CuQvt4NH!h%CqI0ZJjAIqj${fV8}AlQ!3_S;HHeM% zMnTU46GdMa)V%{{7j83i@O;jX z`Fx+NU1#1hSZTF#a*l5&rRelp>c_=oxf97rG{xr`jm9-;)!ExblHI^`4--Eyau418*0r}}Y(3Y-LZO+~JH|T(Cwlh9Ai{0h5W%5Mr7I~z7+YW}OfVW78Y3HP3ze}5 z3pNXr28Ds=3(10&9+1eE8XM^WqhW}js7}IDvtUM+D8iW%Gd4)UO7T_1N+!mPnCZ~e zdC#Uws^s^e{=;OwBj-W+N?83;LzHA~S0jwE;=*m_;* zYwAMmuc8o`tKc~iMwW7q5L_6T4mQg7wZ+*F>~Hd&m2&}y2bXB(!+20rnqzXKx&R0H zC0_Qc;D;(uKO`KG`L|_H@LSy8z8fr}2tnjm>>_qCqR$w!1(C~7`7f#f1F2{nE#!A- zBLnC7Z2uS)%PF~8l<4DHQXzwi+Is1NCiEsN(F{dxUVVV#zmv$@2=bBR^YKHytsG@#v=O;soh&dZBuS5 zy%4s>?UrO~!_&-AC?6)W$J}9kxZP4zv$i|GI0(8@WbmXr@*S}A+eBpC%IhpWC9@N2 zDyJ6cZ;C2se`~-mE4x@q4Kz2Yrnda4x+VT)%-Oz{`~{UF2}MOB33Ks(lISGU9xiXK z7TL?S8XSPj1@=UVJ}oN<0;FF^$t2?ln8X@HP{KRbT>gs8*sxIvng-J&W>yWleC7rh zWLPQ&(1k9fEWe>Sjl{@f7{n$68AHqt4i*~^X2&Ai|Ga7=_(r3)>*){Uy`7k@!_U2y zqad8*e1&}>_k#TUiV5znc_TYtb&&vwCI2-~K!oVj z4`Dnq_>zwVc*1Zy3~T=*9~iqU26J|xNIk}gx>6MUrsz4W_t)z2(3;2qrL#Hl;;t8V z5jCt2h}i`w$a>aPTI%U}+XSxh)b51jFNLN;YPRmIq?CrB)p){{ZD0-X1xM1n(oUsoiLIMNS?NaZ1|?X+>%Lfb+M0y~}u6bR_m zd(G%~Mm#t59FWWL-~srxf37@SyQ`h-YVDK>1Vevl8wBGq`7u_b!EiMWH^A$LtO-r| zQv!$a!;zLpu{XT2bQkOUo-3p8Q7ps-tEM%KeEL3U4OSe+A(a!5kfk8_s)FNef71jyRK3=Y`@Pg zTg7a9u8ulj#UL2<*3^CT%G~u=?i0UcN97NPek#rvM-o|NS zRXPCY5UD<%A6nb1_g*T8g@IJpr`460?WU5ttX|f}hs}c%De$#rRoV>FTQ+O63L2~R z`Q{2G%~e$_pkOJ|zQS^MRC!2feGHFBufb@YPyFD#czyGdkvf)?BE4$23E0)Hn)t1X zO705oMOmyt5Hc{u!Q;Us?RI8=U3P`_B}h`#aFflAv$OB(-)g|I z=4R(O{+ebusOPZt8Psktnwwqedn&b!QEPg>ZmX?+mp?aHMU5WzzI1(3H`o@s=Gz!Qcq}dXM#cYuZ=oyqDe2jkSyZ1@6sSla)zMln=Sfx&MQ&9H zs^0DWnDp6wsnS%J1IQ|Fqyd#GwkmULlqA2I)kQ`t8dQWK?KMfKV8x^`d-<#iG>|jW z#E~hNr8|nw9xX>@pvX|9dkhKM_*Mfdv&d8Wn;e?W(<;lJQtQ zSo8&(VWI#cbI~x$^4)R05;A9^bE)F9bBj6Th(=%98x2VB(?&Rh^)5{O?Ji7&mOi$& z*$e6rD5StXfB$0w$yr&=F#`8QY2=)fMz{TF^{6SqHwEvC8W$h!A$E_J*@_t-QN6bj z*f#j*%{Zkqe?M$Lz6ncx$Uh&Q6__|Db*rSEC&HxwgFXP-_`D%=TeK)>Y~^JF&)}_1 z%>E~mq(G!lBFR-7qKe_XxPfTVkH$Fqc=N=hNnyRZUb&gdvDwjv1oN5W8JrDp9$@UT z2_sVMp5`!KT)fF1D>Q8}!F~zn#6C;yEGZoKo76Y_Uyp)&|8Xn72R;l&z_xg z%P*p!c>0%2Sc=amBdxIhhi`FBm6YWDuaYU8nKy>Q9RIzh687hx;T2;LBxN2!1Z#lJ z0XKFJz9;&co9i)<$+Lv^Vi2^qKX)jd`t?`}B$48_XJd0Cr9AtB#4O`0=^b?YHyXJ= zS(7=_ zhQiK27?ThZb^jukbi*X-*V3@0Mj99bNtd+Oz1q@$v*6p{Sx&R&S{`L$HZ)E8p;>>m zrLSZ%z)kfZtsP0FnjUVM7)gL)dAy0+0Pfw;HMvJbdYV77`KX$#!o=wLj$grFiYSB$rtF;Wh zUFoPiY3z>LDh%ncoDKh$tuQV#VX4>62$`-ZlhjQ(9=)V@gU{SbeN5tlR_O?ht zBGr1^OEhwBrXrvTB*b3-L?>HlDXY7C93pb zB8hd%C^@+(7k=`G90>*3dKN~P`bJfdw52Q=qiQJshch28X>lR(51BE3Vm?HgBY7bu zDtGP|aZ*=9TQ^;?k{CX5n6loPWWrdkpZZL4!Kk%R41*)79Lh#GAokO1CVl?tFx$AZ zr^WDVF}F8h$##48(aPrRb;SGms*2tHj>P?FYzEJ&+XL`;Ctndu0XGlrVt)KV;#cb^dB4wQS;FO)-%nd8C5fI+Wux1A=ArC`bkb_Q9s^F zQ0M}gD23`2bTo?NAToxSp>Zw0FrN6}DizSb)l(DTdNblz0pTE~AigobX<)0p*YU9b zk>ybP5x^v$)xn;E?PhVt^AGbR*HLbIvMItggy@A|=c+!W+MeoBeITVR_>J2-rx{O> z2OQjtwNRgSOQEatMVw&@#n94Tje$ci>Nujl(oO6(eNQctqZwl&0y{#Y1taqDo^!55 zpk5h=xi4&)wawRp~bcy@*}bY=`TK=6_OpyEc-0jg?KT0>fY){CUNg{~QWrZs!`*dZc zq^5Q(m`E@>7MoW@N=5D66`1A>7lp36NKtgOE4&pmjvoYdtUXNDNCn?Fm}m#ccenQ4 zrfQ3cm5z=%a`EzbdA&(PyxU)P<8QSsZa-yPN1bYS9>0Edd^JmH|GC|NUz@IA%3B*)w7C0$Xz`HCK;uCdR{x*bXz#7MPfj~wOUjiu2`nDGgi zx>!o(;{k8n_OPX`$85S5ZcCGNpYo?thg0g4%I9{1hJ{VB`1r2+)Xj2=U?LvPHE8#v z`J?2FyGYS7RPxt-5$wGe>Na@hUj|nfi}<~)ypM_8DqEeQwlV03i{%_&?Cx)o?Ikm* zCTBhl?}v`Ikv`LMWn^0?42(fs*`}ppfVD|Klb@FA;k3&!=dnrYZUM6I{!nXH+p2rz zz4>wE^fl)z?VkpZyB6d}(dfu^W>p!@Y#mv}YvJFVb5qh;D<>|j?2uVvS+*QATy&h# zJHm_y!hm!qIF9nfIj1(og@pnn9+gNPaI8}aO)~1CfTgBv&H0idzW{zFvg2d1iWpt8 zni&Fh*R07b=)rYVlXuzY;@J}@z)a?K#2n^E{Q8#g?$sYDT&BV#25z*MlXK0A%ZVrEMdWDp%B3)p{hV(`pwY6Ede>2e=@41k*NG)mt^m!yrQ+|1y~pgzDxcj)E3$TYe*@s#lM!9i;c<7c*!%4|Q_N->zRwin!#dI2*0IX-LB9Q)7DK5pc*KS{ z-B$Qd4J-5rUh2Z71D4Kmpa3I6WIrgLl>!gO!%mv%fKZlcX>TnnbixtJ(0RH*goH{E z2%Ws=ngot=Q?c*az`M41T4ZpQ!>%HFh>ktFJtocDq|)nSR#v(vC!b@<)67_u(&PIN zw^2H^?<1wn;caZw6~fo9;k$9!wew+$2LsZ zM*s9^EVkD3Z7(tQ^L8~S$MpMU#n9KSB{YiXrLz9K2KyZl2uaqn0eCzN2Q7`~PWEYoeN)tyUWJP955|FF6 zN-ez0`*HjyxmRcx(WQX@H+rac@N8VDBRdgzmwESo*JP#M7XbyjMcPZ`=)ytJI@Wox ze|O&?K)>dZK9;*ExQDu^mfECGP%l7zuk@$GnX>C~+h3u`*HA&>+oG5u(blOb!q-{0&5lXe< z>NdX3;a*w+98F)4-zw-rOnX|$x)`JftU7HPSDK|UO$NwA4R=}oVx_Q+4>9|`dKokn zjE|+{mYSuYtF{%+VREWNOVyLMDeJtYI>{H~S@eY{$czLt=Js^IewoZ)G?d!jU*02% z;&y4GiuOAeDffRc)HeBtEJHC zDqB!fKinOiy+(dScP~G(s&Z6%aXRz7?$pNAYPo)>!Q;K`Ojs`ayaxVchquuJz|>y8 zP-yGrE-pLS*-`_9X#dN$9*UGElM@R{9QE06jDFyHS+oD`-E{POoHJ}P3Ep)vn&6BhhUgogU<&oRqemd$Bd~26qe2IdPL)u4W;h+O&gPjpL5rJbyQ|Wj>CskW zKmP5$egXIw($8erR?S|g?$TV--s3Sm+t6?nt+#R?9Q`xV^|3F5E$2#`QYn@=(b_y? zzSU+qQxiQEO{}+>-u5|?gJAQinUCb4Vvdbw;r&y_qE&CDa=xs2Y!->x=*@)^4Y=n@ z9zM^gER^YfHdYjCWzpOaQFU1g25!5)nUeSGRV&3r45?luLHQ-z^iFU3T>Vh&-RTwT zRr|8_Eb|@&!^?fZb>+Dr7V2g84DLnc{UEdb-V^K1d_K6(i}U!m5B;&&8^!CTP+m>qy)N5r=>va9FPyqkx4)?ix&vSw8a-WG;`*cuq38?p@ z9uD^r_RZxr=h+^~^0nmJaJwm%>jL{eUWa#*ehdviUH@|mE(QLle5P}=oB37<_j+@W zcr4Y(EBy}PZN;lyE%%7%tk)O1Gx)s9+`yY)(yobbp7FFhWQ80OC&a5c!HC=g!<%uf z5eoZe@i@KxyxSHNO}Jea3wDPLiBCpTm{MiDF`yx?$xYHj)I;G=P#UT(AgtiD5Ebqr zj%A_}ug;7*c(MquG!JiDZteE+&n-RuLoZc(x|nwP*?X)1iFeaE%b-&y$56j!cj71j z1fKPi*=75*&X?j@xN>`Sj;*cks??tEIZWh*f%Q=LoxybHwAk8xQ#So8%s0R`1c-#!-}7)l4l0Hnb@4OND(jc(??X;z>`WHEq9L41RmK2KQZ~}>ZO0bo$v4qe&LvM>1x7?XH73LHJ#V<`>pm$ z=SON_7MSB{`q(2aB(%My;wMl437mVF*&kBz<`jwvDa|F_Dbtia$kqOdgP7iZ1NR0* znn_MuENWY=rl+eTHHK*r5Me;xJk-G_f4I#i%v!gj6}sX+fl|)Q57rIOdcy4P70;S zaURUEOzQU~KtV>1v^A%~rBQ|n_HOJRFXzUEsgkO4QT?r;RoD{{b)o94j+>E=lo)(x zo*C~jIgeyH4s-0$75Px8T%o%xfl&^7UP9plU}6Jlq%1O+49yd7tO@E$Vavi=Lgh)i zKPO?lq6EG}`SsKVe@O<#cb#Mm>Re24`nbFWQu%SpZ$bcfB;Af6qmZcD?wa zPjsJmwR)VcZ*9AcV_sM4-ZklZrJ}QW)=xxU>Y{Y>+9s!d{hNsMSfKMM$Gy$DN$A$q zz8q$>4Qx&3P>y%Ih1cc29&YV+8<^-QaCO7KNpPW4W#BSse^$NLy^hq?eb{UKzWVId z-BbDA#k_RB=DN7LrL%N(x2N*l;-sT^p1$unDZcQh!|@Scz{lBg<#+U)+ZmSYdPzao zu-$%~f7HD&D%QQ`rrWG(U13eLMcnLC@f?qQ_CO5nV(-(;eog@0GTb`uatfQW>622X z>*%&Zds|pME52LWg!MTePY>jaF!vgVQvl0R%VENG@Vg*R6sz z1B(HI)Hni1QqjW(^+^Tqa=7(fG*!G!^o}&&p1IUH6X` zSCwA0HAj)f*PPH;na)C?w7;}3B|15OTICZ*V@Y8RFRwmf;jdh-HtyW6M6T31mYWhg zELQ#1EN(nYUl_gPpH~Zf^M81;(^d(oPL*;W=afY3v&EKyZsZuGh_!TjAV2ZI;5E5P{S%yi)u%QkRZ*|1 z+7>l}JG)mHnKMSCMKYX!`ZX&Bk|;ph+<|2{?5fYK#ho%s33V|B{R}E<9Hn zyM(rcy#Db!j-+8lXDRuFXiY9m5bswKesv-Q1e=<;*r74YqAhaKqeTxFP>`zlrq_Pf z$sJpOM?cOfTWzaM&w20fzxw{wPJ8VU98#rS5Q8?Mndum#@tJ-TWFo75@ftcRb)1OZ zd3JQ=5v<4&p_}%_>h&RMh2M5_Iy0R)8gUvVJ|(8qy5E3Uywv7cP;S+wtwVzpg1dM2o1wjsF+On8^Dx>LtZZx5$vFfp%>6_d}xI zcZ`d)m#mjYQKyI%5|_wb!%NIdzIbdHd4(R{0y|>tCMll22wh}tWU6q7knqo%amPI_ zqSdKBo33uz#`(v^v~yU5=KY8zyD2(jU{kpVhG=7{6=x9+#zw}$aj5oYN1_L@WX zh$^>P;#;P`>tj0nM+{MR`F^HTd=vYFAV zV%Yn^pE*ddLDWvZXDjTb;w44m;m3U*ZiNs(T<02|#M7u&sx}LG+`EtHJi;*#27WNweHZ-`G#!l-nI)a&_@zJy;i0gI}$2wKV zN0NhF9^)%&>{J{^u(t$5)I&sMDW%$Q;1#}1BqoPyZJbf-9pdSCeN%fzaHWs`)32oZ@y~&dxwb=sx z+}}6cus&`#VOVP_F<*a0eygpZRQ5oVPSw3Cd!$I@YB*uIM^{QIVbOGQl*}V%474cP zz6TIx^qmuss&hLv`XmTx*6IR-V(iVsL&qc|dxpu#YR1*>kfM|HL@S}haI3tyPknzpbaw=jus%W+#tCw$ zCqb_IIYl)J3LdUcN9TO~C4MFdm;hmD)k**qpb$``P{FG$vv?-`X!f{!X7%XyDBR3Y zW;$BgPUJZHju>?UXW3sMVl`gZI%c$|mMk7qgzc0Ckm55Nhcr59e|*BkjlkS`Q=Bcu zCUI`e3>+?-G>pn9R~}h?Iq%vHI2f@0lnK5+25=Fx4L^NvF8V{#M~K%SKE^I08K%$TCALfd<<>-q;w(&|XqOk469Yuh-XUoywD?alzEomgcAXTU%T! z0KQSB3N`W`EnK%{OZqd&^69BA1%E@%|_ zI#3klWCdgGd;!wJZMzPxZuRua*XCsIJMeL$SgOx)e2AD-vx zrQIqxp3|hXE3Ng?a%%gQNdO(L)fdEF;@SJsvCFWHmjyj5(jTx}39HTccSl+Tn<-|R z4hEcd(iT&-PHud@mDf9OYqUm<^2%mC>Z;cVQa#w7`p28M2$1lPOoAR*u!Ns)$K?$R zi~xjdF#~err3_}O29$R1G4(xM{Rde|=~Wen{IA(>6{jr3LOMz{RzbU?tVYiMj?Li_$1+G?hITd&F-vy;F9&U81+5%JO#@jnJX_!^H5Uk@b zhn$ql@_AAzBoXk)+RK{N*Jn@wpGWb14{UV17+O`t`;8Qw$eScF+I=XZSxJ&PH zh0iXwtJhuVzn(v~I?-~%%bU#x!#d{=j&;GG1(4q;K{xIIN-VDsN>J2EM%i&IJa6Bg zBHXxo0h?q#XoIHtwH@B^NLmTNl50EZrZ{T%<>E?`+afz@6c77IPBgS=MQkdZV(U(2cz`M3-W9 zi^hTy?Xf}GiIlnlyE0l$(;6$s2dTym!lEKq#&I_3bqUMH|E^YpKJ!TOcJhBAf zylh?G*&9=7XodzJDGCkVs5%1&l1X50oE#uhssD3g_o_j@$VhF5p+>0EtW%6*HXO}* zYllb=Y}Ry(Iis2zxUiIUlWnuhg|)u4Z!Qy#9OYsGzcJ>A+u#>IxjYkTM#uJGSc&ZJ zm~G}QjDFgS(VcwQOW#uS4A;HrEs?@L7pXzlYTMfE{^M~P{&Rc#jAwhI{tX??G9zas z^S&Gjpaf9Cny2OS1M{>reap0@o5w<)khFlQpCwopYlo7tAcdK9p~(|r;WQDQs!C5K zOGGp`pI6~-9K?QPGuSFiT{&kc3vF!RS0#Hs*oKhWUh>d^Q4b;~Wt(}t#1#hFs5^U?VX zuLC*VfBV#1$k@XGj`E-9Libvu`Pwec^oG> z;C{6t~IK-{2_$?X_M;SUH#``W>coxMvuep;X` zCDkF~n>r86?>mJbBstatwsdN*f=E*RZ}WsK*al@aw{(y;Uo9d^1c6A=h?@~{7i*LV zok$p+dPA}rEjkaS-v}&}s4#vI@gJow)a0BK(C{IEV3t8MM4l`ed}3r`I$0(OGpNC? z0SN@Jocc6lpW@Jc+X6Xp@5ehM-Rt6=-f*Wp9hQr_d%g5sCLL5;KnFU%UPFVHcRSvf z>mni#(MqhSh~0hD+4$ZAEwuHxWwYDD+Fr^a$5G8@rv_@$iM&B*yr9P`DQ6jl#$nArcRW@(PS!6K7?_ z<3ML1Ax7M)$#kP3{G>`pu?lO896&X#rx&uN7zje`vKAdMP__BB~<~iTg0!h z)pSBI^lfI%&FQ_3mu{AL*_s;GbBl|4w*bly_*BL4MeuUVrrb338WUGtTX1PWn(q@- zda$#GyK1JpPxn;M%zwV~lifYddt#nt_m^YHRcP!n z3$?=_JT)POB_}d>`hs1}Nm70k;aKdufph1N} z%?PdO>gRYb)6`t8Yl}Cr>!s)T_XtP^Bw!2by#O=}(u@`o0Q1!GHsUW9a|(5u{{%$x z9G4y|A9D&wk`kKZCkTpQ;0m@qp4?iJ+0P;bsO4o9klOx;O4B2QpFHy8O}+k-3Mj9=^RY`4^= zdtT+gUbTj9NZJ)V^v1;n*SaP5R+UpU7=m#z_O`>WAW{NNfd%?3wp^@!O^TdD=wQTR z8`!>0;NW){l)U4*t$EIuW0>VQ+A%#_^JS%8EnKm>L-1m>|29ASk z>JpoD+BlI@R2gRK48CEo>3?t3r+n!pl4T z(@<9n^F;cNH3{3A z(zCS>meDt*kihyq@vsP+>AOvDs|v>6Z|7%^IzBY+vzIgc<{c-Xl$4{xJT81DnPGJC zojTdjBo`n1Q69QJ>D)Ua@y1{p%RHVl1&Up*RmNM}Q;S-^jXwwOn95rN3Y2)D04e0!1v=NWY>nXRO@iJuLF) z69VmDHBk7RboeWJL1t=fej;_f0#nq#zYmmGV$CltRs2g;&C`)uP9{q&wwdc|qloKT z#lKC?%3%zj1Lg0Q(RmKVJDD9UK!G+qiqyTzSqg^|7fvSa;gpe&|7rg-Uw~9i=DvUE zdA4w}Iv_!;YCaRkRdr37w12bSU7kA5@t&gAR}lo3@ERK%JxCCoWzZ}1bk^5#+{wl( z+t0XNW>DkHiHI_BMILZx)gIFB0!BtBbY4C6lbd{!#nDZ>og{!c)&8g~U9i2kzlktu zBe4~0Wb(x8Wk}6$LdWn(x;(i7Yuo&afb=dGm)HjGFxsHK7(zX%cm zNQ!m{XH*f&jPk6MhAa&Qg()cD0{pLfT6@HLC}0DmR`h97VWf1zh7h(V;|NPcfRDL2|%31s6d_A$<(SzWdXTM%h-7OgUC_*&}l%CcFZ;sd#c$~LU zL`~P5e)-EmmV)jRhQkmql~ajCCLtm+9@_WM$ibmFWoWdb*pyKR^Phjt_OW$@C)*5( z^5T5w>i^C*_+6Low^!mfL5&-0cnRf%SE=Jnq|1zPlz+*h1l6HeG*22uCU^RK25(S< zYu&~`(A9l+#?x4G?p0=VG3CR{mhV02eHpU6_;k|@SnS@p`WYDssjjl|k1Uh!0|UXE zsjbcz>#cLCAKOu;)!3AwK!l2UkMgJ1c>r_eXoGTAlj@@SCvqGSeIgMV#eO~A88gR; z-QX0pkz;9Bv!yR=hMeYd*h(f5v8Qd;c*|VDTmZx64DXA}(6n1NA#j$n0fY|%>bmg- zX`CIn>u7WZclJcZ@z096rHV3M6W`36^jKQDhkAYQ(ZWd>*}j32yi3w%MG;2UL2eje z5-zQ2t0`yIe=MWmCtvP>Hg(M{niIhpz~NX|{Og~n_v$jma5-ZsW20d{GkGvj+AP?b$EyqrU(;<{ zRs4ZaAxxQZ(J69l;cfFr8*-jd`=Q!ueIw((;d%IuuBATf%B9@OpIvRfgm$65N-#Sa z>@z#``s9*WZA4xlEt$a?_cB52beX%2Ey6utQ{_)b5Itsw@yIIQp$I-J!2i5IYwB>h z=Nlh{GF;n8c`F<`i6U}Xhjo}1k#er&di*U+DmlNOzE7npVAGcZ<_+vGK8rE%=g7cF zri}xa0B*9}#?~_SfZy(Gv@Nb+>ra`eE`HYmm1evp1x5?{hD{H(yW4-?)%MN?X1<-~ zUqD7Li2BES2a)7}867v%i*Dk~3M767z_A@uuRkW?@?wo4q_hjB3nG6p5+qhRjkT$j#v;%mp2-gGJGkeEv!4= zO-HuJe=#zR{E6<_^)v1)O)*ubZr_K(n-)d}ZePtV=i% zVryf@RE?sLn&IT4aVzAOAWN-~x~#UWl;bYp{^KaoE4fQ*D;LF>O*=!=lmmN-=3M?% z7V&;!px{?xSrU#-Ua5Fx7 zLAY14=goqrHTY|p>UQ>+^f>*^Rp9(`lfzMO)8JTjcYWtsSL)MXf1I&`fyqlAFzkq`B%_0i=7BPqpUG2}k_+4^Jj;&*t?``n zwzQ6Q)3&*DzLYYTJvUOk8NXLXJf)5`1hl@g6XeE*CbLE^u>Ug&P>z$8YNV+qi3s)z zMN61s?n)OrphK@MbbouZY3UcPn36@2OW`K|qZIWl{x~}^iRrqrT{rQ7I`MwlM<|C4 zE(%mJZ}_peE=xWk=LLCtvbe~cJAN3yk_hngOB`{gU!gyRVjCuNb{xO8N}`%bDA`Rv z%J0f4=J*29D8l6HWI0?amu@GWeza#bBa2a_QEVWI(s&>8joWUUGLwb3 zK-Me8!tu`D zosAKL(EG!xHq#PQQ!}H~ZvPJ8PPfbfp2U%vUx{1PK2ncj7zCp8V&=NAeX3#}&0@B{ zVA$e7WC6mfZF{2H88S|-4{;ATx9+dp-R62s>W9oY(+?~yf5P%tko}1Zr@agQWcmq_(_-IlJeA&8JFFurOiemy$5mnQ z?11X@Ld0q=vm%^)-Q;8H`GiL)g0S){pUBRMOdH7pE9ZRq8;)%5lzf|+IUR{ICw}bp^ZOr8vl~EUffH6tJ=iBv zCx+N-M0D-_O{S|}dLawXc)r<_Nk@w1fwtw|f}e`8v{c{}N=NZw8NP_bDnzk`JfyJT zQEnMH)cF6wItgHHcJO~4;K*FoLCH0qd2*87UcNuhHVxqWD<(ddcs3O!$tqGsAc^%y z>LtD<$LF?<1+t*_zD9cad;xd^zk)it@q=44r*)>z-F})8lk&e1w=Fa#GkjmhKZTO& zwK0Fwiyfj?m9>+ZO$?I@>qMfX>(SR=V?1^>Vs;Sln+8+;_+-#?jo=1bQt(T`$;PLn zD6D$h6MGOu)7PK>XY)4?7TqVc{f27El;1+1)Ku5{YQCWw*`)|@ps6P#3WymRyB7WZ z^Szp9=S)2hQ#|a?G%?+dyjny_8Nr#fFcqd$uvAa}pS(_q9r|FSO^a>xb-C*P3LvM6yDsv7}lN#s}?_mOC*1As+vVTWeYVNdzVb%VMWY|2VY*VDXX zo+fb2-P>COufv7&Y{SfZjPbyI1CeImS2=+!6ymDDy=`w5kC9O$ztpDvY zLy#2m-u^7b&*9ix3pFrX&asej0LFeqb!sK46NI8HI$@(ubTWsh#$}60K=0)GA!i{Q z-EYi)2!K(Bzu3>fsY9hsij#!NMeFB0W(o**gtHS{jQl(VZ!1Da?c)s%5`Nb4f#3RZ z|G5|Xw;e2J_hYjw^v>sAXGG#FkpdY<+*vJ;Z?iP!v3|d@_jrc0L_DB(jDAlbc6gUj z4*rmPrHDnM}{_$vNLv_s$*d~4=| zeH7S%CCwY!@T*dial*cKtvl47Vk7#}ra9c`_Y)#1qMBwjoGEm#m0#IZY}5{Bfx=oy z6xHpnlWw3bL(>&FM&u94H-<)?#dO3MM^vjq89$oF=&{Ri1dQHW`$yaW-)p7y$d}kk z5nj+aH1stiREF@a^XD=_bUZjo#e%G%MCDdKP0zh(8`4=u4 zb>e*U3LN4HHmo^g)jt#L!rVD!BfR4)S&cv9KU_un8a6+aBWRX9&k>X+>6E|hYLE)( z28;_=Jrqxr1i82!riRSEsGow*JxqIIPa-OIH0|Ml-Y<6C5Rnm|KJqW~&I=OiiozpWUY=^e(2yAwy6C z!p8e4gm`(eUw))AIaX1sh~ugP?CGJ?4vH1U%VE+6HbBB>utcA7nt0xVigeoKVXh4L zya?h?0tWYPRlrlqKCV6*x*1kW&|w#UoG~MN!khcu2Qb$D5M2niFBS)ELA;?5r{k!k zq(9GN&A4LG*7Jqu8#2}+bN4Z-x-=Wu1~a>N1^KwWJbejo-~5!d1hp<3I(M9>IKnb3 z8>C>JR&4ruBKSF`NtRJO-3JN;XSz;8wu`hh%6`RO+L_DJOylW)Qp+=}vb5!RMSV+O~+FC*3+zQKm6@&5oiuFZX$}zw2}xvl|y`idB=-o7lT8m zzCTnZX{V@2V@zqTNUT5+4c%h=8Pv2SrNVKN%g&{K+TL$k0z;fxCdt_MOw>qBUz}|t zoBFZ&h25bK@_Hyn;YJHT_GWc>>Cs|_mvu$`+w2l`lWgP?wWz<6z!08`r&*78W~)dTT$wPsw@3692tLIRBGH{x67*jg5zw7n$XMG7v8ZAJ2cW(1w?{ zkLp4rWYzo3cQRGNd@@y*-BX^OknXeSFb$=!2f9Dh4sG@K0AUzd#4iC<3UOQfdwb`oulGrr-ww3oPWO&WCqEH_$J8>LO$O z)K~wdqVrz+mD6u|7z!Au9Ep`#2{O>a83Rm@8x%X(-|PmgpYGtw26Yej zYp~Fn+<=*l8x^Vx=GQ&~m|5@hTI>rCR8{oV@U1U6x995+d?xb8MI=Ju zCv@Q`1Sn+W=}CFvX|Pbp{V$gma+;i+@1$R#eBft(!N9mnZc?4N~`E4*zNzh^OJQu}pz~ZO9uDz{ZM4*Nc;aF3yTQy6vaAv4RApHBBDehq(9bk%BrG zapG)*#B_Fg+HqU`0LuH@-lSm`#!&$4MPH6kT3vH%Xy~MLy*7{)vAHE6tA4N_$a-Yh zU$!4SIVmO1l!Z^ekAyH&OkxVS7y!9m8UMI&jQN&4OU>aGov!T?^L(2h zJ3yxJ<02q-kn61yq4k2|0XK<6Hp?KXLv7=jv_(yil@$ic2h!(@C8%JkEbJCTx-aL2 z@z#8CCPLKD)IsjPL;MJ@|Cf;|jJ8(fl+aCU>*@15$~(#?O=C;{;3jx9gS1S)@%9J#<`7eyq>!QHp*rMT^!Z%{j; z1uy9U$JYPH^7kZR#t(ptA~MuoE^1mNrCCa;Hvz|yBZ|4}9TH97c2yTy*t6T+Rn*OC z6d>e--f%1v0|iBG^ohy8m6cSzS2YC%qZc^^YHV9X6MoLdG{NQx0&y zk6jb~Ve8KJ`m8wK9tea^`s<_#htX%O32SzVNF&OUf?+kN>31oLPSYo-2{#gh5x#?| z`6;@muLkO0uks<5&g;(Sjf86Vjc`{`Qe~qD!|$E9m?{ToXfZA zHE)=V0P~zdU$lZ$TgssvLUduoG$SD&nej)wBaD+=OsGF82x+-Q_XG;+d-ye227wsc zsJg!rAK^y&Or~W4P#90BM22HqTLF=lLR&Zhbx3{(cL4Pq3G>WhQWW#!E*W6Huyk;$bTaKe}gBJgy~kHXn}y|}yqylMU|WBQE$`F!C$gFx90_dz`pFG? zTu~F^;HttVYX;()AN_uN5ePhUS_t2k!%{26jQi(a~Hga&oMFST4r zK#%=w(cU(JCdX~L#$+_G8cIZig$A!stNZN3>g@F3e!8#e34vwCZ#n&2>Z64QXlcL) zIWRDv1z{k5fd7&abu%K(cpPUOb-y_H_bB_{fLot@{BML0Zq|7<48wZJkux~vdcn&M zZeJ(8h%eHub{_Z~i{QfH@c0~qdyb$%pUKBSF_Cky^0>U>+xuL+AHRI$Grl-Lk8ESZ zMggPtympp*2>?w%yeNmuUIG%8&wWFPBtpG^C6aeb0tf)dymuHX9&nA8Y7-GwJr(PhyMwV^NXW`F&L9PiQ?Sxi2b<3ifj?efjWW&k_6F-=%GX}Qv z4}-?uHSrAS@lf>iVH!k=z$Kub#?AcrJjTk;5GVmQNl-aZB0N-O!%`(X5(`P1B8BFP z``hTFdgfMTT@vhS(X7?F5p`d4Zi{JdSD*K-q8+h3Od^FX&mR_@qa3NS?dP2Zp1-*Y zCl3mzcz#|UlOh$NF4k~ns0+nVx}+3*F-+{QQ7QOXW^a= z=FOb9sMVK~6kuJ{f9h6PvP`Xn#uXGmFK-#uQMJ_AeL~LDD5?Iml*XuFue&nv6`+tn z-%Nf>F75PEUstL0$t_w%oGoyb$DQZ>8acgZ1zmw|$x)vuH-LkT} z8YuUSs;B3Dkw$+b(UG3$`*atF9gPanO?H<7(=KL%U^)$5DA1^E^2Za4U@#k%mCdgG ze{0)Es^Z^$*LI=F;aJQpYh$Awv67Zn5tWn6-EPhKH#!E*wY*4Xi&3UgZJ<{D??}P^-l;FM{r3;EA+oE5Msadx?Z-7w1a#8XMsN3ntTWs?%HStSBBUPphf^*f_z=?xy`p8Ph5@StnVI&i;;3Hwom zi5bFD{Md)l-q)6Qs1MVe*j7(5ZN9H5&7E%j``1=Z!zq2!c|WLed~%opsFGn!MK(U; zl-H4_akD==B}Vi#{GrEdo^-L@4a=>*wEbeyy(}udHO-~5;TdLjsV@1O(jSM8esEz_ zyYRW7o;zT%_g^S~>t>{#Lu(ix+&oQlSHGOdoi$#`&!2j$SaMN-JGV9?yp_o7yZ*KFZj{t8}%3pp3h^xIA5O$ES@^>xTz(2C6Q@HtiLQ592~7$Vz{NJzkihvyA{J^ zxl-K?C)EJtNJ}u=XZkslDlFM>o(QnihP@Kk{K98966?V?30lokt`x{$RNAXLc?tjy zuI`b!t70^7>_`1k5NY0s|M+YwCt~t`thSdJJaZ`F>FF0oCC-=M=X`%h+3NdpU@CE< zzF{UMxx=K`!(!v!e#`#J?WHZvBFNGPJ9A3DM6yNme+A^XJ@Ippzb0r$j(QG3lZERx-P z9tIvxnToa~@;#AA$;wx`QZCjS+gkb9Cl)KN04IJejVOIzMfB%iMa5{24Mxwi53V}> z2J{cU{25L05OeBHoV2y2*!a_F)ysl{S*sJbQ_W__o1*Z(tPF=;7xTA3a?sln5bM73 zG4QeM(n{Oe7V>Vw0(mYBB-M#}^1{Lh`_`GAvIdDy=~u6nwZ&qLb4m4uIu-A`o~U7D zCGmkJu$Ui8J>8SNcAS(2a54fov9k#$w)1~kP9h}OjEJn;?$U`TMf4_xS)_eCE*9BH z=0Io;3fQpAC0L{gft(+HHNY<>iHnU{@#p1O&Lt}Ir>s>BRyU8MHKShnp18uAo)fbF znZ;{bW=vbE)8mPVZ|>S~s1ZTCr8#g%hG%XBUa87k#SBcFG|=s@d59ev?hA)5zGU3b zxF~8}Sqgu$OI2SPL;JKhugKaib73^`;>*1&2d~$>GE-FoXlvtIh>hQ<29BlGTmT%E zGN}3_cYR;zA}X`}+DeaHW>A7!t*i=yndmX%+8P=jf?@k#b}Jq;J%FsRCHf0SDjtkq zazv_y6I5+hQ5)TmPU#5iE4Au$?gTz=hckbDjS5C;LU`-i_e)DVzOs%DX0j5a4#~aA zFR}kG}1;riP8~`^9JrfrtUZYiN z#*&W2V>WUaOi~WGQB;Y42bdi1w9MS`MMk^H<}0`f%5EVF6%7R`-H|4v3bvv4{PAE+ z$&sL_voXD|>kVVGHE{M=zGONlnfE44b{)?{;m@*K93ocPnlX?-f#M#F;o#a(NTISrqsZ-0Am8a+XyPm)D&Au0> z+I3L@bLWMr)}5%a5b4|B$hbkuza#PP+c25LCV=zJSFsolD)mYLq`xY6D-DCt{5O%s8K{*xa{I-;j_{1(h=}mo?$E(~ z-7%LkPBlk*#WWH{@>XYUmvVM(#RFph$h6z%Gv&cfAwB$yTR$RhJYCqIqAW#J#9&qA zM}zV56-Ji3-8T8mJVVZ0!b`S4-;-;XHqD*C7E_v_mK=ZSq`%Rmqfs<>YeN<+Bx+!? zKcUceX_#OHCj*1Tp8H$6E}=TyS91p|wsf%06z%n&T_5^bx;p}ZT~8W+CKIqAZnDpr z#()uHF|FJtrZ1&2_K)CeVu4h?WG-hQ6O~yU85EU}*w~Dq*o`_C#a8AqY;MMGWwX=r zO8U|1X(dTcjk3>}`IWseM+_(7dYO52^}v_DE3Rg|eC@N(d&5ol;Uh^-8yi^Gp8Qee za={||eAgtNepytm-rb@qrKfS!YF;m>l}URE={$D7`R!~=ecIJG8rtpVirO~PcfXcW z5RcF)Q!?~3IO@+wS}_d}7sT|3O%0UiiTKDH-)X1o8yr-AMnbBgVeKgxwoLLFj(H*I z^9d8dsVmWruje+d4|4prN|Q^-C0Ucp$DMAaC11aGtbi(zVTY}qbyZld4Ni`_q_Nwp zkt_Ba_}VY08>@dRIvaNW1KycR8y|1>f)2o2_!KXSJqqq#k-gWapPdreg!J9h+hph2 z^Cy#jHZxtAvT(QEsRX^g%?(*O4lU4gSFJ(AvVU3zY$CJMz}hM=W5VYV!#jx!;d4sb zd$S6Vpmn6t$5(zPoS@2VUfi->(1P+O%}ieY9QalMr|aedMP0O-!k=jCwzi>-=Nbs? zP;HwsZ$7!Xld$GX<5)HGsQhTUXlC1SK{3Y4jBO)*bsAvLF?!=!ezWBDnKt}H0tdA~ z)Inpo&Bg6B=Wigwz@!&cb;#)Z>%STi7zA`8FYRO+j9+K$Et8MJL^G}Ek2J!aY^*aq zy*}IftkS4R4rwEA{11*nBln~X8eQk`ox3>MQMxoCNwMTjp^i)aElFNkejGw1)ud1r zGogXqXb~Jw<9PME@wnleDLBlIS{5(x2YG<+t(z2$zk(j2n4a*0RDvCrX|!-sRnTo? z5|9GNy&i2*8aL4Kt3V8^z&~Ckz=gn}Ux<@TY#sDRK~{nb%BG$fRlCtzOkQS-Rm-^a zkt%}oLvy&z;ftZX_@ot-| zj!FMq_CuKG?nrH>3r`F&pw{gA69R+-u>PggQGprxhbj*Kyq^fuNqWgzA-i6UZ$E_n zqZFq!ZIY)mKgm#0a0mr|&O&N5kskhT??Q96xY3-naACgYx>%okgLPBqL`uK&w@1jF za5t`!&5base^?D&!R(qiOihT0)RhgBCU{_VJkHgWJw7jZGr#GiRoBf;Goq;JUeOyL zf8k>uq)|_iOWx8y#eaZuM)j9v?q@sybtd`Fc+eYxjmO8VarY`E>0 zTU<{D(b5H&@BGYn1Pt`;m@7}_riD3xf}q^H^yf$Y2NVp6p3St_$+Gf`CNNIh@vn9NZou%p7rFnYb0m$zh*OS<%!FQKG zh+!!G63hD=*eLGf?{~F(EJ>$CS;<-Q@So`&<32sy`Z+)L06QU@10tfXoeA#x#^@tR z)|xCN8IEe)7KzFhHZ)T?;r?P0Ht1sndMwWYTb1~ke+U@y2Y*{SNvQjC5EDJmCvqEf zT~7vV^mcjn1&@xR5p$cMkX|)!HQ(%d6&Vqt#d_3OgoGbAs-N#h=M=6o9awuYu zXCyyX=RcKiF{#wVV|Yx;sfekMKiHNfMV3g&*d*4;wsL8GlD}711An%CEj!a7_4LBS zJUE(FP;LI_R7dKxJglj7I7`feo2l9MIPbfg#H$e3{dD;QX6>UM;S8A^DqeSIpFFFJ zisJ>bq$+4A-aWjwP!JvtPY`;%q~$|@clq;HVU;_HQK?-<$njeh#j>Zg;21UYE;t9K ze-BKrL*tnt%<$q`%e7%1O{b!bV-_5~JLDreSz!l3Ytb)qhpNZD_cF%S+g;~9E#%7D zmS!zq#^sW-1@pDNy2|EQR4kBg&HauV9kx_S6lfcb`WWXM_bQ$8n{ym^G$$V}nU@i* z5fbOny4@zoCtQ(*_8W&oT8 zT#lGGr}Zv`BSwOsS?JWX^X~{ba*WlJI}^}Sv&aJ7xgAbpYfXE5LBCMzqU=JXxbl9eK6*gvHl z#|d_UZjHl3neU+H%e>f`Y@NU8!U=(#oL8$qcF`{inhf zc4u?ZKx~MvZ~5^&g7>0icSpq(J7NzyAtut2|e}A^C zBb)sXa{=Q~{<`&d@i1}x@SR%a43hlY-mH#fK}3YwcR_{o>WG2wt(pu;7efQKwGEp3 zLD4sAvkZJ9;4HqhPgY`!9e;l~9Vr-dV&V^Ue2a|ZP?gv2ACFSv1Z5HwSx|V9h9!z3 zzfw(e3>xvU5n}Dp@{MXIMnqoGo2U_TwzG?*mB`g7$cCnV*4S2C8zOCxCw5m%cQcq# z3Ox~I%i-l*rYQb_Yk#@jn`s;W_y&}c6+DKjbGE88o_F2gS0&}UymJesNffI>aD zXNnWzAH63GnDBh_2Dr}`h)jVazm0pJ^G&@P?cr}Pu)%%Xt&bWyY^&BtfV7%?(|ee3 z>NKOJ4Gf8F`*~LJN?!4{4{W|~0$HCaK_VOLA2tt}%knc6wJ+pWcg+8yK`JhavC=2g_zvb?O<4v3ekb-VmXfdUYtlOU8z@~kat zKbCh9k~yl;C{sint8>mWx%ADZqqSZ2n{ zR%+fJKVaGVT6yAp`$cYv*0R%~%j9I}@czyft`SKt06)(yHGGQGmmFQdu%UkS$-BNM==m|y0y&aS&a5+Ag?-ho*KGv^XZXh7Hr}!46#eD%uG({ zAI+t&K!v5Mm^XL)Ag^O5PB6R22>@qEO`2NbHE~qqu*bCsU8#zsP1L%6R90!^t;FH5 z^mSgvRVpTBe1+@m{XADBD$RpfzMD3wLBbq}PNXy@`FHeCKfTFokE?KdB|8IT@$XZTdy7K$h{{mp-Rkar1)szE z$bX#>UW|qyjtvf~Be)vi83-_>1X6DFeiLM`)`wR5dAahONDM zEo@#i_||f>eo&dli_jr6L^vMjHwbi6ZqD*Zej>aJ_IR{W$4U!k*<2-lzW^@wO7}=N z2>S<7aix!YxeghdXQc94#L1|eo*U~bnd$);HN#LUp3LQyM3CgQamoj5m3txdma&vK z8?3L57+rdoPa!zx5fu!2*#gHvH9YKk8WAk10>_jdW6yxEnD*zpsW~o^*8iff6<#D*YGp-T8=Z~ z8JeY$HLevL$uN~KKJxiOI*O1!loCE6b7-t@&RlHch^sTEenXzRlxAWczoIQKI0Fe? z`raWSfA)6Nr6SQk5m-&a|Dg$to_US>vF>EUqPJYDW3X@qWedajv}Jn{)I)F{XByTT zGvd`pmQ46b(nL#TK(|MYCk2>?5$;0aVCw zU3m^q8j(?WO}lMVs1FxAv~3Z?Q-ZkwVQJ|-Vm)e|s3XoQGSwX{*Q-t1j*h2$V!(M; z=~Z}+NH#og1d*T$xms!7*CM0Hci+e&L zVByrFmI6zrpiM)|0}i3Wk8CP4#;wm=Xc@eY4;ggaY`2_%oT&!FU!}HWDLG$aeznnm zVJ@rhrgp%JKGXtG2T|ar+=ZsSRoA_K@=78PJr03MfF>y)@1ZjL#H^&gYdzp2u?s@t z;9s1+%iVMF9g^q1c$zNex;un683C;hvtFXL2?|7voybF`18g%w#x+$Z?9NHuL+ zRYy9pD)7+z>l;l6i?OL`KcfXzlL*M9SeCh^3PnU7(Z_)k>J$iWPdC12OLOTNNi4Uk zY&Q@d&WSe&^sc5i0$BsD65{i6kiB~QZ7jChFu$PG`R4a{oF%`BH-HEY!r_PzNQ`)# zlv&s015U=FXuuga0sma}mf$|+zYlPz>UlqHv~mf^qog@!{SX(P3Y8CK5Hk}-8f1^4 zB^Vo3G`kVl+9010vn0>#O*Bj_5mTn{>^Bbiwac+68&h%7CXCD!nI#oWnq%Q4hIODt zH0(l*E&wz%ZK$^tK$^!G|yy!h?BVXD3GNAxJE+qSlyY z09Y#-{_kzV`~S0vs;7e)1&e~QwTjD6WEOdf4_(rSti{RMg@TLYL*ep&1TPf49Bh2- z|HWvh8$Y8@#*Jgo$Uhfr=Osgg#&toS+hI?GCWRANTNSc zcLVeW8i$R;nBuT#mG&c@iF6d2C2>d8%B#F6T^}idQ9yKjcjiAg(NrD$xC_x`ey;ql zydfGEvE<2@$I3}S^j!n}{p+_2$_~M-ZV<7X%h&P?o?sz8`FAtIkLZ~f2AN$3Sz>=K zw$yhHYM(dz_&S*WTn{Prj@3Q;d7`o~Is&82JUqWD0HcgBLPXWxc!MX<3w`hfY~6T$ zFPah4Nhh~nzV(_91(NvTFn2JG?nP7iT-LsBR7IZWK^= zS?fq48%2OII{9LvcXITi^UWdG)XX!9yx76E@TCi@SaJCJ_AOZDv7zqyz2qagetj$d zk3=~Wl+jzv$EN|5--hD57lCXO=UJxChqhiPfG;PYmtxTK z5YX>+0rYwUdfsCJy^}-6K<|4Okf)F0Ezr~6#rx3|=;=xW^a6%lC_o;gK@Usk2E!kT z24raG5(s%*0zE50?z-O|?ZI;pR|d!i5OQ?`gn&V>dmzZ(7Ni{bHfPYD_l&V(V=S^pFfZ8r&j(?|wU&f?OIv-lMx;AJeO+s#%_*Fk&w_z7}89@ca2dUS3|n z*Kf|R?-v){q}?zNw{I$m&o^)FWsm58v$sGmWgvOA&Pa&2NA=tpup9E`cQMip&iAwT ztb(*Z=|Z%!?*LII2d%FxUia^}V94#2JLJ~a9QahX@gAE^889Sb>sfovf> zH-p|ox|&J$A+PUy-A~n!cgWjEACAcPUbXiOxQmSCF_sSFM0_6FYjN`?-Xvdq*^od9~l@l4uZD~RtMfHw!l-~ukMho zAjlJQ_DdP$+vv{Q(~VYUUbl_s8@C_O&1WZtSxW2F=b7M9ExUg5Y33p5P3rnN=2XUn zUe}sRUN4n* z9Nri67rn9tb-z{Ytr%=Mpvi0BQ(@0#|9q0SYY}7)17*|jgCUDI+-?9amV}ws3Ql}Y zQWWs|0yxjv*39M1JE}A+P!wm&7d(6cX0OY3erwJfJspZN+FyMb-0K18=CVOJKyMY3 zrVl5pZ^62n`wu(~)zcKdM^pB17cy(18+B7fBH>PVRt2QP=NCDiCnbD&ZTYsv_nP%f zT<(*z&y78R@3uJ4?OQ14&DMMUmuxKt1}wUO``I^y3QZ>US>Z3lYf3My9+^z|Iyx%i zO9pF`w({>0#?xj1u;`x6>H7YpRPH99rSCjJW@B}s)0JdYlQY4nCg7;PxQSSNja#=7 z!+n2e89SYC6NxXUb|Dn>;C3D$9_31Ur+x)++8WaEvl0RJ5d{C`4d=eZ8bv%2=qN}F>He)@_TTIy))xjwy5B{=L8ZI!NUuo`Sf=IOvFXAynjlM~vq ziOddjJeVahaqW!Taa`l8<#PK5?qB%rXT)8#KHSvW;xzIC9*jQ_9a9+ME?&JzYx=&{ zt3r5I59T<#8#@!ivT@|IIH=bkRj67I(tTjm*PUFr_hhdXXr8*c1!%G5ljEjR-)Yp7 zSFRaVj7C1dcnuXB&rKYvm_C^8g(Xd?=p5I+Om*-#&FkSGMJOdvzi?w{l%9lh1A5={ zkS3i<1UF}V!G4Co+>NmYqoc0xd?xtWc{iC62V8IK%BxQiQw6q73MU5IYu=~P%~V1X zc}w&E-gld*qLlEp^bFirqrO94RJ2)I?IL(ur<;J|%K*R3gpJ*zu&t?rE|RvPCB7kf ze%~zVwRrbanAB2!x0xv%ju^fa4hN*JKt4lBhmMUi6{HgV4dc%*Z!jkDI6onE4~Xt)6^Gv(iPY zk51$R?1kJ_0&&-(hr%V!y~cEsAd`i`$7MSRleadJlF;&PBNj*yAhO>nnP6H`CVdD|$0F z>?_)L=l0WWY?H?&Gz!;V=-e;2@cbmjxT^Mr|Me;Q<-7An(GYePWgHvc0~*o;+C&&* zatFvxPz%r?_~EQy_7?RL9QS-zwl|X49&>l+-8KIe*zVejoo)VNqVxV&lS`#2OVhG* zZrw34`EKR;cvJdhIic%9`yZ;4XM!h;(Iy2zVVs!Np0)Xca0#v1AFwmO4mqrSvbe`? zCAYq@J4@iOSjJCwUbsOfIxjpBvuTV4~g(X&+w$&a7Ige85_sjTZgx_1W6L zZ_nocbQ=%WFYgAOG||V9lKPw~50Le4ydwZICpPpTmi> z5&tpT`C0GBQ4QIm_uZRbQg{B1gLE}mc~EAmxSbiJYpvwM*4L^?kU)WTQx#}d#q;2U z^x#vtByocE;4{HO{osSPwAScpH|Z|UwI$#cb1&d9G`e%SJV92!G{w2HeBW9dSL+(k z_NF4&-1L}Aps|j^%~qv*{oZd8K8@o}o$t?w$>>V#j{^*&8~4mamyv9Vj?xNcEjezWqSCrDz!H|6LXShnu32GKUd)61*l1v9~@4zgG|4f@j-a zq6W{M|CWz#X~>^L+9pa`JwJW)+{ZXtYkMfFA|&I$u#wzcDzecM-Hm&oU$fgRvNxYr zTVqass3C3Yb6ZAVYkcZkY!DwZG&`Ng$OySPcO`oW*y$+D&_Fe?|2TKZ+7`^v0AoZ> zls7)6pwDgC@aw3Iz8SRGAuSzT!&mjWwxBQVwDE&9+eg-!y2j2<^tYZKS8i7S3O%3a zbBkh^oWFWQg5&UI=R`xqX7r#(X?$at-@RxyM^kh>b;UL(yuDHtdf1 zPv)lXJ6dQq(=N21rHzqZjJj!0AKpCI!TxXOZfcZIy#0R57%xV^)1}oZW9*M&i#3H4 z)(3aPZt>Hl|Hajthb5W!?ZZ!ZQ%+-Ljir`~H7!=|xi9FH?U_zFiMypKxi6%MfX=jO zxlLK(&XlQ{Tc)CjLT-?`P;RKGq$sE;s0fIN{w{LndG7c9g9GHii);BT=jS}nFBgPX zsUb`hCQILI2(QjUpEW4cZxfCML5|XI5xVHzZY`GLCP+`?TGIOY9fQ&4X&wHjKtk~5)AomsS=AdUgQ+LkIYVG$i;kt3Sf zFh&b`8Tg`>*g?J6Wa)Ow@|<<*AS##BJ_sVaHAk~i2>rZU4aH=w#}%gJmS`a6LF5wp zHA`i`AEl+=8egj(d5Qc>s%?Wl7S|FdS@1g9Rh7Bu7x4}&@&K2DntcFvc6BiBiF^RnN1&^0O4|ofs zWyFr89ZXA9Jnsj_IKd)rQ2bVf(t=oWX3vPJ!KwTo*w-RGfeXsE(36a$n}f7oTL@n9 zYS+|5X}u$ zmYHT!Qe{0o2!dCUmNTRXupp=Q!1mzs)PZ9p(lWy>rB{$cDa}qPQ=DK%DtZfMt-41b z#ni!T^zLHcpot^K-M_gH3*OJa8D;-%nC4T>{tqNw)bEr06SoLE4otzwy;8viqoq*-Ej>aPh$vk_4x(C>GZMWAj>Jwouky= zpv_95+jS;g{@qc%v4d{m*@#egf4jz`|5Off&r)w?7hXsx)cJ~A+L!9Pj4Eu5Mc8;B z9hd;_EC8*r$aBZbyLgeNud4H_+%T4l{z4nvltxlN5hpH5?tLX3LLZ}(@r&nuO!PPk z!em%!b*%jiq{6$r8B24wp?g2T|HL{~s^eRJAOF-`I$Rf0w`=)G5o`Toszk3}?hAj+ zyzpL}IVJUlFW+bV$l`)73#iv@hOA!0l<<)no4HgQ$-96aJCV* z3b5N4YiF*EHTW_*OMykuC&enQ_nr61d!NyEuFZCW+g~5my+>dKgItGWMlb`t>D;y$ z_8QLF;r-a}oT&k2A21M6??D4VXm+UoG8*~3d_4#n$j@DHzYnRdKrUj-&|NR&w*Is| zC*Y%dZ0jE?d$xN2x)a#6Psm63O304QdUOs|o5OoL&PnDis1p@|pqpJg9IQKeV95d1 z2<7BHgnsgA^ex47sD6)H;2USx!h<@-`ZT4eZ0fElS`E5OqQYzWV}{5z{&s9=`__=L zKh_Vx$1Zk9e1wkfzS)yi(s0+N`fWw!2Kp7^YqnP3Uct46n=DtREK7da7$*TWk{i_% zlPdOT5Z(RXN))Z9-1~1OS{m~SQD%cbBYcTgW)5Lv``F2ChX-0>WV_T@Ke{%@N(~Fu zU2ln_3bCOye5wy*9hp#O1lOLjAwnYV5b_rqpSOoEH9pU*tLEIMUnV#ZAvZt)jZM6l z)l26|A~b)&1OA9B@_Dm!cj9PJCG5uIi*DMr=<6iSL47Wy%Q!cM{RnAt+Sg?yGB7d! z$zmJ)iha^QIG|jH1Nddqa$s$5?xf|h8O3YwI=nv2!LQU0>~2zJ9Sv>?E-mb}R_;h{ z@AN(!DwDQ7eC6TCEi8Eb0i-AzZfuO>Od zHu5O~Oaw7c)NN28QB|ce_!;Y$tQrynEvGsUh}x#y1v%$J8s%gNNkN7T9BFR`tG11- zlFdwJ2B4CAIvjhT&)%VTNtV0R>JxaxS?2QNcgrrv3Q`IzieYD*6YqU-5Bp*wblw=_ z>8)^zVucs2AA91)j{4}A-t@avF z{5m3n#nY~@mPeL@u$C1wSsBNMC9Il*OQ$>q4Ui&L&I3~UK^wo$5%UE$LZA3N2g*Jg z&9sslT2kCSHqdv=F02g|n0NYnq|i#HkvVzTJ%RT1{EVJ1Q)@k?wuhYXq}AUueN^ZU zMWZtWvX7+AuY;})EryoceiaJKjZZ8(keAIA*w-RF4Nzq+5baVe`-;?oBLn-XdPjh} zi*n|N$(-%9{R%79)x;E#a$XuGnkzy3i2A7}qo2^O`GuAp(mczl)F;Mm%~=!X;Zx5= z)MU+peN}}k*CP?*#%;MK{iqi)cV6LZ@S=O9Hx4vN-phfS_)_)QD4QYg`;kXWvS7E= zpS(|bQ>0PqJ5WyR~-^viv3hS-bJr*>@KTNjeVH!E;0nLL&IGLu*<>2 z2uGTH+?6V8GpiEagQ>6q?%mR%1{bz#Rr(6LYqb-kvlWk*muZe+s_e7Y@SY^M%$DL#9 z#99v>;U378B<)1i8EAMu4_-KI-O%P0|7JvG?-B2FNeO!^=yoNRMQ=lt>qmJe3Od1H z@_&%SUmKlygD`ubuo3!W(2?puuawm}Pr6?g$J&))Y!L3xEI**w`lxPUNLQOb)%57T zd{MnV#x(q}F7W0a<$=l|#Fz67Ll7mT0Sr`$tInZ!kfoZ=q3;9{>CNAZ2DlW0>9{OG zP3!qnR$^<}e~15liP=1x;SN_z*vgCid%&M7-}Gmq8L-uVp_R~b!BPL4;qdjH(ZL^o z0qUIhN4H(m07BTlZ)d_5gG1ZZOt%66>*^r)MULVo=+fQ&9diL7ZdcYTgwnTyU`Y!C zHqR)sGTnZ}`jvDvZ7)^4bn9GGf@8AtF0as}6PqVyu&;w+Zjsz;hD6_FsKt|q|f#4P-O%(5(GmH@b6*3olK28$E5fs-&fkdfR#j?FB zxuXhPozO*yYY6ac@XLkP1m=aLfxUU}xRK-phY+ZNHyjDxz~j`9{B$8Fpp{skviT{M z@Gl83bMybBFwvxp40~f0{oBH~-xXL($3U$QqW1vr7Ivm9NCOG9qc3>*$RH=7ePdJH zO6ZOa{F-pZ!Gui;>oQVKA6~EHF~h9WQJvDK5mPR(eAWqGaTsIR1vcQ|Kd|51W-ea( zgGBH`UEP!=bs9ya-A;nn=x8>3%c{mFtyv@ zmSqsUV%~n(#Lruaz5|yXKyV-XD8u^z+%~;S(2sA1r+gzq>niNJcW_(Kwe?is!i;Fv zDTv0cM`*=zU801$L67RB`w#qTh;Q11Nlv$prYLeWW2bc=Y)`iX3Y5Nd`*&P7Lw_PRY5IAv z{x26A`V%ra$$PhLrdYNV?)`Buo@v%8<%@L=VH&`p z)>VM0iZiR!nH9$2VNAdHmD%kz1v%aEUyTom&~qJsz6zb;X-QmY4k9U|yPpaZ(#rav zW|D?UpO)fUl=h%V0g<-NFc-*|eLxb0f9qQ${qp&NYifD9CKDxt8~bI)AJh$>atKb; zyAJwdLiRFb^GER^$ee-28|XXpQTh|b-Nq;{x$lF@1Z}XK)YxzdI`75LRmVhm)_xeg zHW3{zamn*Wg_71ScZmM@Mv_P|9jPk{o0!{To$z7I{Ifc?$Av+Ws;}@4uM>{azmd8m zRQ4x*Eb@0BaR#`ra*wc#(Zu2WiQO8NMQUkyIDpKKF~BLKH%LHHae#-rv)U^Pgh=Uq`qmzOiQpLnn02zpFIZ~^W6OAB zW@UZ+s4r+#adsLL$Mo-93T%$LDAf+M2}(M2Do&FP;BK7udQitq`Cr``wor-Bi_nm2 ze;B%2S1c{q7>md$XIuG!_ty{>7wdOa#zcakT&+HAOC;UACg~dLjqt$Js{{}(w_2jM z42?)CN}YBtwMSoYN$RbqH`Ab(_xxUy~LigK3a>;_I!z*g#W?X&5K^uQ*T_rBcz)@E;ZIR$$;L< zYZ^YoI*Ky+DdXGSaYir5#=$S zhasAa-?^et&RBMR`Q#V!6{yE$6xhp%TzR>+aGq^hrjDl+=^{49P^*5sJ!*LG{u}v5 z^$wgZ@TJ_#;Cl8hmcs37Utl5(l4tbQ3tR4Gly_^ii=Bt>LD*kBFk5pXNv!9%gP{-y>88DVALO}MTo>1KQUUQSNR?IZkzSSC|+e;9x^OF zwlH;QVWj=)sJ*fI>WNT(V+v4WWO$+ixGQej*9yV3mq@ab9=1^6MpU3_7Rb%v)AT@r(K(GRN36Ivq20p$rm*R^1vf z)GVRSg5&BVk-i9oU z86E(Oc`q2CjUDURv!sBPnE#%8K-E^U{yw|ptzUuL?$ea4*c}f5RApat%Ww3AQtN%^ z-`*cmDy4Vj8OJRS9tvE|>q`MsD8U=$L#QI}p%3GS-x z5rK=ZjiyN^Q1Oy52AJD1wQB@;B`flg1jIAefjA|{aBx7LK-3RIT^*t>^+J|R*J?F3 zZnm2M#SznfG(IO`bBlEqA*MAct)eI+!4rwu z`>`XXrZ+&FXlr%W0)Ss%iIpJWsYjhzrBVZ1I-FbQF@j3Rs4(djk~IaGyVF^RVS zw}X?tSbj~mTVA++Y4en3lMb?G)gd~*LjNe za6YBSy5lB4T2SS-ZcnT|tr_gRHk97$v3Fh%%<_4m7h?4PZw2a+L8E&#Dzf*KK-l3d z;#sM=du^^`$6)KlfV@}#jI`7<@Z*%|)r6F`**@r<$xnjy#-Y>2*RlZJM0e>*H;Q+s zA*?LlIzvpVrbfCtp&b%@I29|>p+K;G(DBqNmy_bfM7(v$QJVpMTw_O2c9jS4V{1}g zFX~?w#x`By-BHsqMYpSMFNJ&yim|3l_V5w?=({v=*UF{4dhK2izZ@8Y9jY7WP&U4s z4dK{kLqPp+Lr5m}o!%tKSsUL8a*r7>Mvub~^hZEk?X6Jb`m+}hL%v5|r6t?sH zkFdRqoHujX*u(@`Bf!cU!9B0VOlfOQ`^C>6#0G26qN9~bQJ*ub<`O&bv*rn}CFcKV z2FRtcR>YGqYxmzV6P%3dlTKI*N-@p%Zfwgj36DS~EX-DU)K9KHN4n2$(!d3wEb2{y zuJVKL_1rz4GrP8zGQ(afPo!2z%R;3oS3m!`5yc|GBCHoQ)(QPiA^(*rCULEt>YCA= zB23x6Yl>X@Uy>m7DXQYf*sFB`^HjyKt>Pagw`JfpPi(bCwZ!rwtIEJax$UoYooMcf z`9`I1_qcxcp)n;*>sPzR(iG8abBOt0?A^O>^#f%76SKXVKiRiFi6msUI{6Cd$0}?7 z;!nVm_)*gh0I!(?@S1tBVeWoGs_Ac^j<8p=ZpK?2Z^qr6Kc%6$9y*1O#q#ld47tdf zpvb&!m87Ynz)WTir#q^iQdlP7_;m-{>gt z-^PF1iNvsrs%Gyy&+zo zx0hu9xx3*aVcu<758wmgS)#CZ89$RP8svkcWlSJ<{zaO3Dm^JHyXd2gni+2_LxxUR zT`B^(&SMAh}CNfn|_DJbf8yuGsa~U@N86?q59a{!N>UrI-#925^`iq@ZStGW06e^aH~kD z{N(VTIW$@7BmR`7J{?GX7#B$WVMH?jl6uw*m}PtcXZaKVU}vCy#o`tEsAa`%5!U}e z>HLn3dDtIO`5dbM8e7f1?t7v*c<}~gMXr@)oL4mU+TM#t5nCj zx4F1VJDTeoamtW8$oVdDB0#&-15*pjshE{N?X|dO9c7U3rDpz2{1m8JkRSQ`Wi_i4 zQcWkGw}}8MR+0E=CGi-4Kd`W=D5n!L;#d6c|5K&Rlk_2u)6VgMHkv7q?00(wG_*wY zK$dDdGbqQ^B|#Os2;Mx{^Lvc+o5E(^HDVI|{})59pLlMTz>vJgYrEGTrY)lGxYxeO z1mFt*NxzFCHDcxn%T~foEVQ@r-l@Qzry+0`UP6!hG$Pd_4?MBmPa)fU;l z*NAO7XQG|*+CE~87?=A|UVni22Z=P5jo{8W;;yOKBo8qa!;o}iMlHWkayE!&yfYdO z1vn3DIdR}L-+QGoRe+rr?BYp&bDM$ciA(Pg>EQs$+`uBJC!UBOo$dv0qJ*9xsIxK8 zcu{KQwSjz3zN=&pWU99AOV02Mj((VZkXOHeI6!*SVFWnAeyiozOx zr+6eeMAJMS!2x-`bw?BURwJNPOQNVrTF#`lc6&gDDU!!>jRb}BzBc9 z_d@xKPR6x$MO(lJ9U8MyMzvf>vrZZ!%p;D%6y~ink$YI63EJf$QybA9 znSdY5>RTgW1Rsz14z1;U{D-L@S&jL25%KQQgi+bWO)jZcPIN7YGo2JS7_OY9_3ng| zQHljZDwBq)=c{%R(j#?r5pf^pS-T{DP98N|qzo9}UuBO>!AaOc7xID0wjp+AFC(xC zmMr5;&3HKsCH9W)Y{LNnOv?mn5K#An*Wa7I4TDb~@=DP>xARAXnUF8&Dqp=(Hu+009t zd5FTZ4wlkOS3$r%gzh?|fE~wAh|onY{lwU;%QPihMW00I5xajym6Y!Ry+fi-y>RLO zt`D|j)YNa$U-}XNj<1||QS;W`VZjGhVdv)^kh)VXMEcw_^p!l{g{<`$gZxx=akBYe zKs^8XBka&-Ja2vS-6!xpp4FON^L+LDtm&1(==EDicFTMgJ%DZ};A`;0G*o4Tn1ZP6 zmS?L*+$R_|i=!Kfdd%~4pn6$&KFih^dkw}0ch;0Tn(ttQ3ooR**L=OwPC0y`<*v%E z{M*%j1bxiC5SZ&HgjZy#!f?=B6*Fe${SbY4?m1~-(C+<^TK3cu*)F>>Hd>}mN&QMS z{GN?1Em=u>@QW#KcLu>^B_IS8U%e_RWM<){sl6Kvot@+ z3YPdi_GsKSx?oIse18{UC1`ydEb;e!!t%4Ey#GrM5gYEHTCdE^P2>Lw)NOFo=j0Bb zfB1z!xejQ0>bmih ztD3>j`&+uj;lK+mWLFtf_p@g1 zlAe*SikG~5ovm`-L+Jg9X5WUX?X!|(-ATOTcX(uf41h;P{{@e(fM!W}YVIlHc%w*u zi8UiRQ-J4QBi(w_*cJ@04{lZ&4kEOnzYwL#V29~ax-)YAwB)n-`xh+nx%0zRX^j9={WtKdQ-BZC<;uW^q!&Vw+CXkDGjf=45SXfaMlCWAAjcWYuV8LspG^0NpTC z25mWUS*glv=(5U3&?<)LPv9`wiA8>^lS@H<8~ga@14fhkCCS`Yoxrzo z1^2jB#dByfg7*L zjn9^4MQxo%h#6o5h_D&iI=j>(YVnw@llQTF$=$eGkFF{pho^i6?6bb53m;-9{13&I zR*yA~qQmjlKqq9ViJ#$9fy#mY5vH+OIV9gZ;YI||32P-2A;znhTuf{<^<_4Q*Ne?r({(8ngZQls+Mlx(H_a9fbscop9!!^$|2(hMIkg**=qe8Z zY?4%|S~Au>U+L2blc1n6p4@e4;KM2+prx}4?_w5N=6JL{ex9||9baLxp++>e4gm^569;wq?qW(7@S zyVz@nBy9!M0RHcu75<`^=WIPFFW;q~q-W$%k9ED+XW8VA&-rtQ!Qtbr4>Q8PJcPj7 zoYGH)Hpc@?PL#RyN0hwauyK~h$`^x{fR!w!ZBxALs9SK-qygo})T^mm0AyKE%3h-T z08ScMDJC)aUl7|kaFtogb1_s|xIE9v+vz;j@nFlgt$^~=?euT|MDB_rMY2`FfP^OG^%c-?x=ROY(8)M~){zCpSx==%g-sa8&8}#$s#X-!L#A#=07V>F5dKuB-PndbrolmrmHe9Viza$rcNyn;rtK-U(yI|KU7 zT<0T&M!BOHQ|PLGV3+x0t=BO!D^rdJU}ehtZe`-Kh}OusVm9}0$(I}~s8-#9nYrm> z8ggzqPtSO}mfH~OYd?%%snV&S*HzZI= zK=#Td52JmUC~%OazsUS<@1%-@#@9;c+|?vC^&tky)a|(O6`1GT@cEE-e3*a9BhFqy z!NH=JUyYm3b!1C&7f3a+kdK*>Ro*;#=9I6QNz z-JzE3IubRi>Z4REY8@<#f^Ry8&vig9`ma6_5{?%IW=B4y9FDOzG+937^Zt`_+!bj| z|Kj9lk58+sCrq#aWhgT-ZQnF8<+~@R8u2{tYTtP~uNQAkpQ2p$9G2shEUEfQ^0-5$~b9So-+SlUB;Q0cWH!!KbT#kSr|T+IV?S^3lDN? zrkY|R2(R7&B}o8`k6<9JhlTuKx?r!eBs^`W)cNozVdV>{w%(@uZV{XM3S42_8rM;O zN|_Gy^>LZ4Xn5_m`C<^UH%rgKN)A*dM%!n$<-}14bn~=azLR zJXH)pXjTgfFlF2(a)geYKdUU>h3}1{_#`~ByEdAXM5-brH z^TZkY+wWHXj4y|cVj>QU9?sDp7Oe?4+kjIGO-=D9SwY^Th!fi~TP9An&Q?UB^j|C< z8IlA1l2-?LIeH30#W_<-tQGBm1RygpL~^Wjp3UP{CXFigK+n<#Qc4_)!hW%DpgjSE ziu>dz!HBTeBiz= zx#<;@Hz9Y(zP2kkb^Zr>SEYw8`}X&%sE!MyQ`3kSIWQHzWk*fP0%**w8F^%?2{1&k zqGc!je_iHX8n4;SHIaP-tK&q?+G1n`c4ORAVWjqjBm%!xG;S>m9L9UebF+_edUxGK zlcZ<7dmjP8fwcly1z>BMn=xq0h>K~^1ZK5fG=4IJrLyoQ*!y^%!QZz&ns4t+()9VY z=?~fE`)Cq(H^|8*O{6nvnMd#GjpDY$ePfX_)guMaCIeGs9#9z%2t@Qe`!}lztDM@0 ze0%ZIH>)NDEQcaO0ygA$ehd9m6Ep`G^kDz%SHxmj`TQ{;7zS~Gc2HToj< zfhcOa@fqGkCTpaKPSezQGQ%&xOV-S@|7g=^q|tjDGaTsFT-rwz-0g~urD~!quB|)c z#TUBRuQ|x491LOfK_^>SosayG*HMd<84=Yuf`0hFotHKb?elva{5<2*H43^eny1Ul z<nX4$zrhMEAnNclra`K#+0 z@=okpOvQ!1=p8nhfhmgHG`qvSy>clsX<*`9PF;iI0o&I2)aBdHg5nhx$HCT}Q`a_u zM{7KgbAzSB)E_B#u)ODi+0~{_l<4kntx>R0qUDt6Paw>$2|QedmS~Ln)f}Jqzr1tP z=qc?#u+Gq@;PJ)$UK7(x2iRE#{Zv_=gPTS{ZJU_JJ2 z*kJtV{;%sjKGs(VxXBA}6JVu48pCUqr$d>E>Gm18a$WV{{|Q>3@6NH)Pn#@0tM@zc zol^K&?ENXd-N1x-GhNbuEBV0@!go8d^ggR$uqKgQ5K)fQq&x~#7gTkwl$TbJ46EWi zDB%=dT@V7ZKa$uk6tjoz_>*6UZ(xStAzte>)`~Gb#0Zv_z>F%0wUB;*4u%FBm>3A% zv#{C@zhCZdFkYV!E{_c+vIL}R=sz5!fQ@ei9Rx4jE0Fz$p5jr=u* z$To#tj->!7`Ld$L`1(n^x}=(?Z{~m+4dC@b$0)lK(&Khm{Ju7w?WnVa`iooh(nLPL z?u<^|0^@iB&8AgWXm+c9nSI0|KR{#PW^o4{i{2+rx^@njD8k+muC$YX zw%)fHFKWxLYACsqURk6Mqt6qA0FMwOC%nnsx>ZJt07Vc;;#HTfL2Q5Gjru5HpyutB z8FCW8k*3yUx&Ch%1U@!wZ-RL9MLbSqhm6~-)mCrlHa8w#2{qrCTKaJv_)nl^ll<3V zmq8T333hoy9f<=hVLZ^rl=t4vX1>5M+VFTjC^L%rZvZQU5&+k5*P@r7&X#pWpw};G ztg8w%IR6v=%~2fy`;P%-w>$h0V?Utj9@=f^#r(J~bY!-D=5`$9ZYB2NjdChhhJi+0 z_hw7YZkXPW+ub|=08Tv6qQ7@%y0CXPWC;A&&uZb9V1nzp%B5$0>cAog3=Tl_n)i3{ zOlgRtDLE|CDXbO-wSF(kYxwxhf$jUm5#Y(3zB$#Z?-fwLPzZl%tD|r>WfhR8Qv`sIck0VEx`e&O4lpUvS zq~kOq{jbG1a4yH zl5I6mV;`i(8jPF!ib7UUz7oY}JMPP05CTiw;*-+BPUSp7r1@1th4=3`mR~M}&aNtD zu1~$lS^w_xNf@5g5hRklFqrzev5~PIL55z9s z@^GuOu|!zsC+uAQIvfzD`^yJ{syL@RvN9)_Ic2fkHET-udaOeV!Em>09~*U#kRO|# z0ydQnyj_C?>LOQ>i%@z76sJ)dJl&7THi++a*C@Lf8#hC$RV(6{r{X!jmCnZ~oa3#t z{fHcV#RuNdCBx5vQ2x~sNBmbQZ$f0<3;JeTADn@6>B@O7Ffanxg*#|fOTaeudT}jU zaxdj5B$Q^N`Ez-s5!B!3rb*FYr)qA2p~DMl5N!a$I&o)A?Gawrr)-G7k9|i&hWrWj z+D#Zy#!Y$%5?yi=-n(HBOP%`TRC~P4K;;A&s4PT7=H+;Ubb6F_`RPjVL5J&kflFAH zE5O-5zN>0(HimI`TRrQb4L{7`$fJwBVxu?_n$}%w6x`Z_%9s}=;@4q%5_~eOV=I~g z9Ta!o)d^b3=427VD>(XW!*V7l@Gb@;68DbzmB zs9ZHJYKeTfkV46G49bhd=lDSp{L6ZU?13h8Q*L1P`13F zCB_Xm){2+QhE_(NbxJ+e#ZHgUny=Y80$=6CVco7M58dtI>cH!|-L#rWJ0JeLWJ+Wm*ON9h++&A$pL>f? zjFX9*015}7HvrnWMO8kLIMy0UDtXl~6D0le(3o>IJDh6~)mdj?xC)TdF|F!ZU)5)! z!RB4T>#NArN9X{;o~3?#a>ZXQ?<_PVY&)?9Ad{QA`dr}QI*l2V{H@PTeEaU47Y*uQ ztXupD(YP~xpl%&GDrlNPIfVs(adeRLnK%TY=D&T1({%>#q}gy`MfHR!ma3m1QjS=A1>PM-Jc=8BLx-V|$_hdCbOw`dtfH z=Q=KHY!y#jz!E#Z9yvZgh*`WwHf6%dE617HFtVvaaH&}d1@qR6^@e$w4O>I3p}W{q zWCOVdi#vT0SB8G}Qnz`%VSU-qhJgeXbPqwqKT*mhdGjY@yAD)e8cPM6hEit_bv0@o z)>NCd@No4c-Srv}W%g%w;l(bsFUKBDRm5yGMYRFcMBaUHrKYeoPlnxBz9v^)w5SdT z0e{=FMVZ2T%~|$y2om^!s5Ng;5m{JK3B`>D4M0;?x;Mr;@ec(()WixwkI8(Zp54h7 zrx>_n9-r=grRl{Y{=jKpU7Gh5yC)|Njui&cuNh}lsSu{2oce-7Zh*P6;LTJ)#hdw$ z2zq2*jrcU+=T7T#;T`52|L!Sr)L;<;|=gcGL5T7<>~7#4vS zrPqc+oPAt&zo^Y|bYc+-x4x|V5Nw){;FYT88i_L9M%yi3h{NroD|Xa)v^|uu zBF#%sb?Ex4oal+CW!xNT7-zjQS7MT7qj$K11M9Hu<_8|u3n1FaKeqRzfZ_ zTt;!Hf#039CFlTn0*)pz&eSRVuvOQTENk{VPi#)2b#J#|#p>FS3-@T0hsvgNZKp|K z&wUMMl*AB#!aLuT7`<0-qV2Zc(^zi7XzG*-|BhMwK}hmR<63PgS}W-=_sheZ5%$0d zYM?yCJAWTT0f-Y#*ip7_=}&r~0QkoXtfJd7atc3zawba8X030N&40fw+*&)RU@!VR z(fbT%Kl1^wa0#N24yJ!QV-=k$2dhl}2T(7VD4aG)*cLCWdARNBc&ws!-H5w^QtN%d z-v>nOw>kX8Z)96~`gV!>@ZbllgDHfMfB}zNb?YSqB>$6Aj?Wp^lkYt0OrW+|`+dh! zT5EM4;ne4X?uplS?&;Nz5Vi?%ARKh>AO;^Xx{w(ic}9M&tt4jMlKn%)L_e}2>wp}k zEyB2-rR3Ic9zORGXZtvbDz+u1;WPZaMovn?*q0DtMc=wl=4lx#NoFm% zt+{oI@QLnl_%PdCCqEs$regtd!aAJ)ePgaszB^aJqNm*VYvW^l#O*6X@h3e#>?&-1 zQS030{SFvwGj8Y~1OCidGI8AP?DG{GE9z|b`E>}lMQhwsZD-v`-7lK}v9QA6n{<0M z64pJBw$!Ah@7J`(?;1-~bPyox9ON{0O`I}1u$yy6f?|Ab0^lP#k^?!){(&7lhG??3 z;pA}W4NDTi3{*Pyp6VlY%*;k5`6nUu9*LyoqVWonc!z9|)m#CLk~}Vd6vLXh3UBzb zlq%Mn)V8z<*S$1cbW(Ji!u$)e9q$|G#OkP)-Wsy>BUtxGs%HtW2tfy=u17b<`mKVAX{lrI)UxtW|M8=wh$mbY!CiZKg(xgNk{1b#?BY zfM~v*7Lo=N<}CT~cBFPg%?q>@Qv~CpN{T^P(u4~=+D=zuAT}R5J_JgWKaTbGNIYqZ z>N3FJTKZ3#PlVl=0m7TdvOIL8C~^Xz?fT?$k|lQt+>%*Q7w}A;q%sI z^1$p29zmUtMRsat8+sKZTB-0A4yPKez`0ryvoUsUJoY?^gpK5$jO(vx#56NXEG|~2 z?*sU*rWohYbU{`OzgS$_hq`f&zpzU1Yb*wl@JB>y%lAN5#5@QiF`u^cs_uwAul;$^ zWX`SjF1Mvu%=ms_7JhMGR!Cc41h1Rnd`TY)+QMFF9k4DAPqRI86Tmv5 z!Pv*);3{mty2QOpkjon|F^!#pqAp1EZCax)4HrX3nWH1wL6l;_QDNB4Qnp#Nb&q<5 zXm0jwou(W_k3H+IJrUrZToP_v4!T!!Kpf!S-|yQrHmHj1FquPt4oz*`hNM>30u7%B^EDJ4`yjZ>-XF>uTpP zLsSsw*C35>OTlAi!w6GTa_??t&;#4>Y4GkT7X`C@@e^N`jd$l7nOMRb_(RN^D%y^? zS){g&S$k@)-+=1QGDR{8PP7lM)ZEB>h+KRcf>_|GuXo{p-k4zgXJf)^4OtNf;f)=@ zia*tC5Ant?md~{iFl)kS$O89wUiydW=un|J3})wgPB3d*FAAd21=Xp*k9ItLvrEnR z&R1|$M*;Qy9lrZ-mgzTkA-*tsg{K>jN0n#e1Tq8as!Kq&{$qX>GQ^UfyOnLY9%QLe zo*=|{rvCEuW#&{En35R@a5?0uaK(wWSuJ{;kFL9oc5a&<^9I4p(zn9;niv^6|Q^ue%c$XTbjj1>$_+W1`LL~%G!PH;JK^;j>ssG-Qa$d=YVT#|6r~uX_)Gc1f8fU3(Jzb;?X;C z?S^_l{;JRN#(eC+*fM>U@rZO$;{#rp`kjM{W!ENNgaq4*y|(oLCPEN9}SJol2QdMR=tuoqcQ-N9Y`N<~qg);~Z< z!~H(AA0W)xYHi;L`yR8_{<@eHh|FHle}D7i56a1%*9jDUzy935mOKFTy}y6EXz=}A zpPyU2op)-fn8YUEme3tK)Y}o6^~cRUEiET$X;avWN%W$4MW@T~8D`-QN~iM8T+4G{ zZ3S?{F<#{zR+i7@rsvK-U-fRsNgM9kllq_IMX1Znw2>)P3 z?#kbVtqmEady%p7VpBsZ13Ge8QQ-i529M^NKS$RuKG#zS**9X= zmW)R|RSiE9(wbaXnQe2=eoR9Sz;|^~dNQ&Sw2uG>EVC3RM2MDwG6bWqovP)duBczY)*$FS*#h##D1v zBnVJ;k-nerAM=%@_wgC#n$8jYbky5^fa!PK97=rY{}lY5*o$BBkpKk@xduvLI&>(P zC#JV=gglk&_!Di@_WI_FM5FbRh{-iFo^tz3t;zHyg#O!GUy5?y=_?j|Pa0c3HuY`4`hUrI^zegG>1sQhM^#(B5(h0N27 z>&vE*TFfHTY5{WT?#s~Z#kb$Snu8*NN|5>!s4YKwUusHBbx&QTnY=-%m|49Ab2@MJ zSJk<;3XAnNsohGX0g2_UN}7PIJ@s1Ty!En`XsD+lYT9#20<~6OhvC<7G11=LqOyyT zb~SM_=i3eUm=ckDL~gk34AxZ_&DH(RznE$Wm`4Ku6b@}+9}PE}>?^>kALJ?MeYS3x z1~M!0zA`(yQYNBYU--qdH8Fb8Pj9!&!hpfqk-A&i4VtETX~AJfLK-N^0IW~0+bf$; z%!ZN|8+kDDLCeLzx)Y(Sw-r0z(iXnLn6}tNTVKiUG5}d=?A`6r`ARlC{MPj9dru{( z#grIeoaLTe^!hTuYtIJ&mer}~d++$&z-dmMxNi0I;^K6q#0BRYnzuLRt8-ZU$STH2 zv|t1qXOEML{2HgmqA;;zxk|Zwgv#&2+g}`kfn%Dr%XP**1sz`q_UfQ`&LqRX#>Bn@ zvo~1M$?EyA0OAdL@-54`CtzR#w)66#uCLv$ERMVrrq)-(J`o#draV=1z3T{GfW69) zf2gI28$w1*nR|iUPu4{|)q;tYAQM;IpJ;{qQeKXODLA{EnTu0TJ=#aiiJc+XV#Adi zChU&*m9oFSMyi-Oh8^#2%`~fGcHUe2;D1qGDmjxCg+nNzSYStYL?n71oF!_GoE@U& zh()L2YVF}};I~1@B4(byOU&nyzVPG%zfy>FH2NK71WkeMhojlW39EAPIHKFod~^0jY*f)Wkl1`wsgvpGqGJ`5$a)t)2lE=cNdA~ zL;;-y%7UYC<5P_yTy$oFUl44>(Ys?)XgyU+>APQCL-OP)7f93#e^p%2MyE$OvSO97Gm7D*|Gy_uTSy$VAJ!8O-rs?ScK~g`m zN2{nvO0b4S`7nH}QHKGGK6ixlK#i`GA(sRH0P+&b^%I3cs;VR|YZA{U@IuWQ6e3!K*nsX2^G5 zC9C`}lWy|R{VFEl`V5b%l?IXD=!6)DWIU6jq$5s2>V#_F5qyAvU*6h2Z=1$e6|N6 z$UN++L*m;I^t7Z5oLI~8*BbrA-gg;kHrxIhIhXE$9sgXI`~R3a@3^G*{g2;sJx5PV zPseiPI%R3*%FKcDoMUNa=_$*-aa0aOaswW-v~rc^9#mFVP8_(=9FUW8;XqJP$bqOR z2#Ef^)VcTm{;)uJSRkLz=ly-ZU$5t@4y-nsA!drz4vI|=@TNCG=PUP30ke@2(5@~b zxtosBUDXXSqY^MIFM`Z|zICP5;qKo4(1s#v|FO;S$=|fn@_(T_;6X4CFDyG`de=r1 z3=`bYX0LP>{SeTo5-2T4GerNl%JcaDRbG58qvBhcXD`vYmBzR3LGI|&HcFfHYHa^k ziPpJ|NsAG&`TS+qSWZ|x7Gw#;*-^;z^FXt@fP`bF=vc;|bhdR)vS#Obd zqD1kx^~Cw`#t~MulSq{(067A`1fgijPA8f8tnm#+7uwu07jNsp$C~JcIZWW3E5V;` z+}EGo$hi<8`W9I^ek=KcpCQ6E7U#zA!i{fF=!bW-dR(kG8Q&I{({3>Pmt0?+KUzm0 zhnqq}j|&38X$+lf`k{fIDdt5PX9;aJMHx>UEytZO5PD6Bhtn5L!WhHVX?o8IpW8GKfdu=rQFi{7XvEo-v(4a5~-(i(%l^q(d~ak zH5%T^Nh_RUd5QPPPAvJ-;f>1$nJHpZ4z{w{JEV&mq-+r#2IgAnRQTY&is_aBB_ovr z7rE3Rv?it-GtO3-vVk(5s;j1ORZs@L9^c1;mr%m+ea2c***k`Y zePCbwQRZ1ktq9MH0EGa3!d|}Cd$s7zT14NeJlhWDD_3Wyz~%6P*1vjUc66p#*KDDJ zuylpu{uE<(x5`bPM7M8avIoppt_7tA!}iU)W}DKhDhECNWW#5g^PMUsIL2PIZVhLk z+0?I*BdZGrXd)QYGoXoGV_uYKZtxR$s0rYykbn^V^c}%{SlQIFU8D)Y_ej5laGE+Hl-+ zfex)PB)?5H+x-DB!yEE#F{l=o&E7Ap4~}HJ*P&93HLcty*|pRg>JIlLZorg=UkX}E zVb5yqEWkO)g6caSE6gm|2j8-uh!ZRQxxNI@$6P~}qCd_1u>aiEg2%d0zkKso1-HR3 z4Ptb8(@(Xfl~D2t z8!p-~>&q*vd5(x?ognSS8)UQmK=6U}w==?D%DNvu|C+qKas;v#PkB6jyMn*8W`K&gDro7U3~1?L&P3nPh(vT@H;s1}geUs4sZmsA(4K3r8MUjNJN= ze0>+)P@^Ymk7OY-21%{=Ocu?KT>fo%j^l!67hjD zJR$n+X13FE5`Y(+HEl`cR7?^g-Dt1T9|`PnsX`@1UMlKYXy)bIwc?e|v?iq;KwoN3 zp2Y*Qp0xW)>&nQkw4mLm`buxP>l5HdCbqW|cVQifliN(B!yT8;YR2Cuy#TXg?+%vt znR7Qd2aLT8PND0YPk`?Brq{aJdl=KdxY4Tv3&ug8n?8?YK36+doY7slR2f6rRnC8a z`jApe!bXYG|E#o2Tj}Zd?=ce7J>Xa5eLcvWYxCR3eqdWD0cP!BzX69lV;jFKd=1mL zJ*>4aEW^&cfryZ;E2J2XQM|Q)LyJj!vKsE_jDakEKuU1by%xJQ3Io7Z=d-kcFWk`k zH^Z!R6Q7^OJ0<=76SLa$Sz!E6=owQf4L}S6fN>uEg#JwmC|i;an%8`_JW%1K5%!F~ z95Z%u=K2K2sxSm{MA2=qxRDfRwSHPypVtm3J(ILp&HMT}ghc0GHL6WJo?YRKoPI-J zk#XC*ZG2Fje|E*Gq3uAYmcOI0V6tZ!I`2J))W+2HvV=02*Y_{$sHt?n26SFuQYvZ2Gi@he&g846YhR%REGceZ zJ*4A=hvL=KIU!H#Y7sMh&2Ng|94zjEfZ=~Uo-<^?t$s?58O)CgE8SbDWxUPVSmL=% zd9&t5Ls1Vsq%j|hcA~FfK34MA0F!h4of_ z^kJh+S9!zH`Z;^jBu%1Rcfj$j^N~JHlFe#QC@+3ta$}_B~d-Ho8Y=vOGkN!9NfJc z?~x7^v^ou*YigJ+Mn)<1j#|7wH99pT>7Bcg6MrVannOJ#Tey> ztLvt8HPkju&g=DQ-%1aFqzp7DU=8#of(l4S@`HV*Tmu{D1u#IrQ?*bJ&c`z%uJK

j!M@dRd-NPRv0lat`Gl($V3&)U#O;jK@cNKsR?>tH znsb#Q&-uJ3-+W*lLgxhna9)76zY*IW)h|sFPtAT86JDWRslXX-Hsr0RZa1j}rHob% zLYtRK!x3%~UZb@G@Y>6STmY4l(KIjU!Q>mX*A27zR`Lu++_CIvTLxLL{Nb170phkCP9OL12jm-P)FZs z`J4{!n^(HaS$eF=y2={gJ8LQ<>I?6I%(Y$JW{ zC+O2_dHO*vlsj&Hrs060H6zFXLNw!-kH0I$cz}LQ)MenCvYs(gJDQ}%>Z&Rh4kbr$ znxst4uBxQzO#Crb^#*?==+LA7ot`>`-5Azn4pvfzSU1O3SOq|e{QBy;nOzNjjJ_@z zm{43T8Q|f_-+0&5vNX%g|>8At$6EbQx+NvxIXseqtdx4 zfa?SDGfVEf>x1&m^$`mbx<0}*39AQE2W z@X4mN>B2fGVgRr-$(_NE=lSqSaSWXofrEdm_7Uil)(e%BE)Qvndq$D(%UCzoM&Ga< zBM~1e%l9A@Edz}6=UCE|KH%nSs85NRYN%%@6wuSny0U8#Kk`Y{d@OAnJq2F%HSXD1 z{u#yxuo;@B+Asx&uR4Wd6`W#|dW>P7j0ee1UkCHuY7ZLP7(oxzu#H#Mtp8)#`+8tt z@xTJk-H-jyeaJ)IZxekY{;W88H3J&rC2sTAoE7X4k#_1(_XNhTD55BAC9O)8$@lx8^ z^D@BDIhnxJy%uRhPTQw5t4SV00HfzeLQ_n~`VREYRR3AAK>B>Krhg4>eAG8o%G`q? zc=__$qvhBkm5G|-e0aP3npt28!xk;eYZYO3 zn6Ejo<-H2;+0(_~XtLR^akr}uA|JaA4D*8wqyVj`)`VDJ5cSv5YsBd>rt$W)ds_0|490j`|KpXK71~s9-zPwp z0gCBc2)5l*&LOh*FGN4D#KY}}RpB%K=V8Yt z+1)`;Yr;Mu8qW#J-tD>w6il>WsqU4(NZ&&4K}~-q8Z0uu30dyAJ{Li&g&9YNxmrNw z==ZGJc)qOTcD#{BY|<+DwhQe~A6QZByKG&eJn=wrrPd2HeXlWEnwOv(N9CXZTh)c zwAwIgF8T~fEg$CZ*cSc1Z*?%NKZ+1V;YOa;tB+EB=&x6>$uS#?#Sjfzm=>lHmn+r_ zY4h$Mfvs;NFXpGD(-hL}S-?r|Hs}74>kB+E8{Mq$5-!g+rdGwZ89uWh&MJpWJ#HjmD(Cv~Vbz%^3ryU){*xn%T zON<;OyaKm5is?Z%nBQnH548zwG^X}U{?Z4*V-%_>&{&^;klZf$^>4AS%4_%&<$ZFJji z31Y!`D7S&8STXCE)YoI`D)FxG0Ht$u(H4%`J)87^u9Q;8?cR!dg#RqM{H2sv#C$p| zB&NSAT+S6NWN$8ND(3WgYIRPU(az=cE81<>oozwcr|gtknQ&Q{0oN50P8A;7>F(dn<=KqrXV-H)iF+B+}$5hzNgduBrp0 zmNY3@kT4u_%%<~BSThKk(xXf-2q7iN3q^pbozO|q0sR{wc&k&IMwyk6(|T%5S;%R9 zCgimC>o>SN@*}W;Zx%}8&j)=FXz5iYdA}Oce{sgDcWG^Mz`Z8yxpiLoXA?UA&+J_D z%=tDdEbyBDDWagNG1%lnrL`vE)2^e1M%nQqNiaZpBSlv41cI33w8*hvBt|N~XD^gh zDq+@+&3!Sdz)RykpI5Oi&j;EEZ;?ye6d>|h8AkM7lc5h%EJP1>CgHB?FV6VKaNKCliXfz5m5k6OR!k-V zmrqH+We+e%1I{RE1!G|3#-v$}`A~7EuG(MGPj$?g#{5v$6AV)fsD`L32UH8+zGTA& z75;DWoc;+=9nxR6d(d&}31hW(`VZ%{Lxofqcy@piY$|(;DeYuY&i6jFwdn{xwDnJ+ zl(Asf=Y-c+tx1S}foxrh3|-LjK?vTyA^zntx!ru%!{hv0RyC4h%zOF08Z5=WHh1g) zDq^M6D{lq7D~1n1so&ofXjhnWP$wCk1^`>yrg)1kre-&?2GSU5U7gM2b#^vmzf=6) zyJ~gCL`ncn2O$#&-d*6&oi@fnw+{Xu;Z`)zyftCw7CqftE@a{W@?W~&Oh0cOKRmtIif{G(Wj6K9b=6@8_q1rayo{3}^!$c>TY(toR}Gc)T;sz@%T@vQ6^9maE2uUbCFn$>^cP?A1_k+3raDr6|oN&s^qge zLmdGKA#B<5RRH|Sa*lOH#1PxDb-6&I6$wK@AFb>An5>F*Mp|z#{+5(VM4Jf-1XX4^ zTOZ3LkRpWXYBQOb9`MS-)O+htcO^z8iQRpv8HAA0iUI^nD|qcSdYin8!Nq4n^){){`N#STBMf8Np?jr=W5 zv+}l(z&=#U=&LPz_5@k$JxtrVa;qBa?ICczV+zlw-*`hb7#QwOM#7F1_d5Z+^1(lI zY94*#l@|cK@*({d1%AGeSk8ZGlD&kuMyB6)$ZV@D0MW4x1*JuVPYtrd<|5!g1Mr-N zcr*^3axHpmLd&hs`Div|S)Vy%z@mR}qXP=?iq5bGn-GNx0B?m3Q#-&*trOyi+~IiE z+qLN%03PDaH`)(imj<3e;;8_rw$-r0a?=Ib8{@(I3~m8j#3`@u2^ymeKUWC`?1_&Y z%})nF0FM|O18(OLm z{PR^vAPGs}YzWVW1^|&>;Ps6a2RbrM5IQr3MPCMx*K!eE-L;%f1vh}N#)q9WWh@w% zD>vecg&0>8p5Ll#IUP%>pJ!P(S)2owilarxv0ulYw!}>*j6H1_uUeY4yQ#HvDs7$k za#t`%IZzZ(1EAwB?YcA60<3zAf|MAIb=_aOw!ImjfL9y=^bD*VjfFjfwaI7yL8%~& zCfF4Es}IwIp@b21PWILo52tPKEJ5)@^f)Rt<$PhLxPF3L00*Jm18&0igV5kxc_8GL z0p&ru_Y7%j*U_Uo3c!{1@Y1I=GUaT6GwPo+aEX_mbe?eTj`zr5PvX5f%mn^Vsp89EM>%04xRT3P>CHT_;<^eUpDfrE^n#S+P#G-NupzI=+e&^eP ztuMSTgr6`M$xoPzG$sePhYE=_pNSJ;bgRV*W%VVQD}4%_YnrPStCXi)-_C>$89APQ z?em?*g2X85P1&0H-d|HB89)_JJ)c;tGp~h85}vtDtJlARKD&0z zASi%xN6>GYWqNTdGA#?CTT?N4Kk=DimrxV#{f7o%70n)tzShrPz`ZH+Z~Usxl_O6j za+UW^12KfXX}Qa+oU|||YQrwgqq1-T52UPw6@bFr9IZS?%`90v!5kmR;k zE0~_>meu)+nCX?8szMW7IHm0XAffJ~xQay4fX?V> zS0vTF{xSM{j6q*#R()!aRy_q;>GHpXB{O0Nr|H%hZMnd`q+B~ojv}jP#hcJFXX}nt z2I8!ec$AQ!wxt5QcZ8kTY@^`iJ~^bv=w4pQPQiU9Dgo(B+1|ObJnJ$|*B^7x_S>vf zRzJu2vYOE-;kBy#jU)t9`nKGyg?-R_sHu@%-@#R7-^m^Mj!UjBNigFDSC%07KupUW z>7>)5RLq8YZ}#=Q_2bJ-KXSnOP@`gC>VR7WYP_YyWL!SqI1u|}r_CV0d0y~dsS2bY zTV3ORcZ{@S@O`Mn_!uim)a+gsw=l6JhB3g(`2aP>w0Yin>y(MhLSJnZ0h{aM!1(ym zDD6K^fVYj+gP1$nog?}Gh(Vq1FXk8k5xo%%1)F}~Q1ppGa zN7Cyj+<}?TK58P^{c8F4Xa0#0K+y;DIlOR9zVU!nG+}!i9i!KYxEzj3r`ZF0Ipb*P zQy`%zQag4GDjhnHzjScUYUhz~P!A2NxaW?epavUeKk~Qnj{SWJ|31HnJdlyWB@)tPugpiQ;uvV=Pooo^|q+oqr!^f;B zCW(KH3|KL^-S(IMGr!aZZjpMQ3x;unO;!Ar{Ys)sg?Q)yxLnltMddLSZW-`z zG$q3W+{QDmX;A%<-}uu?cApZk!FZXkBnl=0`dkj0@ELrkNVyp51JacT1L+)`#GkTj zXD-R5e#aaG2?@VReOqld^}i90bj1-uUW_da>H`%Qd8xgiGUPY$Z$~gDh+c9YhCN=H z#fVKbiTy&6=$AA1hW{eXuC0r?=k=^WPRODO^AhrWU(Wmq+<|%l|G~!2R6x{Oz}qRcPMo9|7R@S`JS<)^iRf8(0>3`sIS%uZK|ZX;g#6HK69DUMU(04#|U|v`TmWC zlL5rd9||_j2<2+lMsG(QQ0`w6mrDcG%kAuVA7T7LTc$LCSFL`wo&yFjCGzoS@!v5e zpoDLiM?aL%1XgLI+P>kY%n9u5c&kecHZfMX*S`~jN`&b5aO80VsRUMtump1nCwFlZ zB5k_+!DyQKRIbPz=y5~KqT|Dbyvo-KU)8~`vD2a&d6>t{TC;gYSQ9)369vQOYB~g9 zej@%*qv9jHAX0gtcf4$0lt{5}TQ*-qp;JFhE!!GRM6fs3BcJ)=ceI8o=udOaIc3U? zmxg2W1daZU2u9Dv*g@yrXJHy;=7+~n{g1x`z0kW4wp4`}(MogBr@JT#&}5p%QUT4> z`RjTD-+HTNNAPMlI)QVWl$9?0xQj zn!0251`qjRFDlXO%(9a{glq#MwiGQK*7ulY8F|cYVD&xUZ0*lJpoL#(FhLYPSIDlP zn%kId8VA|#(x=^4(>W#B_Js!cfL1-+{sIGO(k2Ucq7l zft;+_L2O+j0F!ZauQCC2fr|jr)Db%^)h9vh9*o*BX9jbb=T>>Ssmjn1opV{SPw=>_ zE?>uM2uWm5WdFqbA9f6zInO1-BCq2shh3QpQoHO?Oj!J~B@hIo0eq3-Bvi?1pG{yJ zIr7bl);k62`636`A)r&(dN3}smjoKTmS+%TL0MEBb{HQUdqKw$FsoB$N)_Yi(pGal zSo!+P84LI$iFL311KL3`6C_E9uru{=tbJWU&otS;xT41&=k45kbk%LNN|CnO{FtZRIF5ISq;7d`DP>pl10!XAi*{L4@tD8gAm;MI2 zzuQscP4D%;=^B81{}>S1()9#rIESx-_f6di;l`E-whKx`X)wwR0!W@_kFzhxw4BWvC!k6Sz zy34s*W<_sshc%Uie4IxzI{sa+ro}7)eb!;f`By;r+<&NS=z+MlH&MajD)1Z4kN4rP z8HUP#4;r8?iKuja8<2FoMLH`wO~#w3qf1)5?o*{U_XbSQIEL&y;8$VrUnKQ!7rTp=>KN z3To@T>n%9(wjiL_FxKnJ)u=Qz7)bg*dhHBJxNM&P4E!tmR<$N;czZ3=%w!==M5&hz ze-|}Mzu*sIyhf02u<{93SxRtY#Pt}3<(B#Kg-Xbl-K1X1fmDzmM-Lx*@usx->qbJz zXRqtcbHZGY&Y-dvXxH~x&{wm2WHn(DE>7?J#C#~6^O|@YOUWZD(Rks^P>W zFfX^dL;M|24@&UJUoH;oVQLFFS=4)`be({TcUoQl^Qhl2eTr%PHZor-{@<2gtb)It z@Lq#ix^T?a3h}Q!a$xSr`E?$41O!sTW{4$XV;hr~!VFQ*_AF2;;Wf^@BbjnjJ>bBS zAg2;}4sWo&1e8X{Xm8?qzS&%J1McU+&dagqsOm|^(4ch#9WA#!f_M;Ob$;9htQ#E5 zOtDT`4=kW#B9y0S-v11UVuY=Nogg6N<5WV1d0V<^67Uhdk^PU}_KGvE?AojLEIrat{+K=oYb$pLP zz%+nOn+*UHuQ%^3qt`y5TpG6X`CKqd7b-}NJKWj+=-QNsvUu`#sm@$^n31N{{p541 zm9u#0$+lnj*w{_T`|iiH{E*;Pv%Sh$(ssn`gi?}Z{XAr*D^60(M&1xQ({<7Pywq9z zcpB&THp8=&u>Odzv`|l==V_M1BBvL}@jKcPBAi1cgAmGo&H@LgUyXl_P8&Rq0n5A2 zwx>{1mG&_@bf|yGK8zma?>bQ_dB+gXk8wYVNwuWv zDRxV;VY#;ab7yDUANcFc)(UpoAIuWHI<%=jQx~=r8_phdH4K?;e<&hd!OoFUH4K?+ ze{8Ox3IuG40xxsD*br(h{?7{*zVb5qx}xv_ogH{VgG31nBz(S7_hT1-J78`ryd$D2 zUeI9HnLr3g7J%9leqiNpA&-Q2*`%1NiRCHGR z)s*WF8f!&A_m|Dh+I!Qv(FoctM3e5llY!0j#c7LS4~lpcE%Mv5tAnzuNbNZyU<_+L z|E%9ik*o}h2=3SZ7=m8rs6uI-XT1V9*KeWliM52nbz5$4OtgmQxM=@+b=e<7{9Y)- z!+u*`zX2Rfye0pBF~%$aEpl)d|5pj^weV(v1g@cC*#e*jdP`f%e3z zfLkYE=PW)cs}r>J6(Na{7@k5WA?XK7=R))9Guyd>Z_C~^p=}9Cg(N}tEahP~NOWuj zZl2O1*JbQ25KT(mu?5z8Y{#d)?`xfl`nJ|@LFxp6aM^4>{eT7h@=kPlD&M1G7JI@f z_JE@M7VLmrEX+Li-m0H!VEjDW<9-kmm6r+eZ0|;1K+yIpx{f**cHU0=P`N}mL9wHRi=3}l z7ZI2Yp2448qn3|rc(^m;l*Ewo+d2n@Yk|I|%**ObjKakoC2SAJ9jydkVul1Bh<4y?x>i(ydxA1xicM+J?zGc(KT24_&}O)vY9$9VlA!_rJGgI;fIBK z_MEMnFE=cA1^$s!Vp;Nz=MHLss^+~Z;$a#%P2{gGNPOdOA{OEY@5pR40NcY;FV9ad z>l0aK2M>bI&bL1mKD5a09Ly=8`$%IsyTr~0C9j!JtJ9pBPYA=pzBpyE)SaI#n^h7c z<~~6UIx^{OFH*|q6c{O`>i9pO)CRfZa5X>pc%j2MN8T(utl2Wa|s@ZTI7s}zr zEbMDe8JKjKB2Y*rZq=21Rsf%|-hb37fDc;L-2S&4QbMA&eg-nBz8(angIaf9@;F42 zQ;23!+7x>IN`hRVVW?K!z%$rBW%|%AX-hz)yE;#QYWpp`Wt1Ho=00bO%OGwX*xM*- zRNq*u_nf?CUcbgL;IORdmYB%eIF2Y;E)p`+N=fBdrVLQhpnK=D5I!jb{#Aiwc3PWa z->z@Y)^W!W=fL(Il50TbDM$^WkhK;y7P}H3dR~{Ehh9&vp%EN|>wd($=7(vDh>6P^ zhRn3biHK>j8Fi_{8!nsWJ$-Ti5tiMS=5ylymGmH!6PP_kX z0FX!NioeP6JU`odZ7-6+CCoHWd)rMUvGE~f+l-fTz5y%d&DSv-n5$_5|7_oK27Nr1 z9oDo%^?oge(&1Qv8zQYpdJStIAJ)V4g?~}(_{Taem}74w;-&Xqn+sebp>=hO1WXlU zXG@zoaV(Ol6M0vC@Y_56&s#1@-Ev&5*%D{$h`VyqW}D=3h2TAziu?e3`c|%v-AMGn zIiDCsj&-X3ereVN5-pdY)z^75#Py))Akw=7yA*RTqZdkhe?TWpOb&JDzS z;%^IY%yEl)tb}V-yEo#8W?Qryvjf*+_q1$UHdfjn&k|?5WMdYn09`=eZ#5WaH}-ZX zZlcN}Q(`K^NlMO_pWN&1@hczYC-=PK(`;cRbOh%f6|7_#wDK-Rp$;AUgIP;7?deL? zWe0M$*edVr>ST|t=?4|4HcDE5ve`bv@y}K<4M;7_ni24GY!QclXX9RRLCPdi&R0DG z)#gxS$yk1e5S($7N)%KzOV1~nN5^*DQu6p<<_Qj7aK-AqH7-dqze&f=VIM-0vZ)F> z!SP~NyRR^y4Qa1=Z6MqZyT{wPSSrVr?n|?JI$GxvU~8L3{pX~fDefg_$P-s`lL2DtRU67<+3&X0fti-_Y~Y~cgNwNmQz9jx(6TSoBUPd? zuci<#ZZ7#T!+!iPOoagcm)TKG*Z654g6Ce5W*ag>sZB)sZ_cs&##7B6Cm?rRteBJF z%mC7G1$UzL$F@(DW`>ss>a0}5R}0KnvOvwwprVpJVICw1b|u19?41YrI1^X}h9Rpi z7Z7m>u;I#~-Yc}sSL)-p?R1C{mCLm|%;9CD`V8~N3hAAWN@rq292&1!j_23F5EhDU z%KA^SZX?g+EdxV>2QhOzL+^O)$A>mvS+K7qxyA{)_>!w5yvEs_3-mWL^W2wgICN4elH$ZAaqX6v2+#2=h;6bg~=$_)jiQ zMnsxgyN=ymZN?jvdF_uV%mQ9|Dj~n=r@oCrnK~PdiYh3Ap?fzX=QsQ@7a3w z=B&2qS810URPOHO*QH^Zw)7vw+s!#G{cSw~c2s}FzK>LQB#NI>wnkp8OYPhFR0=3m z7GRm9yQ~uqHG@`jOg95sORcVXfMJ7xBnx^dcG)(a)$*yadnP6YR-X*b5|9W7khUA$ zla8^s_HGkQdz7$+Z1AeVat03&d1)<2J5p8- z0jgUcl^c@}$q(Aq))817@pO_Lv zP)%)%I@T82exaY&ly$4~{?|C3?8jl-CHl$fzg%PyPvvc^_4I8$#U`frxyHBI#rS0u zS)@phdMuY#caMdB6?amo~Ue0nn{58)wjk0-+a)A6-%i%h+huiBH^{-=w=Ql1!=YP1S zlYEl@H$_i2|Ih9u9_h!T=P4&3&pD%PaFS~G&k4Hck!$Z-t$38B!r88pGv@3;ho0A) z=J5pTM)28{k!{&w&Beso@L9?$|7xG1d5Fil?_u{JQ*ZKuc(sC%b{i9 z6c{8%?muGYIkhH!AxtPS5Rw^MqG(A2X+e8lJzBk&8ifiA)&% zxb^b!p<4sO2*^msabBA>7u7#$P#JFxXSm zZVY2s$MJWSK3>JzbSUP69xLb{7LAYf53YKtVzF^OA>*}D2GZ*7!0sX|WIBN;UM-k2 zOkXMP{;`qgDt7?=^}4=2pZ3Z-YoF@}$ImoOjqOF5evmo$l%d)^d8Jzq2=+RG&j-{- zQE_hq$sYr3KN6lOW%^e!^!-3d zKIYZ7Iwu>wboY9hU-bUBKS4}1+vF69&c0mycz@!+sdKpt5o8~^E1BIITnq7YROMBv z@KdX59l4i{mSeLu&j(u|B~j18nMtpC38$wZ=>8;H3OCZ39K>384olvZV|$y4*ImQi zJZb&OZHRCg+Q>Bik$wPd+p+)hIjIGMa|{#BbD32SZI7zTX7z_5OXyoh`C31_)cETh zaPUVu^asFump3L(PY*otpW(@yOUfPgFz>@C%v;OgZxRoh$pp45Vt+G;w?W`9?0t=N(FWXAaJx>NF|#SYJO>( z5^_7QL5OTc^Y;=RmsH}7dr~)_M^SCQ+!D75S9wp+S9-FwHt-PiFR)a3`A#8Mavit= zfL&%wV5|SmZT}^taHI3tWQxI}Im5I^s=XfE$;&a`*ZIMe=9R9H^kflcAQmK7+IZN0 z74#*Fba8#+WLd!xnB}@+m!)Y%k8hA||5yj&Z@Z^`zwN!?&_a4;{kjt~c)y(L8-{H) zkGwm@(8EL_pD}M;y}q_L4Zm6tk6JpGyQ|w&i; zuQkzj^o>-E=Nb+*pD0+!p{W^q^kQ|`;gX#`^RpnsY%#H!Cc8fuc5c%h=|QK|*DReq zyt_`rGgEJ+Ce3X=b_^w!WzOL*M?P7afHDn#7 zY*v7f`!ltViyk(+pq&$c8C)l$`N`l^k3mq<@Tp)7w%5bPSu7(WvbGGwJ;1r%tOHpVi!|_C$B;kz5=c&-8 zW1sx}4B4DjSVzN*#kSPo0W|a%yOxJ}V6t97zC}uWkJU$(iCCI4TJmvAe#rHkW~ zrpGV-Vq=&zx|0-rMeb`IIOW=PIZ!}juvHiF+=keBUEAw(e z)Pwj5J=i|n4L2q3Xr!OQqDYi6%OLTtfr)UiGSlIt6y^%qP|a9w(|cLrclR8 z?|an?vSx41hIbY>&*+#Mn!obc$iFUw)3K>kiV>8Jmwy^dPf|rCxT_AjUmqx)mF0>q zt(Tb(xp0_IWZe=T!ulmTtv^|25PPeyDT?(v#5m7vkNYfU06cD3A4|Fq;Teh~7qw`|wZ5fj-JPM%ztL zqTI_}wbIqD#vi;TX9KCw2xr|n7hEMMZB93R>s zrmq-w-}I|N-Nz?fmibpJo^Wz~>S7L=U@1wij`$Sp4=>s*GP`J~zO#nrU60h2Q!dct zZqr;fYGON>!5-{U@$t#Fa5HsLJYqyOkNKCm0}4^W%s)>Xg)0OEUMxS3RkNn?otw|y zYP(qRab8le74y~YL$v&Lt(sA{P%G6}z6(=u2yX!TE&98gE zE512jeR;5tO5{vZE|Yw3Xzt_OD7lGloYD5~_hIZgI9@|c&GXTv4Q$5KNa1WkQk z-8cS)!Rhx%{RPQ>J!~chik$u->UfCccGud!O@Ph;S;3vc5BV9Z`k4k#Py5QCqIvdr zLuL=ZE6%?{C1g%LdXl*D5}6RKONV&ZIk~%Bo5IgD3NB4oz_qYp-M%j)wyi?E%V3t% z+T1UfbFx~rA^~f2v0?1y6Qh)UE+?@OzlvU(iEOazDezL@S^-!F$04Jffzz`mMQK;B z%-7ZP=zt5R~4Q{k%gvwnG$1fjffBL@nu&b)cU)`HDXe>t=)k8k@8OFF>mrjOUJGkM+9$aS&coJKdwpmNliRpL35w6 z>cW-uz=vC{J#MN{{2KXTL>SLc{;a;X9?$JQUHMhj!`b~iEW0)56L?MM`p0!eA5eA7 zUgcc(Qd&Ikp114Ld4^ku&!87ts#hXIy5#Lqt=HwVVl1EX0P$P(E$mz2128Uq+q(Ov zqDUS4FJ%3r=1o{Yx5&}%hf=W|CKtN(grGs=x zMo}3AK}G2hdPX`#N=QfsQBbOY(jg)$N-xqwLPrcFN((*oNDUB3A?;({_x=8zweC7+ z-Fw%5PI=CL_Rf<;IrM{`fb!*LQtAZBlC1s<$zP~A^qKb>7B!iR1^KAx^k1^3bB!N~ zbBZ+~(uDgzz$f?}O_7B3D8bdDh33Z_Pdxe2i|S$IuW)F8QP!~gp>B=W&9W@6*>*Vv zc*&M<;HdCUJiPxr%7<&~cdwww_db0<{ug$)z*u^nyaF@djh{#X0-TmcFhYWyi=v(i-CTny?ukM_BTfp!9Eo zLHxzWR?DD<#Dr$0N`XJZ71k(U&Qtv2ES&Bct7A=!-c$0HNUZ^%e^a-NYGPi?UkUaX za|yQsrZ&4Gs?o)*RCjg6m(@eUnisLY-9u*eT2oTo$YX0-aow>>g@(2w+X4Co^mh|>K9UxyTh1C0Nm^{v z+GP?9tql6>Y_49hvY5x-nfd1rs%z@vR8C91w|v7C+|1k8!#Az3ay(g9JC6^{u=TW& zUwXk^O2c$-w-8XSkde~No7U*zfjdiS2;w=Ob)zi8Bwt{xO;5zHP|tnmgA{zebix7F zCxUGtN%-8`I-*g&@b&{E;{M6dFYyv%xn4Wy=Tx|Qb|JR#8TJJBuLbmD>PEG@99U__ zqDyn9+hr)oZepu7Xvbe6VR7H$+6W<16?OdG!Y$IrmgLJ{4!MF7==xdx|2So5?Vmsd ziUk*J2hC^2`^E7A`lJb{CF+#)!a{z>aT8jZ2leazagM#kX@-5`Rh<5{<%FG;o@%#- zS<2&ddT}F7>Nu-vPEf4NlYt)c#0(|@|{EfHYa0_0VzepX+%$}QiVVim} zB9sX0HR#2r)K|BpW_hQ{|DXp|9zsaL@ooOhW0j~ktsR*UP39wP>3tsOdJtvMBdFQX zRHiFSh1~Kw<xHqG;p)F68PPSr_HcBZ~Y_M1xl4xoU4LOjQl z@};;Z2k#g}ET6=Q}}c5H`FR^!CMZkj{;cecvhCGarwiZ^b6z~e4T1&=2;DYveIGnSNU z-1W)nLYof}caS|zA|twbLhpIC6^XhOAApT!NgW+J?nx_Z4BbI0sI^HyjS|f?zf!v> z1iaCUD(g}{GB|-Is!t;+v`lG#;M`N7g-t6~+F^{UoLz!%a|ObV3_grCy(U&&6lLszANXD$ zA^#e8c!;6>cIRU9*T==3JeSqlt)`a4|Edk{Y0^&B>W^T z67yND0LnAOGcM1qMGYZKHX!aM?jj@q!VuC+fv2sqqoh(KysUq9Dr5cc)H+4-8FQqy z>t8+w|D)k<;+Ltf)JciYPdy&bhtrOT)-$yIs_gOi_w(JyHlOieOuJ4q_AL9Hv8e#y zhBnt)wXjXtS1lV|n^B_5f;rUW=Z$+aVGhe>#=ZE3e;-$$lYcXSqyHJgcf)%;3Z!Zb zYm{*kNLg>7@9*~{q9Ru(l~yZ)DGRN_CNHntJN`7#8uY zBE55sKr%oDqmVK%LCvA`nV!{_t_iPBX}KXtGMw{WRUIEn>oRVj&SUVL;sKNcgg9G>S~b+cPexQ^650?eVw+^mRZE# zMvvDs^aNgJt&X{x%{5*C^z5?^G_=KEdt8Pz`Ag?XmTts=+^HXXAH>Bw+SCPhy__$Y zRjTTI7BzuGaIDWoD->8@}VD<;hz zr1WV2R@AGNv{e?S!dc_mj>no}OFPhQ{su_=L%YmFBd8<%7RM@Ig2I=ai~UetLFkt( z$nS!Dwn0{{Tppf~T-uwjm|sd%>$Mb?=>6&*^Chdfdu&l*j7n@m4m(Wc{)upHzG(6Dn!@2@243zmi>yeHkKGq^$@xEG>S52l8 zhiE6MX2Aa%X3Lg6tH(CY#jgv^vZaA3*Oj`TPQFuW}Tbxk59o}>O8q>w9 zQGC_%i@!VI6WZhh=Olcz*1h=)MuPIIs`yF*IOlQZ32QB#s?at5;@YHxog?jQZGIQ7 z>^@$%^Ul%CR0&$`-m`i$c)+>s^L7NN;A-ID%ozgS%@1^EbMV8@>-)h97B> z)92+&gN6enW!MB9ZtJK4#Zo`Lld;(ToU>ajM(;iJ;sgQd{bMS<@R8Jrk& zJNUVWVPo3qln)%|hw|M`GF*j+c%a1v?obDl; z0cv4s#_wE;`}e==q=laY76P09u29V9{|S!fxanfV^aWFrwk}7NCvG1f9$JA82jBlR z1RXbwP$Qsos?blfO)8TlahB7s`{MLu={nHl1Trz&c%?c!L}cAjP`nAfd60Te?jWvD zUywHF8-0WqKuyw+N<3RGL#9rj935qJ$LNj?P7|XIMA>c(-?P-_=dn+G&AeK;S^BpB zft2dB$(n2eJ`UcEVozJq8Or#J5E&y_iZs=nMzZZBetF}i}+^o zgfUTz=k$w>D}wO1BTjMBUbubT+oq)tXHWv#ne*H!iqe%Wt@Da~a0%!Mp*Irx+mk^p z^9eOO8v#X^79^F4Fy#^-k_vYHwwySFtA_2&|i*E4Syhy?U&6nc_q$LBHMYwySB&hGbpt+7hd zicP(VS6pps1UdIwI9*GQH5Rn5?_^vm0fJ&El7Z>AFTpp!S=R%86QlcvZLS4SEN+nl zKOh`WS`o7~&1n78s(JUFXOrB!y|+vkTl-e_c>m_~(Up4-)2}(G`DsL$Xi!(>UHh)^ zY7aC(E=%l;e1-(cjGZCanBna_I%D*Duc#`e>PoA*X`1_e*f$|l3%O}D@}yRszS6+j z7B)q}yulhKH+k_Cuad`0GNcwk;yydXI>7~1jxuQkiFB;F&-{-%M zy4dwci!fN9=@Le0aK$NVr!QVA3k=@CIZju@ayteXHU9O{{nx>*p;m+A>?bc289OY0 zpi*og)Bb>E2cNQVfqr4U`EC_BAf$os*3VF$Mx;#E(d!FroqUNHZR}daLMDRW9S%^# zO;Uf}lU{tGFJ%?=HNS;gxVG4~O%Ct#D(#&8)AOXu;-~gg{-lUq6tJx38 zR(_KyCkwpy-ve*RYrDw_PYg|8YC0rn9Z%l}IV- zr)8xQm5{W>+mE)`rFvH5RQ1G6vZ4BX+pBQ5E>U|~nPAs0z{``JdlaF&9AqN1P#@;$ z=z$C@AS;*s8DJ1MqBwFpo8S>RX8Q@Y-I~~2k)%ZnspC&m^oyhn8HJ&5$yJp<$G7W~ zpE~gSxk~*hbvUrP9Gq>-_I_zf==r8Lsnrn^lZc#(HB%@dsc92`l^ zS1_3{-`RGsFCN9p+2b^HS3GR4#ASZl#BV)8#Z_J>jqU(wZb~!j(##6fFBee&O_;P^ zAXD;-JYujx@;C!rB~IEBhP4R!T3X3Z6#M4NcHsOhafg9lfpinxFp^)6oO`(61Is`X zogvn2tkt>)*}PJf1?bb$fotndl-|Qq3t-MmN6A?4fF`v}sJdQhYIWz?BEAkvZJ*EU zKpZXg&@FD*vr}E}05p!;de!&Jmh&fNDW;1$svGrS9Uh0$dr4LNCUljIp-XytA!aw(Sg@PfIp>zmZVy&#bTf#h){e zRb$0q7Y(a+s!%92mo2A{hLbi68awr=^4ELQP0Ib3prUsj$`cB-`!4}`eyvx~#8B*4 z5atG%e2olxT{Q1f`-tG7%XW+-5AN!*I0PjBSOukb>*@w^_}j8N{rwGt2!_Jjaqr9| z{VViTMBt_gi(eaNX)*Q>bprU-4zigTycKrU)6IMq!LP{yO~ z>JP&=brw0Fjm_o!gFl0*N&y>1m0+Wx255)?pbc7B4+{oAsg$c6u>0Ao%cZu?cb;ZM zezk(^9^^&-`t;cOFL8fvJAeDzS%Qcc$B}!;b|ULjU@M3Y?*_}}Q+K2G#MVc#K#Gp( zPULIcy$#udxo7K8Q3hO7$FB#!S3gDnVM~CLQMfZL_jD^adLxHC5e3m z>N5?kA~e(^n4vNVIsh40=%>Vh zkBt+px1i}w0z@j*_%Kcy&jY<|Zh)JsZFZ5#Qi@%MRZ$+M#E^omJJbW07UF)#Kz&8` zagbk1c=Iq?(vlt#xOti!ILS%p&QsU6Lwf(^wmyU2MWjEc%-ed9ZDCuDe>w#n>!m{_ zzkL?9Xh~l()v;KuWshkC&Fj1#c6A4&Sbf+x zR8f_%;ZUm+I43DimMaY$?=h_UOgc}Xz7=b-IO{1qX;8*ujDzF@*k!l|;x*khkB!g> zAM$Xi)6#1Q4o1)so!Zxy-x2KH55hFR)b?PoqP6+Q%Je~6d_RWKziu;La3&0}n(tn6 zXwPtKi`){gEkuylgU0AgSB zGo6*ooUwfyw#87!X&GYTy^FS`nXvYRGJ*wVOjtp)EDu z0x5AQffQk=sF4d>Yl|tg#mo>9GXicg+ZF^;#Ep1%M!cGWlv4SsWg@kEf}hR(o3aII z{)vt@?4%wzTCNerr_Km&Vvd9_<9&^TATo{6|7A%dls7Tb9;;^vB#d23&@sgWuWevJ zP`dzLOqp$3y?)wR&Q3=}87`dB>Rl^Ta5f@rc03v)RKSHr=%81-tPVH{cJy?;IdDhK zP#8)uLsS4i^W3X)_??KdoM6UTyD-=BXfNDp{C+lFv|vvkRk{He4fOL2C1V&8GK||; zrpSSKFg4;k>}ZXf(s-Jxk%$LnNLwL-ExoYe!LU$+3IvK{TE!cJd*woIY=y~0z-Kq2 z8-!+fS`lyn@G&)Lla{%)5k6`pf{;amfJyC)SE2}qgFmz)wEYx=nGrz8Mq3F1&oZCQ z4ypAPQ}oD0_s7f3Q#RA{mR5w|#!HZVQJ#eSu5vnEjAJ(QkGP|1?qtP7AJPLXOEGwm zvK-~g4mwlG6ZAvZqXA<;5kH)G!${;?{F-r9l*|}V%nww>ZKH#eHc(LiowiSNA>!m z-VL4zMow_1^)z+)VDPN~nTYV&>F98w8Lkw@kUla}CpX552JuVB^z&h#Gs~m%g~Ddy zCaY)}PU7oERkSvOfT8$02U?{?l)qI@e3zdyxKO=kOFqPS62YC^=a%S$oLoxDVM63r zUO*N!MS}my?#jz*l4b>4%RO7XN3%!)-lcgl<4m;$A4+1J#OJj?PO0d{R@v@=Cp}mr z%>4-&A*2{i4wSh;IcNxg$j{LfqW=Nmp6E79(c7Z65d}b?Q=myhanV2`6;icz83TKM zi0C$X0=b*5kQp(bCyOxHTBr8Z=I~XVa-#xh@mkmbLVD535nv$ZUsM z(~W5OQEy`iT5y@e&7%D@)>5amvCe|#d4%?a^Uawd6B*oS zwa&K8hIzaw4?c@m|KEvL48ekIU#6Y$in-MCSs3(!WFZ&TML@g8BMfu}ih1sNkztZ}|O9NrF1z&AEp zJFq=x=!i4G4(d7(tt~VvZ%5OxgO;Fa#2SSu~F=lh^VeCMdDdP$9xuz3|y7;@niSb$105xbLw=TW6I) zOWpk8#E^;{a}b3eOIMp)h(q(At@!ajr>smdiAmg!MxjknzTjs5!Bo_!D>4OF+MKSD z6JUr<83s|?S_K%q(~X(>twMZWm(~~HqXc%4e7+Sa*mV`0_%&s6AE+KGleKSS(Rw*f zz*^kGSbeW;Sil-2WsMWYeeyzbDN^Erh~Z*IL9u&rexPDJ@ z|DNQq8GXLr$G@`WvyR+pEK;SL&-*zNg zONfBDO4x<}ISgh`KBmCx4au>_E!a;LU;*esFQ`HT8jz*MG3Z|jLp5+v^v)~c#F2oU z{5~SrSki3egu?eR3YScYj@a_?lpaPog>Uu?NHOAb1&)@ zQfaCYDnq+7d&N`}>P5b0Vm8q@{gSV3RreDQL((fpqYh^@E;dZkm6ts#z$N9* zQFj--0pERy&+I1mpOq)WnfpZ6zP(NT{1zP1Ix&%$*-(%&jhKp&2peFG85?eOv6R~2THNBnl%CDG8>?DW!%T?A_QhDkw?R2Wiw0O3h z92OU4!78YiEn65nj5$Y^Y6J*GtiJ#JL2^keHvPsu*#s(%JD6a^J(drSZCuVwO!iZ?m)g3>is|yO zok7BgPKDb)-QY0WM@=&`ZG#8ft)~rqE8+Sa8jhyto$KD@%9(4~wV)Pg?D;vS?UZ;| zf}c|!sr`76;jA>7HJb{V1$WLTt1;%3#RAaUE}oTRg~|*0v|Fzcc;svCW#Dr0Wn9`j zMXMib12|%cM;Lc6k{^(C+5we)15{wWPD^FSA8IlQTvE!d-&{i5aDNAFu8v!ENp3WI zfOqCB*yZ;pBk2)*w#Wh+PEjH5Q4MKMPv`64J@t{B1jdxX=X6L#D@B-AE*+|<9rmFw ziT8ARW^rnB&QqH@+jyF{G0DG^HL$@kx9dLdIw?NRg*Oqt%8`sCM4c~V&F4BB2fTcW z)WmzAg6?MoyscK=q(l8B6T`EFZ;OLdEtKR zk-D37BNt|ADRE;@bv1GBTMkbmp>ltUQkxr|ZacpCeHpf)Ut_h1f<)y^uHjIgd8~e; zfbs(`WD~^3Y5Uf%$-zbCA89Wux2-cLLRqgM`(c)<_TmM?bpr`?8ODK3*-@+o7SBj& z1AQM2q#v7!fw^s{4g+@C=j(UrDOv1OR!ftl)=os~@4tv{ao(16W)*yI)!t(E{e6cS82OA7ua4}iVScg1#VJO z2={lRsC)nXZ;ggrBNf~hrMs+br2BZ)(9Z&ci?X3Mz(|JaRe0MF0Pa*T?>DKk$^wg7Q(NP=0?Uwd>em&NAV8I}ENU4ib z94?YLYCAA~QJn&+gRG@fWRr{^hUeWJ|2;Os4UR8V?duwe3i)>OR%^OnQIaEtR>WSm z+?UVMFY>;m%Y@*jm+u%0(R8uTv;+xr+Y~7+sv}n(-jD27sC{UC3J6}XjEX$IHgSH` zl~=H*8&%OgksDe6a^#8Hi~OiAn6L-AGsg2m?2n7{cn8jQYMoTd)3xc*uV*`oHy_Ku zF9uWv|1Y9@aETGSkw(pK5L2T_Z$cP}t>-?d?mmdSd?g>1fx}Gne9C&f{o6_p@749u z8Dwf<;68XVT@}pwkuxo8d)L@-{s+3cf)@F4)0k1=UlfD>)p=5P#x)M>YvjmHP7-H& z1ut+;>swz|2^NJ|OpuG_Z{#a#@QIt!96*AMs^m=7o^Lv&<-H)DtA0arO&bV@Vq6E*gy(gClwK zEtTDp=ZD7*SNIjRJ~WjP$pb-XXc3GgS?vTqgqo9UT;^ z#Ynt#jI(hMz0(E*^uX9b29@ac$eMS6o=8&Ayc8jw=Th2tCe+F;j~bccwB*l~p|rSU z)YYSl3MgyOSc*M&a)C>PvEM1Z0o%zDrR`@GVR3d|@I2$X0J$k6LV*v5%EMr~k;%7Y zAXeJdzsLys@NgnZ>xz5pqV!{bQ1Qg$kmS0!j=Nk_M^+vef?Dd9ym& z5CSyOeqD9)U?pa^H|VV9&-HF_`9@68OyAV<5LPsgVIJ%vmK$CynkOwtXgN*sA5V;? z2@>S=0%tMNv=UK-zvl&E+D3_dowgeIpmYis-c!j_YNY;*LjD(~z<74OXVCu-*n{e- z=D-`FXgQ;qHYmCq+7h(4Ss1<2(e|vty}4X=I(kL$vs_kyYjgBUN!}_H{4h>8X!^h< zRc)@haT*=H*3lN)Fy9;kYZa;x79fc_9XxFdwIzO*{jZOeTl2L3(lV zd=;cQ-T4bs@ATQLxtoct62iP=Q(>g+74|CJNQW%56qKjS zKEuhN7rMl6j_}2%{z7i%tU<#l4lR^**EIlCX8WO7L$7IVV80v)0A^7BhExbQ~wyy=DC?QTsthSP0AG2NCdDzcQU$8G_@#lXrK~4Xw#($v;pE>W=9cl6m@slv%MKR-idnRQnO+PdSOLh zko?L~m*l;P$A|%5FIh94lubBDe?^AvBQTC_fzqc{vrzJMHJ?26wV)1N(U~S{NUH68ev(;Rn|X6`}B#;=Owmo zEO@)UeF`RBOwbBKcR~G=UofbpxbrU{`&a{WIqxV#wV+740z<@tgO;XvH6Yb<#j}W zbc;IqQaVMy00aq9aXk5}GSi?} z$Hk9TI$`|Gca+%+L)h;KW&X~)!0F5FVSY=z=pHjzqdL{#uOpcc6eI={p#K7LCTsFY z)^;?Ta%xxLeRH;V`j46`Dx+r8di@0-y%1RXQ&`X9-}^uK7U-H~OOREL?NDvZ=uPS; z@zI8qdPT&$Zn*)Pdc&`MS&H?G!Wv%ShV)VipZ~)OZ;KBnMkV}4I4u+CuVPH<3St}H zs?``FABvQO-kTWmU3(iteVOHTF4GeE+vw2srC*tI$<4iSs5 zUo5jub?%F-Tme_sS|vD5$PpZJbts--KhZ(o>UgjRc+a$+A|{* zYWu#kccMCye^e@R453^b$^_!BeUIE8G;Pxnq%blAednQm6d0oYxp)c6&1nMXt{M^j z?bn|h-R91G|98b}n2#Yued)rO5mtDWM&NMhq zble@cKUwpTzFD*d{RPQJjT>!Elo=i&Gsfv#UMkY3h6_AHH~E}o7Uja^%GjyaHv^{P zX@1i1m5XaX*V5O|6DQaVyhDXwDO0QVvejzt{A;sjPh_(rfc856+7&;KgIgH42H@0; z;}>ShcfiqFE$p9`NJk(f?2-z#e=NV~S^XE4d84^MI&WJ=O7m2nmZSI96Fi%{*W

pJeYPV7ES8X$n{U2Dxq~%{e48>79<5frUH#bjs!!=ZNC^7|v8DW}bZzn1 zilkPC;#j8n#x>~xXc4SIKcR+VH4>K@=Jzm?^No{etaRX-93**x@3QJ>5X5;Uv zA3_^eQJPt=8RhHvn@lBDj}U%!DHFjnzW%xI_fM-T-Gw2h>g}X&>xXp!j4oMqpV6&{&}nAS zpW9g~(qp~eO^;zY9~G}y$Dd4}ZxN}VCLx;(&U%4nGMf71DG6K2<;0u*HI&l7W3Au4 zypXs$l{LT8F@>?6q)ROBJHfrJ=8Rl2b#{ibvknEU!t70!b756`5%2s@C2Iq?PNY}R zge3gc_NMHS{o{)EWwgis`Qrmu4V9a&TOVAu!I5ZB-JPcxt!sDtdS%g;KMb?-UiE5P z>RlI%5Ps*8JQ(b$sk$b$1cnCqnS9;onDm}Ag%e9h?;71ZM7uF%f8Hibbav>qyVO4wT>U>r}Oq6QlaoMYZWj zSylX#lwY>&^_v=Pwabg*cy{^5xP0qN35DmF^uBhe9>DYzV38){;hqF_HgSJKE7gdQ z&yCExAeXqFTP^{~nhT%P?P_iNm4o;}8I!+e`66A}Arl}MehiRhiTQ`?S(@OPZWj$J zs5%m9^+M~u+Y{+SY7*MGbk0b8rZs$Pp2rGj(OdVQSG0-Z#oFd3vfS&ez(0zkKDR=~ z;dB0!u3^HDSX^9ALMrz{SpEys3uBMg{;6TiFyk1r!J!%CAa;z(FGzdNme*%S2irU4 zQ|*vrOiNftpy{}0ci1P+9E^J#p1yUPXbp*ooIAB3bW87btBuan!N`+wQr(Yg)V#uF zsopE=Z%fJGI<=OxS&_@8_Pn1}T>)nr&~sUz$i!k~l|`MJ^*$|(vP^F~l%}MoLfL-# zQZcx1>x(@!OLZ%I>+omsd7fXsI3BJzM;0MKxcI?hB=`G>Vlax}f7EeFu#$T?@0qH? zroJ2qudJ#mnd;l!Uq5RE@LdWZ=7 zfv#15OJ1zT4KfhMeFbJ%TA_QN zna$|TeANZx4yi{Mt4fZf7U&DYkGoil%;dM-N6F3f#=Tz9mA^Q? zQ+w=%)uT-C4%1#oHB(k#&ZPZbEXaKeaZbB#bgGm})n2Wj!;iS^RRs1VK_=lO&fnqdwSiAuYL-t{lu%fGYf>vF!w#;{ zwwrghOP5Zh`RO+vQ{EbOlXL&{b@gdV@t1}_VqD5}-7v$#t4Q%@vx@8mgwui>{@Sq? z{W!ImbLPbtu!klIE<)RXZ{0cqyOMbU?FIa#jBbxz&}!5z`eG%ebhz$yB?RTGq}KFf zA*GH_nUGMpG0DA@xUD?NzG4g?LA;kH#@9VI8E40SkzH`|@iWO!?jG66MyguXhQEkh zO*eqJJ?b@@ol`V6bzTQ@jsj^;aQjfsC^!fk(Vz^--ObPY`?0EAu9#ZuPD~PCo0Ztk zGLNwKiJBq{wJJWzu97*8FteyV(6i>B+`9mo&;m0bdu7YtIhmm}(IR=8M2tkgMO^@R z6IVEKU#8;RBHXO#tQM4D?!ODrEshYi79l$I(lgWHC}Y7MY172Ma27%xwW=gn%cM7F zj`ntFUw{j_eKFZG5FlVQ97T067pR*B8rh(ZDF`!|QwxWCG|R~z`|oA&^HWabv)$Pf z6M}9`rqKL*t8daHR<(E3eAMEai8tw~1_PIn=a0)h^1X{$@Q{)++aG5f(r!vI%esCH z?LD_|7U7jvW;Ls(KCBv{aHQ3fpEU4#-jy!QA8T$O8K#E zr(|9=LUU(#_NKb?Dac<4w>()OymI@c7gmv3RkVBeK#ykoPw#|k5LH{jeq_lkBW?av zNQ)vf!e_n4&$zmZn(zqdJ`pbe>!zNBf?})#=@{Dhr!}`tI8%{b`j)P0L~1(%3c*86MEa7 zAgONVFiN1A$5$dMw~;V0!x;(?X_ONBxwWR0_S^2_le`BvZ0NHOE_TfXIxbugIT5q4 z1SEP!p0mIESs31N8tk^v{_;qxj&~z<(^im%k?Y#XTA2^a4%W_*y;3cG5dpK)2}9 z*ZmPQY^Gt;D{&FDMJVreI%oZlZ9z~?@?Z2AquY-YZ}G4L!s8B>?a+^O7a!qATL!(z zlnY^q?%uYW&uTD(4+omi`h{7U+{;ozfJM1ilONYW=Qlx<3N^yGq{?^HXUUg!LauL) z?%IV-?{ExPggDBuwl8%L*=G6&w^d2PV?$Iujwd^DBZKtRE_}mwN87d45b+ed9U&Wl6 ziy7%nOzwd3TovAbr&~9qeiXvmT1T94x$LWwF#mpqI~=ylW{#1bZWz7X0~T@z@7fSL z7H`*iuA@I(DSQ?Zu>aYvs8XmQ^fu^{xzuC{7Z4pcv&xAam|9!08#9FUNkK*s=Wwp3 z9O$LH9$<3%v%6uUxsc|I*zPJqHPA}+Crpo(JL3X#jxH#kd3s7vgU#H1&tk{#ov<2Q zuKOzN*e8vN51Lv<4c1|KGTENs=PQ|d&WI}<3vgy2(q#V*ubbImW^fMsmiz1B6bSQ? zb%Ir-Y_xZAenxmBJITg!gi|olk?b`mmn$$r&vri5u)dd6^KN)KYcoMB#+KeHWVLUP zH82w!Q-su{5KmD0dFT&%!t!kj=jmBF>wSQryQc9^z%`?E)80cJ&>+n`;hXYdHC9cp z6UK7u3@Bz1X!!!_P=CAc!zjS(h&W}Sc)(GYrz5I5))4^Y@qiK1>j(?qK>cIo;L4U* z733eFU=p_Jl#x!pCp2xVn35a*g!esK9d~CtdZiLEd&-xUJY4qJm>d}=NX7)K9ei*%%6%Q1-+`&MU?>! zDCe=`?wxj_s@Hj2&^!0GWCajAmk^7PpV~U9QJ?NKc6r{>H*0t}-&ekYUMHe=LGzTE zIGnQPQs|%i;I|v})}{_#7uef;ekadk1c-RB>G3fW(?`! zL?orkAoIK5rR|WWf1eaT@Oa+3Y>pZDhzUgTW9InlI6R6a1l!~@}nb3pM0vp4`f<>G` z`}#J#wa;3eflmY1U~}ymhQ=^n#1gmTfp?tFz6OCOwy+*pr56T0UJOC?D(xgHuW&(2 z>w&djOU@rjXR?ONHzv{5MIG`B@>{~RLTWf#KoyR_PX{Dce_VDh*<);DM{v{6=#0nc z7}Pk%RJjrjz;e>-HATL;L)^UTm7*ZslG^!r@*R6%3mayZz$naHRz^Zu{KY!}eOSHv(Lj*Pt zSzws;RrH^=h;c*vwi9XXM_tC$G_8$U7zcy6^BvY_33Ybvd-p|shA+e&k2 znXR+g(p-EyUb@LHp?944amUe8;|MwKt$1jw3i!DbAO`vm5LJ@29rjvC%v%jz($aPT zoiN^F6hw^+rfQ>+;+szt);q^^Rl}yXe3)&v;}KMqEc-Q3RY)=VfaM{g1nzJozkVkt z2b;IvZ0p>GFF|L~gk86~0C*DLco_P2@JQ>ABrb7)yi$vJ3%#3(nANvHy^M30&wKK1 zl`kFatA{pX;N;?)iov;>h4(oyQS);NUnbMC=OO}6}_D# zzTCXoak+3J7#FCms}qG{XYCmKYiBJ#vQ!JB>cHOJ*WV^bj(VLds3#Et5$npfL1iAC zf3U>e^RW);WOu1?4c|=Tbp}T92#A^hm4jPooCiP_A)kcq<5b-+GR`l>d4b#zUur0t+z)C4d+S8M;%4pCAIzHD&onELF*{ zSI4z5vnJI;TbB!l8uco_%V`d~m!zx?81q){@f9|OkvYmvsj2UHRKoYpcdYTnaefc1 z>0$9sc5tQVZjJ>3EN3@=rQf<@?MF)cB^>PRw_=~t&pVaQaS`#C)g}^geiq{Cg^lGg zDT7O;^#_H5YMU{%_qhvfuaNzs^;;ESfXmQu*U_M=mCW*$GjdSrFmA=R-<~0FP>)@O z7;lmmS}N(H+{t%rYa$~V4>SBDpSrJyuXOt|Q#E!*oKCZHrq77|fs;)^!^6fQ9j>CGc1F7Or=eVkINaQ{Z4>>9+ZXdS3(PJyAQ8r|{6^ru?&S zGl>o8+MHFM{kB%ur6zvA(OuRJHh<_PP;%QqR*_*GQqc2pZ%H0|O&j`QA2La46-UlU zQv`$2dW@#a`IYX}pZb8j$=qi%$HPB*vrg|g{&o>7rnODfkS6Irta9-39OQ#dh3^KG z=oVZPG`4!&a9LZmow0G6;PwQVWSDFL3d0*nmVYXLO$eQ}d_dpH#r}iFpo6~{Z{|H+ zW*|0{6sq%_juqflYOJo9KvDXcf6=J=uT8dEDnInR)00bwQt3Im8*vn)iZ2?L4uPXL z%4o zG-Boh>eC4|aJ}w1HJWcT|I+xF3Rz!xh+x{zs|j#WB$RAJt;5}-Y(?0opXoeArNolk zwVvi%*THq}0-3!BfKmoV2efu0-zC?vmRmQwE8+B?bOv*RL3%)y9>F)uQ#$d}?|j+!+tBH_TJIs{hxF9yAf|rcyD>@nHdd5)<4{rc~=otA$5B;XHgb zzKm=C+V;yxdqM9R(EPyJXNDt2YaP8=_gB}#@Y4{XyBW&Cigl<1Jvx(CEe9hr8~;PT z{_LjH@HmID z>HK%j3bnHv4`F>yYYu*wyq$Thcr#1qk%?HUjp6*#EFIV40_Ccg;DqoziD#& zES!X|l-(|@ZIoXY=iP}4gk3P>% zT}{E>m*97!`2GSonXa}I+_Czb>~w-N#&=-TkvlL7XBXiA8ef@(>5AI)`$}aiIFC4M zy*S5mbv8TL?D>MO3CCbBChG583tIwGI7AEpIc3QbJHTBr^1mia;(Dn$B#$*6>e|AsNAgNh>jiFZW02I?Us!UXEwa+1;%(oh_ylJ~RD;&p^POQ5&FmlKbhw(iv>oV5F2zZS#a(lDt!U4qlk#b0^t^vs{EYAoe8n zcorWNgFboi6;mU*^{O9Xoq3 z+-mczTze_&F(h)yifQ2$;9C6df_=54Ni_*(Q&RI?Yw0=a80tCsjFa(+ADU!aI1m2> zpHpKoHFA|DH|5lCamVYV&!%(sL;BIKaCaV_uK?N zr0l~( zXOm(Izf-7m>mgYO17BKKw^zg_!jqh5z#X;D?=?I_yMB)2cXiB;@mm~~o9~RBdXBx; zG*nwp&IcQl#d$c7-tbtSyPIT(6uTRbK}?9RE}?P&^hbU6+8V|pU51~Vz@9zFxM9z! zmt0}BL!B$)Z<3vwbn#GO8u?y2ncA!*Nb?s+Z6 zbAG?M&b>5lVIQ3HJHe-VkNGz3rB90Q&&k=O{uc2Gti8=ykE_KUW%`X4 z>0WsJzzOF@KV{3oHIsP7NpcI{-^NacHDn|G?(#$M+{J3HiCx6Yz~kX_y&mtS&a?9< za9iZKgmb`S_%Gv{cKX|USmSE(#_r37S-5i<%wN!hH(`ri#U#}5Wz}t&t!DrIPC7)M z2<{Y|+RojpWOu4Dt^Hnt=kDPju(#8p!8=(oSZimou{rp?hm&&p6C6nhUW;nBEd|fp zmWIRezU1KdU6BJ@#lwo3Qwk^fCGwC{Jk>jJOB<_DSHQfG<19VyRNNJbKZtu`a89bn zWPM%4$vuUtdpz;?>StSrkrm6MOVeAOH}jFgP~a(WQ5&O9lC69=^`%U~_bNTh$ z>csmZvw3&wFDCigr25vVe!zQ}?R~3wd(v6QNi~$z|H36RcTx7Sh_^9)mCUzXDO`9` zzK`5*4ppa&!z8EqEd7D|i&YPNj4`ZmLYA$w7(?>Hy{DBD8ruba}P@NBM&HYV*(o&JH0blf@Y&amU;b z*5YI8r)-{g!S6ukuI|j(W3}7xtWoyNb9Ki$p48-Z$!&87tjB1|h1q;dUsk?9U&cx{ zZpD~p_vBOI7+U$n$42SS%4RCJX8wv8HZH#t>rR^IiD#O4mO2T)M^buYHX(FaLfk@D zZ0|YitT{Ra&zVoT%0GEamv8j@B{+}b`-rTzNeC3L}-UqKSpZYpL=28A&b#6iX8S%a3QVnm(mT|u>ScN>A*Zttzv_CBA zJd`Bf-E@Gy=TPs8ZR~^jtu`JKo&{gvgK}f5CgH>^et>$sKA)F6jw^#(-m9O8=(^^Y z+B(l0v$vv)Gr7Oo#z?I499Fn2E7o$`E_+FSAmK0Gr2CR6poElw}oRKdu-FjanLzPdsW$f}K`+^K5af;q&WZ)1^ z^HPe_Ia|Z?M@Q*x>1;2)PI~1sAslM+EqQY+q&2s;_o3z`EEcty z6@w({Kd~?}?RTw`PmylJKjM$6h48vD$!H%J_O(AJvE4p6?@;8c*i+>>?h<@|3)p2+ zOpxR|+5eFwk5*4YT*JOC#UE|G8uoZXC!`C`RcH?vJZNT(!~=nUm?Q3%Kvv;`lJ-J* zANRF=?hwzy5azSMqsr?AwDaghyoa7h_n7gajWlyuyEIt@K@GnJ>Q>~_4PdJPIgf`K~5>Bx>km>55a33OOsFV zSf4lqZUF89AE4YR7{cq$V~zVw=gDKF;O7STJxAnUG-l5^#jwf?O{(ch%ArT$MDA)Ct3wbOW;|Whd z?7=u?1E_^|S<#$D$*!-#UVa4}E9^qOI(UP-&)ElE#N$pKriPn`t0!kf?H92s`IsUd z^?VGqh{B3(?$c|Zn{!^lH{h~~ywsttrSHe+{I1z9+seE6*$WMqOPt5p=;KM= zyNT<}et@HQb&aQn2a2i{bo+L!bIsWxuJgMZUlsUj;iJ_VDveIK&VI$ZD*jpNusGO) ze@nr+UiK^zr>}ge>}VA3?B_9)qll*%i(1lhto}Qx*4D6V&}YHV;O#7XNNs?=_kM-5 z+wtpJe1OSZ4xVpBuermSniTv^7AJ2$>L42=TfLe?>`x9gmPQ8Q+Z5v$@`b{v)EL|U z8-8SEw=T$Ufp>db=CrT1gmYm}O9uC1E5#WR_paXaTxBkbbA#Wuyr5*FbaIj4dP>zL z*Ejj;2F#%YSahDoTSzIxl;&R6frTP)lQDct3@8QGA3bu6?C&W|})uJ~(u@9eiQ1bdbo<7ghE?0uxJt?^5YsVIJI z?FzM+aHiO7&-ZD~eeJa-ZT;yaUH3ixmqS1fEk z4BekXwa3IvQ)73)|H9!(F}lgXv5^twGCUu6sP@ao4=1EEfgI-|x6M5b#9+>|VPlR} zxBRY!6izs`lln)=e3tF=It=w4>|T^Z%bIu2I>NqZ=_+whRIQ5rU-p81UMG7BgBIZV#ze(o#7rL75D$wRWS+>|IF`!c1UF!7 z*!yGpqxOq(RlbiLJBMDAt5FRY_l!)+tvZfi55M*$B-)gW;3tp^&J$qYzMmxvu9xq# z@jeC5O?eI+JJjMr+TZIPe5vo$)On5=ev24Ewh$b}c`;G>1opOh43UJl#PzM}^n@uq zH`4k%*?QlzBOH~$B`?AE)_Z;i`zD!!-|;#oazw<&`)XG?UuMFO$S$mWwdzN_o=Sd{ zeF45EIn=w8g2qK`)x=+sn4xJa;q%J!{K@$_$7gOo*&uHHfoP1J_gSGL!2v5@g zSbeMW&xcUY6M^$5&Lh5f3N`ThyJ{@4`lf`GL~|59i>qg!!gc&t8I`-)XpN zA8M_N);eo_*u#O|I%W`_&XO1GpJS<(dz8Ip&wErZuE2lw`pG;iFGB7coStR7*`J;j zZ)I^3?%R16{fHIMdkw5)Cn~qVUM}iJJg56y=XugTF7{Bcrkv@59fO;0c~jH3*WmZi zmBZTpk^84MZ)*A!CF|6G5~pFm{LD<{s9OGRg~7m4FI6X~rA!*fr1}+dPxcw&an+n~ zZ=d@w=1K9E?=?A`>b`Ncl7S-pGl{#U&br91g4Z~s$z!J2;6d3Z?sCldxwN*0o+E+7 z4pp8#F3{S!-pkfv6O2C=Ck0XH)aE6DCovD4pXA6r;iu zv2V%iOiT4Mc~{?;o4#bYKjnXX&op=%e<`2L`5B&HYi~oLR7!dZ(Y;HU-~TV|Y=% zIEPbi^W^L{xB+}xt}@9O!OANx`w;w`^1dz|J6xELSLwQJ0rzS}Vcfny>@{Z(RKM>p zhR*&8zjKzL#dpGV)I3j;Q);m$>QGCSXZFCa>R8|suxI%7(&$2qudpwQizoRI_=$dR zknb~Tum!QGp9?O(ORXLI7~GaA4)SxE4t1>7USpTw%*bCmm($d@IF});kA9&e)QmW8 z7hlll@|cS#u8z7P!?5CfeD5hXMLcp=ZLr5M;zW{s3HnA{L*4s|mpj(+VDCK^Nfoy^ zFZ&++j6lw_F)R~9t=~Fs%%@}`ws8=A*1nN7;ylizo0>TQAE3j+sgvZ%eU9+2=f-7E z`u(PEze{}%-mTw%%Dxohiq%|Z$*ST+a+g^(x?bxfy*tsDhWq8rLgzUeIgaYKBvlodJY-CB^{)8-_IgA)IL*B06*gUMfaiZ zRqE~AA$UDg6jzyqx!AMk{7R`9FiH;Mp^1-FAM5#h;d+ZRkjs6jHO%|qH8#W#a6z2K zzw#Z&+V7;=#VEed>m=m6O`gzOVd=B-QWSH&SN!gI&-YMkc=f#15);>N*h|AIPsHiV;i~kf-NR^WU+KpE{GXxI}BiUMS9U;Lca>bUYVBT=>ZR4E5Np90>pPxToFc z8TI|9@k|x3`F`cnjE5Q*={9nLEO{N1+UL&dqW74sqn2k^<-qrk5G$ZpI?Kbb6*AG- zbH|Jq#z8$N=Xs~sGx)hER#6vm4`R6LYp<8~c-Tno?K#P5y?i0Ml3Gg7@?PJE?&p)tZQuF%KynGv@v7`M<@^Hd1T^ac$rJDszI9ji9&u534F$0(mmyzA$o zz?y;#nxn%0!*i#q(+U0(o@5Fh^Z2==yE-q1iBcmk4Nh?1AkNp%izT)I?=tUC z>-A?J_@(`h?Ouv=`qSq@iLEWJ1Bb#(b-rlQT4v_C^Iy~!8g|p1m>-rcL~c2&*>P19 zTlqO@+A|ix2h649z2{HZW5N04C-IwjQQzxJ>}HeaqAlX+)n0n|w<^6o`Pz+udLGB3uM$Xb}LP|H*3wj0L1wM4F*~EYBgIMVZ+{PKZLOnNUajDG-i z)7g8Gca01-eRBN}C&)RM)QgnR$*#tI*1oiML7(NU6`N0R-mc+bWS28>f2?B!Ct)wy z2Qa}!;;-Pwq*v5-_G6`g)MXWFm=8-|+IoN@zu{-nh0g!CGSRFN_pe4_cHh$k=H3Ut zuf+Qp8#`aB9>LLY_hwYRir>xA#35~-$Yl(iK^&t#dmf-a|Mn;wiEP4IG;^2WbsAp) zzn8@MMd~()g&W;Tk}c@JsI7BrXF8vL4ntCJ%2}RX+YCpgH8Z)_KEQVW59@z2 zR&-3ZE@J}~@7vgOSn=H0f4ETYtj4Z-ETMWxlZj@3z1yZ3R<#8yf7HjL*gomF$sztu z^W?SC$7alp&U?*euKIee-+pe-TeU&$dbGT@wN1Pu9bq35xz4lx2CkQL6ZWTg!ud7c zT`tI~{CvCDhng(s*kw1!L#3ByT;=?@RyE?p*^M1t#gX{7HkRn^I~e<=!KY8n_!LK3 z4lLF6Yv1XyiSWkiUM|@%I0?5^m)1@;gZt8ZJJIGcF4_tC;<7vKEA!1BA@dW+cxxXN z`y$tli#VGE`64!LFb4ZS*njCIoi!a1HMlP{shv^)83VH?9VZ`b9n2p1!F zaJx}h^JcsI6jnU7*9#H{cDi*IPk?Xno9ZKN`W&3Ihx9=)2YCoTM@8>#&(=COChS?n zhm}U&G{>CXM;#{jUG`^M6v>^}MsLWiwOK-~w`k&DuN7g9_FM+@lNWFbUmQ#9lj@cgRv3th|niwlGN0&ra`SMlQS)N6xfJzhP_op z&K#WFy_xwnXLP@;vy?TIw}*7rnqO+TL+T^YSCh1@V`Q{9vpSl~L{lP{cn-=hEPvl6 zUl{Mxi0=oVXj!AzUh_9GuEJik)I01SDfee}F5SyS+X(b4dr;CZWP;oiK>M=Ed8v9P zkaJQ~O}&1*{JtulK}|UGH3R5yX`i#XYX0ie-vebA_ou_$8kglFW_iw2dc1eiD_!dJ z=zrO{lnadcW%fP7BV4JPyM7$*TLU>gXq&29wUuWez)U3G1l#o zgF~6bev+(zp*)N4Zj!8%d3K7wP`AYUW@6mvN}cbL+}gm8^lz~TNZD^u_dL{?Ugs<5 zd9l{8jPI58<LZJOTX|PzT5S9MQ+frx!W`Ez3BpV}k#KwOnNlfb`e9ROhSk z7yBX6Hjusq;34TzOj``OP;zdtS=i54`b$zqYRpoR|FmUwUrpXe!FoK}5js|*_qMFJ z6Mq@yE6%AZw>AFSDY{hil`~NImbtIxU5mUgQ~HX~S6|Ru8IQ_*1j^oub1Z6z%HELD zUjcajq*fcT66RXBwD+#mK6Fm{y`A*1g%5#uBv$*$2PgeK1N>5b>+*8~K9auF(5KPQ zRA46FuO#^uie9qbG+xQCE}faqIX|J70#{}I&nQ1iy;JO0jowP1k=9{V{L`g*>KsIo zPwF$?Uvxt2`W&Wk`NX>gXRq1cgG=`-*WRi1IM12-y4YX#0rJcZZJpegTFX(%_Jp>hy0rPyMu3uyF4@oYZ z#Jn4YTbMI`o#w225Y&2Od&ZRu`$O{48L!rMXrFv?ReTpF=BwJnT!zVdG+ktiYyxTMAyk^q8_7i}f0`ekC z+fw?KUY*K7@ylsD0$9~k*Yp*v$NA8oyJkM{TV%FU?ffv$Ebeu1;^!}A!y=t4x{-53 zz67xzbBd*3P;dzsHfl|jlf<3mee{ON>>%Rdn?i>-&nI}6>t)uwfCsoU=N+> zGbNWaevNA=u%_gYwJzPQ3ww8s{4D3&UFP%kIQO`ZSMb9ipG$fb0kco>MYYE%eIuGb z^!XhU?`3uhWo&`lv%FaBNnglP-K#pD>lB_)`>*Q*GaP|9T+CIwcGCNfz3@8bkWR^6 zo{Q4EncRh}i8MzN-z zc}v$b=S7^U`$2$*S-(p^5qrW)zD7yUw@P#;2fOvy43kDtiRNCuB-MJGK2RkM}NWo^bC8io~h{> zWmmB-&MP^_SX`VRatva8s2k5Q%2chdF&9snF~@&5;6Laj-U}3cBf+I!Akcp&xR3QB zTo-7S{Y$fa0P2VyG~YV8myP#$5dYCno%y%5y)b`p{69_D=bU=+h-W zYn}8<5`B*R2Z{6ac%DDtPpKavufq1u^2Wd$x;G>Jpqc(?@x4Pj$4K`TzjxWMl`%Q# ze?`1_NW9G)+IWsC4~j94C=YjuAKC9v_tp)?dt2Bb8UF<*{fETnJ1AQ5i8e%Tt3A;C z#(q^(br-Q-897vOz7zIN&90Gtzj#*wM&X_1ydRJ?`Whcc+R=CmG^X>wJ$-!T{(y%g z?JA6Q5(fqT6ubjlzefy_cl(M=qU_nPTffLwwSKu15*WZ2&#{Mi&F;?PV8z(%mD7R7 zc~@iE%g1wnOMSm$U!tuB8l^2);ya$Bt_3Y|o7@4ZaGUgF-eX;$I=zHX^(x&?z-Tf)8EI~6mt|*eg*qm^zirh&}mtI zSw0s0rDD<@uSdz_S4)J z^QErjI$`_RO~s4gFt`PXtA`Xq+bI+2PO;jcSF}RKbSs)Y)oZmF@_gy zJnYfQ{8;k_nxL%}KcjBY{+JI+r-!8Lde#GxFSYE_em0Gh`m|2rd&a%JOFg4tKkEI` z{@9cFJutcCmq6EMz4}W!(*8K;EXmpE)APD-dTm}E>}io7_^$L--Z|-gA93l}X_+E)p==WNp_eNzc^iM-Gq;hnx-~jqY5s4QqObeyTp%nB4~@cQL;ndN%&O zapGeZ|59+Lc^;q{sad5yzjCRMu;Sf0T*Q0!O1w*KB=p(<148%6+KB-Rdx%)Tlg3~Z z_wX%>P0g5e<0RfAx%#EO+PLJ812$_ZD?Bg?@OYWGCuh<)sg?Dh{j%?n#KGaG5?nxk z(axn_W>fEJ!B_O_esEITq{r{TU#u%4O-$l5$RDY%$8#NYa)xm$^w?@y4VzQ)oIi}~ z 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Ν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

y>*n-UCdhbm54490DmtSo?~;! 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 literal 128539 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

;7dO{5C`_kAItMz8k!IHv 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�^M^fM>m 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 Fe*j5zA}Rm? diff --git a/src/python/monero_daemon.pyi b/src/python/monero_daemon.pyi index 8d03bf9..791efa5 100644 --- a/src/python/monero_daemon.pyi +++ b/src/python/monero_daemon.pyi @@ -171,7 +171,7 @@ class MoneroDaemon: Get a block template for mining a new block. :param str wallet_address: is the address of the wallet to receive miner transactions if block is successfully mined. - :param int | None reserve_size: is the reserve size (optional). + :param int|None reserve_size: is the reserve size (optional). :returns MoneroBlockTemplate: a block template for mining a new block. """ ... @@ -325,8 +325,8 @@ class MoneroDaemon: :param str wallet_address: is the address of the wallet to receive miner transactions if block is successfully mined. :param int num_blocks: is the number of blocks to generate. - :param str | None prev_block_hash: is the hash of the previous block to build on top of (optional, builds on the current tip if not given). - :param int | None starting_nonce: is the starting nonce to use (optional). + :param str|None prev_block_hash: is the hash of the previous block to build on top of (optional, builds on the current tip if not given). + :param int|None starting_nonce: is the starting nonce to use (optional). :returns MoneroGenerateBlockResult: the result of generating blocks; height is the height of the last block generated. """ @@ -335,9 +335,9 @@ class MoneroDaemon: Creates an output distribution. :param list[int] amounts: are amounts of outputs to make the distribution with. - :param bool | None is_cumulative: specifies if the results should be cumulative (optional). - :param int | None start_height: is the start height lower bound inclusive (optional). - :param int | None end_height: is the end height upper bound inclusive (optional). + :param bool|None is_cumulative: specifies if the results should be cumulative (optional). + :param int|None start_height: is the start height lower bound inclusive (optional). + :param int|None end_height: is the end height upper bound inclusive (optional). :returns list[MoneroOutputDistributionEntry]: output distribution entries meeting the parameters. """ ... diff --git a/src/python/monero_rpc_connection.pyi b/src/python/monero_rpc_connection.pyi index 09067ea..8396ce7 100644 --- a/src/python/monero_rpc_connection.pyi +++ b/src/python/monero_rpc_connection.pyi @@ -55,7 +55,7 @@ class MoneroRpcConnection(SerializableStruct): :param str proxy_uri: proxy uri. :param str zmq_uri: ZMQ uri. :param int priority: priorioty of the connection. - :param int | None timeout_ms: connection timeout in milliseconds. + :param int|None timeout_ms: connection timeout in milliseconds. """ ... @@ -72,7 +72,7 @@ class MoneroRpcConnection(SerializableStruct): """ Check the connection and update online, authentication, and response time status. - :param int | None timeout_ms: the maximum response time before considered offline. + :param int|None timeout_ms: the maximum response time before considered offline. :returns bool: `True` if there is a change in status, `False` otherwise. """ ... diff --git a/src/python/monero_wallet.pyi b/src/python/monero_wallet.pyi index 9318afd..485ac5c 100644 --- a/src/python/monero_wallet.pyi +++ b/src/python/monero_wallet.pyi @@ -1019,8 +1019,8 @@ class MoneroWallet: """ Set the wallet's daemon connection. - :param MoneroRpcConnection | None connection: is the connection to set. - :param bool | None is_trusted: indicates if daemon connection is trusted. + :param MoneroRpcConnection|None connection: is the connection to set. + :param bool|None is_trusted: indicates if daemon connection is trusted. """ ... @typing.overload @@ -1032,7 +1032,7 @@ class MoneroWallet: :param str username: is the username to authenticate with the daemon (optional). :param str password: is the password to authenticate with the daemon (optional). :param str proxy_uri: proxy for the connection (optional). - :param bool | None is_trusted: indicates if daemon connection is trusted. + :param bool|None is_trusted: indicates if daemon connection is trusted. """ ... def set_restore_height(self, restore_height: int) -> None: diff --git a/src/python/monero_wallet_rpc.pyi b/src/python/monero_wallet_rpc.pyi index ce477cc..b9f13dc 100644 --- a/src/python/monero_wallet_rpc.pyi +++ b/src/python/monero_wallet_rpc.pyi @@ -32,7 +32,7 @@ class MoneroWalletRpc(MoneroWallet): :param str password: Authentication connection password. :param str proxy_uri: Connection proxy. :param str zmq_uri: RPC ZMQ uri. - :param int | None timeout: Connection timeout. + :param int|None timeout: Connection timeout. """ ... @@ -88,8 +88,8 @@ class MoneroWalletRpc(MoneroWallet): """ Set daemon connection. - :param MoneroRpcConnection | None connection: rpc connection to set. + :param MoneroRpcConnection|None connection: rpc connection to set. :param bool is_trusted: set trusted daemon connection. - :param SslOptions | None ssl_options: rpc connection SSL options. + :param SslOptions|None ssl_options: rpc connection SSL options. """ ... From e8dd4e403edf4c717f98132e69cedf6080e2cb24 Mon Sep 17 00:00:00 2001 From: everoddandeven Date: Tue, 28 Jul 2026 16:15:16 +0200 Subject: [PATCH 2/6] Bump v1.0.0 version --- CMakeLists.txt | 2 +- debian/bookworm/control | 2 +- debian/jammy/control | 2 +- debian/noble/control | 2 +- debian/trixie/control | 2 +- docker/build.sh | 2 +- pyproject.toml | 2 +- setup.py | 2 +- src/cpp/utils/py_monero_utils.h | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1b531ba..7d88246 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.15) -project(monero VERSION 0.0.1 LANGUAGES CXX) +project(monero VERSION 1.0.0 LANGUAGES CXX) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) diff --git a/debian/bookworm/control b/debian/bookworm/control index 0146a12..072a9ac 100644 --- a/debian/bookworm/control +++ b/debian/bookworm/control @@ -11,4 +11,4 @@ Package: python3-monero Architecture: all Description: Python bindings for monero-cpp This package provides Python 3 bindings for the monero-cpp library using pybind11. -Version: 0.0.1 +Version: 1.0.0 diff --git a/debian/jammy/control b/debian/jammy/control index 0146a12..072a9ac 100644 --- a/debian/jammy/control +++ b/debian/jammy/control @@ -11,4 +11,4 @@ Package: python3-monero Architecture: all Description: Python bindings for monero-cpp This package provides Python 3 bindings for the monero-cpp library using pybind11. -Version: 0.0.1 +Version: 1.0.0 diff --git a/debian/noble/control b/debian/noble/control index 0146a12..072a9ac 100644 --- a/debian/noble/control +++ b/debian/noble/control @@ -11,4 +11,4 @@ Package: python3-monero Architecture: all Description: Python bindings for monero-cpp This package provides Python 3 bindings for the monero-cpp library using pybind11. -Version: 0.0.1 +Version: 1.0.0 diff --git a/debian/trixie/control b/debian/trixie/control index 0146a12..072a9ac 100644 --- a/debian/trixie/control +++ b/debian/trixie/control @@ -11,4 +11,4 @@ Package: python3-monero Architecture: all Description: Python bindings for monero-cpp This package provides Python 3 bindings for the monero-cpp library using pybind11. -Version: 0.0.1 +Version: 1.0.0 diff --git a/docker/build.sh b/docker/build.sh index 050bfe5..58d1fab 100755 --- a/docker/build.sh +++ b/docker/build.sh @@ -2,7 +2,7 @@ set -e DISTRO_CODENAME=$(grep VERSION_CODENAME /etc/os-release | cut -d'=' -f2) -DEFAULT_VERSION="0.0.1" +DEFAULT_VERSION="1.0.0" if [ -z "$DISTRO_CODENAME" ]; then DISTRO_CODENAME=$(lsb_release -c -s 2>/dev/null || echo "unknown") diff --git a/pyproject.toml b/pyproject.toml index 71d5ad7..46e633e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "monero" -version = "0.0.1" +version = "1.0.0" description = "A Python library for using Monero" authors = [ { name = "everoddandeven", email = "everoddandeven@protonmail.com" } diff --git a/setup.py b/setup.py index 42e012a..9c4f37c 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ setup( name='monero', - version='0.0.1', + version='1.0.0', author='everoddandeven', author_email="everoddandeven@protonmail.com", maintainer='everoddandeven', diff --git a/src/cpp/utils/py_monero_utils.h b/src/cpp/utils/py_monero_utils.h index dba7327..5b0feb6 100644 --- a/src/cpp/utils/py_monero_utils.h +++ b/src/cpp/utils/py_monero_utils.h @@ -62,7 +62,7 @@ class PyMoneroUtils { public: PyMoneroUtils() {}; - static std::string get_version() { return std::string("0.0.1"); }; + static std::string get_version() { return std::string("1.0.0"); }; static std::string json_to_binary(const std::string &json); static std::string dict_to_binary(const py::dict &dictionary); static py::dict binary_to_dict(const std::string& bin); From 41ea9ffa193121cbf87e5fb0d09ac6c0a91643dc Mon Sep 17 00:00:00 2001 From: everoddandeven Date: Tue, 28 Jul 2026 16:26:36 +0200 Subject: [PATCH 3/6] Improve debian package CI --- .github/workflows/build-deb.yml | 37 +++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/.github/workflows/build-deb.yml b/.github/workflows/build-deb.yml index bb7d795..da7faa8 100644 --- a/.github/workflows/build-deb.yml +++ b/.github/workflows/build-deb.yml @@ -77,10 +77,10 @@ jobs: - name: Setup qemu if: matrix.arch == 'arm64' || matrix.arch == 'armhf' - uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 + uses: docker/setup-qemu-action@96fe6ef7f33517b61c61be40b68a1882f3264fb8 # v4.2.0 - name: Setup docker buildx - uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 + uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0 - name: Free up disk space run: | @@ -88,21 +88,26 @@ jobs: docker system prune -af || true - name: Prepare build environment - run: | - PLATFORM=${{ matrix.arch == 'amd64' && 'linux/amd64' || - matrix.arch == 'armhf' && 'linux/arm/v7' || - 'linux/arm64' }} + uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60 # v4.0.0 + with: + timeout_minutes: 60 + max_attempts: 3 + retry_wait_seconds: 15 + command: | + PLATFORM=${{ matrix.arch == 'amd64' && 'linux/amd64' || + matrix.arch == 'armhf' && 'linux/arm/v7' || + 'linux/arm64' }} - docker buildx build \ - --platform $PLATFORM \ - --build-arg BASE_IMAGE=${{ matrix.base_image }} \ - --build-arg THREADS=3 \ - -t monero-python:${{ matrix.name }}-${{ matrix.arch }} \ - -f Dockerfile.linux \ - --cache-from type=gha,scope=${{ matrix.name }}-${{ matrix.arch }} \ - --cache-to type=gha,mode=max,scope=${{ matrix.name }}-${{ matrix.arch }} \ - --load \ - . + docker buildx build \ + --platform $PLATFORM \ + --build-arg BASE_IMAGE=${{ matrix.base_image }} \ + --build-arg THREADS=3 \ + -t monero-python:${{ matrix.name }}-${{ matrix.arch }} \ + -f Dockerfile.linux \ + --cache-from type=gha,scope=${{ matrix.name }}-${{ matrix.arch }} \ + --cache-to type=gha,mode=max,scope=${{ matrix.name }}-${{ matrix.arch }} \ + --load \ + . - name: Build monero-python uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60 # v4.0.0 From 8a4a1704e60d48a547abce0f9451992fe7e5f227 Mon Sep 17 00:00:00 2001 From: everoddandeven Date: Tue, 28 Jul 2026 16:41:46 +0200 Subject: [PATCH 4/6] Rerun tests on busy daemon --- pytest.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pytest.ini b/pytest.ini index 679a423..71b3681 100644 --- a/pytest.ini +++ b/pytest.ini @@ -1,6 +1,6 @@ [pytest] minversion = 6.0 -addopts = -v +addopts = -v --reruns 5 --reruns-delay 10 --only-rerun "BUSY" log_level = INFO log_cli = True log_cli_level = INFO From ccd59d215ed35fe9130c2c7831e115ef8b412052 Mon Sep 17 00:00:00 2001 From: everoddandeven Date: Tue, 28 Jul 2026 16:57:37 +0200 Subject: [PATCH 5/6] Add commit hash to monero-cpp html coverage report --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 958b5e4..4cd2f2c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -148,7 +148,7 @@ jobs: lcov --capture --directory external/monero-cpp/build --ignore-errors mismatch,mismatch,inconsistent,source,source,gcov,gcov --output-file coverage_monero_cpp_full.info lcov --ignore-errors unused,unused --extract coverage_monero_cpp_full.info '*/monero-cpp/src/*' --output-file coverage_monero_cpp.info sed -i "s|$(pwd)/||g" coverage_monero_cpp.info - genhtml coverage_monero_cpp.info --output-directory coverage_monero_cpp_html --ignore-errors mismatch,inconsistent,source,corrupt + genhtml coverage_monero_cpp.info --output-directory coverage_monero_cpp_html --ignore-errors mismatch,inconsistent,source,corrupt --title "monero-cpp coverage @ ${GITHUB_SHA::7}" lcov --summary coverage_monero_cpp.info - name: Upload coverage report From 8023bf7743be9b9bcd9633d284878048ba78be9c Mon Sep 17 00:00:00 2001 From: everoddandeven Date: Tue, 28 Jul 2026 17:00:12 +0200 Subject: [PATCH 6/6] Add delay after test environment setup --- .github/workflows/test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4cd2f2c..328e311 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -97,6 +97,7 @@ jobs: - name: Setup test environment run: | docker compose -f tests/docker-compose.yml up -d node_1 node_2 xmr_wallet_1 xmr_wallet_2 xmr_wallet_3 + sleep 10 - name: Reset coverage counters run: |