alby-hub/README.md

428 lines
15 KiB
Markdown
Raw Normal View History

2024-07-05 13:10:18 +07:00
# Alby Hub
2024-02-02 12:09:15 +07:00
2024-07-05 13:10:18 +07:00
This is a self-sovereign, self-custodial, single-user rewrite of the original [Nostr Wallet Connect](https://github.com/getAlby/nostr-wallet-connect) app. **❗This version is not backwards compatible with the original app - it requires a fresh database and connections to be re-added**
2023-03-21 18:01:09 +01:00
This application allows you to control your Lightning node or wallet from any other application that supports [NWC](https://nwc.dev/).
Connect apps like [Damus](https://damus.io/) or [Amethyst](https://linktr.ee/amethyst.social) to your node. There are many more available on https://nwc.dev/.
2023-03-21 22:05:50 +01:00
2023-05-16 17:20:04 +03:00
**Specification**: [NIP-47](https://github.com/nostr-protocol/nips/blob/master/47.md)
2023-04-24 15:51:51 +02:00
2024-02-02 12:40:38 +07:00
The application can run in two modes:
- Wails (Desktop app): Mac (arm64), Windows (amd64), Linux (amd64)
- HTTP (Web app): Docker, Linux (amd64)
Ideally the app runs 24/7 (on a node, VPS or always-online desktop/laptop machine) so it can be connected to a lightning address and receive online payments.
2023-05-16 17:20:04 +03:00
## Supported Backends
2023-03-22 15:15:07 +01:00
2024-07-05 13:10:18 +07:00
- LND
- Breez
- Greenlight
- LDK
- Phoenixd
2024-07-05 13:10:18 +07:00
- Cashu
- want more? please open an issue.
2023-04-21 19:14:59 +02:00
## Installation
2023-04-24 15:51:51 +02:00
2023-05-16 17:20:04 +03:00
### Requirements
The application has no runtime dependencies. (simple Go executable).
2024-01-19 20:01:00 +07:00
As data storage SQLite is used.
2023-05-16 17:20:04 +03:00
2023-04-29 12:49:29 +02:00
$ cp .env.example .env
# edit the config for your needs
vim .env
2023-04-21 19:14:59 +02:00
## Development
2023-04-24 15:51:51 +02:00
2024-02-09 15:05:11 +07:00
### Required Software
- Go
- Node
- NPM
- Yarn
2024-02-09 15:05:11 +07:00
### Server (HTTP mode)
2023-12-26 12:12:51 +07:00
1. Create a Lightning Polar setup with two LND nodes and uncomment the Polar LND section in your `.env` file.
2023-12-26 12:12:51 +07:00
2. Compile the frontend or run `touch frontend/dist/tmp` to ensure there are embeddable files available.
2024-06-17 19:42:09 +07:00
3. `go run cmd/http/main.go`
2023-04-24 15:17:14 +02:00
### React Frontend (HTTP mode)
Go to `/frontend`
2023-04-24 15:17:14 +02:00
1. `yarn install`
2. `yarn dev`
2023-04-25 15:54:56 +02:00
### Wails (Backend + Frontend)
2024-01-19 23:17:37 +07:00
_Make sure to have [wails](https://wails.io/docs/gettingstarted/installation) installed and all platform-specific dependencies installed (see wails doctor)_
2024-01-19 23:07:44 +07:00
$ wails dev -tags "wails"
_If you get a blank screen, try running in your normal terminal (outside of vscode, and make sure HTTP frontend is not running)_
#### Wails Production build
2024-01-15 16:08:18 +07:00
2024-03-26 00:20:04 +02:00
$ wails build -tags "wails"
2023-04-24 15:17:14 +02:00
### Build and run locally (HTTP mode)
2023-04-24 15:17:14 +02:00
2024-03-26 00:20:04 +02:00
$ mkdir tmp
2024-06-17 19:42:09 +07:00
$ go build -o main cmd/http/main.go
2024-03-26 00:20:04 +02:00
$ cp main tmp
$ cp .env tmp
$ cd tmp
$ ./main
### Run dockerfile locally (HTTP mode)
2024-03-26 00:20:04 +02:00
$ docker build . -t nwc-local --progress=plain
2024-06-24 15:13:12 +07:00
$ docker run -v $(pwd)/.data/docker:/data -e WORK_DIR='/data' -p 8080:8080 nwc-local
2023-04-25 15:54:56 +02:00
2023-08-08 20:36:03 +07:00
### Testing
$ go test ./...
2024-06-17 19:42:09 +07:00
#### Test matching regular expression
$ go test ./... -run TestHandleGetInfoEvent
2023-08-08 20:36:03 +07:00
### Profiling
The application supports both the Go pprof library and the DataDog profiler.
#### Go pprof
To enable Go pprof, set the `GO_PROFILER_ADDR` environment variable to the address you want the profiler to be available on (e.g. `localhost:6060`).
Now, you should be able to access the pprof web interface at `http://localhost:6060/debug/pprof`.
You can use the `go tool pprof` command to collect and inspect the profiling data. For example, to profile the application for 30 seconds and then open the pprof web UI, run:
```sh
go tool pprof -http=localhost:8081 -seconds=30 http://localhost:6060/debug/pprof/profile
```
For more information on the Go pprof library, see the [official documentation](https://pkg.go.dev/net/http/pprof).
#### DataDog profiler
To enable the DataDog profiler, set the `DD_PROFILER_ENABLED` environment variable to `true`.
Make sure to specify the required DataDog configuration environment variables as well.
For more information refer to:
- [DataDog Profiler documentation](https://docs.datadoghq.com/profiler/enabling/go/)
- [DataDog Profiler Go library](https://pkg.go.dev/gopkg.in/DataDog/dd-trace-go.v1/profiler)
2024-06-22 12:22:01 +07:00
### Versioning
2024-07-05 20:32:40 +07:00
$ go run -ldflags="-X 'github.com/getAlby/hub/version.Tag=v0.6.0'" cmd/http/main.go
2024-06-22 12:22:01 +07:00
2024-02-01 22:09:17 +07:00
### Windows
Breez SDK requires gcc to build the Breez bindings. Run `choco install mingw` and copy the breez SDK bindings file into the root of this directory (from your go installation directory) as per the [Breez SDK instructions](https://github.com/breez/breez-sdk-go?tab=readme-ov-file#windows). ALSO copy the bindings file into the output directory alongside the .exe in order to run it.
2024-02-14 17:19:01 +07:00
## Optional configuration parameters
2023-05-16 17:20:04 +03:00
2024-08-02 18:12:14 +03:00
The following configuration options can be set as environment variables or in a .env file
2023-05-16 17:20:04 +03:00
- `NOSTR_PRIVKEY`: the private key of this service. Should be a securely randomly generated 32 byte hex string.
- `CLIENT_NOSTR_PUBKEY`: if set, this service will only listen to events authored by this public key. You can set this to your own nostr public key.
- `RELAY`: default: "wss://relay.getalby.com/v1"
- `JWT_SECRET`: a randomly generated secret string. (only needed in http mode)
2024-07-05 20:32:40 +07:00
- `DATABASE_URI`: a sqlite filename. Default: $XDG_DATA_HOME/albyhub/nwc.db
2023-05-16 17:20:04 +03:00
- `PORT`: the port on which the app should listen on (default: 8080)
2024-07-05 20:32:40 +07:00
- `WORK_DIR`: directory to store NWC data files. Default: $XDG_DATA_HOME/albyhub
2024-03-04 12:51:58 +07:00
- `LOG_LEVEL`: log level for the application. Higher is more verbose. Default: 4 (info)
## Node-specific backend parameters
- `ENABLE_ADVANCED_SETUP`: set to `false` to force a specific backend type (combined with backend parameters below)
### LND Backend parameters
2024-02-14 17:47:53 +07:00
Currently only LND can be configured via env. Other node types must be configured via the UI.
2024-02-14 17:19:01 +07:00
_To configure via env, the following parameters must be provided:_
2024-02-14 17:19:01 +07:00
- `LN_BACKEND_TYPE`: LND
2023-05-16 17:20:04 +03:00
- `LND_ADDRESS`: the LND gRPC address, eg. `localhost:10009` (used with the LND backend)
- `LND_CERT_FILE`: the location where LND's `tls.cert` file can be found (used with the LND backend)
- `LND_MACAROON_FILE`: the location where LND's `admin.macaroon` file can be found (used with the LND backend)
### LDK Backend parameters
- `LDK_ESPLORA_SERVER`: If using the mainnet (bitcoin) network, Recommended to use your own LDK esplora server (The public blockstream one is very slow and can cause onchain syncing and issues with opening channels)
#### LDK Network Configuration
##### Mutinynet
- `MEMPOOL_API=https://mutinynet.com/api`
- `LDK_NETWORK=signet`
- `LDK_ESPLORA_SERVER=https://mutinynet.com/api`
- `LDK_GOSSIP_SOURCE=https://rgs.mutinynet.com/snapshot`
##### Testnet (Not recommended - try Mutinynet)
- `MEMPOOL_API=https://mempool.space/testnet/api`
- `LDK_NETWORK=testnet`
- `LDK_ESPLORA_SERVER=https://mempool.space/testnet/api`
- `LDK_GOSSIP_SOURCE=https://rapidsync.lightningdevkit.org/testnet/snapshot`
### Phoenixd
See [Phoenixd](scripts/linux-x86_64/phoenixd/README.md)
### Alby OAuth
Create an OAuth client at the [Alby Developer Portal](https://getalby.com/developer) and set your `ALBY_OAUTH_CLIENT_ID` and `ALBY_OAUTH_CLIENT_SECRET` in your .env. If not running locally, you'll also need to change your `BASE_URL`.
> If running the React app locally, OAuth redirects will not work locally if running the react app you will need to manually change the port to 5173. **Login in Wails mode is not yet supported**
## Getting Started with Mutinynet
Follow the steps to integrate Mutinynet with your NWC Next setup:
2024-07-05 20:32:40 +07:00
1. Configure your environment with the [Mutinynet LDK parameters](https://github.com/getAlby/hub#mutinynet)
2024-07-05 20:32:40 +07:00
2. Proceed as described in the [Development](https://github.com/getAlby/hub#Development) section to run the frontend and backend
3. Navigate to `channels/outgoing`, copy your On-Chain Address, then visit the [Mutinynet Faucet](https://faucet.mutinynet.com/) to deposit sats. Ensure the transaction confirms on [mempool.space](https://mutinynet.com/)
4. Your On-chain balance will update under `/channels`
### Opening a channel from Mutinynet
1. To create a channel, use the [Mutinynet Faucet](https://faucet.mutinynet.com/) by entering your desired Channel Capacity and Amount to Push
2024-05-06 22:12:54 +02:00
2. Locate your Node ID. In the Wallet click on the status on the top right "online". This shows the node ID or look in the NWC Next logs. Then input this in the Connection String field on the faucet page to request a Lightning Channel
```
{"level":"info","msg":"Connected to LDK node","nodeId":"<your node ID>","time":"<timestamp>"}
```
3. After the transaction confirms, the new channel will appear in the Channels section
### Opening a Channel in NWC Next
1. From the Channels interface (`/channels`), select "Open a Channel" and opt for "Custom Channel."
2. Enter the pubkey of the Faucet Lightning Node (omit host and port details) available on the [Mutinynet Faucet](https://faucet.mutinynet.com/) page.
3. Specify a channel capacity greater than 25,000 sats, confirm the action, and return to the Channels page to view your newly established channel.
2023-05-16 17:20:04 +03:00
## Application deeplink options
2023-04-25 15:54:56 +02:00
2023-05-16 17:20:04 +03:00
### `/apps/new` deeplink options
2023-04-25 15:54:56 +02:00
Clients can use a deeplink to allow the user to add a new connection. Depending on the client this URL has different query options:
2023-05-16 17:20:04 +03:00
#### NWC created secret
2023-04-25 15:54:56 +02:00
The default option is that the NWC app creates a secret and the user uses the nostr wallet connect URL string to enable the client application.
2023-05-16 17:20:04 +03:00
##### Query parameter options
2023-04-25 15:54:56 +02:00
- `name`: the name of the client app
2023-04-25 15:54:56 +02:00
Example:
`/apps/new?name=myapp`
2023-04-25 15:54:56 +02:00
2023-05-16 17:20:04 +03:00
#### Client created secret
2023-04-25 15:54:56 +02:00
If the client creates the secret the client only needs to share the public key of that secret for authorization. The user authorized that pubkey and no sensitivate data needs to be shared.
2023-08-03 13:29:43 +02:00
##### Query parameter options for /new
- `name`: the name of the client app
2023-04-25 15:54:56 +02:00
- `pubkey`: the public key of the client's secret for the user to authorize
2023-06-05 16:06:25 +02:00
- `return_to`: (optional) if a `return_to` URL is provided the user will be redirected to that URL after authorization. The `lud16`, `relay` and `pubkey` query parameters will be added to the URL.
- `expires_at` (optional) connection cannot be used after this date. Unix timestamp in seconds.
- `max_amount` (optional) maximum amount in sats that can be sent per renewal period
- `budget_renewal` (optional) reset the budget at the end of the given budget renewal. Can be `never` (default), `daily`, `weekly`, `monthly`, `yearly`
- `request_methods` (optional) url encoded, space separated list of request types that you need permission for: `pay_invoice` (default), `get_balance` (see NIP47). For example: `..&request_methods=pay_invoice%20get_balance`
- `notification_types` (optional) url encoded, space separated list of notification types that you need permission for: For example: `..&notification_types=payment_received%20payment_sent`
Feat: dynamic budgets (#226) * feat: add transactions table * feat: add transactions service with makeinvoice method * feat: use internal transactions WIP * feat: check unsettled transactions * feat: use transactions service in nip47 package WIP * feat: use transactions service in NIP-47 handlers * fix: transaction list colors * fix: tests * chore: remove old payments table * fix: return budget usage as sats * feat: use internal transactions table for keysend payments * feat: consume nwc_payment_received event in transaction service (WIP) * feat: update existing transaction from nwc_payment_received event in transactions service * feat: update existing transaction from nwc_payment_sent event in transactions service * feat: handle async payment failed events in transactions service * fix: tests * feat: correctly implement NIP-47 NOT_FOUND error code * feat: intercept self payments * feat: isolated balance and visibility * feat: validate keysend payment does not exceed app internal balance * feat: budget check in transactions service, correctly pass payment errors to NIP-47 response also reduce query duplication * fix: order transactions when looking up transaction * feat: add fee reserves to unsettled outgoing transactions * chore: rename app permissions max amount field * chore: rename transaction amount values to be clearly millisats * chore: merge balance type and visibility into isolated property on apps table * chore: move duplicated permission check from nip-47 controllers to handler * fix: app name in transaction list * Feat: permissions revamp v2 (#273) * feat: revamp permissions component * chore: changes * chore: changes * chore: add view mode for show app screen * chore: further changes * feat: new illustration for linking account (#254) * feat: new illustration for linking account * fix: update paths * fix: icon props (#256) * fix: use date from frontend * chore: add expiryselect component * chore: further changes * chore: further changes * chore: add date-fns for date picker * chore: further changes * chore: further changes * fix: add central LDK gossip node to help gossip new public channels (#262) * fix: make dialog responsive (#258) * chore: further changes * typo * chore: spacing issues * chore: use scopes from capabilities * chore: change scope type descriptions * chore: styling fixes * chore: fix typings * chore: budget renewal component * fix: LDK mark channel as inactive and show error if counterparty forwarding info missing (#267) fix: mark channel as inactive and show error if counterparty forwarding info missing * chore: remove unnecessary dark classes (#255) * fix: links to open first channel in sidebar and onboarding checklist (#268) * feat: improve migrate node UI (#269) * fix: migrate node copy (#270) * fix: stop nostr when app is shutdown and use context to stop lnclient (#271) * fix: permissions revamp WIP * feat: basic isolated apps UI * fix: new app connection, edit app connection, deep linking --------- Co-authored-by: im-adithya <imadithyavardhan@gmail.com> Co-authored-by: René Aaron <100827540+reneaaron@users.noreply.github.com> Co-authored-by: Michael Bumann <hello@michaelbumann.com> * fix: make transactions table ID autoincrement * fix: do not send unrelated notifications to isolated apps * fix: nip-47 notifications not receiving updated transaction state * fix: migrate existing tables to have autoincrementing primary keys (#274) * fix: migrate existing tables to have autoincrementing primary keys * fix: recreate request and response event tables after apps * fix: remove null from request_events app_id * fix: do not crash when reloading app created page * chore: update pragma commands, add busy_timeout * fix: remove unnecessary migration of user_configs table * chore: update comment on autoincrement migration * feat: sqlite database config improvements * fix: autoincrement migration to delete unlinked app permissions * chore: update tests for dynamic budgets (WIP) * fix: get balance tests * chore: add extra event handler tests * chore: add extra event handler test * chore: add extra multi_pay_invoice tests * chore: transactions service tests (WIP) * chore: add transactions service payment tests * chore: add tests for self payments * fix: notifications tests * chore: add notifications tests for transactions service * chore: add fee reserve tests for transactions service * chore: add list transactions tests * chore: add keysend tests for transactions service * feat: subscribe for payments and invoices (#281) * fix: db transaction should be passed as pointer * feat(lnd): subscribe for payments and invoices * chore: rearrange check for settled * chore: remove TODO * chore: retry on error and add select * chore: publish payment failed event * chore: use json logging * feat: add lnd notification types * chore: remove sleep * fix: incorrect key on transaction list items * fix: test * fix: disable isolated app type on non-supported backends --------- Co-authored-by: im-adithya <imadithyavardhan@gmail.com> Co-authored-by: René Aaron <100827540+reneaaron@users.noreply.github.com> Co-authored-by: Michael Bumann <hello@michaelbumann.com>
2024-07-19 23:30:22 +07:00
- `isolated` (optional) makes an isolated app connection with its own balance and only access to its own transaction list. e.g. `&isolated=true`. If using this option, you should not pass any custom request methods or notification types, nor set a budget or expiry.
2023-04-25 15:54:56 +02:00
Example:
`/apps/new?name=myapp&pubkey=47c5a21...&return_to=https://example.com`
2023-04-25 15:54:56 +02:00
2023-05-16 17:20:04 +03:00
#### Web-flow: client created secret
2023-04-25 15:54:56 +02:00
Web clients can open a new prompt popup to load the authorization page.
Once the user has authorized the app connection a `nwc:success` message is sent to the opening page (using `postMessage`) to indicate that the connection is authorized. See the `initNWC()` function in the [alby-js-sdk](https://github.com/getAlby/alby-js-sdk#nostr-wallet-connect-documentation)
Example:
```js
import { webln } from "alby-js-sdk";
const nwc = new webln.NWC();
// initNWC opens a prompt with /apps/new?c=myapp&pubkey=xxxx
// the promise resolves once the user has authorized the connection (when the `nwc:success` message is received) and the popup is closed automatically
// the promise rejects if the user cancels by closing the prompt popup
await nwc.initNWC({ name: "myapp" });
```
2023-04-25 15:54:56 +02:00
## Help
2023-09-23 20:25:01 +02:00
If you need help contact support@getalby.com or reach out on Nostr: npub1getal6ykt05fsz5nqu4uld09nfj3y3qxmv8crys4aeut53unfvlqr80nfm
You can also visit the chat of our Community on [Telegram](https://t.me/getalby).
2023-04-25 15:54:56 +02:00
## ⚡Donations
Want to support the work on Alby?
Support the Alby team ⚡hello@getalby.com
You can also contribute to our [bounty program](https://github.com/getAlby/lightning-browser-extension/wiki/Bounties): ⚡bounties@getalby.com
2023-12-12 15:29:35 +07:00
## NIP-47 Supported Methods
✅ NIP-47 info event
2023-12-22 13:21:38 +07:00
`expiration` tag in requests
2023-12-15 15:24:09 +07:00
2023-12-12 15:29:35 +07:00
### LND
`get_info`
`get_balance`
`pay_invoice`
2023-12-22 13:21:38 +07:00
- ⚠️ amount not supported (for amountless invoices)
- ⚠️ PAYMENT_FAILED error code not supported
2023-12-12 15:29:35 +07:00
2023-12-13 13:40:39 +05:30
`pay_keysend`
- ⚠️ PAYMENT_FAILED error code not supported
2023-12-13 13:40:39 +05:30
`make_invoice`
2023-12-12 15:29:35 +07:00
`lookup_invoice`
2023-12-12 15:29:35 +07:00
- ⚠️ NOT_FOUND error code not supported
2023-12-12 15:29:35 +07:00
2023-12-13 16:41:19 +05:30
`list_transactions`
2023-12-13 16:41:19 +05:30
- ⚠️ from and until in request not supported
- ⚠️ failed payments will not be returned
2023-12-12 15:29:35 +07:00
`multi_pay_invoice`
2023-12-12 15:29:35 +07:00
- ⚠️ amount not supported (for amountless invoices)
- ⚠️ PAYMENT_FAILED error code not supported
`multi_pay_keysend`
- ⚠️ PAYMENT_FAILED error code not supported
2023-12-12 15:29:35 +07:00
2024-02-02 12:40:38 +07:00
### Breez
(Supported methods coming soon)
## Node Distributions
2023-12-12 15:29:35 +07:00
Run NWC on your own node!
2023-12-12 15:29:35 +07:00
2024-02-02 12:40:38 +07:00
**NOTE: the below links are for the original version of NWC**
- [https://github.com/getAlby/umbrel-community-app-store](Umbrel)
- [https://github.com/horologger/nostr-wallet-connect-startos](Start9)
## Deploy it yourself
### From the release
2024-08-18 14:40:33 +07:00
#### Quick start (Linux)
Go to the [Quick start script](https://github.com/getAlby/hub/tree/master/scripts/linux-x86_64) which you can run as a service.
#### Manual (Linux)
Download and run the executable.
2024-08-02 18:12:14 +03:00
Have a look at the [configuration options](#optional-configuration-parameters)
```bash
wget https://getalby.com/install/hub/server-linux-x86_64.tar.bz2
tar -xvjf server-linux-x86_64.tar.bz2
# run Alby Hub and done!
./bin/albyhub
```
### Fly.io
Make sure to have the [fly command line tools installed ](https://fly.io/docs/hands-on/install-flyctl/)
```bash
wget https://getalby.com/install/hub/fly.toml
fly launch
fly apps open
```
Or manually:
- update `app = 'nwc'` on **line 6** to a unique name in fly.toml e.g. `app = 'nwc-john-doe-1234'`
- run `fly launch`
- press 'y' to copy configuration to the new app and then hit enter
- press 'n' to tweak the settings and then hit enter
- wait for the deployment to succeed, it should give you a URL like `https://nwc-john-doe-1234.fly.dev`
#### Update Fly App
- run `fly deploy`
2024-03-05 12:17:12 +07:00
#### View logs
Main application logs
- `fly logs`
LDK logs:
- `fly machine exec "tail -100 data/ldk/logs/ldk_node_latest.log"`
### Docker
2024-03-03 12:28:27 +07:00
#### From Alby's Container Registry
2024-02-20 22:52:55 +07:00
2024-06-24 15:13:12 +07:00
_Tested on Linux only_
2024-07-05 20:32:40 +07:00
`docker run -v ~/.local/share/albyhub:/data -e WORK_DIR='/data' -p 8080:8080 ghcr.io/getalby/hub:latest`
##### Build the image locally
`docker run -v ~/.local/share/albyhub:/data -e WORK_DIR='/data' -p 8080:8080 $(docker build -q .)`
2024-06-24 15:13:12 +07:00
2024-07-05 20:32:40 +07:00
##### Docker Compose
In this repository. Or manually download the docker-compose.yml file and then run:
2024-07-05 20:32:40 +07:00
`docker compose up`
#### From source
2024-07-05 20:32:40 +07:00
- install go (e.g. using snap)
- install build-essential
- install yarn
- run `(cd frontend && yarn install`
- run `(cd frontend && yarn build:http)`
- run `go run cmd/http/main.go`
### Render.com
[![Deploy to Render](https://render.com/images/deploy-to-render-button.svg)](https://render.com/deploy?repo=https://github.com/getAlby/hub)