Skip to content

Repository files navigation

Lexe Wrapper

A simple Python package for integrating Bitcoin Lightning Network payments using the Lexe wallet. Install with pip and start building Lightning apps in under 30 seconds.

pip install lexe-wrapper

⚠️ Important: This is an unofficial, open-source wrapper around the Lexe Sidecar SDK. It is not officially associated with or endorsed by Lexe. This project is independently developed to help developers integrate with Lexe's Lightning wallet services.

What This Package Solves

The Lexe Sidecar API is already clean and simple, but there are several setup gotchas that slow down development:

  1. Binary Management: Downloading and extracting the correct Lexe sidecar binary
  2. Process Management: Starting and stopping the sidecar subprocess
  3. Credentials Handling: Properly encoding and validating base64 client credentials
  4. Connection Management: Ensuring the sidecar is healthy and ready to accept requests
  5. Port Configuration: Managing the correct port (5393) for communication

This package handles all of these automatically, so you can focus on building great Lightning applications.

Dependencies: When you install lexe-wrapper, the requests library is automatically installed as a dependency. If you're just copying code examples without installing the package, you'll need: pip install requests

⚡ Quick Start (30 seconds)

1. Install from PyPI

pip install lexe-wrapper

This automatically installs all required dependencies including requests.

2. Set Your Lexe Credentials

export LEXE_CLIENT_CREDENTIALS="your_base64_encoded_credentials_here"

Need credentials? Get them from the Lexe mobile app - create a wallet and export client credentials.

3. Start Building Lightning Apps

Copy-Paste Example

fromlexe_wrapperimportLexeManagerimportrequests# Automatic setup and cleanupwithLexeManager() aslexe:
lexe.start_sidecar() # Downloads binary, starts process, health checks# CRITICAL FIRST STEP: Verify connection to your node# Always perform a health check after starting the sidecarhealth_response=requests.get("http://localhost:5393/v2/health")
ifhealth_response.status_code==200:
print("✅ Successfully connected to Lexe node!")
else:
print("❌ Failed to connect - check your credentials")
exit(1)
# Now get node info and balancenode_response=requests.get("http://localhost:5393/v2/node/node_info")
node_info=node_response.json()
print(f"💰 Wallet balance: {node_info['balance']} sats")
# Create a Lightning invoice (uses standard Lexe API at localhost:5393)response=requests.post("http://localhost:5393/v2/node/create_invoice", json={
"amount": "1000", "description": "Test payment",
"expiration_secs": 3600# 1 hour expiration
})
invoice_data=response.json()
# CRITICAL: Store payment index for monitoring payment completionpayment_index=invoice_data['index'] # Save this! (alphanumeric string, not integer)invoice_string=invoice_data['invoice']
print(f"⚡ Lightning invoice created successfully!")
print(f"📋 Invoice: {invoice_string[:50]}...")
print(f"🔍 Payment index (save this): {payment_index}")
# Quick example of checking payment status (see detailed example below)importtimetime.sleep(2) # Wait a moment before checking# Check payment status - V2 API returns payment at root levelstatus_response=requests.get(
f"http://localhost:5393/v2/node/payment?index={payment_index}"
)
payment=status_response.json() # V2 API: Payment data at root levelifpayment['status'] =='pending':
print("⏳ Payment is pending...")
elifpayment['status'] =='completed':
print("✅ Payment received!")
# Sidecar automatically stops when exiting the context

That's it! Lightning payments are now working in your Python app. 🎉

🚨 Payment Tracking (CRITICAL - READ THIS FIRST!)

Most developers miss this crucial step: After creating an invoice, you MUST properly monitor for payment completion. This is the #1 integration issue.

⚠️ Index vs Hash - Critical Distinction

🚨 IMPORTANT: Use the `index` field, NOT payment_hash!

Unlike most Lightning APIs that use payment hashes, Lexe uses an index field (alphanumeric string) for payment tracking:
  • ✅ CORRECT: Use invoice_data['index'] from invoice creation - this is a string like "abc123def456"
  • ❌ WRONG: Do NOT use payment_hash or invoice string for status checks

Complete Payment Lifecycle Example

fromlexe_wrapperimportLexeManagerimportrequestsimporttimewithLexeManager() aslexe:
lexe.start_sidecar()
# CRITICAL FIRST STEP: Verify connection to your node# Always perform a health check after starting the sidecarhealth_response=requests.get("http://localhost:5393/v2/health")
ifhealth_response.status_code==200:
print("✅ Successfully connected to Lexe node!")
else:
print("❌ Failed to connect - check your credentials")
exit(1)
# Step 1: Create invoice and GET THE INDEXresponse=requests.post("http://localhost:5393/v2/node/create_invoice", json={
"amount": "10000", # 10,000 sats"description": "Payment for order #123",
"expiration_secs": 600# 10 minutes
})
invoice_data=response.json()
# Step 2: CRITICAL - Store the payment index (NOT the invoice string!)payment_index=invoice_data['index'] # ← THIS IS WHAT YOU NEED! (alphanumeric string)invoice_string=invoice_data['invoice'] # This is for the payerprint(f"⚡ Invoice created: {invoice_string[:50]}...")
print(f"📍 Payment Index: {payment_index}") # Save this to your database!# Step 3: Monitor for payment completionprint("⏳ Waiting for payment...")
timeout=time.time() +600# 10 minute timeoutwhiletime.time() <timeout:
# Check payment status using the INDEXstatus_response=requests.get(
f"http://localhost:5393/v2/node/payment?index={payment_index}"
)
# Step 4: V2 API returns payment data at root level (no nesting)payment=status_response.json() # V2 API: Direct access, no nested structure# Check the status directlyifpayment['status'] =='completed': # ← "completed" NOT "settled"!print(f"✅ Payment received: {payment['amount']} sats")
# Update your database, trigger order fulfillment, etc.breakelifpayment['status'] =='failed':
print("❌ Payment failed")
breakelifpayment['status'] =='cancelled':
print("🚫 Payment cancelled")
breaktime.sleep(2) # Poll every 2 secondselse:
print("⏰ Payment timeout - invoice expired")

API Response Structure (V2 API)

With V2 API: The payment status endpoint now returns data at the root level (simplified structure):

{
"index": "payment_12345",
"status": "completed", // or "pending", "failed", "cancelled", "expired""amount": "10000",
"description": "Payment for order #123",
"created_at": "2024-01-01T12:00:00Z",
"paid_at": "2024-01-01T12:05:00Z"
}

V2 API - Direct access (no nesting):

# V2 API - Direct access at root levelpayment=response.json() # Payment data is at root levelifpayment['status'] =='completed':
# Process successful payment

Payment Status Values

StatusMeaningAction Required
pendingInvoice created, awaiting paymentContinue polling
completed✅ Payment received successfullyStop polling, fulfill order
failedPayment attempt failedStop polling, handle failure
cancelledInvoice was cancelledStop polling
expiredInvoice expired without paymentStop polling

Important: The successful payment status is completed, NOT settled (common Lightning convention).

Database Storage Pattern

-- Store payment tracking data properlyCREATETABLElightning_payments (
id SERIALPRIMARY KEY,
payment_index VARCHAR(255) UNIQUE NOT NULL, -- Critical: store the index!
invoice_string TEXTNOT NULL, -- For displaying to payer
amount_sats BIGINTNOT NULL,
description TEXT,
status VARCHAR(50) DEFAULT 'pending',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
paid_at TIMESTAMP,
metadata JSONB
);
-- Example: After creating invoiceINSERT INTO lightning_payments (payment_index, invoice_string, amount_sats, description)
VALUES ($1, $2, $3, $4)
RETURNING id;
-- Example: Check statusUPDATE lightning_payments SET status ='completed', paid_at = NOW()
WHERE payment_index = $1;

Quick API Reference

Key Endpoints You'll Use

EndpointMethodPurposeCritical Notes
/v2/node/create_invoicePOSTCreate Lightning invoiceReturns index field - SAVE THIS!
/v2/node/payment?index={index}GETCheck payment statusUse index from invoice creation
/v2/node/node_infoGETGet node info & balanceReturns balance in sats
/v2/node/pay_invoicePOSTPay a Lightning invoiceSend payments
/v2/node/decode_invoicePOSTDecode invoice detailsValidate before paying

Quick Integration Patterns

Basic Web App Setup

fromlexe_wrapperimportLexeManager# Initialize once when your web app startslexe=LexeManager()
lexe.start_for_webapp() # Robust startup with error handling# Use throughout your app's lifetime@app.route('/create-invoice', methods=['POST'])defcreate_invoice():
response=requests.post("http://localhost:5393/v2/node/create_invoice", json=request.json)
invoice_data=response.json()
# ALWAYS save the index for payment tracking!save_to_database(invoice_data['index'], invoice_data['invoice'])
returninvoice_data# Stop when app shuts downlexe.stop_sidecar()

Manual Management

fromlexe_wrapperimportLexeManagerlexe=LexeManager()
try:
lexe.start_sidecar()
iflexe.check_health():
print("Lexe is ready!")
# Get node info using the wrapper methodnode_info=lexe.get_node_info()
print(f"Balance: {node_info['balance']} sats")
finally:
lexe.stop_sidecar()

For Coding Agents

When using this package in automated coding environments:

Essential Setup Steps

  1. Install package: pip install lexe-wrapper
  2. Set credentials: export LEXE_CLIENT_CREDENTIALS="your_credentials"
  3. Import and start: Use the context manager pattern for automatic cleanup

Example Implementation

fromlexe_wrapperimportLexeManagerimportrequestsdefsetup_lexe_integration():
"""Initialize Lexe for your application"""lexe=LexeManager()
lexe.start_sidecar() # Downloads binary, starts process, waits for healthreturn"http://localhost:5393"# Ready to use Lexe APIdefcreate_lightning_invoice(amount_sats, description):
"""Create a Lightning invoice using Lexe API"""response=requests.post("http://localhost:5393/v2/node/create_invoice", json={
"amount": str(amount_sats),
"description": description
})
returnresponse.json()
# The package handles all the complexity - just use the API directly!

Key Benefits for Automation

  • Standard pip installation - pip install lexe-wrapper (published on PyPI)
  • Clean imports - from lexe_wrapper import LexeManager
  • Zero configuration files needed - everything is handled programmatically
  • Automatic binary management - downloads and extracts the right version
  • Built-in health checks - ensures the connection is ready before returning
  • Error handling - clear error messages when credentials are invalid or missing
  • Process lifecycle management - clean startup and shutdown

Advanced Usage

For Development from Source

If you want to contribute or modify the package:

git clone https://github.com/lexe-app/lexe-wrapper.git
cd lexe-wrapper
pip install -e .

⚡ Payment Monitoring (Critical Information)

Based on real developer feedback, here are the essential patterns for monitoring Lightning payments:

🚨 Critical Fixes (Must Read!)

1. Payment Status Value

# ❌ WRONG - Common mistake from Lightning conventionsifpayment['status'] =='settled': # This will never match!# ✅ CORRECT - Lexe API returns 'completed'ifpayment['status'] =='completed': # This is the right status value

2. Store Payment Index

# When creating invoice, MUST store the 'index' field!response=requests.post("http://localhost:5393/v2/node/create_invoice", json={...})
invoice_data=response.json()
# CRITICAL: Store this for payment monitoringpayment_index=invoice_data['index'] # Required for status checking (alphanumeric string)payment_hash=invoice_data['payment_hash'] # Also recommended

3. Correct API Endpoint

# Correct endpoint for payment statusendpoint=f"http://localhost:5393/v2/node/payment?index={payment_index}"response=requests.get(endpoint)

Complete Working Example

fromlexe_wrapperimportLexeManagerimportrequestsimporttimedefcomplete_payment_flow():
withLexeManager() aslexe:
lexe.start_sidecar()
# 1. Create invoice and store essential fieldsinvoice_response=requests.post("http://localhost:5393/v2/node/create_invoice", json={
"amount": "1000",
"description": "Premium subscription",
"expiration_secs": 3600
})
invoice_data=invoice_response.json()
# CRITICAL: Store these fields in your databasepayment_record= {
'invoice': invoice_data['invoice'], # BOLT11 for user'payment_hash': invoice_data['payment_hash'], # Unique ID'payment_index': invoice_data['index'], # REQUIRED for monitoring (alphanumeric string)'amount': 1000,
'status': 'pending'
}
# 2. Show invoice to userprint(f"Pay this: {payment_record['invoice']}")
# 3. Monitor payment completionpayment_index=payment_record['payment_index']
whileTrue:
# Check payment status using correct endpointresponse=requests.get(f"http://localhost:5393/v2/node/payment?index={payment_index}")
ifresponse.status_code==200:
payment_data=response.json()
payment=payment_data# V2: Direct payment data at root# CORRECT: Check for 'completed' statusifpayment['status'] =='completed':
print(f"🎉 Payment received! Amount: {payment['amount']} sats")
# Update your database: status = 'completed'breakelifpayment['status'] =='pending':
print("⏳ Still waiting...")
time.sleep(3) # Check every 3 secondselse:
print(f"❌ Payment failed: {payment['status']}")
breakelse:
print("Error checking payment status")
break

Web App Integration (Flask)

@app.route('/create-invoice', methods=['POST'])defcreate_invoice():
response=requests.post("http://localhost:5393/v2/node/create_invoice", json=request.json)
invoice_data=response.json()
# CRITICAL: Store payment_index for monitoring# Save to your database: invoice_data['index']return {'invoice': invoice_data['invoice'], 'payment_index': invoice_data['index']}
@app.route('/check-payment/<payment_index>')defcheck_payment_status(payment_index):
try:
response=requests.get(f'http://localhost:5393/v2/node/payment?index={payment_index}')
ifresponse.status_code==200:
payment=response.json() # V2: Direct payment data at root# CRITICAL: Check for 'completed' not 'settled'return {
'paid': payment['status'] =='completed',
'status': payment['status'],
'amount': payment['amount']
}
else:
return {'error': 'Payment not found'}, 404exceptExceptionase:
return {'error': str(e)}, 500

Database Schema Recommendations

-- Store these fields when creating invoicesCREATETABLElightning_payments (
id SERIALPRIMARY KEY,
invoice TEXTNOT NULL, -- BOLT11 string
payment_hash TEXTNOT NULL, -- Unique payment identifier 
payment_index TEXTNOT NULL, -- REQUIRED for status checking
amount_sats INTEGERNOT NULL,
description TEXT,
status VARCHAR(20) DEFAULT 'pending', -- pending, completed, failed
created_at TIMESTAMP DEFAULT NOW(),
finalized_at TIMESTAMP,
UNIQUE(payment_index)
);

📁 See examples/correct_payment_flow.py for complete, tested examples.

API Reference

LexeManager Class

Constructor

fromlexe_wrapperimportLexeManagerLexeManager(client_credentials=None, port=5393)
  • client_credentials: Base64 encoded credentials (uses LEXE_CLIENT_CREDENTIALS env var if None)
  • port: Port for sidecar to listen on (default: 5393)

Methods

start_sidecar(wait_for_health=True, health_timeout=30)

  • Downloads binary if needed, starts process, optionally waits for health check
  • Returns: bool - True if started successfully

start_for_webapp(health_timeout=30)

  • Web app specific startup with robust error handling
  • Returns: bool - True if started successfully
  • Raises: RuntimeError if startup fails

stop_sidecar()

  • Gracefully stops the sidecar process
  • Returns: bool - True if stopped successfully

check_health()

  • Checks if sidecar is responding to health checks
  • Returns: bool - True if healthy

ensure_running()

  • Ensures sidecar is running and healthy (great for health check endpoints)
  • Returns: bool - True if running and healthy

restart_if_needed()

  • Restarts sidecar if not running or unhealthy
  • Returns: bool - True if now running and healthy

get_node_info()

  • Gets node information from Lexe API
  • Returns: dict - Node information including balance, channels, etc.

is_running()

  • Checks if the sidecar process is currently running
  • Returns: bool - True if running

CLI Reference

The package includes a command-line interface for testing and development:

# Using the installed package
python -m lexe_wrapper <command> [options]
# Or directly (if you cloned the repo)
python cli.py <command> [options]
Commands:
start Start the sidecar
stop Stop the sidecar status Show sidecar status
health Check sidecar health
node-info Get node information
download Download sidecar binary only
Options:
--credentials TEXT Override credentials from env var
--port INTEGER Port for sidecar (default: 5393)
--timeout INTEGER Health check timeout (default: 30)
--no-wait Don't wait for health check when starting --verbose Enable verbose logging

Web App Integration (Long-Lived Connections)

The wrapper is specifically designed to support long-lived connections for web applications. Here's how to integrate it:

Flask Example

fromflaskimportFlask, jsonify, requestfromlexe_managerimportLexeManagerimportrequestsimportatexitapp=Flask(__name__)
# Global Lexe manager instancelexe_manager=Nonedefinit_lexe():
"""Initialize Lexe sidecar when app starts"""globallexe_managerlexe_manager=LexeManager()
try:
# Use the web app specific startup methodlexe_manager.start_for_webapp(health_timeout=30)
print("✅ Lexe sidecar started successfully")
returnTrueexceptRuntimeErrorase:
print(f"❌ Failed to start Lexe: {e}")
returnFalsedefcleanup_lexe():
"""Clean shutdown when app stops"""globallexe_manageriflexe_manager:
lexe_manager.stop_sidecar()
print("🛑 Lexe sidecar stopped")
# Initialize Lexe when app startswithapp.app_context():
ifnotinit_lexe():
exit(1)
# Register cleanup functionatexit.register(cleanup_lexe)
@app.route('/health')defhealth_check():
"""App health check - includes Lexe status"""iflexe_managerandlexe_manager.ensure_running():
returnjsonify({"status": "healthy", "lexe": "connected"})
else:
returnjsonify({"status": "degraded", "lexe": "disconnected"}), 503@app.route('/node-info')defnode_info():
"""Get Lexe node information"""try:
# Use direct API call (the whole point of this wrapper!)response=requests.get("http://localhost:5393/v2/node/node_info", timeout=10)
response.raise_for_status()
returnjsonify(response.json())
exceptExceptionase:
returnjsonify({"error": str(e)}), 500@app.route('/create-invoice', methods=['POST'])defcreate_invoice():
"""Create a Lightning invoice"""try:
amount=request.json.get('amount', '1000')
description=request.json.get('description', 'Payment')
# Direct Lexe API usageresponse=requests.post("http://localhost:5393/v2/node/create_invoice", json={
"amount": str(amount),
"description": description
}, timeout=15)
response.raise_for_status()
returnjsonify(response.json())
exceptExceptionase:
returnjsonify({"error": str(e)}), 500@app.route('/restart-lexe', methods=['POST'])defrestart_lexe():
"""Restart Lexe if having issues"""iflexe_managerandlexe_manager.restart_if_needed():
returnjsonify({"status": "restarted"})
else:
returnjsonify({"error": "restart failed"}), 500if__name__=='__main__':
app.run(host='0.0.0.0', port=5000)

FastAPI Example

fromfastapiimportFastAPI, HTTPExceptionfromcontextlibimportasynccontextmanagerfromlexe_managerimportLexeManagerimportrequests# Global Lexe managerlexe_manager=None@asynccontextmanagerasyncdeflifespan(app: FastAPI):
# Startupgloballexe_managerlexe_manager=LexeManager()
try:
lexe_manager.start_for_webapp()
print("✅ Lexe sidecar started")
yieldexceptRuntimeErrorase:
print(f"❌ Lexe startup failed: {e}")
raisefinally:
# Shutdowniflexe_manager:
lexe_manager.stop_sidecar()
print("🛑 Lexe sidecar stopped")
app=FastAPI(lifespan=lifespan)
@app.get("/health")defhealth_check():
iflexe_managerandlexe_manager.ensure_running():
return {"status": "healthy", "lexe": "connected"}
raiseHTTPException(503, "Lexe not available")
@app.post("/invoices")defcreate_invoice(amount: int, description: str="Payment"):
try:
response=requests.post("http://localhost:5393/v2/node/create_invoice",
json={"amount": str(amount), "description": description})
response.raise_for_status()
returnresponse.json()
exceptExceptionase:
raiseHTTPException(500, str(e))

Complete Flask Example with Real-Time Monitoring

We've included a production-ready Flask application that demonstrates proper payment tracking:

# Run the complete example
python examples/flask_payment_app.py

This example includes:

  • ✅ Correct use of index field for payment tracking
  • ✅ Background thread monitoring for payment completion
  • ✅ SQLite database for payment storage
  • ✅ Web UI with real-time status updates
  • ✅ Proper error handling and timeouts
  • ✅ Clear documentation of the critical integration points

See examples/flask_payment_app.py for the complete implementation.

Web App Best Practices

  1. Startup Pattern: Use start_for_webapp() during app initialization
  2. Health Monitoring: Use ensure_running() in your health check endpoints
  3. Recovery: Use restart_if_needed() for automatic recovery
  4. Shutdown: Ensure stop_sidecar() is called when your app shuts down
  5. Direct API Usage: Once started, use standard HTTP requests to localhost:5393
  6. Payment Tracking: ALWAYS save the index field and use it for status checks

Process Management for Production

importsignalimportsysfromlexe_managerimportLexeManager# Global manager for signal handlerslexe_manager=Nonedefsignal_handler(signum, frame):
"""Handle shutdown signals gracefully"""globallexe_managerprint("🔄 Received shutdown signal, stopping Lexe...")
iflexe_manager:
lexe_manager.stop_sidecar()
sys.exit(0)
# Register signal handlers for graceful shutdownsignal.signal(signal.SIGINT, signal_handler) # Ctrl+Csignal.signal(signal.SIGTERM, signal_handler) # Docker/systemd stopdefmain():
globallexe_managerlexe_manager=LexeManager()
# Start for long-lived operationlexe_manager.start_for_webapp()
# Your web app code here# The sidecar stays running until explicitly stopped

🎯 QR Code Generation for Lightning Invoices

IMPORTANT: Your UI must display both a QR code AND the invoice text for copying. The QR code should encode the Lightning invoice text string (BOLT11 format) that you receive from the create_invoice API call.

Use JavaScript to Generate QR Codes

Always generate QR codes on the frontend using JavaScript. Here's the single recommended approach:

<!DOCTYPE html><html><head><title>Lightning Payment</title><scriptsrc="https://cdn.jsdelivr.net/npm/qrcodejs@1.0.0/qrcode.min.js"></script></head><body><divid="qrcode"></div><pid="invoice-text"></p><script>// After creating invoice with lexe-wrapper backendfetch('/api/create-invoice',{method: 'POST',headers: {'Content-Type': 'application/json'},body: JSON.stringify({amount: 1000,description: 'Coffee'})}).then(response=>response.json()).then(data=>{// Generate QR code from Lightning invoicenewQRCode(document.getElementById("qrcode"),{text: data.invoice,// The BOLT11 invoice stringwidth: 256,height: 256,colorDark: "#000000",colorLight: "#ffffff",correctLevel: QRCode.CorrectLevel.M// 15% error correction});// Also show invoice text for manual copydocument.getElementById('invoice-text').textContent=data.invoice;});</script></body></html>

What the QR Code Contains

The QR code should contain ONLY the Lightning invoice text string (BOLT11 format) that you get from the invoice field of the create_invoice response. Do NOT encode JSON or any other data format - just the raw invoice string.

Complete Working Example

See examples/payment_qr_demo.html for a fully functional payment page with QR code generation.

After Starting the Sidecar

Once the wrapper starts the sidecar, you can use the standard Lexe Sidecar API directly:

  • Health: GET http://localhost:5393/v2/health
  • Node Info: GET http://localhost:5393/v2/node/node_info
  • Create Invoice: POST http://localhost:5393/v2/node/create_invoice
  • Pay Invoice: POST http://localhost:5393/v2/node/pay_invoice
  • Check Payment: GET http://localhost:5393/v2/node/payment?index=<index>

Error Handling

The wrapper provides clear error messages for common issues:

  • Missing credentials: Clear message about setting LEXE_CLIENT_CREDENTIALS
  • Invalid credentials: Validates base64 format and provides specific error
  • Download failures: Network issues when downloading the binary
  • Health check failures: When sidecar doesn't respond within timeout
  • Process management: Issues starting or stopping the sidecar process

Package Structure

lexe-wrapper/
├── lexe_wrapper/ # Main package
│ ├── __init__.py # Package exports LexeManager
│ ├── manager.py # Core LexeManager class
│ └── __main__.py # CLI entry point
├── examples/ # Usage examples
│ └── simple_usage.py # Simple integration examples
├── setup.py # Package installation
├── pyproject.toml # Modern Python packaging
└── README.md # This documentation

Requirements

  • Python 3.7+
  • requests library (automatically installed as dependency)
  • x86_64 Linux environment (where Lexe sidecar runs)
  • Valid Lexe client credentials

Contributing

Contributions are welcome! This is an open-source project and we encourage community involvement:

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests if applicable
  5. Submit a pull request

Code of Conduct: Please be respectful and constructive in all interactions.

License

MIT License - This project is free and open-source software. See the LICENSE file for full details.

Copyright (c) 2025 Mat Balez

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software.

About

This package is designed to eliminate the friction in getting started with Lexe Bitcoin Lightning Network integration. The Lexe Sidecar API itself is excellent - this package just handles the setup complexity so you can focus on building great Lightning applications.

Key Design Principles:

  • Standard Python packaging - Install with pip, import normally
  • Minimal dependencies - Only requires requests
  • Clean API surface - Simple import, clear methods
  • Production ready - Proper error handling, logging, and lifecycle management
  • Direct API access - No unnecessary abstraction over the Lexe Sidecar API

Open Source & Legal

📝 License: This project is released under the MIT License, making it free to use, modify, and distribute.

⚖️ Disclaimer: This is an unofficial, community-developed wrapper around the Lexe Sidecar SDK. It is not officially associated with, endorsed by, or supported by Lexe. This project was independently created to help Python developers integrate with Lexe's Lightning wallet services more easily.

🔧 Open Source:

  • Source Code: Available on GitHub for transparency and community contributions
  • Issues & Contributions: Welcome! Please submit bug reports and feature requests
  • No Warranty: Provided "as is" - please review the code and test thoroughly before production use

🔗 Official Lexe Resources:

Author

Created and maintained by Mat Balez

This project was developed to help the Python community easily integrate Bitcoin Lightning Network payments using Lexe's excellent infrastructure, with a focus on eliminating common setup friction points.

Releases

Packages

Contributors

Languages