alby-hub/README.md

641 lines
29 KiB
Markdown
Raw Normal View History

2024-09-04 15:01:14 +07:00
<img alt="Alby Hub Logo" src="./doc/logo.svg" width="400">
2024-02-02 12:09:15 +07:00
2024-09-04 15:01:14 +07:00
<br/>
2023-03-21 18:01:09 +01:00
2024-09-04 15:01:14 +07:00
## [Alby Hub](https://albyhub.com) - Your Own Center for Internet Money
Alby Hub 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
2024-02-02 12:40:38 +07:00
The application can run in two modes:
- Desktop (Wails app): Mac (arm64), Windows (amd64), Linux (amd64)
- HTTP (Web app): Docker, Linux (amd64), Mac (arm64)
2024-02-02 12:40:38 +07:00
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.
## Run on Alby Cloud
Visit [albyhub.com](https://albyhub.com) to learn more and get started and get Alby Hub running in minutes.
## Self Hosted
Go to the [Deploy it yourself](#deploy-it-yourself) section below.
2023-05-16 17:20:04 +03:00
## Supported Backends
2023-03-22 15:15:07 +01:00
feat: app child key derived from wallet master key (#736) * feat(appwalletKey): add GetBIP32ChildKey * feat: fix interface * feat: adding subscription WiP * feat: handle nostr subscriptions for lifecycle of apps * Delete .idea/.gitignore * Delete .idea/hub.iml * Delete .idea/modules.xml * Delete .idea/vcs.xml * fix: remove unnecessary * fix: missing handling legacy app * fix: review fixes * fix: use app.ID for key calculation instead of passing in event * fix: add TODO * fix: remove unnecessary check * fix: improve err handling and remove check * chore: store master nostr key to avoid deriving each time * chore: rename app nostr_pubkey to app_pubkey, extract app consumers into separate files * chore: finish renaming * fix: update app wallet pubkey on app creation * fix: not NULL check * fix: fix HandleEvent * fix: error handling * fix: error handling * fix: move StartSubscription to start.go * fix: remove duplicated error check * fix: make tests use AppsService for creating apps * chore: remove unused code * chore: minor event handler improvements - fix error code response when failing to update request event - fix log content when failing to decrypt request event - move logging of app to correct place * fix: add event_handler tests for legacy app * chore: add comment about legacy apps in deleteAppConsumer * fix: remove unused app from tests * fix: error handling in startAppWalletSubscription * fix: only create event info and nostr subscription for master key if there are legacy apps * fix: add legacy tests * fix: move fetching of Nip47 event info to deleteAppConsumer * fix: fixed arguments * fix: use require instead of assert * fix: adapt GetAppWalletKey to use DeriveKey with path 1' * fix: for backends that don't use a mnemonic, create appKey from nostrSecretKey * fix: cleanup eventPublisher Subscribers when relay reconnects * fix: bip32.FirstHardenedChild + appID * fix: remove unused env vars * fix: generate new mnemonic if empty * fix: add tests.CreateTestServiceWithMnemonic to fix TestEncryptedBackup * fix: handle both relay and main ctx Done * chore: add keys tests * chore: add extra assertions to keys test * chore: log when legacy app subscription is created * chore: remove unnecessary break * chore: add log when relay is successfully connected * fix: only auto-start node if it has been started before --------- Co-authored-by: Roland Bewick <roland.bewick@gmail.com>
2024-11-07 13:06:01 +01:00
By default Alby Hub uses the embedded LDK based lightning node. Optionally it can be configured to use an external node:
2024-07-05 13:10:18 +07:00
- LND
- Phoenixd
2024-07-05 13:10:18 +07:00
- Cashu
feat: add CLN backend (#2026) * feat: add CLN as a lnclient backend * feat: add hold invoice support for CLN backend * fix: reduce CLN form to just addresses and lightning dir * feat: add README for CLN grpc go code generation * fix: cln backend does not support keysend with given preimages * fix: hold invoice notifications in CLN backend * fix: remove dead code in CLN backend from ListTransactions * fix: env example CLN_ADDRESS_HOLD with different port to show it's a different service * fix: cleanup of CLN ressources in all cases * fix: cln backend's GetNetworkGraph only fetches specified nodeId's * fix: cln backend: only advertise hold methods for nip47 if hold plugin enabled * fix: cln's Shutdown should not stop CLN itself * fix: relax the LND README line regarding env configuration * fix: more nil checks in clnInvoiceToTransaction * fix: prevent feerate overflow in CLN's RedeemOnchainFunds * fix: don't access nil errors for empty reponses of certain CLN methods * fix: nil instead of empty string in cln's GetNetworkGraph return types * fix: nil checks for created_at in cln's clnInvoiceToTransaction * fix: set minimum tls version to 1.2 for cln backend grpc connections * fix: cln's subscribeOpenHoldInvoices doesn't give up as fast * fix: deduplicate graph edges in cln's GetNetworkGraph * fix: print the error string, not pointer address, in cln's ListChannels * fix: remove cln's ListTransactions completely * fix: use ListPeers instead of ListPeerChannels in cln's ListPeers * feat: cln's MakeHoldInvoice supports minCltvExpiryDelta * fix: use named return err in NewCLNService * fix: cln listpeers log message * fix: incorrect import * fix: compile errors after rename --------- Co-authored-by: Roland Bewick <roland.bewick@gmail.com>
2026-05-03 21:36:13 +02:00
- CLN
- want more? please open an issue.
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
### Environment setup
feat: app child key derived from wallet master key (#736) * feat(appwalletKey): add GetBIP32ChildKey * feat: fix interface * feat: adding subscription WiP * feat: handle nostr subscriptions for lifecycle of apps * Delete .idea/.gitignore * Delete .idea/hub.iml * Delete .idea/modules.xml * Delete .idea/vcs.xml * fix: remove unnecessary * fix: missing handling legacy app * fix: review fixes * fix: use app.ID for key calculation instead of passing in event * fix: add TODO * fix: remove unnecessary check * fix: improve err handling and remove check * chore: store master nostr key to avoid deriving each time * chore: rename app nostr_pubkey to app_pubkey, extract app consumers into separate files * chore: finish renaming * fix: update app wallet pubkey on app creation * fix: not NULL check * fix: fix HandleEvent * fix: error handling * fix: error handling * fix: move StartSubscription to start.go * fix: remove duplicated error check * fix: make tests use AppsService for creating apps * chore: remove unused code * chore: minor event handler improvements - fix error code response when failing to update request event - fix log content when failing to decrypt request event - move logging of app to correct place * fix: add event_handler tests for legacy app * chore: add comment about legacy apps in deleteAppConsumer * fix: remove unused app from tests * fix: error handling in startAppWalletSubscription * fix: only create event info and nostr subscription for master key if there are legacy apps * fix: add legacy tests * fix: move fetching of Nip47 event info to deleteAppConsumer * fix: fixed arguments * fix: use require instead of assert * fix: adapt GetAppWalletKey to use DeriveKey with path 1' * fix: for backends that don't use a mnemonic, create appKey from nostrSecretKey * fix: cleanup eventPublisher Subscribers when relay reconnects * fix: bip32.FirstHardenedChild + appID * fix: remove unused env vars * fix: generate new mnemonic if empty * fix: add tests.CreateTestServiceWithMnemonic to fix TestEncryptedBackup * fix: handle both relay and main ctx Done * chore: add keys tests * chore: add extra assertions to keys test * chore: log when legacy app subscription is created * chore: remove unnecessary break * chore: add log when relay is successfully connected * fix: only auto-start node if it has been started before --------- Co-authored-by: Roland Bewick <roland.bewick@gmail.com>
2024-11-07 13:06:01 +01:00
$ cp .env.example .env
# edit the config for your needs (Read further down for all the available env options)
$ vim .env
### 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:http`
2023-04-25 15:54:56 +02:00
### HTTP Production build
$ yarn build:http
If you plan to run Alby Hub on a subpath behind a reverse proxy, you can do:
$ BASE_PATH="/hub" yarn build:http
### 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
### Debugging
In vscode open [cmd/http/main.go](cmd/http/main.go) and then press F5. You can set breakpoints in the Alby Hub code and third party modules
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
#### Testing with PostgreSQL
By default, sqlite is used for testing. It is also possible to run the tests with PostgreSQL.
The tests use [pgtestdb](https://github.com/peterldowns/pgtestdb) to set up a temporary PostgreSQL database, which requires a running PostgreSQL server. Follow your OS instructions to install PostgreSQL, or use the official [Docker image](https://hub.docker.com/_/postgres).
See the [docker compose file](./tests/db/postgres/docker-compose.yml) for an easy way to get started.
When PostgreSQL is installed and running, set the `TEST_DATABASE_URI` environment variable to the PostgreSQL connection string. For example:
$ export TEST_DATABASE_URI="postgresql://user:password@localhost:5432/postgres"
Note that the PostgreSQL user account must be granted appropriate permissions to create new databases. When the tests complete, the temporary database will be removed.
**Do not** use a production database. It is preferable to launch a dedicated PostgreSQL instance for testing purposes.
#### Mocking
We use [testify/mock](https://github.com/stretchr/testify) to facilitate mocking in tests. Instead of writing mocks manually, we generate them using [vektra/mockery](https://github.com/vektra/mockery). To regenerate them, [install mockery](https://vektra.github.io/mockery/latest/installation) and run it in the project's root directory:
$ mockery
Mockery loads its configuration from the .mockery.yaml file in the root directory of this project. To add mocks for new interfaces, add them to the configuration file and run mockery.
### 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).
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-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
- `RELAY`: default: "wss://relay.getalby.com,wss://relay2.getalby.com" (supports multiple separated by commas)
2025-05-14 18:56:39 +05:30
- `DATABASE_URI`: A sqlite filename or postgres URL. Default is SQLite DB `nwc.db` without a path, which will be put in the user home directory: $XDG_DATA_HOME/albyhub/nwc.db
- `PORT`: The port on which the app should listen on (default: 8080)
- `WORK_DIR`: Directory to store NWC data files. Default: $XDG_DATA_HOME/albyhub
- `LOG_LEVEL`: Log level for the main application. Higher is more verbose. Default: 4 (info)
2025-05-14 18:56:39 +05:30
- `AUTO_UNLOCK_PASSWORD`: Provide unlock password to auto-unlock Alby Hub on startup (e.g. after a machine restart). Unlock password still be required to access the interface.
- `BOLTZ_API`: The api which provides auto swaps functionality. Default: "https://api.boltz.exchange"
- `NETWORK`: On-chain network used for the node. Default: "bitcoin"
- `REBALANCE_SERVICE_URL`: service url for rebalancing existing channels.
Swaps improvements (shifting to standalone page + one-time swaps) (#1371) * chore: move out swaps from settings * chore: link to swaps in wallet and node page * chore: add frontend for swap ins * chore: update all swap redirects * chore: remove swap dialogs * chore: remove auto swap-ins frontend * feat: add support for one time swap outs * chore: remove unused code * chore: use separate endpoint for one off swap outs * chore: further changes * chore: separate one off and auto swaps * chore: naming changes * fix: tests * feat: add one off swap in * feat: add auto swap ins * chore: remove comments * fix: tests * chore: further changes * chore: further changes * chore: rename to swap in and swap out * chore: do not show swaps for non LDK/LND users * chore: add receive limit checks for swap ins * chore: remove probing * chore: dark mode * fix: swap link * chore: add extra swap links * fix: fee rates log * fix: fee rates log * chore: color changes * Feat: swap out improvements (#1403) * feat: swap out improvements - add lockup transaction id to hold payment metadata - return swap ID and payment hash in swap out response - retries to get fee rates - separate swap out success page with status * chore: rename * chore: show current balance on swap out form * chore: add pulse animation to badge while pending * chore: minor typo * chore: update fee rate retry interval to 10 seconds * chore: use icons instead of badges --------- Co-authored-by: im-adithya <imadithyavardhan@gmail.com> * chore: update comment * chore: remove comment * chore: update boltz client to v2.6.1 * feat: swap in improvements (WIP) (#1411) * feat: swap in improvements (WIP) * feat: new swap in status page * fix: hide pay button when already paid * chore: improve swap in UI * chore: more swap in ui improvements * chore: minor improvements and fixes * fix: typo * feat: add swap in refund logic in case of failure * fix: tests * chore: add swap expired case for refunds --------- Co-authored-by: im-adithya <imadithyavardhan@gmail.com> * feat: add swaps table (#1419) * feat: add swaps table * fix: test * chore: bump LDK-node to v0.6.0 (#1418) * [Freepilot] fix: startup error handling (#1413) * fix: handle errors from service.NewService() in startup code Previously, both HTTP and Wails startup code ignored errors from service.NewService(ctx) using blank identifier (_), which could cause panics later if NewService fails (e.g., unable to connect to postgres database). Now properly handle the error and exit gracefully with a fatal log message when service initialization fails. * fix: compile error --------- Co-authored-by: Roland Bewick <roland.bewick@gmail.com> * feat: add hd key derivation * Chore: add albyhub region cookie to developer page (#1421) * docs: add AlbyHub-Region cookie instructions to developer page * fix: use region from alby api --------- Co-authored-by: achaldps@gmail.com <achaldps@gmail.com> * build(deps): bump golang.org/x/crypto from 0.38.0 to 0.39.0 (#1415) Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.38.0 to 0.39.0. - [Commits](https://github.com/golang/crypto/compare/v0.38.0...v0.39.0) --- updated-dependencies: - dependency-name: golang.org/x/crypto dependency-version: 0.39.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump gorm.io/driver/sqlite from 1.5.7 to 1.6.0 (#1416) Bumps [gorm.io/driver/sqlite](https://github.com/go-gorm/sqlite) from 1.5.7 to 1.6.0. - [Commits](https://github.com/go-gorm/sqlite/compare/v1.5.7...v1.6.0) --- updated-dependencies: - dependency-name: gorm.io/driver/sqlite dependency-version: 1.6.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump github.com/btcsuite/btcd/btcec/v2 from 2.3.4 to 2.3.5 (#1417) Bumps [github.com/btcsuite/btcd/btcec/v2](https://github.com/btcsuite/btcd) from 2.3.4 to 2.3.5. - [Release notes](https://github.com/btcsuite/btcd/releases) - [Changelog](https://github.com/btcsuite/btcd/blob/master/CHANGES) - [Commits](https://github.com/btcsuite/btcd/compare/btcec/v2.3.4...btcec/v2.3.5) --- updated-dependencies: - dependency-name: github.com/btcsuite/btcd/btcec/v2 dependency-version: 2.3.5 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * feat: allow setting LDK node alias (#1398) * feat: add node alias customization for LDK nodes with public channels - Add new NodeAlias field to InfoResponse in API - Add SetNodeAlias method to API with config storage - Add HTTP endpoint POST /node/alias for setting node alias - Add corresponding Wails endpoint support - Create new Node settings page in frontend - Add conditional navigation item for LDK nodes with public channels - Include upgrade dialog and paid subscription check - Display success message prompting node restart after alias change - Show error toast for non-paid users attempting to change alias * chore: use node alias from config in LDK init * fix: make upgrade button non-absolute, remove disabled attribute * chore: move node alias page to be consistent with other node management pages * chore: remove redundant comment * chore: show upgrade dialog when clicking node alias option, show also for private channels --------- Co-authored-by: Roland Bewick <roland.bewick@gmail.com> * fix: always pass in fee and handle mempool errors (#1408) * fix: always pass in fee and handle mempool errors * chore: improve withdraw on-chain funds UI --------- Co-authored-by: Roland Bewick <roland.bewick@gmail.com> * feat: derive keys from id and add fields to swap table * feat: use bip 85 to derive swap mnemonic * chore: mark swaps as failed if payment fails * feat: add process refund method for swap ins * chore: add process refund to swap service interface * feat: add frontend * fix: swap out failure message * feat: add process refund button in swap in status screen * chore: further improvements * fix: wails routes * feat: add frequency selector for ZapPlanner payments (#1312) (#1317) * feat: add frequency selector for ZapPlanner payments (#1312) * feat: add frequency selector for ZapPlanner payments (#1312) +corrections * feat(zapplanner): add USD/BTC selector and frequency option Budget renewal still has to be adjusted * feat(zapplanner): set default frequency to 1 month * feat(zapplanner): set default amount to usd and added (sats) to clarify BTC unit * feat(zapplanner): convert months to days for subscriptions * feat(zapplanner): add open to convertCurrency deps to allow consecutive subscriptions * feat(Zapplanner freq&currency selector): added all currencies to the selector * feat(Zapplanner freq&currency selector): removed bug about 2xBTC(sats) on the menu * feat(zapplanner): frequency & currency all comments addressed * chore: zapplanner fixes - currency sorting - sats currency usage for ZapPlanner - force whole values for ZapPlanner - pass correct currency to ZapPlanner - rename field - fix input width --------- Co-authored-by: jpl-btc <> Co-authored-by: Roland Bewick <roland.bewick@gmail.com> * chore: add reconnection logic * chore: specify fees while locking btc * fix: do not use context background * chore: improve auto swaps frontend * chore: add boltz logo to tx item * Updated Primal app connection (#1428) * Updated Primal app connection * fix: lint --------- Co-authored-by: René Aaron <rene@twentyuno.net> * chore: bump uniffi-bindgen-go and revert error handling in the LDK client (#1434) * chore: revert error handling in the LDK client * chore: update ldk-node-go dependency --------- Co-authored-by: Roland Bewick <roland.bewick@gmail.com> * Read.me adjustments (#1440) * Update README.md 1) We spend a lot of time helping users to fix their problems with Raspi PIs. 2) Computers that are offline regularly create a bad UX because payments in external apps do not work and channels are closed earlier. * Update README.md * feat: add expired state to nip47 transactions (#1441) * fix: use custom mempool url (#1431) * fix: use custom mempool url * chore: return mempool url in info endpoint * chore: use mempool url from info response in frontend * chore: remove default mempool url in frontend * fix: tests * feat: add LDK bitcoind rpc chain source (#1367) * feat: add LDK bitcoind rpc chain source * fix: crash in bitcoindrpc due to not enabling continuous sync * chore: renaming * chore: mark swap status as failed * chore: use mempool url from info * chore: poll balances on node page * fix: when opening outbound channel, extract host part if full peer connection url is pasted * chore: use mempool url from backend info endpoint * docs: add boltz regtest setup instructions * chore: separate swap in and out status pages * fix: remove duplicate useInfo * fix: mnemonic derivation logic * chore: address comments * chore: add tests for swap mnemonic generation * chore: add refunded state * chore: rename columns * chore: simplify swap status frontend * chore: mark swap out as successful after claim tx conf * chore: add address to refund * fix: wails * feat: add resubscription * chore: add logging * chore: save refund address to db and use new address * chore: add comment --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Roland <33993199+rolznz@users.noreply.github.com> Co-authored-by: Freepilot <215356755+freepilot-bot@users.noreply.github.com> Co-authored-by: Roland Bewick <roland.bewick@gmail.com> Co-authored-by: achaldps@gmail.com <achaldps@gmail.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Nodii <13803869+NodeDiver@users.noreply.github.com> Co-authored-by: Moritz Kaminski <moritz.kaminski@gmail.com> Co-authored-by: René Aaron <rene@twentyuno.net> Co-authored-by: Roman D <roman@dmitrienko.com> * chore: rename to receive_amount * chore: remove auto swap success and add boltz link * chore: use constant and rename variables * fix: mark swaps as failed * fix: show receive amount in swap in success screen * chore: remove duplicate endpoint and reorder * chore: add comment in wails handler * chore: use markSwapState * chore: add retries * fix: use one websocket per swap * chore: frontend fixes * feat: add swap mnemonic to debug tools * fix: tx list * fix: tests * chore: further changes * chore: improve copy * chore: improve copy * chore: improve copy * chore: rename, add autofocus on swap inputs * fix: swap in failed state when no lockup tx exists * chore: add interval note to active swap component * chore: remove boltz image * chore: use hasChannelManagement check * chore: use link instead of navigate * chore: mark swaps as failed in case of errors * chore: add comment * chore: only mark swaps as failed in defer function * chore: improve copy * chore: update boltz client to v2.7.2 * chore: use refundSwapRequest param * fix: refund swap method * chore: minor changes * chore: add retries * chore: add retries and use single ws connection for pending swaps * fix: swap fee error message * chore: remove sending partial signature in swap in * chore: log error when update channel is not ok * fix: add tx claimed state in swap in listener * chore: add nwc_swap_succeeded to whitelist and readme * feat: use single boltz ws connection * chore: only check for tx claimed state * chore: use lock while sending updates * chore: handle boltz update error * chore: remove swap id from success event --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Roland Bewick <roland.bewick@gmail.com> Co-authored-by: Roland <33993199+rolznz@users.noreply.github.com> Co-authored-by: Freepilot <215356755+freepilot-bot@users.noreply.github.com> Co-authored-by: achaldps@gmail.com <achaldps@gmail.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Nodii <13803869+NodeDiver@users.noreply.github.com> Co-authored-by: Moritz Kaminski <moritz.kaminski@gmail.com> Co-authored-by: René Aaron <rene@twentyuno.net> Co-authored-by: Roman D <roman@dmitrienko.com>
2025-07-10 18:36:12 +05:30
### Boltz Regtest Setup
There is a boltz regtest fork with mempool service and alby-specific instructions [here](https://github.com/rolznz/boltz-regtest/tree/alby-hub?tab=readme-ov-file#your-first-swap)
Make sure to update your RPC password below, and change your work directory each time you restart boltz (it is ephemeral):
WORK_DIR=.data/boltz-regtest-1
LDK_BITCOIND_RPC_HOST="127.0.0.1"
LDK_BITCOIND_RPC_PORT="18443"
LDK_BITCOIND_RPC_USER="__cookie__"
LDK_BITCOIND_RPC_PASSWORD="f7460d81974b000b63e46c0e880243cf28bbaf93938b6e38494628f1f1700f23"
# or use esplora
#LDK_ESPLORA_SERVER=http://localhost:4002/api
NETWORK="regtest"
LDK_LISTENING_ADDRESSES="0.0.0.0:19735"
BOLTZ_API=http://localhost:9001
PORT=8082
MEMPOOL_API=http://localhost:8123/api
And then run the frontend with: `VITE_API_URL="http://localhost:8082" yarn dev:http`
2025-08-29 16:47:31 +07:00
To test auto-swaps to xpub you can use sparrow wallet in regtest:
/opt/sparrow/bin/Sparrow -n regtest
Sparrow needs to be connected to regtest boltz setup Bitcoin Core RPC (127.0.0.1:18443 with user:password as `__cookie__:cookiepassword`) with an imported mnemonic and copied the tpub from the settings page
feat: PostgreSQL support (#922) * feat: enable Postgres connections * feat: implement migration templates * feat: convert sqlite-specific migrations to migration templates; adjust SQL syntax * fix: add migration to fix postgres incompatibilities in the DB schema * fix: correct SQL syntax for comparisons in the transactions service * feat: database migration tool * chore: update tests for testing with Postgres * fix: update test * fix: explicitly store mock timestamps in UTC * chore: add txdb to go.mod and run tidy * fix: serialize concurrent transactions when running tests with txdb * chore: update README to mention postgres * fix: use timestamptz in Postgres * test: add Github action for testing the backend with Postgres * chore: fix migration name and add comments * docs: add db migration notes to README * fix: address PR feedback * fix: rename the cmd/migrate tool to cmd/db_migrate * feat: add schema check in the DB migration tool * test: use testdb instead of txdb for testing with Postgresql * fix: fix tests after merge * chore: comment out unused VACUUM in migrations * fix: reset Postgres sequences after migrating data * docs: update migrate command in readme * fix: do not allow backup for migration when postgres is enabled * chore: add debug logs for db backend type * chore: use Logrus instead of slog for db_migrate * fix: initialize logger in the keys tests * test: add db_migrate test * fix: use transaction object in db_migrate function * fix: txlock in db migration test --------- Co-authored-by: Roland Bewick <roland.bewick@gmail.com>
2025-01-16 13:17:24 +03:00
### Migrating the database (Sqlite <-> Postgres)
Migration of the database is currently experimental. Please make a backup before continuing.
#### Migration from Sqlite to Postgres
1. Stop the running hub
2. Update the `DATABASE_URI` to your destination e.g. `postgresql://myuser:mypass@localhost:5432/nwc`
3. Run the migration:
go run cmd/db_migrate/main.go -from .data/nwc.db -to postgresql://myuser:mypass@localhost:5432/nwc
## Node-specific backend parameters
- `ENABLE_ADVANCED_SETUP`: set to `false` to force a specific backend type (combined with backend parameters below)
feat: add CLN backend (#2026) * feat: add CLN as a lnclient backend * feat: add hold invoice support for CLN backend * fix: reduce CLN form to just addresses and lightning dir * feat: add README for CLN grpc go code generation * fix: cln backend does not support keysend with given preimages * fix: hold invoice notifications in CLN backend * fix: remove dead code in CLN backend from ListTransactions * fix: env example CLN_ADDRESS_HOLD with different port to show it's a different service * fix: cleanup of CLN ressources in all cases * fix: cln backend's GetNetworkGraph only fetches specified nodeId's * fix: cln backend: only advertise hold methods for nip47 if hold plugin enabled * fix: cln's Shutdown should not stop CLN itself * fix: relax the LND README line regarding env configuration * fix: more nil checks in clnInvoiceToTransaction * fix: prevent feerate overflow in CLN's RedeemOnchainFunds * fix: don't access nil errors for empty reponses of certain CLN methods * fix: nil instead of empty string in cln's GetNetworkGraph return types * fix: nil checks for created_at in cln's clnInvoiceToTransaction * fix: set minimum tls version to 1.2 for cln backend grpc connections * fix: cln's subscribeOpenHoldInvoices doesn't give up as fast * fix: deduplicate graph edges in cln's GetNetworkGraph * fix: print the error string, not pointer address, in cln's ListChannels * fix: remove cln's ListTransactions completely * fix: use ListPeers instead of ListPeerChannels in cln's ListPeers * feat: cln's MakeHoldInvoice supports minCltvExpiryDelta * fix: use named return err in NewCLNService * fix: cln listpeers log message * fix: incorrect import * fix: compile errors after rename --------- Co-authored-by: Roland Bewick <roland.bewick@gmail.com>
2026-05-03 21:36:13 +02:00
### CLN Backend parameters
Can be configured via env or the UI
- `LN_BACKEND_TYPE`: CLN
- `CLN_ADDRESS`: the CLN grpc address (grpc-host and grpc-port), e.g. `127.0.0.1:9737`
- `CLN_LIGHTNING_DIR`: CLN's lightning directory containing the grpc certificates, usually `~/.lightning/<network>`
Optional for hold invoice methods support:
feat: add CLN backend (#2026) * feat: add CLN as a lnclient backend * feat: add hold invoice support for CLN backend * fix: reduce CLN form to just addresses and lightning dir * feat: add README for CLN grpc go code generation * fix: cln backend does not support keysend with given preimages * fix: hold invoice notifications in CLN backend * fix: remove dead code in CLN backend from ListTransactions * fix: env example CLN_ADDRESS_HOLD with different port to show it's a different service * fix: cleanup of CLN ressources in all cases * fix: cln backend's GetNetworkGraph only fetches specified nodeId's * fix: cln backend: only advertise hold methods for nip47 if hold plugin enabled * fix: cln's Shutdown should not stop CLN itself * fix: relax the LND README line regarding env configuration * fix: more nil checks in clnInvoiceToTransaction * fix: prevent feerate overflow in CLN's RedeemOnchainFunds * fix: don't access nil errors for empty reponses of certain CLN methods * fix: nil instead of empty string in cln's GetNetworkGraph return types * fix: nil checks for created_at in cln's clnInvoiceToTransaction * fix: set minimum tls version to 1.2 for cln backend grpc connections * fix: cln's subscribeOpenHoldInvoices doesn't give up as fast * fix: deduplicate graph edges in cln's GetNetworkGraph * fix: print the error string, not pointer address, in cln's ListChannels * fix: remove cln's ListTransactions completely * fix: use ListPeers instead of ListPeerChannels in cln's ListPeers * feat: cln's MakeHoldInvoice supports minCltvExpiryDelta * fix: use named return err in NewCLNService * fix: cln listpeers log message * fix: incorrect import * fix: compile errors after rename --------- Co-authored-by: Roland Bewick <roland.bewick@gmail.com>
2026-05-03 21:36:13 +02:00
- `CLN_ADDRESS_HOLD`: the CLN hold plugin grpc address (grpc-host and grpc-port), e.g. `127.0.0.1:9738`
If you are copying the certificates to another machine make sure you get the `ca.pem`, `client.pem` and `client-key.pem` from the lightning directory and optionally from the `hold` directory inside the lightning directory and keep the sub-directory structure of the hold directory.
### LND Backend parameters
feat: add CLN backend (#2026) * feat: add CLN as a lnclient backend * feat: add hold invoice support for CLN backend * fix: reduce CLN form to just addresses and lightning dir * feat: add README for CLN grpc go code generation * fix: cln backend does not support keysend with given preimages * fix: hold invoice notifications in CLN backend * fix: remove dead code in CLN backend from ListTransactions * fix: env example CLN_ADDRESS_HOLD with different port to show it's a different service * fix: cleanup of CLN ressources in all cases * fix: cln backend's GetNetworkGraph only fetches specified nodeId's * fix: cln backend: only advertise hold methods for nip47 if hold plugin enabled * fix: cln's Shutdown should not stop CLN itself * fix: relax the LND README line regarding env configuration * fix: more nil checks in clnInvoiceToTransaction * fix: prevent feerate overflow in CLN's RedeemOnchainFunds * fix: don't access nil errors for empty reponses of certain CLN methods * fix: nil instead of empty string in cln's GetNetworkGraph return types * fix: nil checks for created_at in cln's clnInvoiceToTransaction * fix: set minimum tls version to 1.2 for cln backend grpc connections * fix: cln's subscribeOpenHoldInvoices doesn't give up as fast * fix: deduplicate graph edges in cln's GetNetworkGraph * fix: print the error string, not pointer address, in cln's ListChannels * fix: remove cln's ListTransactions completely * fix: use ListPeers instead of ListPeerChannels in cln's ListPeers * feat: cln's MakeHoldInvoice supports minCltvExpiryDelta * fix: use named return err in NewCLNService * fix: cln listpeers log message * fix: incorrect import * fix: compile errors after rename --------- Co-authored-by: Roland Bewick <roland.bewick@gmail.com>
2026-05-03 21:36:13 +02:00
LND can be configured via env. Other node types may need to be configured via the UI.
2024-02-14 17:47:53 +07:00
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
2024-09-17 15:53:58 +02:00
- `LDK_ESPLORA_SERVER`: By default the optimized Alby esplora is used. You can configure your own esplora server (note: the public blockstream one is slow and can cause onchain syncing and issues with opening channels)
- `LDK_VSS_URL`: Use VSS (encrypted remote storage) rather than local sqlite store for lightning and bitcoin data. Currently this feature only works for brand new Alby Hub instances that are connected to Alby Accounts with an active subscription plan.
- `LDK_LISTENING_ADDRESSES`: configure listening addresses, required for public channels, and ideally reachable if you would like others to be able to initiate peering with your node.
- `LDK_ANNOUNCEMENT_ADDRESSES`: configure announcement addresses (only required if you use a VPN)
- `LDK_MAX_CHANNEL_SATURATION`: Sets the maximum portion of a channel's total capacity that may be used for sending a payment, expressed as a power of 1/2. See `max_channel_saturation_power_of_half` in [LDK docs](https://docs.rs/lightning/latest/lightning/routing/router/struct.PaymentParameters.html#structfield.max_channel_saturation_power_of_half).
- `LDK_MAX_PATH_COUNT`: Maximum number of paths that may be used by MPP payments.
- `LDK_LOG_LEVEL`: Log level for the LDK node. Higher is more verbose. Default: 3. This is separate from the main application log level, allowing you to enable more verbose LDK logging (e.g., level 4, 5 or 6) without enabling verbose logging for the entire application.
- `LDK_CHANNEL_MONITOR_WARNING_SIZE_BYTES`: If a channel monitor is larger than this value, a performance warning will be shown on the node page.
#### LDK Network Configuration
##### Mutinynet
- `MEMPOOL_API=https://mutinynet.com/api`
2025-05-14 18:56:39 +05:30
- `NETWORK=signet`
- `LDK_ESPLORA_SERVER=https://mutinynet.com/api`
- `LDK_GOSSIP_SOURCE=https://rgs.mutinynet.com/snapshot` (NOTE: by default ALby Hub does not use RGS)
(or electrum instead of esplora)
- `LDK_ELECTRUM_SERVER=electrum.mutinynet.com:50001`
2026-01-23 10:17:19 +07:00
##### Signet
- `MEMPOOL_API=https://mempool.space/signet/api`
- `LDK_NETWORK=signet`
- `LDK_ESPLORA_SERVER=https://mempool.space/signet/api`
##### Testnet (Not recommended - try Mutinynet)
- `MEMPOOL_API=https://mempool.space/testnet/api`
2025-05-14 18:56:39 +05:30
- `NETWORK=testnet`
- `LDK_ESPLORA_SERVER=https://mempool.space/testnet/api`
- `LDK_GOSSIP_SOURCE=https://rapidsync.lightningdevkit.org/testnet/snapshot` (NOTE: by default ALby Hub does not use RGS)
###### Connect to your own bitcoind
- `LDK_BITCOIND_RPC_HOST=127.0.0.1`
- `LDK_BITCOIND_RPC_PORT=8332`
- `LDK_BITCOIND_RPC_USER=yourusername`
- `LDK_BITCOIND_RPC_PASSWORD=yourpassword`
### Phoenixd
See [Phoenixd](scripts/linux-x86_64/phoenixd/README.md)
### Bark
Bark connects to an [Ark](https://second.tech/) server. It can be configured via env.
- `LN_BACKEND_TYPE`: BARK
- `BARK_SERVER`: the Ark server URL. For signet use `https://ark.signet.2nd.dev`
- `BARK_ESPLORA_SERVER`: the Esplora server URL used for chain data. For signet use `https://esplora.signet.2nd.dev`.
- `BARK_SERVER_ACCESS_TOKEN`: an optional access token required by the Ark server (pre-public mainnet launch).
2026-06-05 16:40:43 +07:00
- `BARK_LOG_LEVEL`: Log level for Bark. Higher is more verbose. Default: 3. This is separate from the main application log level, allowing you to enable more verbose Bark logging (e.g., level 4 or 5) without enabling verbose logging for the entire application.
### 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, make sure to set `FRONTEND_URL=http://localhost:5173` so that the OAuth redirect works.
## 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 from Alby Hub
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.
### Running Multiple Hubs Locally
You can run multiple hubs locally to e.g. open channels between the two nodes or test sending payments between them. Currently this will only work with LDK.
You will need two copies of the alby hub repository.
For the second hub, you will need to update your .env with the following changes:
FRONTEND_URL=http://localhost:5174
BASE_URL=http://localhost:8081
PORT=8081
LDK_LISTENING_ADDRESSES=[::]:9736
Then launch the frontend with `VITE_PORT=5174 VITE_API_URL=http://localhost:8081 yarn dev:http`
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 millisats 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 webview (using `dispatchEvent`) or opening page (using `postMessage`) to indicate that the connection is authorized. See the `fromAuthorizationUrl()` function in the [alby-js-sdk](https://github.com/getAlby/alby-js-sdk#nostr-wallet-connect-documentation)
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
## 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
### Requirements
The application has no runtime dependencies. (simple Go executable).
As data storage SQLite is used.
For the default backend which runs a node internally we recommend 2GB of RAM + 1GB of disk space (or 512MB RAM + 2GB swap can also be used). For connecting to an external node, Alby Hub uses very little RAM (256MB is enough).
### From the release
#### Quick start (x86 Linux Server)
2024-08-18 14:40:33 +07:00
Go to the [Quick start script](https://github.com/getAlby/hub/tree/master/scripts/linux-x86_64) which you can run as a service.
#### Quick start (Arm64 Linux Server)
Go to the [Quick start script](https://github.com/getAlby/hub/blob/master/scripts/linux-aarch64) which you can run as a service.
#### Quick start (Raspberry PI 4/5)
Go to the [Quick start script](https://github.com/getAlby/hub/blob/master/scripts/pi-aarch64) which you can run as a service. (Experimental we cannot provide support for installations on Raspberry PI 4/5.)
#### Quick start (Raspberry PI Zero)
Go to the [Quick start script](https://github.com/getAlby/hub/tree/master/scripts/pi-arm) which you can run as a service. (Experimental we cannot provide support for installations on Raspberry PI Zero.)
#### Quick start (Desktop)
Swaps improvements (shifting to standalone page + one-time swaps) (#1371) * chore: move out swaps from settings * chore: link to swaps in wallet and node page * chore: add frontend for swap ins * chore: update all swap redirects * chore: remove swap dialogs * chore: remove auto swap-ins frontend * feat: add support for one time swap outs * chore: remove unused code * chore: use separate endpoint for one off swap outs * chore: further changes * chore: separate one off and auto swaps * chore: naming changes * fix: tests * feat: add one off swap in * feat: add auto swap ins * chore: remove comments * fix: tests * chore: further changes * chore: further changes * chore: rename to swap in and swap out * chore: do not show swaps for non LDK/LND users * chore: add receive limit checks for swap ins * chore: remove probing * chore: dark mode * fix: swap link * chore: add extra swap links * fix: fee rates log * fix: fee rates log * chore: color changes * Feat: swap out improvements (#1403) * feat: swap out improvements - add lockup transaction id to hold payment metadata - return swap ID and payment hash in swap out response - retries to get fee rates - separate swap out success page with status * chore: rename * chore: show current balance on swap out form * chore: add pulse animation to badge while pending * chore: minor typo * chore: update fee rate retry interval to 10 seconds * chore: use icons instead of badges --------- Co-authored-by: im-adithya <imadithyavardhan@gmail.com> * chore: update comment * chore: remove comment * chore: update boltz client to v2.6.1 * feat: swap in improvements (WIP) (#1411) * feat: swap in improvements (WIP) * feat: new swap in status page * fix: hide pay button when already paid * chore: improve swap in UI * chore: more swap in ui improvements * chore: minor improvements and fixes * fix: typo * feat: add swap in refund logic in case of failure * fix: tests * chore: add swap expired case for refunds --------- Co-authored-by: im-adithya <imadithyavardhan@gmail.com> * feat: add swaps table (#1419) * feat: add swaps table * fix: test * chore: bump LDK-node to v0.6.0 (#1418) * [Freepilot] fix: startup error handling (#1413) * fix: handle errors from service.NewService() in startup code Previously, both HTTP and Wails startup code ignored errors from service.NewService(ctx) using blank identifier (_), which could cause panics later if NewService fails (e.g., unable to connect to postgres database). Now properly handle the error and exit gracefully with a fatal log message when service initialization fails. * fix: compile error --------- Co-authored-by: Roland Bewick <roland.bewick@gmail.com> * feat: add hd key derivation * Chore: add albyhub region cookie to developer page (#1421) * docs: add AlbyHub-Region cookie instructions to developer page * fix: use region from alby api --------- Co-authored-by: achaldps@gmail.com <achaldps@gmail.com> * build(deps): bump golang.org/x/crypto from 0.38.0 to 0.39.0 (#1415) Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.38.0 to 0.39.0. - [Commits](https://github.com/golang/crypto/compare/v0.38.0...v0.39.0) --- updated-dependencies: - dependency-name: golang.org/x/crypto dependency-version: 0.39.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump gorm.io/driver/sqlite from 1.5.7 to 1.6.0 (#1416) Bumps [gorm.io/driver/sqlite](https://github.com/go-gorm/sqlite) from 1.5.7 to 1.6.0. - [Commits](https://github.com/go-gorm/sqlite/compare/v1.5.7...v1.6.0) --- updated-dependencies: - dependency-name: gorm.io/driver/sqlite dependency-version: 1.6.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump github.com/btcsuite/btcd/btcec/v2 from 2.3.4 to 2.3.5 (#1417) Bumps [github.com/btcsuite/btcd/btcec/v2](https://github.com/btcsuite/btcd) from 2.3.4 to 2.3.5. - [Release notes](https://github.com/btcsuite/btcd/releases) - [Changelog](https://github.com/btcsuite/btcd/blob/master/CHANGES) - [Commits](https://github.com/btcsuite/btcd/compare/btcec/v2.3.4...btcec/v2.3.5) --- updated-dependencies: - dependency-name: github.com/btcsuite/btcd/btcec/v2 dependency-version: 2.3.5 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * feat: allow setting LDK node alias (#1398) * feat: add node alias customization for LDK nodes with public channels - Add new NodeAlias field to InfoResponse in API - Add SetNodeAlias method to API with config storage - Add HTTP endpoint POST /node/alias for setting node alias - Add corresponding Wails endpoint support - Create new Node settings page in frontend - Add conditional navigation item for LDK nodes with public channels - Include upgrade dialog and paid subscription check - Display success message prompting node restart after alias change - Show error toast for non-paid users attempting to change alias * chore: use node alias from config in LDK init * fix: make upgrade button non-absolute, remove disabled attribute * chore: move node alias page to be consistent with other node management pages * chore: remove redundant comment * chore: show upgrade dialog when clicking node alias option, show also for private channels --------- Co-authored-by: Roland Bewick <roland.bewick@gmail.com> * fix: always pass in fee and handle mempool errors (#1408) * fix: always pass in fee and handle mempool errors * chore: improve withdraw on-chain funds UI --------- Co-authored-by: Roland Bewick <roland.bewick@gmail.com> * feat: derive keys from id and add fields to swap table * feat: use bip 85 to derive swap mnemonic * chore: mark swaps as failed if payment fails * feat: add process refund method for swap ins * chore: add process refund to swap service interface * feat: add frontend * fix: swap out failure message * feat: add process refund button in swap in status screen * chore: further improvements * fix: wails routes * feat: add frequency selector for ZapPlanner payments (#1312) (#1317) * feat: add frequency selector for ZapPlanner payments (#1312) * feat: add frequency selector for ZapPlanner payments (#1312) +corrections * feat(zapplanner): add USD/BTC selector and frequency option Budget renewal still has to be adjusted * feat(zapplanner): set default frequency to 1 month * feat(zapplanner): set default amount to usd and added (sats) to clarify BTC unit * feat(zapplanner): convert months to days for subscriptions * feat(zapplanner): add open to convertCurrency deps to allow consecutive subscriptions * feat(Zapplanner freq&currency selector): added all currencies to the selector * feat(Zapplanner freq&currency selector): removed bug about 2xBTC(sats) on the menu * feat(zapplanner): frequency & currency all comments addressed * chore: zapplanner fixes - currency sorting - sats currency usage for ZapPlanner - force whole values for ZapPlanner - pass correct currency to ZapPlanner - rename field - fix input width --------- Co-authored-by: jpl-btc <> Co-authored-by: Roland Bewick <roland.bewick@gmail.com> * chore: add reconnection logic * chore: specify fees while locking btc * fix: do not use context background * chore: improve auto swaps frontend * chore: add boltz logo to tx item * Updated Primal app connection (#1428) * Updated Primal app connection * fix: lint --------- Co-authored-by: René Aaron <rene@twentyuno.net> * chore: bump uniffi-bindgen-go and revert error handling in the LDK client (#1434) * chore: revert error handling in the LDK client * chore: update ldk-node-go dependency --------- Co-authored-by: Roland Bewick <roland.bewick@gmail.com> * Read.me adjustments (#1440) * Update README.md 1) We spend a lot of time helping users to fix their problems with Raspi PIs. 2) Computers that are offline regularly create a bad UX because payments in external apps do not work and channels are closed earlier. * Update README.md * feat: add expired state to nip47 transactions (#1441) * fix: use custom mempool url (#1431) * fix: use custom mempool url * chore: return mempool url in info endpoint * chore: use mempool url from info response in frontend * chore: remove default mempool url in frontend * fix: tests * feat: add LDK bitcoind rpc chain source (#1367) * feat: add LDK bitcoind rpc chain source * fix: crash in bitcoindrpc due to not enabling continuous sync * chore: renaming * chore: mark swap status as failed * chore: use mempool url from info * chore: poll balances on node page * fix: when opening outbound channel, extract host part if full peer connection url is pasted * chore: use mempool url from backend info endpoint * docs: add boltz regtest setup instructions * chore: separate swap in and out status pages * fix: remove duplicate useInfo * fix: mnemonic derivation logic * chore: address comments * chore: add tests for swap mnemonic generation * chore: add refunded state * chore: rename columns * chore: simplify swap status frontend * chore: mark swap out as successful after claim tx conf * chore: add address to refund * fix: wails * feat: add resubscription * chore: add logging * chore: save refund address to db and use new address * chore: add comment --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Roland <33993199+rolznz@users.noreply.github.com> Co-authored-by: Freepilot <215356755+freepilot-bot@users.noreply.github.com> Co-authored-by: Roland Bewick <roland.bewick@gmail.com> Co-authored-by: achaldps@gmail.com <achaldps@gmail.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Nodii <13803869+NodeDiver@users.noreply.github.com> Co-authored-by: Moritz Kaminski <moritz.kaminski@gmail.com> Co-authored-by: René Aaron <rene@twentyuno.net> Co-authored-by: Roman D <roman@dmitrienko.com> * chore: rename to receive_amount * chore: remove auto swap success and add boltz link * chore: use constant and rename variables * fix: mark swaps as failed * fix: show receive amount in swap in success screen * chore: remove duplicate endpoint and reorder * chore: add comment in wails handler * chore: use markSwapState * chore: add retries * fix: use one websocket per swap * chore: frontend fixes * feat: add swap mnemonic to debug tools * fix: tx list * fix: tests * chore: further changes * chore: improve copy * chore: improve copy * chore: improve copy * chore: rename, add autofocus on swap inputs * fix: swap in failed state when no lockup tx exists * chore: add interval note to active swap component * chore: remove boltz image * chore: use hasChannelManagement check * chore: use link instead of navigate * chore: mark swaps as failed in case of errors * chore: add comment * chore: only mark swaps as failed in defer function * chore: improve copy * chore: update boltz client to v2.7.2 * chore: use refundSwapRequest param * fix: refund swap method * chore: minor changes * chore: add retries * chore: add retries and use single ws connection for pending swaps * fix: swap fee error message * chore: remove sending partial signature in swap in * chore: log error when update channel is not ok * fix: add tx claimed state in swap in listener * chore: add nwc_swap_succeeded to whitelist and readme * feat: use single boltz ws connection * chore: only check for tx claimed state * chore: use lock while sending updates * chore: handle boltz update error * chore: remove swap id from success event --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Roland Bewick <roland.bewick@gmail.com> Co-authored-by: Roland <33993199+rolznz@users.noreply.github.com> Co-authored-by: Freepilot <215356755+freepilot-bot@users.noreply.github.com> Co-authored-by: achaldps@gmail.com <achaldps@gmail.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Nodii <13803869+NodeDiver@users.noreply.github.com> Co-authored-by: Moritz Kaminski <moritz.kaminski@gmail.com> Co-authored-by: René Aaron <rene@twentyuno.net> Co-authored-by: Roman D <roman@dmitrienko.com>
2025-07-10 18:36:12 +05:30
View the [release binaries](https://github.com/getAlby/hub/releases/latest). Please use a desktop computer that is always online.
#### Manual (x86 Linux Server)
2024-08-18 14:40:33 +07:00
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
feat: PostgreSQL support (#922) * feat: enable Postgres connections * feat: implement migration templates * feat: convert sqlite-specific migrations to migration templates; adjust SQL syntax * fix: add migration to fix postgres incompatibilities in the DB schema * fix: correct SQL syntax for comparisons in the transactions service * feat: database migration tool * chore: update tests for testing with Postgres * fix: update test * fix: explicitly store mock timestamps in UTC * chore: add txdb to go.mod and run tidy * fix: serialize concurrent transactions when running tests with txdb * chore: update README to mention postgres * fix: use timestamptz in Postgres * test: add Github action for testing the backend with Postgres * chore: fix migration name and add comments * docs: add db migration notes to README * fix: address PR feedback * fix: rename the cmd/migrate tool to cmd/db_migrate * feat: add schema check in the DB migration tool * test: use testdb instead of txdb for testing with Postgresql * fix: fix tests after merge * chore: comment out unused VACUUM in migrations * fix: reset Postgres sequences after migrating data * docs: update migrate command in readme * fix: do not allow backup for migration when postgres is enabled * chore: add debug logs for db backend type * chore: use Logrus instead of slog for db_migrate * fix: initialize logger in the keys tests * test: add db_migrate test * fix: use transaction object in db_migrate function * fix: txlock in db migration test --------- Co-authored-by: Roland Bewick <roland.bewick@gmail.com>
2025-01-16 13:17:24 +03:00
Alby provides container images for each release. Please make sure to use a persistent volume. The lightning state and application state is persisted to disk.
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_
`docker run -v ~/.local/share/albyhub:/data -e WORK_DIR='/data' -p 8080:8080 --pull always 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)
## Alby Hub Architecture
### NWC Wallet Service
At a high level Alby Hub is an [NWC](https://nwc.dev) wallet service which allows users to use their single wallet seamlessly within a multitude of apps(clients). Any client that supports NWC and has a valid connection secret can communicate with the wallet service to execute commands on the underlying wallet (internally called LNClient).
### LNClient
The LNClient interface abstracts the differences between wallet implementations and allows users to run Alby Hub with their preferred wallet, such as LDK, LND, Phoenixd, Cashu.
### Transactions Service
Alby Hub maintains its own database of transactions to enable features like self-payments for isolated app connections (sub-wallets), additional metadata (that apps can provide when creating invoices or making keysend payments), and to associate transactions with apps, providing additional context to users about how their wallet is being used across apps.
The transactions service sits between the LNClient and two possible entry points: the NIP-47 handlers, and our internal API which is used by the Alby Hub frontend.
### Event Publisher
Internally Alby Hub uses a basic implementation of the pubsub messaging pattern which allows different parts of the system to fire or consume events. For example, the LNClients can fire events when they asynchronously receive or send a payment, which is consumed by the transaction service to update our internal transaction database, and then fire its own events which can be consumed by the NIP-47 notifier to publish notification events to subscribing apps, and also by the Alby OAuth service to send events to the Alby Account (to enable features such as encrypted static channel backups, email notifications of payments, and more).
#### Published Events
- `nwc_started` - when Alby Hub process starts
- `nwc_stopped` - when Alby Hub process gracefully exits
- `nwc_node_started` - when Alby Hub successfully starts or connects to the configured LNClient.
- `nwc_node_start_failed` - The LNClient failed to sync or could not be connected to (e.g. network error, or incorrect configuration for an external node)
- `nwc_node_stopped` the LNClient was gracefully stopped
- `nwc_node_stop_failed` - failed to request the node to stop. Ideally this never happens.
- `nwc_node_sync_failed` - the node failed to sync onchain, wallet or fee estimates.
- `nwc_unlocked` - when user enters correct password (HTTP only)
- `nwc_channel_ready` - a new channel is opened, active and ready to use
- `nwc_channel_closed` - a channel was closed (could be co-operatively or a force closure)
- `nwc_backup_channels` - send a list of channels that can be used as a SCB.
- `nwc_outgoing_liquidity_required` - when user tries to pay an invoice more than their current outgoing liquidity across active channels
- `nwc_incoming_liquidity_required` - when user tries to creates an invoice more than their current incoming liquidity across active channels
- `nwc_permission_denied` - a NIP-47 request was denied - either due to the app connection not having permission for a certain command, or the app does not have insufficient balance or budget to make the payment.
- `nwc_payment_failed` - failed to make a lightning payment
- `nwc_payment_sent` - successfully made a lightning payment
- `nwc_payment_received` - received a lightning payment
feat: add hold invoices support for LND & LDK (#1298) * feat: add LND hold invoices support * fix: add HOLD_INVOICE_ACCEPTED_NOTIFICATION to notifications list returned by get_info * fix: revert * fix: remove unneeded null checks * docs: add extra event type to README * feat: add LND hold invoices support * fix: add HOLD_INVOICE_ACCEPTED_NOTIFICATION to notifications list returned by get_info * fix: revert * fix: remove unneeded null checks * docs: add extra event type to README * fix: remove 0 expiry checking in the make_hold_invoice_controller * fix: use JSON logging * revert fly.toml * fix: duplicated check * fix: move publishing nwc_hold_invoice_accepted out of the transaction * fix: move publishing nwc_hold_invoice_accepted out of the transaction * fix: check the invoice state ACCEPTED before calling the lnClient.SettleHoldInvoice * fix: check the invoice state ACCEPTED before calling the lnClient.SettleHoldInvoice * fix: check the invoice state ACCEPTED before calling the lnClient.SettleHoldInvoice * fix: check the invoice state ACCEPTED before calling the lnClient.SettleHoldInvoice * fix: cancel hold invoice tests * fix: make hold invoice tests * fix: make hold invoice tests * fix: settle hold invoice tests * fix: resubscribe to pending hold invoices * fix: missing WatchHoldInvoice in the mocks * feat: add LDK impl * fix: cleanup * fix: payment_hash * fix: remove unneeded update * feat: add support for self payments for hold invoices (#1304) Co-authored-by: frnandu <frnandu@gmail.com> * fix: remove hold invoices scope * fix: remove hold invoices scope * fix: mock hold bolt11 expiry to 10 years * fix: sleep 1 second to give a change of lookupinvoice to read cancelled * fix: missing timeout param * feat: add hold invoice settle deadline to transactions (#1324) * chore: update mockery, remove unused hold invoice method * chore: remove unnecessary comment * chore: remove unused code * fix: do not return hold transaction if lookup failed * chore: remove unused code * fix: return correct errors from nip47 controllers, remove unused code * fix: failing test * chore: remove unnecessary code * fix: make error message more general * chore: remove unused code * fix: use correct context in lnd service * fix: unstable hold payments test --------- Co-authored-by: Roland Bewick <roland.bewick@gmail.com> Co-authored-by: Roland <33993199+rolznz@users.noreply.github.com>
2025-05-26 11:51:23 +02:00
- `nwc_hold_invoice_accepted` - accepted a lightning payment, but it needs to be cancelled or settled
- `nwc_hold_invoice_canceled` - accepted hold payment was explicitly cancelled
- `nwc_budget_warning` - successfully made a lightning payment, but budget is nearly exceeded
- `nwc_app_created` - a new app connection was created
- `nwc_app_deleted` - a new app connection was deleted
- `nwc_lnclient_*` - underlying LNClient events, consumed only by the transactions service.
- `nwc_alby_account_connected` - user connects alby account for first time
Swaps improvements (shifting to standalone page + one-time swaps) (#1371) * chore: move out swaps from settings * chore: link to swaps in wallet and node page * chore: add frontend for swap ins * chore: update all swap redirects * chore: remove swap dialogs * chore: remove auto swap-ins frontend * feat: add support for one time swap outs * chore: remove unused code * chore: use separate endpoint for one off swap outs * chore: further changes * chore: separate one off and auto swaps * chore: naming changes * fix: tests * feat: add one off swap in * feat: add auto swap ins * chore: remove comments * fix: tests * chore: further changes * chore: further changes * chore: rename to swap in and swap out * chore: do not show swaps for non LDK/LND users * chore: add receive limit checks for swap ins * chore: remove probing * chore: dark mode * fix: swap link * chore: add extra swap links * fix: fee rates log * fix: fee rates log * chore: color changes * Feat: swap out improvements (#1403) * feat: swap out improvements - add lockup transaction id to hold payment metadata - return swap ID and payment hash in swap out response - retries to get fee rates - separate swap out success page with status * chore: rename * chore: show current balance on swap out form * chore: add pulse animation to badge while pending * chore: minor typo * chore: update fee rate retry interval to 10 seconds * chore: use icons instead of badges --------- Co-authored-by: im-adithya <imadithyavardhan@gmail.com> * chore: update comment * chore: remove comment * chore: update boltz client to v2.6.1 * feat: swap in improvements (WIP) (#1411) * feat: swap in improvements (WIP) * feat: new swap in status page * fix: hide pay button when already paid * chore: improve swap in UI * chore: more swap in ui improvements * chore: minor improvements and fixes * fix: typo * feat: add swap in refund logic in case of failure * fix: tests * chore: add swap expired case for refunds --------- Co-authored-by: im-adithya <imadithyavardhan@gmail.com> * feat: add swaps table (#1419) * feat: add swaps table * fix: test * chore: bump LDK-node to v0.6.0 (#1418) * [Freepilot] fix: startup error handling (#1413) * fix: handle errors from service.NewService() in startup code Previously, both HTTP and Wails startup code ignored errors from service.NewService(ctx) using blank identifier (_), which could cause panics later if NewService fails (e.g., unable to connect to postgres database). Now properly handle the error and exit gracefully with a fatal log message when service initialization fails. * fix: compile error --------- Co-authored-by: Roland Bewick <roland.bewick@gmail.com> * feat: add hd key derivation * Chore: add albyhub region cookie to developer page (#1421) * docs: add AlbyHub-Region cookie instructions to developer page * fix: use region from alby api --------- Co-authored-by: achaldps@gmail.com <achaldps@gmail.com> * build(deps): bump golang.org/x/crypto from 0.38.0 to 0.39.0 (#1415) Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.38.0 to 0.39.0. - [Commits](https://github.com/golang/crypto/compare/v0.38.0...v0.39.0) --- updated-dependencies: - dependency-name: golang.org/x/crypto dependency-version: 0.39.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump gorm.io/driver/sqlite from 1.5.7 to 1.6.0 (#1416) Bumps [gorm.io/driver/sqlite](https://github.com/go-gorm/sqlite) from 1.5.7 to 1.6.0. - [Commits](https://github.com/go-gorm/sqlite/compare/v1.5.7...v1.6.0) --- updated-dependencies: - dependency-name: gorm.io/driver/sqlite dependency-version: 1.6.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump github.com/btcsuite/btcd/btcec/v2 from 2.3.4 to 2.3.5 (#1417) Bumps [github.com/btcsuite/btcd/btcec/v2](https://github.com/btcsuite/btcd) from 2.3.4 to 2.3.5. - [Release notes](https://github.com/btcsuite/btcd/releases) - [Changelog](https://github.com/btcsuite/btcd/blob/master/CHANGES) - [Commits](https://github.com/btcsuite/btcd/compare/btcec/v2.3.4...btcec/v2.3.5) --- updated-dependencies: - dependency-name: github.com/btcsuite/btcd/btcec/v2 dependency-version: 2.3.5 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * feat: allow setting LDK node alias (#1398) * feat: add node alias customization for LDK nodes with public channels - Add new NodeAlias field to InfoResponse in API - Add SetNodeAlias method to API with config storage - Add HTTP endpoint POST /node/alias for setting node alias - Add corresponding Wails endpoint support - Create new Node settings page in frontend - Add conditional navigation item for LDK nodes with public channels - Include upgrade dialog and paid subscription check - Display success message prompting node restart after alias change - Show error toast for non-paid users attempting to change alias * chore: use node alias from config in LDK init * fix: make upgrade button non-absolute, remove disabled attribute * chore: move node alias page to be consistent with other node management pages * chore: remove redundant comment * chore: show upgrade dialog when clicking node alias option, show also for private channels --------- Co-authored-by: Roland Bewick <roland.bewick@gmail.com> * fix: always pass in fee and handle mempool errors (#1408) * fix: always pass in fee and handle mempool errors * chore: improve withdraw on-chain funds UI --------- Co-authored-by: Roland Bewick <roland.bewick@gmail.com> * feat: derive keys from id and add fields to swap table * feat: use bip 85 to derive swap mnemonic * chore: mark swaps as failed if payment fails * feat: add process refund method for swap ins * chore: add process refund to swap service interface * feat: add frontend * fix: swap out failure message * feat: add process refund button in swap in status screen * chore: further improvements * fix: wails routes * feat: add frequency selector for ZapPlanner payments (#1312) (#1317) * feat: add frequency selector for ZapPlanner payments (#1312) * feat: add frequency selector for ZapPlanner payments (#1312) +corrections * feat(zapplanner): add USD/BTC selector and frequency option Budget renewal still has to be adjusted * feat(zapplanner): set default frequency to 1 month * feat(zapplanner): set default amount to usd and added (sats) to clarify BTC unit * feat(zapplanner): convert months to days for subscriptions * feat(zapplanner): add open to convertCurrency deps to allow consecutive subscriptions * feat(Zapplanner freq&currency selector): added all currencies to the selector * feat(Zapplanner freq&currency selector): removed bug about 2xBTC(sats) on the menu * feat(zapplanner): frequency & currency all comments addressed * chore: zapplanner fixes - currency sorting - sats currency usage for ZapPlanner - force whole values for ZapPlanner - pass correct currency to ZapPlanner - rename field - fix input width --------- Co-authored-by: jpl-btc <> Co-authored-by: Roland Bewick <roland.bewick@gmail.com> * chore: add reconnection logic * chore: specify fees while locking btc * fix: do not use context background * chore: improve auto swaps frontend * chore: add boltz logo to tx item * Updated Primal app connection (#1428) * Updated Primal app connection * fix: lint --------- Co-authored-by: René Aaron <rene@twentyuno.net> * chore: bump uniffi-bindgen-go and revert error handling in the LDK client (#1434) * chore: revert error handling in the LDK client * chore: update ldk-node-go dependency --------- Co-authored-by: Roland Bewick <roland.bewick@gmail.com> * Read.me adjustments (#1440) * Update README.md 1) We spend a lot of time helping users to fix their problems with Raspi PIs. 2) Computers that are offline regularly create a bad UX because payments in external apps do not work and channels are closed earlier. * Update README.md * feat: add expired state to nip47 transactions (#1441) * fix: use custom mempool url (#1431) * fix: use custom mempool url * chore: return mempool url in info endpoint * chore: use mempool url from info response in frontend * chore: remove default mempool url in frontend * fix: tests * feat: add LDK bitcoind rpc chain source (#1367) * feat: add LDK bitcoind rpc chain source * fix: crash in bitcoindrpc due to not enabling continuous sync * chore: renaming * chore: mark swap status as failed * chore: use mempool url from info * chore: poll balances on node page * fix: when opening outbound channel, extract host part if full peer connection url is pasted * chore: use mempool url from backend info endpoint * docs: add boltz regtest setup instructions * chore: separate swap in and out status pages * fix: remove duplicate useInfo * fix: mnemonic derivation logic * chore: address comments * chore: add tests for swap mnemonic generation * chore: add refunded state * chore: rename columns * chore: simplify swap status frontend * chore: mark swap out as successful after claim tx conf * chore: add address to refund * fix: wails * feat: add resubscription * chore: add logging * chore: save refund address to db and use new address * chore: add comment --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Roland <33993199+rolznz@users.noreply.github.com> Co-authored-by: Freepilot <215356755+freepilot-bot@users.noreply.github.com> Co-authored-by: Roland Bewick <roland.bewick@gmail.com> Co-authored-by: achaldps@gmail.com <achaldps@gmail.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Nodii <13803869+NodeDiver@users.noreply.github.com> Co-authored-by: Moritz Kaminski <moritz.kaminski@gmail.com> Co-authored-by: René Aaron <rene@twentyuno.net> Co-authored-by: Roman D <roman@dmitrienko.com> * chore: rename to receive_amount * chore: remove auto swap success and add boltz link * chore: use constant and rename variables * fix: mark swaps as failed * fix: show receive amount in swap in success screen * chore: remove duplicate endpoint and reorder * chore: add comment in wails handler * chore: use markSwapState * chore: add retries * fix: use one websocket per swap * chore: frontend fixes * feat: add swap mnemonic to debug tools * fix: tx list * fix: tests * chore: further changes * chore: improve copy * chore: improve copy * chore: improve copy * chore: rename, add autofocus on swap inputs * fix: swap in failed state when no lockup tx exists * chore: add interval note to active swap component * chore: remove boltz image * chore: use hasChannelManagement check * chore: use link instead of navigate * chore: mark swaps as failed in case of errors * chore: add comment * chore: only mark swaps as failed in defer function * chore: improve copy * chore: update boltz client to v2.7.2 * chore: use refundSwapRequest param * fix: refund swap method * chore: minor changes * chore: add retries * chore: add retries and use single ws connection for pending swaps * fix: swap fee error message * chore: remove sending partial signature in swap in * chore: log error when update channel is not ok * fix: add tx claimed state in swap in listener * chore: add nwc_swap_succeeded to whitelist and readme * feat: use single boltz ws connection * chore: only check for tx claimed state * chore: use lock while sending updates * chore: handle boltz update error * chore: remove swap id from success event --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Roland Bewick <roland.bewick@gmail.com> Co-authored-by: Roland <33993199+rolznz@users.noreply.github.com> Co-authored-by: Freepilot <215356755+freepilot-bot@users.noreply.github.com> Co-authored-by: achaldps@gmail.com <achaldps@gmail.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Nodii <13803869+NodeDiver@users.noreply.github.com> Co-authored-by: Moritz Kaminski <moritz.kaminski@gmail.com> Co-authored-by: René Aaron <rene@twentyuno.net> Co-authored-by: Roman D <roman@dmitrienko.com>
2025-07-10 18:36:12 +05:30
- `nwc_swap_succeeded` - successfully made a boltz swap
- `nwc_rebalance_succeeded` - successfully rebalanced channels
- `nwc_payment_forwarded` - successfully forwarded a payment and earned routing fees
### NIP-47 Handlers
Alby Hub subscribes to a standard Nostr relay and listens for whitelisted events from known pubkeys and handles these requests in a similar way as a standard HTTP API controller, and either doing requests to the underling LNClient, or to the transactions service in the case of payments and invoices.
### Frontend
The Alby Hub frontend is a standard React app that can run in one of two modes: as an HTTP server, or desktop app, built by Wails. To abstract away, both the HTTP service and Wails handlers pass requests through to the API, where the business logic is located, for direct requests from user interactions.
#### Authentication
Alby Hub uses simple JWT auth in HTTP mode, which also allows the HTTP API to be exposed to external apps, which can use Alby Hub's API to have access to extra functionality currently not covered by the NIP-47 spec, however there are downsides - this API is not a public spec, and only works over HTTP. Therefore, apps are recommended to use NIP-47 where possible.
### Encryption
Sensitive data such as the seed phrase are saved AES-encrypted by the user's unlock password, and only decrypted in-memory in order to run the lightning node. This data is not logged and is only transferred over encrypted channels, and always requires the user's unlock password to access.
All requests to the wallet service are made with one of the following ways:
- NIP-47 - requests encrypted by NIP-04 using randomly-generated keypairs (one per app connection) and sent via websocket through the configured relay.
- HTTP - requests encrypted by JWT and ideally HTTPS (except self-hosted, which can be protected by firewall)
- Desktop mode - requests are made internally through the Wails router, without any kind of network traffic.
## Alby Hub Origin
Alby Hub is a self-sovereign, self-custodial, single-user [NWC](https://nwc.dev)-first rewrite of the original [Nostr Wallet Connect](https://github.com/getAlby/nostr-wallet-connect) app which was originally created to support V4V by enabling seamless zaps in nostr clients such as Amethyst and Damus. From there the NIP-47 protocol was grown until it is possible to create many micro apps that connect to your hub, with full control over what each app can do.