### Show lxmd Example Configuration Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/README.md Display an example configuration for the lxmd daemon. This can be used as a template for creating your own configuration files. ```bash lxmd --exampleconfig ``` -------------------------------- ### Basic LXMF Client Setup Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/api-reference/LXMRouter.md Initializes Reticulum, creates an LXMRouter instance, registers a delivery identity and callback, and announces presence. This serves as a fundamental example for setting up an LXMF client. ```python import LXMF import RNS # Initialize Reticulum r = RNS.Reticulum() # Create router router = LXMF.LXMRouter(storagepath="~/.lxmf") # Create delivery identity identity = RNS.Identity() delivery_dest = router.register_delivery_identity( identity, display_name="Alice", stamp_cost=8 ) # Set up message delivery callback def on_message(msg): print(f"Message from {msg.source.hash.hex()}") print(f"Content: {msg.content_as_string()}") router.register_delivery_callback(on_message) # Announce presence router.announce(delivery_dest.hash) # Keep router running import time while True: time.sleep(1) ``` -------------------------------- ### LXMF Propagation Node Setup Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/README.md This snippet shows the basic setup for an LXMF propagation node. It initializes Reticulum and an LXMF router with specific storage paths and network parameters. Ensure Reticulum is installed and configured. ```python import LXMF import RNS import time r = RNS.Reticulum() router = LXMF.LXMRouter( storagepath="/var/lxmf", name="Central Hub", propagation_cost=16, max_peers=50 ) ``` -------------------------------- ### Simple Client Configuration Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/configuration.md Example configuration for a basic LXMF client. Disables auto-peering and stamp enforcement for simplicity. ```python router = LXMF.LXMRouter( storagepath="~/.lxmf", autopeer=False, # Disable if not a PN enforce_stamps=False, # Accept any messages enforce_ratchets=False ) ident = RNS.Identity() delivery = router.register_delivery_identity( ident, display_name="My Client", stamp_cost=None # No cost requirement ) ``` -------------------------------- ### Install LXMF with pip Source: https://github.com/markqvist/lxmf/blob/master/README.md Installs the LXMF library using pip. This is the standard method for installing Python packages. ```bash pip install lxmf ``` -------------------------------- ### Install LXMF with pipx Source: https://github.com/markqvist/lxmf/blob/master/README.md Installs LXMF in an isolated environment using the pipx tool. This is recommended for managing Python applications and their dependencies separately. ```bash pipx install lxmf ``` -------------------------------- ### Basic Propagation Node Setup Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/configuration.md Initialize an LXMRouter as a propagation node with specified storage path, name, and propagation costs. Includes setting storage limits and enabling propagation functionality. ```python router = LXMF.LXMRouter( storagepath="/var/lxmf", name="My Propagation Node", propagation_cost=16, peering_cost=18, max_peering_cost=26, max_peers=50 ) # Configure storage router.set_message_storage_limit(gigabytes=5) router.set_information_storage_limit(megabytes=1000) # Enable propagation node functionality router.enable_propagation() # Announce to network router.announce_propagation_node() ``` -------------------------------- ### Configure pip to Allow System Package Installation Source: https://github.com/markqvist/lxmf/blob/master/README.md Modifies the pip configuration to allow installation of packages that might otherwise be blocked by system package restrictions. Use with caution. ```text [global] break-system-packages = true ``` -------------------------------- ### Configure lxmd Daemon Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/README.md Run the lxmd daemon using a specified configuration directory. Ensure the configuration path is correct for your setup. ```bash lxmd --config /etc/lxmf ``` -------------------------------- ### Secure Server Configuration Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/configuration.md Example configuration for a secure LXMF server. Enforces stamps, ratchets, and authentication, with a limited number of trusted peers. ```python router = LXMF.LXMRouter( storagepath="/var/lxmf", enforce_stamps=True, # Require stamps enforce_ratchets=True, # Require ratchets set_authentication(True), # Auth required max_peers=5 # Trusted only ) # Whitelist trusted users router.allow(trusted_user_hash) router.allow(trusted_user_hash_2) ``` -------------------------------- ### Set Information Storage Limit Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/configuration.md Configure the maximum size for information and metadata storage on a propagation node. Example shown in megabytes. ```python # Information/metadata storage limit router.set_information_storage_limit(megabytes=500) # 500 MB ``` -------------------------------- ### Handling LXMPeer Synchronization Errors Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/errors.md Example of checking response codes from peer synchronization and taking appropriate action. ```python def offer_response(request_receipt): response = request_receipt.response if response == LXMF.LXMPeer.ERROR_NO_IDENTITY: link.identify(router.identity) # Retry offer elif response == LXMF.LXMPeer.ERROR_NO_ACCESS: print("Access denied by propagation node") elif response == LXMF.LXMPeer.ERROR_THROTTLED: print("Rate limited, waiting before retry...") time.sleep(180) ``` -------------------------------- ### Basic LXMF Client Setup and Message Sending Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/README.md This snippet demonstrates how to initialize Reticulum and an LXMF router, register a delivery identity, set up a callback for incoming messages, and send an LXMF message. Ensure Reticulum is initialized and the recipient hash is valid. ```python import LXMF import RNS import time # Initialize Reticulum r = RNS.Reticulum() # Create router router = LXMF.LXMRouter(storagepath="~/.lxmf") # Register delivery identity identity = RNS.Identity() delivery_dest = router.register_delivery_identity( identity, display_name="Alice", stamp_cost=8 ) # Set up callback for incoming messages def on_message(msg): print(f"Message from {msg.source.hash.hex()}") print(f"Content: {msg.content_as_string()}") router.register_delivery_callback(on_message) # Announce presence router.announce(delivery_dest.hash) # Send a message recipient_hash = bytes.fromhex("6b3362bd2c1dbf87b66a85f79a8d8c75") recipient_ident = RNS.Identity.recall(recipient_hash) recipient = RNS.Destination( recipient_ident, RNS.Destination.OUT, RNS.Destination.SINGLE, "lxmf", "delivery" ) msg = LXMF.LXMessage( destination=recipient, source=delivery_dest, content="Hello from Alice!", title="Greeting" ) router.handle_outbound(msg) # Keep running while True: time.sleep(1) ``` -------------------------------- ### Small Propagation Node Configuration Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/configuration.md Example configuration for a small LXMF propagation node. Sets specific limits for message propagation, peers, and storage. ```python router = LXMF.LXMRouter( storagepath="/var/lxmf", name="Small PN", propagation_limit=256, max_peers=10, propagation_cost=14 ) router.set_message_storage_limit(megabytes=256) router.enable_propagation() router.announce_propagation_node() ``` -------------------------------- ### Initiate LXMPeer Synchronization Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/api-reference/LXMPeer.md Starts the message synchronization process with a peer. This method performs several checks, including sync timing, key validity, and network path availability, before proceeding. ```python peer.sync() ``` -------------------------------- ### Configure Router and Enable Propagation Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/README.md Sets the message storage limit and enables message propagation for the router. This is typically done during initial setup. ```python router.set_message_storage_limit(gigabytes=5) # Enable propagation router.enable_propagation() router.announce_propagation_node() ``` -------------------------------- ### Setting Message Renderer Field Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/types.md Example of how to set the FIELD_RENDERER in message fields to indicate Markdown formatting. ```python msg.fields[LXMF.FIELD_RENDERER] = LXMF.RENDERER_MARKDOWN ``` -------------------------------- ### Handling LXMF ValueError Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/errors.md Example of catching ValueError for invalid parameter values or state errors during LXMessage initialization. ```python try: msg = LXMF.LXMessage("invalid", source) except ValueError as e: print(f"Invalid message parameters: {e}") ``` -------------------------------- ### Large Propagation Node Configuration Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/configuration.md Example configuration for a large, central LXMF propagation node. Features higher limits for transfers, peers, and storage, with auto-peering enabled. ```python router = LXMF.LXMRouter( storagepath="/var/lxmf", name="Central Hub", propagation_limit=1024, # Larger transfers max_peers=100, # Many peers propagation_cost=16, propagation_cost_flexibility=2, peering_cost=20, autopeer=True, autopeer_maxdepth=5 ) router.set_message_storage_limit(gigabytes=10) router.set_information_storage_limit(megabytes=2000) router.enable_propagation() router.announce_propagation_node() ``` -------------------------------- ### Generate QR Code for Paper Message Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/api-reference/LXMessage.md Creates a QR code image for a paper message. Requires the 'qrcode' library to be installed. The message must be of PAPER delivery method. ```python qr = message.as_qr() qr.show() # Display QR code ``` -------------------------------- ### Run lxmd as Propagation Node Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/README.md Start the lxmd daemon in propagation node mode. This enables message relaying capabilities. ```bash lxmd --propagation-node ``` -------------------------------- ### as_qr() Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/api-reference/LXMessage.md Generates a QR code image for a paper message. This method requires the 'qrcode' Python module to be installed and is only applicable to messages using the PAPER delivery method. ```APIDOC ## as_qr() ### Description Generate a QR code image for paper message. ### Requires - `pip install qrcode` ### Raises - **TypeError** - If message not PAPER delivery method ### Request Example ```python qr = message.as_qr() qr.show() # Display QR code ``` ### Returns - **qrcode.QRCode or None** - The QR code object, or None if the qrcode module is unavailable ``` -------------------------------- ### Unpack Propagation Node Announce Data Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/types.md Example of unpacking msgpack-encoded announce data for a propagation node. Extracts metadata like name and stamp cost, and validates the data structure. ```python pn_app_data = RNS.Identity.recall_app_data(pn_hash) if LXMF.pn_announce_data_is_valid(pn_app_data): pn_config = msgpack.unpackb(pn_app_data) name = pn_config[6].get(LXMF.PN_META_NAME, b"").decode("utf-8") cost = pn_config[5][0] transfer_limit = pn_config[3] ``` -------------------------------- ### Monitoring LXMPeer State Periodically Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/api-reference/LXMPeer.md Provides a function to display the current status of an LXMPeer, including its reachability, last contact time, message counts, and transfer rates. The example demonstrates how to call this function in a loop for continuous monitoring. ```python def monitor_peer(peer): print(f"Peer: {peer.destination_hash.hex()}") print(f" Status: {'Alive' if peer.alive else 'Offline'}") print(f" Last heard: {peer.last_heard}") print(f" Unhandled messages: {peer.unhandled_message_count}") print(f" Sync strategy: {peer.sync_strategy}") print(f" Stats: {peer.offered} offered, {peer.outgoing} sent, {peer.incoming} received") print(f" Transfer rate: {peer.sync_transfer_rate:.2f}") # Call periodically import time while True: for peer_id in router.peers: monitor_peer(router.peers[peer_id]) time.sleep(60) ``` -------------------------------- ### Get LXMF Version Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/README.md Print the current LXMF library version. This requires importing the LXMF library and accessing its __version__ attribute. ```python import LXMF print(LXMF.__version__) ``` -------------------------------- ### Get Outbound Propagation Cost Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/api-reference/LXMRouter.md Fetches the proof-of-work cost required by the configured outbound propagation node. Returns the cost as an integer or None if not applicable. ```python cost = router.get_outbound_propagation_cost() if cost: print(f"Propagation node requires cost: {cost}") ``` -------------------------------- ### Unpack Delivery Destination Announce Data Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/types.md Example of unpacking msgpack-encoded announce data for a delivery destination (Version 0.5.0+). Extracts display name, stamp cost, and checks for compression support. ```python import RNS.vendor.umsgpack as msgpack app_data = RNS.Identity.recall_app_data(dest_hash) peer_data = msgpack.unpackb(app_data) name = peer_data[0].decode("utf-8") if peer_data[0] else None stamp_cost = peer_data[1] supports_compression = LXMF.SF_COMPRESSION in (peer_data[2] if len(peer_data) > 2 else []) ``` -------------------------------- ### Get Message Content as String Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/api-reference/LXMessage.md Retrieves the message content, attempting to decode it as a UTF-8 string. Returns None if the content is not valid UTF-8 or is not set. ```python content = message.content_as_string() ``` -------------------------------- ### Basic LXMPeer Creation and Sync Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/api-reference/LXMPeer.md Demonstrates how to manually create an LXMPeer instance, configure its propagation parameters, and initiate a synchronization process. Requires an LXMRouter instance and a peer's destination hash. ```python import LXMF import RNS router = LXMF.LXMRouter(storagepath="/var/lxmf") router.enable_propagation() # Create peer manually (normally done automatically) peer_hash = bytes.fromhex("e75d9b6a69f82b48b6077cf2242d7499") peer = LXMF.LXMPeer( router=router, destination_hash=peer_hash, sync_strategy=LXMF.LXMPeer.STRATEGY_PERSISTENT ) # Configure peer parameters peer.propagation_transfer_limit = 256 # KB peer.propagation_sync_limit = 10240 # KB peer.propagation_stamp_cost = 16 peer.peering_cost = 18 # Initiate sync peer.sync() ``` -------------------------------- ### Initialize LXMPeer with Sync Strategies Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/api-reference/LXMPeer.md Demonstrates initializing LXMPeer objects with either a lazy or a persistent synchronization strategy. ```python # Lazy strategy: sync only when explicitly requested lazy_peer = LXMF.LXMPeer( router, peer_hash, sync_strategy=LXMF.LXMPeer.STRATEGY_LAZY ) # Persistent strategy: regular automatic syncs persistent_peer = LXMF.LXMPeer( router, peer_hash, sync_strategy=LXMF.LXMPeer.STRATEGY_PERSISTENT ) # Router periodically calls sync() on PERSISTENT peers # For LAZY peers, you must call sync() manually: if not lazy_peer.unhandled_messages: # No messages pending pass else: lazy_peer.sync() ``` -------------------------------- ### Handling LXMessage Validation Errors Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/errors.md Example of checking message.unverified_reason for specific validation issues. ```python if not msg.signature_validated: if msg.unverified_reason == LXMF.LXMessage.SOURCE_UNKNOWN: print("Warning: Source identity unknown, cannot verify") elif msg.unverified_reason == LXMF.LXMessage.SIGNATURE_INVALID: print("Error: Signature validation failed!") return # Discard message ``` -------------------------------- ### Initialize LXMRouter with JSON Configuration Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/configuration.md Load configuration from 'lxmf_config.json' and use it to initialize the LXMRouter. Ensure the JSON file contains keys for 'propagation_cost', 'max_peers', 'static_peers', and 'storage_limit_gb'. Static peers should be provided as hex strings. ```python import json from lxmf import LXMF with open("lxmf_config.json", "r") as f: config = json.load(f) router = LXMF.LXMRouter( storagepath="/var/lxmf", propagation_cost=config["propagation_cost"], max_peers=config["max_peers"], static_peers=[bytes.fromhex(h) for h in config["static_peers"]] ) router.set_message_storage_limit(gigabytes=config["storage_limit_gb"]) ``` -------------------------------- ### LXMD Daemon Help Options Source: https://github.com/markqvist/lxmf/blob/master/README.md Displays the available command-line options for the lxmd daemon. Use this to understand how to configure and run the daemon. ```text usage: lxmd [-h] [--config CONFIG] [--rnsconfig RNSCONFIG] [-p] [-i PATH] [-v] [-q] [-s] [--exampleconfig] [--version] Lightweight Extensible Messaging Daemon options: -h, --help show this help message and exit --config CONFIG path to alternative lxmd config directory --rnsconfig RNSCONFIG path to alternative Reticulum config directory -p, --propagation-node run an LXMF Propagation Node -i PATH, --on-inbound PATH executable to run when a message is received -v, --verbose -q, --quiet -s, --service lxmd is running as a service and should log to file --exampleconfig print verbose configuration example to stdout and exit --version show program's version number and exit ``` -------------------------------- ### Access Message Destination Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/api-reference/LXMessage.md Get or set the RNS.Destination object for the message. Note that the destination can only be set once during initialization. ```python dest = message.destination message.destination = new_destination ``` -------------------------------- ### Create and Send a Simple LXMessage Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/api-reference/LXMessage.md Demonstrates initializing the LXMRouter, registering a delivery identity, defining a recipient, creating an LXMessage with content and title, and sending it using the DIRECT method. A delivery callback is registered to confirm delivery. ```python import LXMF import RNS # Initialize router router = LXMF.LXMRouter(storagepath="/var/lxmf") source_ident = RNS.Identity() source = router.register_delivery_identity(source_ident) # Get recipient (must already have identity known) recipient_hash = bytes.fromhex("6b3362bd2c1dbf87b66a85f79a8d8c75") recipient_ident = RNS.Identity.recall(recipient_hash) recipient = RNS.Destination(recipient_ident, RNS.Destination.OUT, RNS.Destination.SINGLE, "lxmf", "delivery") # Create and send message msg = LXMF.LXMessage( destination=recipient, source=source, content="Hello, World!", title="Greeting", desired_method=LXMF.LXMessage.DIRECT ) def on_delivery(m): print(f"Message delivered: {m.hash.hex()}") msg.register_delivery_callback(on_delivery) router.handle_outbound(msg) ``` -------------------------------- ### Load Peer States from File Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/api-reference/LXMPeer.md Loads peer data from a msgpack file and initializes LXMPeer objects, populating the router's peer list. ```python with open("/var/lxmf/peers", "rb") as f: peers_data = msgpack.unpackb(f.read()) for peer_bytes in peers_data: peer = LXMF.LXMPeer.from_bytes(peer_bytes, router) router.peers[peer.destination_hash] = peer ``` -------------------------------- ### set_active_propagation_node Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/api-reference/LXMRouter.md Sets the outbound propagation node for this client. Note: The example uses `set_outbound_propagation_node` which appears to be the intended function. ```APIDOC ## set_active_propagation_node(destination_hash) ### Description Set the outbound propagation node for this client. ### Parameters - `destination_hash` (bytes) - Required - Hash of propagation node to use ### Request Example ```python pn_hash = bytes.fromhex("e75d9b6a69f82b48b6077cf2242d7499") router.set_outbound_propagation_node(pn_hash) ``` ``` -------------------------------- ### Peering Key Generation and Check Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/api-reference/LXMPeer.md Shows how to check if a peer's peering key is ready, generate it if not, and retrieve its value and the associated proof-of-work cost. This is essential for establishing secure communication channels. ```python if not peer.peering_key_ready(): success = peer.generate_peering_key() if success: value = peer.peering_key_value() required = peer.peering_cost print(f"Generated key with value {value} (required: {required})") else: print("Failed to generate peering key") ``` -------------------------------- ### LXMessage Constructor Options Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/configuration.md Create LXMessage instances with parameters for destination, source, content, and delivery preferences. Optional fields can be provided as a dictionary. ```python msg = LXMF.LXMessage( destination=dest, source=source, content="", title="", fields=None, desired_method=LXMF.LXMessage.DIRECT, destination_hash=None, source_hash=None, stamp_cost=None, include_ticket=False ) ``` -------------------------------- ### Get Message Stamp Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/api-reference/LXMessage.md Retrieves or generates a proof-of-work stamp for the message. Useful for ensuring message authenticity before sending. ```python stamp = message.get_stamp() ``` -------------------------------- ### Access Message Source Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/api-reference/LXMessage.md Get or set the RNS.Destination object for the sender. Similar to the destination, the source can only be set once during initialization. ```python src = message.source message.source = new_source ``` -------------------------------- ### LXMPeer Constructor Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/api-reference/LXMPeer.md Initializes a new LXMPeer instance. It requires a router instance and the peer's destination hash, with an optional synchronization strategy. ```APIDOC ## LXMPeer(router, destination_hash, sync_strategy=DEFAULT_SYNC_STRATEGY) ### Description Initializes a new LXMPeer instance. It requires a router instance and the peer's destination hash, with an optional synchronization strategy. ### Parameters #### Path Parameters - **router** (LXMRouter) - Required - Parent router instance - **destination_hash** (bytes) - Required - 16-byte destination hash of peer - **sync_strategy** (int) - Optional - Default: DEFAULT_SYNC_STRATEGY - STRATEGY_LAZY or STRATEGY_PERSISTENT ``` -------------------------------- ### Get Propagation Stamp Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/api-reference/LXMessage.md Generates a proof-of-work stamp specifically for propagation node delivery. Use when sending messages that will be relayed. ```python pn_stamp = message.get_propagation_stamp(target_cost=16) ``` -------------------------------- ### Generate Paper Message and QR Code Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/api-reference/LXMessage.md Demonstrates creating an LXMessage intended for PAPER delivery, packing it, and then generating a QR code representation of the message. It also shows how to obtain the message as a URI string. ```python msg = LXMF.LXMessage( destination=recipient, source=source, content="Secret message", desired_method=LXMF.LXMessage.PAPER ) msg.pack() # Generate QR code qr = msg.as_qr() qr.make() qr.show() # Or get as URI uri = msg.as_uri() print(f"Scan this: {uri}") ``` -------------------------------- ### Handling NotImplementedError Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/errors.md Catch NotImplementedError when calling unsupported methods like set_inbound_propagation_node. This example shows how to handle the exception and provides a fallback. ```python try: router.set_inbound_propagation_node(pn_hash) except NotImplementedError: print("Inbound propagation nodes not yet implemented") # Use get_inbound_propagation_node() which returns outbound node ``` -------------------------------- ### Show lxmd Daemon Help Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/README.md Display available options for the lxmd command-line daemon. This is useful for understanding the daemon's capabilities and configuration. ```bash lxmd --help ``` -------------------------------- ### Configure LXMRouter with Static Peers Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/api-reference/LXMRouter.md Initializes an LXMRouter with a list of static peers defined by their hashes. Enables propagation and provides a loop to periodically check peer statistics. ```python # Add static peers router = LXMF.LXMRouter( storagepath="/var/lxmf", static_peers=[ bytes.fromhex("node1hash0123456789abcdef0123456"), bytes.fromhex("node2hash0123456789abcdef0123456"), ] ) router.enable_propagation() # Peers auto-sync based on strategy # Check stats periodically stats = router.compile_stats() for peer_id, peer_data in stats['peers'].items(): print(f"Peer {peer_id.hex()}: {peer_data['messages']['incoming']} in") ``` -------------------------------- ### Get Message Storage Size Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/api-reference/LXMRouter.md Retrieves the current size of the message store in bytes. Returns None if the node is not a propagation node. ```python size_bytes = router.message_storage_size() print(f"Storing {size_bytes / 1e9:.2f} GB") ``` -------------------------------- ### Get Custom Fields Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/api-reference/LXMessage.md Retrieves the dictionary of custom fields associated with the message. Returns an empty dictionary if no custom fields have been set. ```python fields = message.get_fields() ``` -------------------------------- ### Serializing and Saving LXMPeer States Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/api-reference/LXMPeer.md Demonstrates how to serialize the state of all known LXMPeers using msgpack and save them to a file. This is crucial for persisting peer information across application restarts. ```python # Save all peer states import msgpack peers_data = [] for peer_id in router.peers: peer = router.peers[peer_id] peers_data.append(peer.to_bytes()) with open("/var/lxmf/peers", "wb") as f: f.write(msgpack.packb(peers_data)) ``` -------------------------------- ### Create LXMessage with Custom Fields and Pack Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/api-reference/LXMessage.md Shows how to create an LXMessage including custom fields in a dictionary and then pack the message. The message ID (hash) is printed after packing. ```python msg = LXMF.LXMessage( destination=recipient, source=source, content="Sensor reading", title="Telemetry", fields={ "sensor_id": "temperature_01", "value": 23.5, "unit": "celsius", "timestamp": 1234567890 } ) msg.pack() print(f"Message ID: {msg.hash.hex()}") ``` -------------------------------- ### LXMRouter Constructor Options Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/configuration.md Configure LXMRouter with various parameters for network behavior, message limits, and security settings. Ensure storage path is valid and creatable. ```python router = LXMF.LXMRouter( identity=None, storagepath="/var/lxmf", autopeer=True, autopeer_maxdepth=4, propagation_limit=256, delivery_limit=1000, sync_limit=10240, enforce_ratchets=False, enforce_stamps=False, static_peers=[], max_peers=20, from_static_only=False, sync_strategy=LXMPeer.STRATEGY_PERSISTENT, propagation_cost=16, propagation_cost_flexibility=3, peering_cost=18, max_peering_cost=26, name=None ) ``` -------------------------------- ### Get Outbound Propagation Node Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/api-reference/LXMRouter.md Retrieves the currently configured outbound propagation node. Returns the destination hash as bytes or None if not set. ```python current_pn = router.get_outbound_propagation_node() ``` -------------------------------- ### Persist Configuration to JSON Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/configuration.md Demonstrates how to save LXMF router settings to a JSON file for manual persistence. Includes common configuration parameters. ```python import json config = { "propagation_cost": 16, "max_peers": 20, "storage_limit_gb": 5, "static_peers": [ "node1_hash_hex", "node2_hash_hex" ] } # Save with open("lxmf_config.json", "w") as f: json.dump(config, f) ``` -------------------------------- ### Get Propagation Node Announce Metadata Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/api-reference/LXMRouter.md Retrieves the metadata dictionary for node announcements. This is useful for understanding the information available for node announcements. ```python metadata = router.get_propagation_node_announce_metadata() ``` -------------------------------- ### Send a Message with LXM Router Source: https://github.com/markqvist/lxmf/blob/master/README.md Demonstrates the basic usage of the LXM Router to send a simple message. Ensure LXMF is imported and an LXMRouter instance is created. ```python import LXMF lxm_router = LXMF.LXMRouter() message = LXMF.LXMessage(destination, source, "This is a short, simple message.") lxm_router.handle_outbound(message) ``` -------------------------------- ### LXMRouter Constructor Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/api-reference/LXMRouter.md Initializes an LXMRouter instance. Configure message storage, auto-peering, limits, and proof-of-work requirements. The storagepath parameter is required. ```python LXMRouter(identity=None, storagepath=None, autopeer=True, autopeer_maxdepth=4, propagation_limit=256, delivery_limit=1000, sync_limit=10240, enforce_ratchets=False, enforce_stamps=False, static_peers=[], max_peers=20, from_static_only=False, sync_strategy=LXMPeer.STRATEGY_PERSISTENT, propagation_cost=16, propagation_cost_flexibility=3, peering_cost=18, max_peering_cost=26, name=None) ``` -------------------------------- ### Handling LXMF TypeError for Message Size Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/errors.md Example of catching TypeError when a message exceeds size limits for its desired delivery method and attempting an alternative. ```python try: msg = LXMF.LXMessage(dest, source, "x" * 10000) msg.desired_method = LXMF.LXMessage.OPPORTUNISTIC msg.pack() except TypeError as e: print(f"Message too large for delivery method: {e}") msg.desired_method = LXMF.LXMessage.DIRECT msg.pack() ``` -------------------------------- ### Initialize LXMessage Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/api-reference/LXMessage.md Instantiate an LXMessage object with sender, recipient, and optional content or metadata. The destination and source parameters are required RNS.Destination objects. ```python LXMessage(destination, source, content="", title="", fields=None, desired_method=None, destination_hash=None, source_hash=None, stamp_cost=None, include_ticket=False) ``` -------------------------------- ### Get Message Title as String Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/api-reference/LXMessage.md Retrieves the message title, attempting to decode it as a UTF-8 string. Returns None if the title is not valid UTF-8 or is not set. ```python title = message.title_as_string() ``` -------------------------------- ### Get LXMPeer Peering Key Value Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/api-reference/LXMPeer.md Retrieves the numeric value of the generated peering key. This value can be compared against the peer's cost requirement. ```python value = peer.peering_key_value() if value and value >= peer.peering_cost: print(f"Key meets cost requirement of {peer.peering_cost}") ``` -------------------------------- ### Configure CPU-bound Performance Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/configuration.md Tune router performance for CPU-bound tasks like stamp generation on servers with multiple cores. Adjust propagation and peering costs. ```python import multiprocessing cores = multiprocessing.cpu_count() router = LXMF.LXMRouter( storagepath="/var/lxmf", propagation_cost=14, # Lower cost = faster validation peering_cost=16 # But more work to peer ) ``` -------------------------------- ### API Reference Overview Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/COMPLETION_REPORT.txt This section outlines the structure and content of the lxmf API documentation, emphasizing its comprehensiveness and adherence to source code accuracy. It covers constructor options, public methods, properties, error conditions, and configuration options. ```APIDOC ## API Reference Details ### Description Provides detailed documentation for all exported components of the lxmf library, ensuring 100% coverage of the public API. This includes constructor parameters, public methods, public properties, and error conditions. ### Documentation Standards - Exact parameter names and types from source code - Complete method signatures - Return type documentation - Exception/error conditions - Real-world usage examples - Parameter validation rules - Default values documented - Range/constraint documentation ### Key Features - **COMPREHENSIVE**: All exported functions, classes, methods documented. - **PRECISE**: Exact signatures and types from source code. - **PRACTICAL**: Real usage examples for common tasks. - **REFERENCED**: Source file paths and line numbers included. - **COMPLETE**: Constructor options, parameters, return types all included. - **ORGANIZED**: Logical navigation structure with cross-references. - **SEARCHABLE**: Clear section headers and table of contents. - **TECHNICAL**: Pure technical reference without marketing copy. ### Usage Recommendations - **GETTING STARTED**: Review README.md, core concepts, code examples, and specific API documentation. - **IMPLEMENTATION**: Check configuration.md for constructor options, api-reference/ for method details, types.md for field constants, and errors.md for error handling. - **TROUBLESHOOTING**: Consult errors.md for error codes, configuration.md for tuning, and common error scenarios. - **DEPLOYMENT**: Review recommended configurations, storage limits in types.md, performance tuning guidelines, and security configuration. ### Technical Specifications - **PYTHON VERSIONS**: 3.7+ - **RETICULUM REQUIREMENT**: >= 1.3.5 - **LXMF VERSION**: 1.x - **PLATFORM SUPPORT**: Linux, macOS, Windows, Android ### Documentation Format - Markdown with GitHub-flavored extensions - Code syntax highlighting - Tables for structured data - Clear hierarchy with headers - Cross-references between documents ``` -------------------------------- ### Generate Peering Key with Cost Requirement Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/api-reference/LXStamper.md Generates a peering key with a specific cost requirement. This is used during the initial connection setup between nodes to establish a secure channel. ```python # Peer wants cost=18 peering key peer_cost = 18 # Generate peering key key_material = peer_identity.hash + local_identity.hash stamp, value = LXStamper.generate_stamp( key_material, peer_cost, expand_rounds=LXStamper.WORKBLOCK_EXPAND_ROUNDS_PEERING ) if value >= peer_cost: peering_key = [stamp, value] print(f"Generated peering key with value {value}") else: print("Peering key generation failed") ``` -------------------------------- ### Simple Message Stamping Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/api-reference/LXStamper.md Demonstrates the basic usage of LXStamper to create and stamp an LXMessage. This is the most common use case for sending authenticated messages. ```python import LXMF import LXMF.LXStamper as LXStamper import RNS # Create message msg = LXMF.LXMessage(dest, source, "Hello", stamp_cost=8) msg.pack() # Get stamp stamp = msg.get_stamp() print(f"Generated stamp: {stamp.hex()}") print(f"Stamp value: {msg.stamp_value}") ``` -------------------------------- ### LXMPeer.sync Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/api-reference/LXMPeer.md Initiates the message synchronization process with the peer. This method performs several checks before proceeding, including sync timing, peer costs, key validity, and path availability. ```APIDOC ## LXMPeer.sync() ### Description Initiates the message synchronization process with the peer. This method performs several checks before proceeding, including sync timing, peer costs, key validity, and path availability. ### Conditions Checked Before Sync - Sync time reached (not in backoff) - Peer stamp costs known - Peering key generated and valid - Path to peer available ### Actions on Failure - Postpones sync with reason logged - Schedules peering key generation if needed - Requests path if unavailable ### State Progression IDLE → LINK_ESTABLISHING → LINK_READY → REQUEST_SENT → RESPONSE_RECEIVED → RESOURCE_TRANSFERRING → IDLE ### Request Example ```python peer.sync() ``` ``` -------------------------------- ### Thread-Safe Router Interactions Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/api-reference/LXMPeer.md Illustrates thread-safe methods for interacting with LXMPeer objects through the router, contrasting with direct peer access. ```python # Good: Use router methods router.peers[peer_hash].sync() # Access peer attributes read-only unhandled = router.peers[peer_hash].unhandled_message_count # Better: Use router methods where available stats = router.compile_stats() # Thread-safe aggregation ``` -------------------------------- ### Configure Bandwidth Limits Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/configuration.md Optimize LXMF router performance for networks with limited bandwidth. Reduce message sizes, sync limits, and the number of active peers. ```python router = LXMF.LXMRouter( storagepath="/var/lxmf", propagation_limit=128, # Smaller messages propagation_per_sync_limit=2048, # Smaller syncs max_peers=5 # Fewer connections ) ``` -------------------------------- ### LXMPeer.peering_key_ready Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/api-reference/LXMPeer.md Checks if the peering key is valid and meets the requirements for establishing a connection with a peer. ```APIDOC ## LXMPeer.peering_key_ready() ### Description Checks if the peering key is valid and meets the requirements for establishing a connection with a peer. ### Returns - **bool** - True if the key is ready to use, False otherwise. ### Request Example ```python if not peer.peering_key_ready(): peer.generate_peering_key() ``` ``` -------------------------------- ### Configure LXMRouter for Propagation Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/api-reference/LXMRouter.md Sets up an LXMRouter instance with specified storage, naming, and cost parameters. Configures message and information storage limits and enables propagation features. ```python import LXMF import RNS r = RNS.Reticulum() router = LXMF.LXMRouter( storagepath="/var/lxmf", name="Central Hub", propagation_cost=16, peering_cost=18, max_peers=50 ) # Configure storage router.set_message_storage_limit(gigabytes=2) router.set_information_storage_limit(megabytes=500) # Enable propagation router.enable_propagation() router.announce_propagation_node() # Run stats server stats = router.compile_stats() print(f"Node active with {stats['total_peers']} peers") # Keep running while True: time.sleep(60) ``` -------------------------------- ### Command-line Stamp Generation Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/api-reference/LXStamper.md Use the LXStamper module from the command line to generate stamps with a specified cost and number of rounds. The output will display timing information and rounds per second. ```bash python3 -m LXMF.LXStamper 16 3 ``` -------------------------------- ### Check and Generate LXMPeer Peering Key Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/api-reference/LXMPeer.md Verifies if the peering key is ready for use and generates a new one if necessary. A valid peering key is required for secure communication. ```python if not peer.peering_key_ready(): peer.generate_peering_key() ``` -------------------------------- ### get_propagation_stamp(target_cost, timeout=None) Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/api-reference/LXMessage.md Generates a proof-of-work stamp specifically for propagation node delivery. It requires a target cost set by the propagation node and allows for an optional generation timeout. ```APIDOC ## get_propagation_stamp(target_cost, timeout=None) ### Description Generate a stamp specifically for propagation node delivery. ### Parameters #### Path Parameters - **target_cost** (int) - Required - Propagation node's required cost - **timeout** (int or None) - Optional - Maximum generation time ### Request Example ```python pn_stamp = message.get_propagation_stamp(target_cost=16) ``` ### Returns - **bytes or None** - The propagation stamp ``` -------------------------------- ### LXMPeer Synchronization Strategies Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/api-reference/LXMPeer.md Defines constants for different message synchronization strategies. Use STRATEGY_LAZY for on-demand sync or STRATEGY_PERSISTENT for regular scheduled syncs. ```python STRATEGY_LAZY = 0x01 # Sync only on connection STRATEGY_PERSISTENT = 0x02 # Regular scheduled syncs DEFAULT_SYNC_STRATEGY = STRATEGY_PERSISTENT ``` -------------------------------- ### Register Delivery Identity with Options Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/configuration.md Register a new delivery identity with optional display name and stamp cost requirements. ```python delivery_dest = router.register_delivery_identity( identity=ident, display_name="Alice", # Optional friendly name stamp_cost=8 # Optional cost requirement ) ``` -------------------------------- ### Store & Forward vs. Old Way Source: https://github.com/markqvist/lxmf/blob/master/Zen of Reticulum.md Contrasts the traditional synchronous 'request/response' model with the asynchronous 'Store & Forward' approach suitable for Reticulum's network conditions. The 'Old Way' implies blocking operations and timeouts, while the 'Zen Way' emphasizes non-blocking sends and eventual handling. ```pseudocode The Old Way: Connect() -> Send() -> Wait() -> Crash if timeout. The Zen Way: Send() -> Continue living. -> Receive() when it arrives. ``` -------------------------------- ### Enable Auto-Peering Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/configuration.md Configure the LXMF router to automatically discover and connect to other nodes. Set the maximum depth for discovery. ```python router = LXMF.LXMRouter( storagepath="/var/lxmf", autopeer=True, # Enable auto-discovery autopeer_maxdepth=4 # Discover nodes up to 4 hops away ) ``` -------------------------------- ### Peer Synchronization Strategy - Persistent Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/configuration.md Configure the LXMRouter to use the persistent peer synchronization strategy, which is recommended. Peers sync regularly, leading to better message coverage. ```python # Strategy 2: Persistent (recommended) router = LXMF.LXMRouter( storagepath="/var/lxmf", sync_strategy=LXMF.LXMPeer.STRATEGY_PERSISTENT ) # Peers sync regularly, better coverage ``` -------------------------------- ### Set Information Storage Limit Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/api-reference/LXMRouter.md Sets the maximum storage for metadata and peer information. Specify the limit using kilobytes, megabytes, or gigabytes. ```python router.set_information_storage_limit(megabytes=100) ``` -------------------------------- ### Create LXMessage with Reaction Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/types.md Use this snippet to create a reaction message. It requires the original message hash and the reaction content. The reaction is encoded as UTF-8. ```python import LXMF # Original message hash (example) original_msg_hash = bytes.fromhex("abc123...") # Create reaction message reaction = LXMF.LXMessage(dest, source, "", title="") reaction.fields = { LXMF.FIELD_REACTION: { LXMF.REACTION_TO: original_msg_hash, LXMF.REACTION_CONTENT: "👍".encode("utf-8") } } router.handle_outbound(reaction) ``` -------------------------------- ### Peer Statistics Dictionary Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/api-reference/LXMPeer.md Constructs a dictionary containing key statistics for a given LXMPeer. Useful for monitoring and debugging peer performance. ```python stats = { "peer_id": peer.destination_hash.hex(), "alive": peer.alive, "last_heard": peer.last_heard, "sync_strategy": peer.sync_strategy, "messages": { "offered": peer.offered, "outgoing": peer.outgoing, "incoming": peer.incoming, "unhandled": peer.unhandled_message_count }, "transfer_rate": peer.sync_transfer_rate, "rx_bytes": peer.rx_bytes, "tx_bytes": peer.tx_bytes } ``` -------------------------------- ### LXMRouter Constructor Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/api-reference/LXMRouter.md Initializes an LXMRouter instance. This is the central message handling engine for LXMF applications, managing message routing, delivery, propagation node peering, and storage. ```APIDOC ## LXMRouter Constructor ### Description Initializes an LXMRouter instance. This is the central message handling engine for LXMF applications, managing message routing, delivery, propagation node peering, and storage. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **identity** (RNS.Identity or None) - Optional - Reticulum identity (auto-created if None) - **storagepath** (str) - Required - Directory path for message storage - **autopeer** (bool) - Optional - Automatically discover and peer with other propagation nodes (Default: True) - **autopeer_maxdepth** (int) - Optional - Max hops to auto-peer (0-255) (Default: 4) - **propagation_limit** (int) - Optional - Max kilobytes per propagation transfer (Default: 256) - **delivery_limit** (int) - Optional - Max kilobytes per delivery transfer (Default: 1000) - **sync_limit** (int) - Optional - Max kilobytes per peer sync (Default: 10240) - **enforce_ratchets** (bool) - Optional - Require message ratcheting for decryption (Default: False) - **enforce_stamps** (bool) - Optional - Require proof-of-work stamps on all inbound (Default: False) - **static_peers** (list of bytes) - Optional - Pre-configured peer destination hashes (Default: []) - **max_peers** (int) - Optional - Maximum peering connections (0=unlimited) (Default: 20) - **from_static_only** (bool) - Optional - Only accept messages from static peers (Default: False) - **sync_strategy** (int) - Optional - LXMPeer.STRATEGY_LAZY or STRATEGY_PERSISTENT (Default: PERSISTENT) - **propagation_cost** (int) - Optional - Proof-of-work cost for propagated messages (Default: 16) - **propagation_cost_flexibility** (int) - Optional - Flexibility in cost acceptance (Default: 3) - **peering_cost** (int) - Optional - Proof-of-work cost to establish peering (Default: 18) - **max_peering_cost** (int) - Optional - Maximum peering cost to accept (Default: 26) - **name** (str or None) - Optional - Display name for propagation node (Default: None) ``` -------------------------------- ### LXMPeer.generate_peering_key Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/api-reference/LXMPeer.md Generates a proof-of-work peering key for the current peer. This is a computationally intensive operation. ```APIDOC ## LXMPeer.generate_peering_key() ### Description Generates a proof-of-work peering key for the current peer. This is a computationally intensive operation. ### Returns - **bool** - True if the key generation was successful, False otherwise. ### Request Example ```python success = peer.generate_peering_key() if success: print(f"Key value: {peer.peering_key_value()}") ``` ``` -------------------------------- ### Import LXMF Module Components Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/README.md Imports essential classes and constants from the LXMF library for use in your application. Ensure these are available in your environment. ```python from LXMF import ( LXMessage, LXMRouter, LXMPeer, APP_NAME, FIELD_*, AM_*, RENDERER_*, PN_META_*, SF_*, display_name_from_app_data(), stamp_cost_from_app_data(), compression_support_from_app_data(), pn_name_from_app_data(), pn_stamp_cost_from_app_data(), pn_announce_data_is_valid() ) ``` -------------------------------- ### prioritise Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/api-reference/LXMRouter.md Marks a destination for preferential treatment during message store cleanup. ```APIDOC ## prioritise(destination_hash) ### Description Marks a destination for preferential treatment in message store cleanup. ### Parameters #### Path Parameters - **destination_hash** (bytes) - Required - 16-byte destination hash ### Method Not applicable (SDK method) ### Endpoint Not applicable (SDK method) ``` -------------------------------- ### Compile Node and Peer Statistics Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/api-reference/LXMRouter.md Compiles comprehensive statistics about the node and its peers. Returns a dictionary of statistics or None if not a propagation node. ```python stats = router.compile_stats() print(f"Uptime: {stats['uptime']} seconds") print(f"Total peers: {stats['total_peers']}") print(f"Messages stored: {stats['messagestore']['count']}") ``` -------------------------------- ### Error Handling for Stamp Generation Source: https://github.com/markqvist/lxmf/blob/master/_autodocs/api-reference/LXStamper.md Demonstrates how to handle potential errors during stamp generation, such as memory issues, worker crashes, or timeouts. It uses a try-except block to catch exceptions. ```python try: stamp, value = LXStamper.generate_stamp(msg_id, cost=20) if stamp is None: print("Stamp generation failed or timed out") except Exception as e: print(f"Error generating stamp: {e}") ```