Use a NIP-46 remote signer from LNbits without importing the user's identity
nsec.
External Signer creates a separate, disposable client key for LNbits. Requests travel to the remote signer through the selected Nostr relays. The signer keeps the identity key and remains responsible for approving or refusing every request.
Never paste an
nsecinto this extension. You need abunker://invite from the signer, or a signer that can scan anostrconnect://QR.
Version 0.1.0 is an unpublished release candidate. The implementation and
independent signer tests pass locally and the public CI matrix is green, but
there is not yet a tagged release, registry installation record or production
soak. Do not present it as a released production extension until every gate in
RELEASE_CHECKLIST.md is complete.
The inherited LNbits dependency audit is currently a production blocker. See HOST_DEPENDENCIES.md for the exact evidence and decision.
This is an LNbits extension. It is not a wallet backend, Lightning node, payment processor or second implementation of LNbits.
| What your signer offers | What to choose in External Signer |
|---|---|
A link beginning bunker:// |
I have a signer invite |
| A Scan client QR or Connect app action | My signer scans QR codes |
An nsec export only |
Stop. Do not use that secret here. |
The two routes establish the same limited NIP-46 client. They differ only in which side creates the one-use pairing secret.
Before starting:
- keep the signer open and unlocked;
- decide what LNbits needs to sign;
- use the Identity proof preset unless another extension needs more;
- make sure both LNbits and the signer can reach the chosen
wss://relay.
- In the remote signer, create a new client or app connection for LNbits.
- Copy the complete
bunker://link. - In External Signer, select I have a signer invite.
- Give the connection a recognisable name and paste the link.
- Choose the smallest permission preset and select Send invite.
- Return to the signer. Approve the connection, public-key request and one-off identity proof.
- Wait for LNbits to show Connected.
The invite secret is encrypted until the signer acknowledges it, then erased.
- In External Signer, select My signer scans QR codes.
- Give the connection a recognisable name and choose the smallest permission preset.
- Select Create QR.
- In the signer, choose its scan or connect-client action and scan the QR.
- Check the requested methods and event kinds before approving.
- Approve the one-off identity proof and wait for Connected.
The QR is a ten-minute pairing secret. Create fresh pairing makes a new secret after expiry; it does not revive the old one.
For a standalone walkthrough and troubleshooting explanations, see QUICKSTART.md.
Connected means all of the following completed:
- the NIP-46 client and remote signer established an encrypted session;
- the signer returned the user public key;
- that user key signed an exact, connection-specific identity challenge;
- LNbits verified the event signature and every requested field.
Use Test connection to request a NIP-46 ping. A completed ping confirms a
current signer response, not event publication or payment settlement.
The default Identity proof preset grants only:
get_public_key
sign_event:27235
Kind 27235 is used for an unpublishable, connection-specific identity proof.
Broad sign_event authority is refused. Every allowed kind must be explicit,
for example sign_event:1.
The Nostr Market preset adds the exact profile, encrypted order, deletion, stall and product operations needed by that integration:
sign_event:0
sign_event:4
sign_event:5
sign_event:30017
sign_event:30018
nip04_encrypt
nip04_decrypt
Selecting a preset requests permission. The remote signer is still the final policy authority and may require approval or refuse any operation.
Requirements:
- LNbits
1.5.6or newer and below2.0; - Python
3.10,3.11or3.12; - outbound access to the public
wss://relays users select.
No additional LNbits extension is required. External Signer uses the public
nostr-sdk API already distributed with LNbits.
Until a tagged repository release exists, link this checkout into an LNbits development tree:
lnbits/extensions/externalsigner -> /path/to/externalsigner
Restart LNbits, enable External Signer for a test account and follow the pairing guide above. Do not use an untagged checkout on a production server.
Administrators should read ADMIN.md before a staging or production installation. The exact seven-day evidence procedure is in STAGING.md.
The service helpers wait for the asynchronous signer response and validate the returned data before returning:
from lnbits.extensions.externalsigner.services import sign_event
signed = await sign_event(
user_id,
connection_id,
{
"kind": 30017,
"content": product_json,
"tags": [],
"created_at": created_at,
},
)Equivalent helpers exist for nip04_encrypt, nip04_decrypt,
nip44_encrypt and nip44_decrypt. A signed event is returned only when its
signature, user public key and every unsigned field match the request.
The stable integration contract and error behaviour are documented in INTEGRATION.md.
- The identity
nsecis never accepted or stored. - Client keys, pairing secrets, parameters, results, errors and approval URLs are encrypted at rest with versioned AES-256-GCM envelopes.
- Public API responses containing account or pairing state use
no-store. - Relay subscriptions and publications are isolated to the selected relays.
- Production relays must use
wss://and resolve only to public addresses. - An account may have ten active signer connections.
- A connection may have twelve operations waiting for a response and sixty user requests per minute.
- Unanswered operations expire after thirty minutes. Completed and failed operation records are removed after seven days.
- Revocation sends best-effort
logout, erases the local client capability and purges that connection's operation history.
Read SECURITY.md and ARCHITECTURE.md for the complete trust boundary.
make verifyThe ordinary suite excludes opt-in signer interoperability. Current evidence, source commits and physical-hardware limits are recorded in VERIFICATION.md.
External Signer is copyright The Crypto Donkey and released under the MIT
licence. Project support links are deliberately configured in
.github/FUNDING.yml:
Sponsorship does not buy signing authority, preferential security handling or access to user keys. These support links do not alter ownership or attribution: this project is The Crypto Donkey's.
