Authentication
Overview
Lexe has two main authentication methods:
1) Root seed: The root seed is the wallet's master secret. All child keys and secrets are derived from it. The root seed gives total, unrestricted, irrevocable control over funds in a Lexe wallet, and can only be rotated by moving all funds to a new wallet. The root seed is required to unilaterally recover one's Bitcoin if Lexe ever goes away, so it is very important to back it up to a safe place.
2) Client credentials: Lexe client credentials are scoped and revocable credentials encoded as a long opaque string. Client credentials are well-suited for giving limited access to an existing Lexe wallet to 3rd party applications.
The rest of this page covers these authentication methods in detail.
Root Seed
The root seed is the master secret for a Lexe wallet. If the root seed is lost, all wallet funds are permanently unrecoverable. Be sure to back it up to somewhere safe before depositing funds.
Authenticate with the root seed if you need total control over how secrets are generated, backed up, and persisted, or if you need the ability to create new Lexe nodes, for example, if you are a wallet developer. The root seed can be constructed from arbitrary bytes, and can thus be derived from a 'higher' master secret.
Generating a new root seed
Lexe mobile app
For most Lexe users, the root seed is generated by the Lexe mobile app and persisted in their phone's secure storage.
- Google Drive backup: If the user has enabled Lexe's Google Drive integration, the root seed is also backed up to the user's Google Drive, encrypted by a strong password. As long as the user remembers their password, or stores it in a safe place like a password manager, they will be able to restore their wallet on a new device by simply connecting their Google Drive and entering their password. The Google Drive integration is built so that Lexe does not learn the user's email address or any other personal information about the user.
- Seedphrase backup: If users want to opt-out of Google Drive, the root seed can also be converted to a 24 word mnemonic (commonly referred to as a "seedphrase") and backed up directly. Storing the seedphrase in a password manager like 1Password is a decent tradeoff for most users, but it is best if the seedphrase is stored offline.
Lexe SDKs and CLI
The root seed can also be generated using Lexe's SDKs or the Lexe CLI.
- CLI users run
$ lexe initwhich generates a new root seed and persists it to~/.lexe/seedphrase.txt(Unix mode0600). The user is responsible for backing up their root seed in this case. - SDK users can call
RootSeed.generate()to sample a new root seed. They can then callRootSeed.write(_)to persist it to~/.lexe/seedphrase.txt(mode0600), or use one of the available methodsto_mnemonic,to_hex, orto_bytesto manage and persist it themselves. See the Rust quickstart or the Python quickstart for full examples. - The Sidecar SDK does not support root seed generation. Create and persist the root seed using the CLI or one of the other SDKs.
Any Lexe root seed can be used with Lexe's mobile app. Simply open the app, select "Restore", then paste the seedphrase into the app.
If desired, developers can use their own RNG to sample the Lexe root seed, or
derive it from a higher secret.
For example, a multi-chain wallet that uses the Lexe SDK to integrate Lightning
can use HKDF-SHA-256 to deterministically derive a 32-byte key from their own
master secret, and pass the bytes to RootSeed.from_bytes to construct a Lexe
root seed from it.
Signup, provisioning, and updates
Signup
After root seed generation, the next step is to register an account with Lexe.
No personal information is required; all that Lexe receives is the user's
ed25519 pubkey (the user_pk) and Lightning node pubkey.
SDK users can sign up by calling LexeWallet.signup(_).
For CLI users, $ lexe init already handles signup, but $ lexe signup is
available if it is required to sign up manually.
The Sidecar SDK does not support signup.
Provisioning
Once signed up, it is necessary to provision the Lightning node running inside the secure enclave, by giving it a copy of the root seed. The mobile app and SDKs will connect to the secure enclave inside Lexe's cloud and verify that the Lightning node's measurement (a SHA-256 hash of the node binary) appears in its trusted measurements list.
The trusted node measurements are hard-coded into the app, SDKs, and CLI, and can be independently verified to be trustworthy by auditing the open-source code published in Lexe's GitHub and reproducibly building the user node enclave binary from it. If the enclave's remote attestation passes the check, then a copy of the root seed is sent to the enclave via a secure channel. From here on, Lexe can help keep the user's Lightning node online, but Lexe cannot read the root seed because it's protected by the enclave.
SDK users can provision by calling LexeWallet.provision(_).
For CLI users, $ lexe init already handles the initial provisioning, but
$ lexe provision is available for provisioning manually or updating the node.
The Sidecar SDK does not currently support provisioning, but may in the future.
If you would like to learn more about this process, you can read the SECURITY.md available in Lexe's GitHub.
Updates
Whenever a new user node version is released, it has a different measurement, and needs to be re-provisioned. Because the trusted node measurements are hard coded into the clients (the mobile app, the CLI, or the SDKs), updating the client is required to update the user node.
To update the user node to its latest version, simply update the app, CLI, or
SDK, then call LexeWallet.provision(_).
The Lightning node will run the updated version the next time it starts.
You can call LexeWallet.node_info() and check the version field to verify
that the enclave is running the version you expect.
Using the root seed
The root seed can be used with Lexe's SDKs and the CLI.
- CLI and Sidecar: Pass via
--root-seedor--root-seed-path, or set via env (LEXE_ROOT_SEEDorLEXE_ROOT_SEED_PATH), or store in.envin the current or any parent directory. - SDK: Construct the
RootSeedand pass it intoLexeWallet. See the Rust quickstart or the Python quickstart for an example.
Lexe Client Credentials
Another way to authenticate a Lexe wallet is using client credentials. The defining feature of Lexe client credentials is that they are scoped, revocable, and may have budgets attached.
Client credentials are designed for giving access to 3rd party apps that need a limited amount of control over the wallet, and which don't need (or want) the responsibility of generating the root seed or managing backup and restore.
A client credential is a long, opaque string that looks like this:
eyJ1c2VyX3BrIjoiNmZkNzY0MTU2OTMwNTA5ZmFkNTM2MWQzYjIyYjYxZjc1YWE5MWVkNjQwMjE1YjJjNDFjMmZmODZiMmJmYzQ3MiIsImxleGVfYXV0aF90b2tlbiI6IjlkVENVdkM4eTdxY055VWJxeW56M253SVFRSGJRcVBWS2VNaFhVajFBZnItdmdqOUUyMTdfMnRDUzFJUU03T...
Creating client credentials
Client credentials can be created via the Lexe mobile app. In the left sidebar, select "Client credentials":

From there, you can create a client credential which has access to your wallet, and add a label to remind you what it was for.
Revoking client credentials
To revoke a credential, simply navigate to the same menu and press the delete button. Unlike credit cards, there is no need to ask any 3rd party service you shared those credentials with to delete your credentials from their database. Any further attempts to use your credentials will be blocked by your user node.

Credential scopes
NOTE: Credential scopes are currently in progress. Currently, all client credentials give "full" access to the wallet, and should be shared with caution.
Client credentials will be created with one of the following scopes:
- "read": Read-only access to the wallet. Can view wallet balance, list payments, and listen for incoming and outgoing payments.
- "receive": Has read access, plus the ability to create invoices and offers, but not pay them.
- "full": Full access to the wallet, except for the root seed. Has the ability to spend all funds, create new client credentials, and provision new node versions.
Credential budgets
NOTE: Credential budgets are not yet implemented. This is a highly requested feature, currently in progress. Stay tuned!
Client credentials will also be able to have budgets attached, which will limit how much the credential can spend over a given time period. For example, you will be able to create a client credential that can spend at most 20 USD per month. These credentials can be used to pay for subscriptions, and give users the confidence that services cannot charge any more than their node allows.
Planned denominations:
- BTC
- USD
Planned time periods:
- Daily
- Weekly
- Monthly
- Yearly
- All time
Using client credentials
Client credentials can be used with Lexe's SDKs, the CLI, and the sidecar.
- CLI: Pass via
--client-credentialsor--client-credentials-path, or set via env (LEXE_CLIENT_CREDENTIALSorLEXE_CLIENT_CREDENTIALS_PATH), or store in.envin the current or any parent directory. - Sidecar: Set default credentials
via CLI (
--client-credentials,--client-credentials-path) or env (LEXE_CLIENT_CREDENTIALS,LEXE_CLIENT_CREDENTIALS_PATH), or store in.envin the current or any parent directory, or pass per-request via theAuthorization: Bearer <credentials>header. Per-request credentials take precedence over default credentials if provided, and are useful for controlling multiple wallets from a single sidecar process. - SDK: Construct the
ClientCredentialsand pass it intoLexeWallet. See the Rust quickstart or the Python quickstart for an example.
When using someone else's client credential, remember that you are acting
from the wallet owner's perspective.
If you instantiate a LexeWallet with a user's client credential, calling
LexeWallet.pay(_) will spend the user's funds, not your own.
If you need to charge the user's wallet for a good or service, you can do so by
using the user's wallet to pay your own.