It provides separate accounts with minimum trust for end users. Live deployment at ln.getalby.com.
LndHub compatible API implemented in Go using relational database backends
- Using a relational database (PostgreSQL and SQLite)
- Focussing only on Lightning (no onchain functionality)
- No runtime dependencies (simple Go executable)
- Extensible to add more features
- Fee reserves are not checked prior to making the payment. This can cause a user's balance to go below 0.
All required configuration is done with environment variables and a .env
file can be used.
Check the .env_example
for an example.
cp .env_example .env
vim .env # edit your config
DATABASE_URI
: The URI for the database. If you want to use SQLite use for example:file:data.db
JWT_SECRET
: We use JWT for access tokens. Configure your secret hereJWT_ACCESS_EXPIRY
: How long the access tokens should be valid (in seconds, default 2 days)JWT_REFRESH_EXPIRY
: How long the refresh tokens should be valid (in seconds, default 7 days)LND_ADDRESS
: LND gRPC address (with port) (e.g. localhost:10009)LND_MACAROON_HEX
: LND macaroon (hex)LND_CERT_HEX
: LND certificate (hex)CUSTOM_NAME
: Name used to overwrite the node alias in the getInfo callLOG_FILE_PATH
: (optional) By default all logs are written to STDOUT. If you want to log to a file provide the log file path hereSENTRY_DSN
: (optional) Sentry DSN for exception trackingPORT
: (default: 3000) Port the app should listen onDEFAULT_RATE_LIMIT
: (default: 10) Requests per second rate limitSTRICT_RATE_LIMIT
: (default: 10) Requests per burst rate limit (e.g. 1 request each 10 seconds)BURST_RATE_LIMIT
: (default: 1) Rate limit burstENABLE_PROMETHEUS
: (default: false) Enable Prometheus metrics to be exposedPROMETHEUS_PORT
: (default: 9092) Prometheus port (path:/metrics
)WEBHOOK_URL
: Optional. Callback URL for incoming and outgoing payment events, see below.
go run main.go
To build an lndhub
executable, run the following commands:
make
To run your own local lightning network and LND you can use Lightning Polar which helps you to spin up local LND instances.
Alternatively you can also use the Alby simnetwork
LndHub.go supports PostgreSQL and SQLite as database backend. But SQLite does not support the same data consistency checks as PostgreSQL.
Prometheus metrics can be optionally exposed through the ENABLE_PROMETHEUS
environment variable.
For an example dashboard, see https://grafana.com/grafana/dashboards/10913.
If WEBHOOK_URL
is specified, a http POST request will be dispatched at that location when an incoming payment is settled, or an outgoing payment is completed. Example payload:
{
"id": 721,
"type": "incoming", //incoming, outgoing
"user_id": 299,
"amount": 1000,
"fee": 0,
"memo": "fill wallet",
"description_hash": "",
"payment_request": "lnbcrt10u1p38p4ehpp5xp07pda02vk40wxd9gyrene8qzheucz7ast435u9jwxejs6f0v5sdqjve5kcmpqwaskcmr9wscqzpgxqyz5vqsp56nyve3v5fw306j74nmewv7t5ey3aer2khjrrwznh4k2vuw44unzq9qyyssqv2wq9hn7a39x8cvz9fvpzul87u4kc4edf0t6jukzvmx8v5swl3jqg8p3sh6czkepczcjkm523q9x8yswsastctnsns3q9d26szu703gpwh7a09",
"destination_pubkey_hex": "0376442c750766d5d127512609a5618d9aa82db2d06aae226084da92a3e133acda",
"custom_records": {
"5482373484": "YWY4MDhlZDUxZjNmY2YxNWMxYWI3MmM3ODVhNWI1MDE="
}, //only set when keysend=true
"r_hash": "305fe0b7af532d57b8cd2a083ccf2700af9e605eec1758d385938d9943497b29",
"preimage": "3735363531303032626332356439376136643461326434336335626434653035",
"keysend": false,
"state": "settled",
"created_at": "2022-05-03T09:18:15.15774+02:00",
"expires_at": "2022-05-04T09:18:15.157597+02:00",
"updated_at": "2022-05-03T09:18:19.837567+02:00",
"settled_at": "2022-05-03T09:18:19+02:00"
}
- Using low level database constraints to prevent data inconsistencies
- Follow double-entry bookkeeping ideas (Every transaction is a debit of one account and a credit to another one)
- Support multiple database backends (PostgreSQL for production, SQLite for development and personal/friend setups)
┌─────────────┐
│ User │
└─────────────┘
│
┌─────────────────┬───────┴─────────┬─────────────────┐
▼ ▼ ▼ ▼
Accounts: ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Incoming │ │ Current │ │ Outgoing │ │ Fees │
Every user has └──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘
four accounts
Every Transaction Entry is associated to one debit account and one
credit account
┌────────────────────────┐
│Transaction Entry │
│ │
│+ user_id │
┌────────────┐ │+ invoice_id │
│ Invoice │────────────────▶+ debit_account_id │
└────────────┘ │+ credit_account_id │
│+ amount │
Invoice holds the │+ ... │
lightning related │ │
data └────────────────────────┘