Lexe CLI
The Lexe CLI allows you to create and control self-custodial, always-online Lightning wallets from the command line.
With a single command $ lexe init, the Lexe CLI will generate a root seed,
save it to ~/.lexe/seedphrase.txt, register an anonymous account with Lexe,
and set up a mainnet Lightning node running inside a secure enclave inside
Lexe's infrastructure, where only you have access to the funds. Your Lightning
node is always online to receive payments, even if you aren't. Furthermore, node
hosting is free.
Install
Quickstart
Option 1: Create a new wallet
The seedphrase is saved to ~/.lexe/seedphrase.txt and auto-loaded on
subsequent runs. Be sure to back up your seedphrase to a safe place.
Option 2: Control an existing wallet
Export credentials from the Lexe app (Menu > Client credentials), then set via:
LEXE_CLIENT_CREDENTIALS- Set in environment or.envfile--client-credentials- Pass directly in CLI--client-credentials-path- Provide a path to a file with credentials
Verify your setup:
Agentic payments: L402, MPP, and beyond
The Lexe CLI is designed for agents and is compatible with machine-payment
protocols like L402 and Stripe's
Machine Payments Protocol (MPP). These agentic payments
protocols gate a resource behind a Lightning payment and use the payment
preimage as proof-of-payment.
One-shot payments (Spec: L402, MPP charge). The server answers an unpaid request
with 402 Payment Required and a BOLT 11 invoice. The agent pays it, reads back
the preimage, and replays the request with it (e.g. via L402's
Authorization: L402 <macaroon>:<preimage> header):
# Pay the invoice from the 402 challenge.
# The preimage serves as proof-of-payment.
preimage=$(lexe pay-invoice <invoice> | jq -r .preimage)
Sessions (Spec: MPP session). For streaming,
pay-as-you-go billing, the agent funds a session up front and tops it up with
further payments as the balance drains — each top-up is just another
pay-invoice. Unused balance is refunded back to the agent, received with
create-invoice.
Scripting
The CLI is fully scriptable: most commands output JSON (always or via a --json
flag), so you can pipe results straight into tools like jq. Results
are printed to stdout and logs go to stderr, so piping never mixes the two.
Demo
In this demo, we set up the CLI in less than 20 seconds - install the CLI, create a mainnet wallet, and generate an invoice.
Commands and CLI Options
See the top-level CLI help with $ lexe --help:
Lexe CLI - Create and control Lightning wallets from the command line.
Lexe wallets are self-custodial and always online to receive payments.
Create a new mainnet wallet:
$ lexe init
The seedphrase is saved to ~/.lexe/seedphrase.txt and auto-loaded on
subsequent runs. Be sure to back up your seedphrase to a safe place.
Control a wallet created from the Lexe mobile app:
Export credentials from the app (Menu > SDK clients), then set via:
• LEXE_CLIENT_CREDENTIALS Set in environment or .env file
• --client-credentials Pass directly in CLI
• --client-credentials-path Path to file with client credentials
Verify your setup, view balance:
$ lexe node-info
Receive:
$ lexe create-invoice
$ lexe wait-for-payment <index> # 0000001778115215123-ln_e1f8e...
Send:
$ lexe pay-invoice <invoice> # lnbc10u1p5...
List payments:
$ lexe sync-payments # Sync payments to local storage
$ lexe list-payments # List payments in local storage
Precedence: CLI args > env vars > .env
`.env` is loaded from the current or any parent directory.
Usage: $ lexe [OPTIONS] <COMMAND>
Commands:
init Create a new Lexe wallet
signup Register with Lexe and perform initial provisioning
provision Provision wallet to latest enclave releases
node-info Get information about this Lexe node
analyze Get information about a Bitcoin or Lightning payment string
pay Pay a Bitcoin or Lightning payment string
create-invoice Create a BOLT 11 invoice to receive a Lightning payment
pay-invoice Pay a BOLT 11 invoice over Lightning
create-offer Create a BOLT 12 offer to receive Lightning payments
pay-offer Pay a BOLT 12 offer over Lightning
pay-lnurl Pay to an LNURL-pay endpoint
withdraw-lnurl Withdraw from an LNURL-withdraw endpoint
get-payment Get a payment by its created index
get-updated-payments Get payments which were updated past a specified index
wait-for-payment Wait for a payment to reach a terminal state
update-personal-note Update the personal note on an existing payment
sync-payments Sync payments from the node to the local payments cache
list-payments List payments from local storage
clear-payments Clear all locally cached payment data for this wallet
export Export this wallet's seedphrase as 24 words
help Print this message or the help of the given subcommand(s)
Options:
--network <NETWORK>
The bitcoin network to use. [default: mainnet]
[env: LEXE_NETWORK=]
[possible values: mainnet, testnet3, regtest]
--client-credentials <CLIENT_CREDENTIALS>
The client credentials string exported from the Lexe app. [env: LEXE_CLIENT_CREDENTIALS]
--client-credentials-path <CLIENT_CREDENTIALS_PATH>
Path to a file containing the client credentials. [env: LEXE_CLIENT_CREDENTIALS_PATH]
--root-seed <ROOT_SEED>
Root seed as a 64-character hex string. [env: LEXE_ROOT_SEED]
--root-seed-path <ROOT_SEED_PATH>
Path to a file containing the root seed (hex or mnemonic). [env: LEXE_ROOT_SEED_PATH]
--lexe-data-dir <LEXE_DATA_DIR>
Data directory for persisted state. [default: ~/.lexe] [env: LEXE_DATA_DIR]
--rust-log <RUST_LOG>
Log level: error, warn, info, debug, trace. [default: info] [env: RUST_LOG]
--without-db
Use wallet without local payments persistence
-h, --help
Print help (see a summary with '-h')
Command Reference
For any command, see detailed help with $ lexe <command> --help.
init
Creates a new Lexe wallet.
Generates a fresh seedphrase, persists it to the Lexe data dir,
registers a wallet with Lexe, and provisions a new user node.
Idempotent: safe to call multiple times.
Usage: $ lexe init
Options:
-h, --help
Print help (see a summary with '-h')
signup
Register with Lexe and perform initial provisioning.
Requires the root seed.
This command exists mostly to support specialized flows.
`lexe init` is usually what you want instead.
Idempotent: safe to call even if already signed up.
Usage: $ lexe signup [OPTIONS]
Options:
--partner-pk <PARTNER_PK>
Partner public key (hex) to earn a share of this wallet's fees
-h, --help
Print help (see a summary with '-h')
provision
Ensure the wallet is provisioned to all recent trusted releases.
Should be called every time the wallet is loaded to ensure the node
is running the most up-to-date enclave software.
Idempotent: safe to call multiple times.
Usage: $ lexe provision
Options:
-h, --help
Print help (see a summary with '-h')
node-info
analyze
Get information about a Bitcoin or Lightning payment string and its
constituent payment and claim methods (if any). Returned information includes
the type of method used (invoice, offer, onchain, lnurl-pay, lnurl-withdraw)
and the amount constraints requested by the counterparty.
Analysis results include either a `payable` or `claimable` field.
Payables (outbound) can be paid using
$ lexe pay <payable>
Claimables (inbound, currently only LNURL-withdraw) can be claimed using
$ lexe withdraw-lnurl <claimable>
Usage: $ lexe analyze [OPTIONS] <PAYMENT_STRING>
Arguments:
<PAYMENT_STRING>
The Bitcoin or Lightning payment string to analyze
Options:
--json
Display output as JSON
--no-qr
Don't render the QR code
--payables-only
Only show payables (outbound payment methods)
--claimables-only
Only show claimables (inbound payment methods)
-h, --help
Print help (see a summary with '-h')
pay
Pay any string which encodes a Bitcoin or Lightning payment method.
If there exist multiple encoded payment methods, one best recommended
payment method will be chosen.
For finer control over how to pay, consider first using
$ lexe analyze
to resolve the contents of the payable string, then invoking the specific
pay command for the payment method of choice:
$ lexe pay-offer ...
$ lexe pay-invoice ...
etc.
Usage: $ lexe pay [OPTIONS] <PAYABLE>
Arguments:
<PAYABLE>
The string to be paid
Options:
--amount-sats <AMOUNT_SATS>
Amount in satoshis.
Optional for payable string with encoded amounts.
--personal-note <PERSONAL_NOTE>
Personal note stored locally, not visible to receiver.
Maximum length: 200 chars / 512 UTF-8 bytes.
--message <MESSAGE>
Message sent to the receiver with the payment.
Supported only if sending to BOLT 12 offers, HBAs pointing to offers,
LNURL recipients whose wallets accept LUD-12 comments, and Lightning
Addresses of wallets that accept LUD-12 comments.
If the payable doesn't support messages, this message will be ignored.
Maximum length: 200 chars / 512 UTF-8 bytes.
-h, --help
Print help (see a summary with '-h')
create-invoice
Create a BOLT 11 invoice to receive a Lightning payment
Usage: $ lexe create-invoice [OPTIONS]
Options:
--amount-sats <AMOUNT_SATS>
Amount in satoshis. Omit for amountless invoice.
--description <DESCRIPTION>
Description to encode in invoice. Visible to sender when scanned.
--personal-note <PERSONAL_NOTE>
Personal note stored locally, not visible to sender.
Maximum length: 200 chars / 512 UTF-8 bytes.
--expiration-secs <EXPIRATION_SECS>
Invoice expiration in seconds. [default: 86400 = 1 day]
--partner-pk <PARTNER_PK>
Partner user_pk for partner-set fees. Required for
partner_prop_fee and partner_base_fee to take effect.
--partner-prop-fee <PARTNER_PROP_FEE>
Partner proportional fee in ppm. Required if partner_pk is set.
Min: 5000 (0.5%),
Max: 500000 (50%)
--partner-base-fee <PARTNER_BASE_FEE>
Partner base fee in satoshis. Requires amount_sats to also be set.
--no-qr
Don't render the QR code
--json
Display output as JSON
-h, --help
Print help
pay-invoice
Pay a BOLT 11 invoice over Lightning
Usage: $ lexe pay-invoice [OPTIONS] <INVOICE>
Arguments:
<INVOICE> The BOLT 11 invoice to pay
Options:
--fallback-amount-sats <FALLBACK_AMOUNT_SATS>
Amount to pay if invoice has no amount.
Required for amountless invoices.
--personal-note <PERSONAL_NOTE>
Personal note stored locally, not visible to receiver.
Maximum length: 200 chars / 512 UTF-8 bytes.
-h, --help
Print help
create-offer
Create a BOLT 12 offer to receive Lightning payments.
Unlike invoices, offers are reusable: multiple payments can be
made to it, including from multiple payers.
Usage: $ lexe create-offer [OPTIONS]
Options:
--description <DESCRIPTION>
Description shown to payers when they scan the offer.
Maximum length: 200 chars / 512 UTF-8 bytes.
--min-amount-sats <MIN_AMOUNT_SATS>
Minimum payment amount in satoshis.
If not set, the payer can send any amount.
--expiration-secs <EXPIRATION_SECS>
Offer expiration in seconds from now
--no-qr
Don't render the QR code
--json
Display output as JSON
-h, --help
Print help (see a summary with '-h')
pay-offer
Pay a BOLT 12 offer over Lightning
Usage: $ lexe pay-offer [OPTIONS] --amount-sats <AMOUNT_SATS> <OFFER>
Arguments:
<OFFER>
The BOLT 12 offer to pay
Options:
--amount-sats <AMOUNT_SATS>
The amount to pay in satoshis.
Must satisfy the offer's minimum amount if set.
--message <MESSAGE>
Message sent to the receiver with the payment.
Maximum length: 200 chars / 512 UTF-8 bytes.
--personal-note <PERSONAL_NOTE>
Personal note stored locally, not visible to receiver.
Maximum length: 200 chars / 512 UTF-8 bytes.
-h, --help
Print help
pay-lnurl
Pay to an LNURL-pay endpoint.
Use `lexe analyze` to get information on amount constraints,
message length limits, and other details of the LNURL-pay endpoint.
Accepted LNURL encodings:
Lightning Address user@domain.com
LUD-17 URI lnurlp://...
bech32 lnurl1...
Lightning URI with bech32 lightning:lnurl1...
Usage: $ lexe pay-lnurl [OPTIONS] --amount-sats <AMOUNT_SATS> <LNURL>
Arguments:
<LNURL>
The LNURL-pay string to pay
Options:
--amount-sats <AMOUNT_SATS>
The amount to pay in satoshis.
Must satisfy the recipient's amount limits if set.
--message <MESSAGE>
Message sent to the receiver with the payment.
Sent only if the recipient accepts LUD-12 comments, and
truncated to their specified length limit if necessary.
--personal-note <PERSONAL_NOTE>
Personal note stored locally, not visible to receiver.
Maximum length: 200 chars / 512 UTF-8 bytes.
-h, --help
Print help (see a summary with '-h')
withdraw-lnurl
Withdraw from an LNURL-withdraw endpoint.
Use `lexe analyze` to get information on amount constraints,
default description, and other details of the LNURL-withdraw endpoint.
Accepted LNURL encodings:
LUD-17 URI lnurlw://...
bech32 lnurl1...
Lightning URI with bech32 lightning:lnurl1...
Usage: $ lexe withdraw-lnurl [OPTIONS] <LNURL>
Arguments:
<LNURL>
The LNURL-withdraw string to withdraw from
Options:
--amount-sats <AMOUNT_SATS>
The amount to withdraw in satoshis.
Must satisfy the endpoint's amount limits.
Defaults to the maximum if not set.
--description <DESCRIPTION>
Description encoded into the withdrawal invoice,
visible to the LNURL endpoint.
Defaults to the endpoint's description if not set.
--personal-note <PERSONAL_NOTE>
Personal note stored locally, not visible to endpoint.
Maximum length: 200 chars / 512 UTF-8 bytes.
-h, --help
Print help (see a summary with '-h')
get-payment
Get a payment by its created index.
Fetches the payment directly from the user node (not from local storage).
Usage: $ lexe get-payment <INDEX>
Arguments:
<INDEX>
The payment's created index
Options:
-h, --help
Print help (see a summary with '-h')
get-updated-payments
Get payments which were updated past a specified index.
Fetches updated payments directly from the user node (not from local storage).
Usage: $ lexe get-updated-payments [OPTIONS]
Options:
--start-index <START_INDEX>
The cursor at which the results should start, exclusive.
If given, payments that were last updated earlier than or
equal to this will not be returned. If omitted, the least
recently updated payments will be returned first.
--limit <LIMIT>
Maximum number of updated payments to return.
Maximum value: 100. Defaults to 50 if not set.
-h, --help
Print help (see a summary with '-h')
wait-for-payment
Wait for a payment to reach a terminal state (completed or failed).
Polls the node with exponential backoff until the payment finalizes
or the timeout is reached. Defaults to 600 seconds (10 minutes).
If already finalized, we still fetch the payment
to ensure we have the latest metadata.
Usage: $ lexe wait-for-payment [OPTIONS] <INDEX>
Arguments:
<INDEX>
The payment index to wait on
Options:
--timeout-secs <TIMEOUT_SECS>
Timeout in seconds. [default: 600, max: 86400]
-h, --help
Print help (see a summary with '-h')
update-personal-note
Update the personal note on an existing payment.
The note is stored on the user node and is not visible to the counterparty.
Usage: $ lexe update-personal-note [OPTIONS] <INDEX>
Arguments:
<INDEX>
The payment index
Options:
--personal-note <PERSONAL_NOTE>
The new personal note. Omit to clear.
Maximum length: 200 chars / 512 UTF-8 bytes.
-h, --help
Print help (see a summary with '-h')
sync-payments
Sync payments from the user node to the local payments cache.
Usage: $ lexe sync-payments
Options:
-h, --help
Print help (see a summary with '-h')
list-payments
List payments from local storage with cursor-based pagination.
Defaults to descending order (newest first) with a limit of 100.
Use `sync-payments` to fetch the latest data from the node first.
Usage: $ lexe list-payments [OPTIONS]
Options:
--filter <FILTER>
Filter: all, pending, completed, failed, finalized. [default: all]
[default: all]
--order <ORDER>
Sort order: asc or desc. [default: desc]
--limit <LIMIT>
Max number of payments to return. [default: 100]
--after <AFTER>
Start after this payment index (for pagination)
-h, --help
Print help (see a summary with '-h')
clear-payments
Clear all locally cached payment data for this wallet.
Remote data on the node is not affected.
Use `sync-payments` to re-populate after clearing.
Usage: $ lexe clear-payments
Options:
-h, --help
Print help (see a summary with '-h')
export
Export this wallet's BIP39 seedphrase.
Prints the 24-word mnemonic, suitable for importing the wallet into
the Lexe mobile app. Pass --qr to also print a QR code encoding the
same mnemonic.
Requires the root seed (not just client credentials).
WARNING: Anyone with the mnemonic or QR code can take full control of
this wallet's funds. Only display this in a private location and store
the backup somewhere safe.
Usage: $ lexe export [OPTIONS]
Options:
--qr
Also print a QR code encoding the seedphrase
-h, --help
Print help (see a summary with '-h')
