Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
88 commits
Select commit Hold shift + click to select a range
a53fa7f
initial
ponthief Dec 14, 2025
56f2cb2
init working
ponthief Mar 14, 2026
aee231e
utxo redesign
ponthief Mar 21, 2026
29fb0f1
blindbit url issue
ponthief Mar 22, 2026
fe59e4b
update blindbit config
ponthief Mar 22, 2026
951965d
wallet balance
ponthief Mar 22, 2026
630f19f
showing balance
ponthief Mar 22, 2026
f55053b
readme api docs
ponthief Mar 22, 2026
5293cf1
working bip353
ponthief Mar 22, 2026
218ad1a
move buttons around
ponthief Mar 22, 2026
3045167
fix bip353 address update
ponthief Mar 22, 2026
1df2511
fix hr address update blank
ponthief Mar 23, 2026
d47cd6e
taproot signature hash
ponthief Mar 26, 2026
adb8baa
tnx signing and broadcasting; bip353 send
ponthief Mar 28, 2026
c90918e
mempool space config
ponthief Mar 28, 2026
b5c648d
qr code and broadcast confirm
ponthief Mar 29, 2026
a8d05e6
load utxos in db
ponthief Mar 29, 2026
2227b2b
scanning directly from Blindbit
ponthief Apr 1, 2026
c92847a
fix to clear balance; bip353 validation
ponthief Apr 1, 2026
2cf8680
scanning progres bar
ponthief Apr 2, 2026
406ef23
last scanned height fix
ponthief Apr 3, 2026
7f3258c
admin only Blindbit config
ponthief Apr 4, 2026
54d3eee
test broadcast tnx
ponthief Apr 5, 2026
4a21ad7
remove not needed html js
ponthief Apr 5, 2026
8f8182c
reformat with uv
ponthief Apr 5, 2026
8f37777
handle unconfirmed_spent and broadcast
ponthief Apr 6, 2026
46fddbd
fix dependencies
ponthief Apr 7, 2026
3a412c8
update README
ponthief Apr 9, 2026
2d1cc07
add to lnbits-extensions
ponthief Apr 9, 2026
63b27f7
path update
ponthief Apr 9, 2026
cf1770e
update _all_
ponthief Apr 9, 2026
3111adf
fix migrations
ponthief Apr 9, 2026
84352e7
manifest init
ponthief Apr 9, 2026
4b816a7
rename ext
ponthief Apr 9, 2026
636923a
no background jobs
ponthief Apr 9, 2026
e407d0b
to siLNt
ponthief Apr 9, 2026
7d571e8
fix index api docs
ponthief Apr 9, 2026
448812f
static changes
ponthief Apr 10, 2026
b7ce47f
silnt static
ponthief Apr 10, 2026
45b72aa
static file fixes
ponthief Apr 10, 2026
2dde7a6
configure localhost mempool
ponthief Apr 12, 2026
73dbf12
add support for more than 1 SP address
ponthief Apr 22, 2026
e2be454
load saved subaccounts
ponthief Apr 23, 2026
b35d6c0
readme update
ponthief Apr 23, 2026
6440bcc
add badge for unsaved sp
ponthief Apr 23, 2026
bf39482
update readme api docs
ponthief Apr 24, 2026
283043d
support for Blindbit Oracle v2
ponthief Apr 29, 2026
5b63975
fix utxo date; set oracle fork
ponthief May 2, 2026
5ede7d0
fixes to lable generation utxo discovery
ponthief May 3, 2026
08feb61
change encrypt decrypt algo
ponthief May 3, 2026
25311af
rem bb config rec
ponthief May 3, 2026
39060cb
fix incorrect balance and DNS resolve
ponthief May 7, 2026
347533a
drop storing keys in the db
ponthief May 8, 2026
cf5d6a2
fix create_wallet
ponthief May 19, 2026
97c4518
update bip353 address in Cloudflare
ponthief May 20, 2026
b0cf1c1
add option to recover the keys
ponthief May 22, 2026
e5db8fb
add user managament for Thrilla
ponthief May 23, 2026
b48ff29
add device authorisation; email verify; transactions
ponthief May 27, 2026
5541f81
add new wallet generation
ponthief May 30, 2026
6ffe50c
add recover utxo option; fix CF set
ponthief May 31, 2026
648c826
fix invalid creds for Lnbits
ponthief May 31, 2026
c1d0d8e
refactor scan.py; bitmail limit
ponthief Jun 4, 2026
c566500
dust check fixes
ponthief Jun 4, 2026
cd9ff30
fix labels in scan.py
ponthief Jun 7, 2026
94b3ddf
boltz swap
ponthief Jun 10, 2026
fbf66ee
boltz refund complete
ponthief Jun 17, 2026
ef14404
add Fulcrum and Payjoin
ponthief Jun 26, 2026
32e7d72
payjoin complete
ponthief Jun 27, 2026
75e2bfa
add ntfy notifications
ponthief Jul 4, 2026
3cee2dd
health alerts ntfy
ponthief Jul 6, 2026
e63cd98
improve scan/FE slow responses
ponthief Jul 11, 2026
f3265b1
add APK for mainnet
ponthief Jul 20, 2026
6feac0a
bip353 fixes
ponthief Jul 22, 2026
dfcbdca
refactor blinbit_config
ponthief Jul 24, 2026
a85501f
Complete get_blindbit_config → get_backend_config refactor
claude Jul 24, 2026
6e3a6c2
Purge orphaned BitMail/alert records when a wallet is deleted
claude Jul 24, 2026
0081c95
complete backend refactor
ponthief Jul 25, 2026
dcd6723
Merge branch 'claude/refactor-blindbit-backend-config-howibj' of http…
ponthief Jul 25, 2026
5a2139a
Make the per-user wallet limit per-network
claude Jul 25, 2026
818e5dd
Merge pull request #2 from ponthief/claude/refactor-blindbit-backend-…
ponthief Jul 25, 2026
5c96481
Add GET /bip353/available for live username availability checks
claude Jul 26, 2026
bf05f9a
Merge pull request #3 from ponthief/claude/receive-screen-react-nativ…
ponthief Jul 26, 2026
aac17d2
Wallet: default last_scan_height to 0, not 1
claude Jul 26, 2026
f67adc4
oracle/tip + config: require network, drop silent signet default
claude Jul 26, 2026
9df63d7
Merge pull request #4 from ponthief/claude/scan-screen-from-to-edit-x…
ponthief Jul 26, 2026
9097212
Contacts: scope the SP address book per network
claude Jul 26, 2026
d77f42c
Merge pull request #5 from ponthief/claude/scan-screen-from-to-edit-x…
ponthief Jul 26, 2026
6a925f1
Contacts: enforce unique names within a user's address book
claude Jul 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
308 changes: 300 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,305 @@
# Example Extension - <small>[LNbits](https://github.com/lnbits/lnbits) extension</small>
# SiLNt — Silent Payments Wallet Extension for LNbits

<small>For more about LNBits extension check [this tutorial](https://github.com/lnbits/lnbits/wiki/LNbits-Extensions)</small>
A [LNbits](https://lnbits.com) extension for managing [Silent Payment](https://silentpayments.xyz) Bitcoin wallets, with blockchain scanning powered by a self-hosted [BlindBit Oracle](https://github.com/ponthief/blindbit-oracle).

<h2>*tagline*</h2>
This is an example extension to help you organise and build you own.
---

Try to include an image
<img src="https://i.imgur.com/9i4xcQB.png">
## Features

<h2>If your extension has API endpoints, include useful ones here</h2>
- Generate Silent Payment addresses from a BIP39 mnemonic
- Store and manage multiple Silent Payment wallet accounts per user
- Generate up to 10 BIP352 labeled SP subaccount addresses per wallet
- Human Readable Address support ([BIP353](https://github.com/bitcoin/bips/blob/master/bip-0353.mediawiki) email format) — validated against SP address on create/update
- Blockchain scanning via a self-hosted BlindBit Oracle with real-time progress tracking and stop/resume
- UTXO tracking with automatic balance updates (unspent only)
- Send to Silent Payment, on-chain, or BIP353 email addresses
- Configurable Mempool URL (supports local instances via http or https)
- Admin-controlled BlindBit Oracle connection settings
- QR code display for SP addresses and subaccount addresses

<code>curl -H "Content-type: application/json" -X POST https://YOUR-LNBITS/YOUR-EXTENSION/api/v1/EXAMPLE -d '{"amount":"100","memo":"example"}' -H "X-Api-Key: YOUR_WALLET-ADMIN/INVOICE-KEY"</code>
---

## Requirements

- LNbits instance (self-hosted)
- Python dependencies: `embit`, `httpx`, `coincurve`, `cryptography`, `dnspython`, `ecdsa`
- A running [blindbit-oracle](https://github.com/ponthief/blindbit-oracle) instance for blockchain scanning

---

## Installation

1. As Admin user, navigate to **Settings → Extensions** and add Source:
[Ponthief-Extensions](https://raw.githubusercontent.com/ponthief/lnbits-extensions/extensions/extensions.json)
2. Install/Enable the extension from the LNbits admin panel under **Extensions**.
3. Database migrations run automatically on first load.

---

## Configuration

### BlindBit Oracle Connection

Before scanning, an admin must configure the BlindBit Oracle connection via the **Settings** button (⚙️) in the extension UI, or via the API:

```bash
curl -X PUT https://<your-lnbits>/siLNt/api/v1/backend/config \
-H "X-Api-Key: <admin_key>" \
-H "Content-Type: application/json" \
-d '{
"blindbit_url": "http://localhost:8001",
"blindbit_user": "",
"blindbit_pass": "",
"mempool_url": "https://mempool.space"
}'
```

### Mempool URL

The Mempool URL is configured alongside the BlindBit Oracle settings. It defaults to `https://mempool.space` but can be pointed to a local Mempool instance for added privacy. Both `http` and `https` are supported.

---

## Usage

### 1. Add a Wallet Account

Click **Silent Payments Wallet Account → New Wallet Account** and fill in:

| Field | Description |
|---|---|
| Mnemonic | 12-word BIP39 seed phrase (AES-encrypted client-side, never stored) |
| Born at Height | Block height of the wallet's first transaction — reduces scan time |
| Human Readable Address | Optional BIP353 email-format address (e.g. `alice@domain.com`) — must resolve to this wallet's SP address |

> The mnemonic is AES-encrypted using the born-at height as the key before transmission. It is never stored in the database.

### 2. Generate Labeled SP Addresses (Subaccounts)

Click **+** on a wallet row to generate a new BIP352 labeled SP address (up to 10 per wallet). Labeled addresses appear inline below the main SP address with an amber border. Click **Save** to persist to the database — unsaved addresses are marked with an `unsaved` badge.

### 3. Scan the Blockchain

Click the **Bitcoin** icon button on a wallet row to open the scan dialog. The dialog shows:
- **Scan From** — last scanned height (editable)
- **Chain Tip** — fetched live from the Oracle (editable)
- **Blocks to Scan** — calculated automatically

Click **Sync to Tip** to start scanning. A progress bar shows real-time progress. Click **Stop** to pause — progress is saved and the next scan resumes from where it left off.

### 4. Load UTXOs from DB

Click the **database** icon button on a wallet row to load previously scanned UTXOs from the local database.

### 5. Make a Payment

Click **Send** to open the Send Payment flow:
1. Select UTXOs to spend (checkbox + amount shown)
2. Enter recipient (SP address, on-chain address, or BIP353 email)
3. Set amount and fee rate
4. Click **Build Transaction** — reviews fee before broadcasting
5. Click **Broadcast** → confirm in the confirmation dialog

After broadcast, selected UTXOs are marked as spent and a Mempool link is shown in the notification.

### 6. Resolve BIP353

Click **Resolve BIP353** to look up a BIP353 email-format address and display the resolved SP address.

---

## API Reference

All endpoints are prefixed with `/siLNt/api/v1`. Authentication uses the `X-Api-Key` header.

### Wallets

| Method | Endpoint | Auth | Description |
|---|---|---|---|
| `GET` | `/wallet` | Invoice Key | List all wallet accounts |
| `GET` | `/wallet/{wallet_id}` | Invoice Key | Get a wallet account |
| `POST` | `/wallet` | Invoice Key | Create a wallet account |
| `PUT` | `/wallet/{wallet_id}` | Invoice Key | Update hr_address, last_height, title, balance |
| `DELETE` | `/wallet/{wallet_id}` | Invoice Key | Delete wallet, UTXOs and labeled addresses |

### Labeled SP Addresses

| Method | Endpoint | Auth | Description |
|---|---|---|---|
| `GET` | `/wallet/{wallet_id}/addresses` | Invoice Key | List saved labeled SP addresses |
| `POST` | `/wallet/{wallet_id}/addresses/preview` | Invoice Key | Preview a labeled SP address (not saved) |
| `POST` | `/wallet/{wallet_id}/addresses` | Invoice Key | Save a labeled SP address to DB |
| `DELETE` | `/wallet/{wallet_id}/addresses/{address_id}` | Invoice Key | Delete a labeled SP address |

### Scanning

| Method | Endpoint | Auth | Description |
|---|---|---|---|
| `POST` | `/wallet/{wallet_id}/scan` | Invoice Key | Scan blockchain for UTXOs |
| `POST` | `/wallet/{wallet_id}/scan/stop` | Invoice Key | Stop an in-progress scan |
| `GET` | `/wallet/{wallet_id}/scan/progress` | Invoice Key | Get real-time scan progress |

### UTXOs

| Method | Endpoint | Auth | Description |
|---|---|---|---|
| `GET` | `/utxos?wallet_id=` | Invoice Key | Load UTXOs from DB for a wallet |

### BlindBit Oracle

| Method | Endpoint | Auth | Description |
|---|---|---|---|
| `GET` | `/blindbit/config` | Invoice Key | Get Oracle connection settings |
| `PUT` | `/blindbit/config` | Admin Key | Update Oracle connection settings incl. Mempool URL |
| `GET` | `/oracle/tip` | Invoice Key | Get current chain tip from Oracle |

### BIP353

| Method | Endpoint | Auth | Description |
|---|---|---|---|
| `GET` | `/bip353/resolve?address=` | Invoice Key | Resolve a BIP353 email-format address |

### Transactions

| Method | Endpoint | Auth | Description |
|---|---|---|---|
| `POST` | `/tx/build` | Admin Key | Build and sign a transaction |
| `POST` | `/tx/broadcast` | Admin Key | Broadcast a signed transaction |

### Config

| Method | Endpoint | Auth | Description |
|---|---|---|---|
| `GET` | `/config` | Invoice Key | Get app config including mempool endpoint |

Full interactive docs at `/docs#/siLNt` on your LNbits instance.

---

## Data Models

### WalletAccount

```json
{
"id": "abc123xyz",
"user": "usr_abc123",
"title": "sp1qqw...",
"balance": 100000,
"hr_address": "alice@domain.com",
"network": "mainnet",
"last_height": 840000,
"last_scan_height": 842000,
"sp_address": "sp1qqw..."
}
```

### WalletAddress (Labeled SP)

```json
{
"id": "xyz789",
"wallet_id": "abc123xyz",
"sp_address": "sp1qq...",
"label_index": 1,
"created_at": 1710000000
}
```

### BackendConfig

```json
{
"blindbit_url": "http://localhost:8001",
"blindbit_user": "",
"blindbit_pass": "",
"mempool_url": "https://mempool.space"
}
```

### UTXORecord

```json
{
"txid": "a1b2c3...",
"vout": 0,
"amount": 50000,
"priv_key_tweak": "...",
"pub_key": "...",
"timestamp": 1710000000,
"utxo_state": "unspent",
"wallet_id": "abc123xyz"
}
```

---

## Security Notes

- Mnemonics are **never stored**. AES-encrypted client-side before transmission, used only to derive keys at creation time.
- The `scan_secret` (scan private key) is encrypted at rest using a server-side Fernet key.
- The `spend_key` is encrypted at rest using the `scan_secret` as the AES key — double-layered protection.
- BIP353 `hr_address` is validated server-side on create and update — it must resolve to the wallet's SP address.
- Configure `mempool_url` to point to a local Mempool instance for transaction broadcasting privacy.
- Admin Key is required for all write operations that affect funds (tx build, broadcast, BlindBit config).

---

## Project Structure

```
siLNt/
├── __init__.py
├── views.py # Page routes
├── views_api.py # REST API endpoints
├── crud.py # Database operations
├── models.py # Pydantic models
├── migrations.py # DB schema migrations
├── helpers/
│ ├── wallet.py # SP address derivation, key encryption, tx building
│ ├── scan.py # Blockchain scanner (BlindBit Oracle client)
│ ├── address_resolver.py # BIP353 DNS resolution
│ └── curve.py # secp256k1 EC math helpers
├── static/
│ ├── js/
│ │ ├── index.js # Main Vue app
│ │ ├── tables.js # Table column definitions
│ │ ├── map.js # Data mapping functions
│ │ ├── utils.js # Utility functions
│ │ └── bip39-word-list.js # BIP39 word list for mnemonic validation
│ └── components/
│ ├── wallet-config.js / .html # BlindBit Oracle settings
│ ├── wallet-list.js / .html # Wallet table with labeled addresses
│ └── utxo-list.js / .html # UTXO table
└── templates/
└── silnt/
├── index.html
└── _api_docs.html
```

---

## References

- [BIP352 — Silent Payments](https://github.com/bitcoin/bips/blob/master/bip-0352.mediawiki)
- [BIP353 — DNS Payment Instructions](https://github.com/bitcoin/bips/blob/master/bip-0353.mediawiki)
- [BIP352 Light Client Specification](https://github.com/setavenger/BIP0352-light-client-specification)
- [BlindBit Oracle](https://github.com/ponthief/blindbit-oracle)

---

## Contributing

Pull requests welcome. Please open an issue first to discuss significant changes.

---

## Author

Created by [Ponthief](https://github.com/ponthief) at [Bitaurus](https://bitaurus.net)

---

## License

MIT
Loading