Commit graph

3364 commits

Author SHA1 Message Date
Roland
d8ef0e70e0
chore: sync Wails CLI version in CI with go.mod (v2.14.0) (#2547)
Some checks are pending
Multiplatform Docker build & push / build (push) Waiting to run
Code quality - linting and typechecking / linting (push) Waiting to run
Backend testing with Postgres / test-postgres (push) Waiting to run
The Dependabot bump updated github.com/wailsapp/wails/v2 to v2.14.0 in
go.mod but the wails workflow still installed the CLI at v2.12.0. Align
the CI install and document in AGENTS.md that both must be updated
together.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-13 14:41:11 +07:00
Roland
d2cebc5c6f
fix: replace react-lottie with lottie-react for Vite 8 compatibility (#2546)
Vite 8 changed CJS default-import interop: with "type": "module" set,
a default import of a CJS dependency now resolves to the whole
module.exports object instead of its .default export. react-lottie is
CJS-only, so <Lottie> received an object as the element type and
crashed LottieLoading/LottieSuccess with "Element type is invalid".

Swap to the maintained, ESM-built lottie-react, aliasing it to its ES
build since its browser field points at a UMD build with the same
interop hazard. No other dependency is affected by the interop change.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-12 23:52:50 +07:00
Roland
edd283cdb2
fix: update encryption scheme for node migration files (#2539)
* fix: update encryption scheme for node migration files

Migration files are now encrypted with AES-CTR using a key derived via
Argon2 with a 32-byte salt, the same derivation used for encrypted
configuration values. Files created by earlier versions can still be
restored: the restore path detects the scheme by trial-decrypting the
archive header and checking for the ZIP file signature, which also
rejects an incorrect unlock password up front instead of extracting
garbage.

The migration screen now also tells users to never share their
migration file with anyone.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: reword migration file warning

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: read full migration file header before detecting cipher scheme

io.ReadAtLeast can return once the smallest scheme's header is read,
which truncates the larger current-scheme header when the reader
delivers short reads (e.g. a network request body). Read the full
header and only tolerate a short read that still covers the smallest
scheme.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: extract migration files to a staging directory during restore

If extraction failed partway through, the partially populated restore
directory was left in the working directory, and the next startup would
apply the incomplete restore. Extract to a staging directory and only
move it into place after every entry has been extracted successfully.
Also reject archives that contain no files.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: assert traversal-specific error in restore backup test

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-12 22:14:49 +07:00
Roland
1c7abc62e9
chore: add Bark terms link and exit disclosure to security page (#2544)
* chore: add Bark terms link and exit disclosure to security page

Link Second's Terms of Service from the Bark setup security screen, note
that the hub must stay online so automatically refreshed funds do not
expire, and clarify (via tooltip) that unilateral exit is not built into
Alby Hub yet and must be executed manually with the wallet data.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore: improve copy

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-12 22:04:43 +07:00
Roland
1c7c026e54
chore: make vite config compatible with native config loader (#2542)
Replace __dirname with import.meta.dirname and use Vite's native
resolve.tsconfigPaths option instead of the vite-tsconfig-paths plugin.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-12 21:40:43 +07:00
Roland
5125418188
chore(deps): bump dependencies to fix Dependabot alerts (#2541)
* chore(deps): bump google.golang.org/grpc to v1.82.1 and edwards25519 to v1.1.1

Fixes Dependabot alerts GHSA-hrxh-6v49-42gf (gRPC-Go xDS RBAC and HTTP/2
vulnerabilities) and GHSA-fw7p-63qq-7hpr (edwards25519 MultiScalarMult).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore(deps): bump react-router to 7.18.2 and refresh vulnerable transitive deps

Bumps react-router 7.14.2 -> 7.18.2 and re-resolves fast-uri, js-yaml,
brace-expansion, minimatch, picomatch, flatted and @babel packages to
patched versions, clearing the remaining open npm Dependabot alerts.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-12 19:57:27 +07:00
Roland
363c22f6d3
fix: switch unlock rate limiter from per-IP to global (#2540)
Some checks are pending
Multiplatform Docker build & push / build (push) Waiting to run
Code quality - linting and typechecking / linting (push) Waiting to run
Backend testing with Postgres / test-postgres (push) Waiting to run
The unlock endpoints were rate limited per client IP, which is derived
from request headers and so is chosen by the caller. Switch to a single
global rate limiter (one bucket for all callers) and apply it to every
endpoint that verifies the unlock password: start, unlock, backup,
mnemonic, apps, autoswap, unlock-password and auto-unlock. A small burst
keeps unlocking and immediately performing an action working.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-12 16:25:56 +07:00
Roland
3b3c37dd0c
fix: remove legacy acceptance of empty unlock password check (#2534)
* fix: remove legacy acceptance of empty unlock password check

CheckUnlockPassword previously treated a missing or empty
UnlockPasswordCheck value as a match — a legacy compatibility path from
before the canary was always written. It now requires the stored value
to be present and to equal the expected string.

StartApp checks for the canary up front and, if it is missing, stops
with a message asking the user to restore from a backup rather than
continuing. A new IsUnlockPasswordCheckSet helper reports whether the
value is present.

keys.Init now returns the error from reading NostrSecretKey instead of
ignoring it, so a read failure aborts instead of generating and saving a
new key.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore: add operation context to unlock password check errors

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-12 14:48:06 +07:00
Roland
979644cf68
fix: limit LSP opening fees for JIT channel invoices (#2535)
* fix: limit LSP opening fees for JIT channel invoices

JIT channel invoices are now created with a maximum LSP opening fee
instead of no limit: the fee the LSP advertises in its LSPS2 opening fee
menu for the payment size, bounded by an absolute ceiling of 5000 sats
or 10% of the payment, whichever is greater. Invoice creation fails if
the LSP quotes a fee above this limit.

The minimum JIT payment size calculation now uses the same ceiling so
the advertised receivable range matches what invoice creation accepts.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: validate invoice expiry range and guard LSPS2 cache reads

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-12 13:38:13 +07:00
Roland
f4010e239a
fix: validate swap out invoice before payment (#2536)
Verify the invoice returned when creating a swap out before storing and
paying it:

- the invoice payment hash must match the payment hash of the locally
  generated preimage
- the invoice amount must not exceed the requested amount plus the
  quoted service and miner fees (with a small rounding tolerance)
- the lockup address is checked against the swap tree, matching the
  checks already performed for swap in and refunds
- the invoice is verified again directly before it is paid

Also renames AlbySwapServiceFee to AlbySwapServiceFeePercentage for
clarity.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-12 12:33:40 +07:00
Roland
4c5bef42c6
fix: require full access api key for log endpoint (#2537)
Move GET /api/log/:type from the read-only API group to the
full-access group, matching /api/swaps/mnemonic. Add tests asserting
a readonly token receives 403 from the log endpoint and a full-access
token can still read it.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-12 12:29:03 +07:00
Adithya Vardhan
0c24ab84c1
fix: avoid leaking raw postgres error details in duplicate key response (#2538) 2026-08-11 18:45:59 +05:30
dependabot[bot]
459b825cfb
build(deps): bump github.com/lightningnetwork/lnd from 0.21.0-beta to 0.21.1-beta (#2517)
build(deps): bump github.com/lightningnetwork/lnd

Bumps [github.com/lightningnetwork/lnd](https://github.com/lightningnetwork/lnd) from 0.21.0-beta to 0.21.1-beta.
- [Release notes](https://github.com/lightningnetwork/lnd/releases)
- [Changelog](https://github.com/lightningnetwork/lnd/blob/master/docs/release_branch_management.md)
- [Commits](https://github.com/lightningnetwork/lnd/compare/v0.21.0-beta...v0.21.1-beta)

---
updated-dependencies:
- dependency-name: github.com/lightningnetwork/lnd
  dependency-version: 0.21.1-beta
  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>
2026-08-11 17:07:03 +05:30
dependabot[bot]
e3278beffb
build(deps): bump github.com/mattn/go-sqlite3 from 1.14.48 to 1.14.49 (#2514)
Bumps [github.com/mattn/go-sqlite3](https://github.com/mattn/go-sqlite3) from 1.14.48 to 1.14.49.
- [Release notes](https://github.com/mattn/go-sqlite3/releases)
- [Commits](https://github.com/mattn/go-sqlite3/compare/v1.14.48...v1.14.49)

---
updated-dependencies:
- dependency-name: github.com/mattn/go-sqlite3
  dependency-version: 1.14.49
  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>
2026-08-11 16:36:30 +05:30
dependabot[bot]
852b30fa02
build(deps): bump gorm.io/driver/postgres from 1.6.0 to 1.6.2 (#2515)
Bumps [gorm.io/driver/postgres](https://github.com/go-gorm/postgres) from 1.6.0 to 1.6.2.
- [Commits](https://github.com/go-gorm/postgres/compare/v1.6.0...v1.6.2)

---
updated-dependencies:
- dependency-name: gorm.io/driver/postgres
  dependency-version: 1.6.2
  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>
2026-08-11 16:36:15 +05:30
dependabot[bot]
ffc705e536
build(deps): bump github.com/wailsapp/wails/v2 from 2.12.0 to 2.14.0 (#2513)
* build(deps): bump github.com/wailsapp/wails/v2 from 2.12.0 to 2.13.0

Bumps [github.com/wailsapp/wails/v2](https://github.com/wailsapp/wails) from 2.12.0 to 2.13.0.
- [Release notes](https://github.com/wailsapp/wails/releases)
- [Commits](https://github.com/wailsapp/wails/compare/v2.12.0...v2.13.0)

---
updated-dependencies:
- dependency-name: github.com/wailsapp/wails/v2
  dependency-version: 2.13.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore: bump wails version to v2.14.0

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Adithya Vardhan <imadithyavardhan@gmail.com>
2026-08-11 16:22:33 +05:30
dependabot[bot]
d3847fdaae
build(deps-dev): bump vite from 5.4.19 to 8.2.0 in /frontend (#2516)
* build(deps-dev): bump vite from 5.4.19 to 8.2.0 in /frontend

Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 5.4.19 to 8.2.0.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/create-vite@8.2.0/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 8.2.0
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

* fix: remove stale react paths override in tsconfig

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Adithya Vardhan <imadithyavardhan@gmail.com>
2026-08-11 16:20:48 +05:30
dependabot[bot]
7c7dfa6876
build(deps): bump lucide-react from 1.7.0 to 1.28.0 in /frontend (#2518)
Bumps [lucide-react](https://github.com/lucide-icons/lucide/tree/HEAD/packages/lucide-react) from 1.7.0 to 1.28.0.
- [Release notes](https://github.com/lucide-icons/lucide/releases)
- [Commits](https://github.com/lucide-icons/lucide/commits/1.28.0/packages/lucide-react)

---
updated-dependencies:
- dependency-name: lucide-react
  dependency-version: 1.28.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>
2026-08-11 15:48:31 +05:30
dependabot[bot]
621db07fc8
build(deps): bump @fontsource-variable/figtree from 5.2.10 to 5.3.0 in /frontend (#2519)
Some checks are pending
Multiplatform Docker build & push / build (push) Waiting to run
Code quality - linting and typechecking / linting (push) Waiting to run
Backend testing with Postgres / test-postgres (push) Waiting to run
build(deps): bump @fontsource-variable/figtree in /frontend

Bumps [@fontsource-variable/figtree](https://github.com/fontsource/font-files/tree/HEAD/fonts/variable/figtree) from 5.2.10 to 5.3.0.
- [Changelog](https://github.com/fontsource/font-files/blob/main/CHANGELOG.md)
- [Commits](https://github.com/fontsource/font-files/commits/HEAD/fonts/variable/figtree)

---
updated-dependencies:
- dependency-name: "@fontsource-variable/figtree"
  dependency-version: 5.3.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>
2026-08-11 15:40:39 +05:30
Roland
4402d2fff8
fix: remove request bodies from error logs (#2533)
The Wails request router included the full request body in its error
log entries, and the HTTP app creation handler logged the whole request
struct on failure. Log only the route, method and error instead,
matching the existing behavior of the /api/mnemonic handler, and log
only the route and method for requests in the desktop frontend.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-11 15:49:26 +07:00
Roland
5f9a88843c
fix: validate LND and CLN credential files during setup (#2528)
The setup API accepts file paths for the LND certificate and macaroon
and for the CLN lightning directory. Previously the raw file contents
were read and stored without any validation.

Validate these inputs before persisting them:

- LND cert: parse the PEM and store only the re-encoded certificate(s),
  discarding any other PEM blocks (e.g. a bundled private key).
- LND macaroon: unmarshal and store the re-marshalled macaroon.
- CLN lightning directory: verify it contains the TLS credentials
  (ca.pem, client.pem, client-key.pem) that CLN loads at connect time,
  including the hold subdirectory when configured.

On failure, return a generic error to the client and log the detail
server-side. File paths remain supported for Umbrel-style installs.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-11 15:05:56 +07:00
Roland
3d22993389
fix: validate return_to redirect URLs (#2532)
return_to query parameters are now parsed and only http and https URLs
are used for redirects, both in the frontend and when the createApp API
adds the connection parameters to the URL.

The production frontend build now also includes the same
Content-Security-Policy meta tag that is served as a header in http
mode, so the policy also applies where no HTTP headers are set, e.g. in
the desktop app.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-11 14:57:51 +07:00
Roland
0b0cbbd985
fix: make event assertions in tests wait for async event consumption (#2531)
The mock event consumer waited a fixed 10ms before returning consumed
events, which was not always enough on slow CI runners and caused flaky
failures (e.g. TestMarkSettled_App_BudgetWarning missing its
nwc_budget_warning event). It also appended to the events slice from
concurrent goroutines without synchronization, a data race that could
drop events.

- guard the consumed events slice with a mutex and return copies
- add WaitForConsumedEvents which polls until the expected number of
  events arrived (up to 5s) instead of relying on a fixed sleep
- use it in tests that assert on consumed events; tests asserting that
  no event was published keep the short grace period
- normalize event order in the keysend self-payment test, matching the
  existing approach in the self-payment test, since async publishing
  does not guarantee ordering

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-11 14:48:41 +07:00
Roland
fa5cc3511e
fix: prevent backup restore from writing outside the restore directory (#2529)
Archive entry names come from the uploaded backup and were joined to the
restore directory without validation, so an entry name containing ".."
segments could resolve to a path outside it. Reject entries whose name is
absolute or escapes the restore directory, and confirm the cleaned
destination path stays within it before writing.

Add a test covering rejection of an entry that points outside the restore
directory.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-10 23:42:45 +07:00
Roland
037765794d
fix: keep showing migration success page after creating migration file (#2527)
Some checks are pending
Multiplatform Docker build & push / build (push) Waiting to run
Code quality - linting and typechecking / linting (push) Waiting to run
Backend testing with Postgres / test-postgres (push) Waiting to run
* fix: keep showing migration success page after creating migration file

After creating a node migration file the hub is halted and the Alby
OAuth token is intentionally removed, so visiting the homepage sent the
user through /start into the Alby OAuth flow. Track the halted state
in memory and redirect back to the migration success page instead.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: synchronize migration flag access and propagate zip close error

Make nodeMigrationFileCreated an atomic.Bool since it is written by
CreateBackup and read by GetInfo on concurrent HTTP handler goroutines,
and finalize the migration archive explicitly so a failed zip close
returns an error instead of reporting a corrupt backup as success.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: return minimal info response after migration file is created

Once a migration file is created the hub is halted and the database is
closed. GetInfo previously only worked because every config key it reads
happened to be served from the config cache; any cache miss on an
error-propagating read would fail /api/info. Return early with a minimal
response instead so the migration success page does not depend on cache
state.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-10 15:37:26 +07:00
Roland
56d118a851
fix: remove dollar sign from linux install scripts (#2525) 2026-08-10 15:33:20 +07:00
Roland
ffee8cbcbe
feat: enable migration from postgres to sqlite (#2524)
Allows users running Alby Hub on postgres (e.g. Alby Cloud) to create a
migration file from Settings -> Migrate Alby Hub. The contents of the
postgres database are copied into a temporary local sqlite database
which is included in the migration file, so it can be imported into a
fresh sqlite-based hub.

- extract the db_migrate CLI copy logic into a shared db.MigrateDB
- also copy the swaps and forwards tables (previously silently dropped)
- only require VSS in the source when migrating to postgres
- show a hint on the migrate page when running on postgres
- show database storage type and VSS status on the about page
- don't log an error when removing non-existent db files before restore

Closes #2500

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-10 14:20:41 +07:00
Roland
6d0cb6fd2c
fix: bark onboarding, migration messaging and receive settlement for bark 0.6.0 (#2523)
Some checks failed
Multiplatform Docker build & push / build (push) Has been cancelled
Code quality - linting and typechecking / linting (push) Has been cancelled
Backend testing with Postgres / test-postgres (push) Has been cancelled
* fix: update bark onboarding and backup messaging for seed-based recovery

Since bark 0.6.0, offchain funds are recoverable from the mnemonic
alone via the seed-derived recovery mailbox. Remove the outdated
warnings that the recovery phrase is not sufficient, show the standard
recovery guidance for bark during onboarding, and expose the
seed-recovery scan result as a 'recoveryreport' custom node command so
users migrating to a new device can verify their funds were restored.

Closes #2512

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: settle bark lightning receives in the new delivering state

bark 0.6.0 added a 'delivering' receive state between preimage reveal
and settlement. The receive claim handler only treated
'preimage-revealed' and 'settled' as paid, so claimed receives were
published without a preimage and the transactions service rejected the
settlement ('no preimage in payment'), leaving paid invoices pending
forever.

Recognize all states at or past preimage reveal via a receiveIsPaid
helper (a positive allowlist, so an unknown future state degrades to
pending rather than falsely settled), only mark the transaction settled
when the preimage is present, and prefer bark's own settled_at
timestamp when available.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: replace import channels checkbox with LDK-specific warning

The 'I don't have another Alby Hub to migrate or open channels'
checkbox on the import recovery phrase screen only applied to LDK but
was required for every backend, and its claim that channel funds are
always lost is wrong when dynamic channel backups (VSS) are enabled.

Remove the checkbox and the channels bullet from the import screen and
show the caveat on the Security & Recovery page instead, only when a
mnemonic was imported and the LDK backend was chosen.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-08 16:39:02 +07:00
Roland
d198b19bef
feat: enable typing card name when choosing other card (#2511)
* feat: enable typing card name when choosing other card

Closes #2457

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: reset connect-card dialog form on open and show empty name validation error

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore: use shadcn Button for other-card option in connect dialog

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-08 13:38:46 +07:00
Roland
5f4e52bd88
fix: publish transaction events only after the database transaction commits (#2520)
* fix: publish transaction events only after the database transaction commits

markTransactionSettled and markPaymentFailed published nwc_payment_sent /
nwc_payment_received / nwc_payment_failed (and checkBudgetUsage published
nwc_budget_warning) while still inside the caller's database transaction, so
connected apps and the Alby API could be notified of a payment whose row was
never committed, and subscribers reading the database in response to an event
could race with the commit.

Every function that writes transaction state now owns its own database
transaction and publishes its events only after the commit succeeds:

- markTransactionSettled and markPaymentFailed open their own transaction;
  callers no longer wrap them in db.Transaction
- new createSettledTransactionFromNotification inserts transactions reported
  by LNClient notifications for payments the hub has no record of (external
  payments, received keysends) directly in their settled state, removing the
  transient PENDING row and the zombie row left behind on duplicate events
- markPaymentFailed now refuses to mark a settled transaction as failed,
  replacing CancelHoldInvoice's in-transaction ACCEPTED re-check and also
  protecting the SendPaymentSync error path from a racing settle
- checkBudgetUsage returns the budget warning event instead of publishing it

Closes #2506

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: serialize payment failure with settlement and propagate lock errors

Address review findings on the previous commit:

- markPaymentFailed now takes the same payment-hash row lock as settlement
  (postgres), so the settled-state guard cannot be bypassed by a concurrent
  settle between the state check and the update; it also returns not-found
  instead of publishing an event when the transaction row no longer exists,
  and reports whether this call transitioned the row so CancelHoldInvoice
  only publishes nwc_hold_invoice_canceled when it performed the cancellation
- findSettledTransaction propagates errors from the lock query and the
  settled-transaction lookup instead of treating a failed lookup as
  "no settled transaction exists", which could defeat the dedup guard
- TestMarkSettled_Twice no longer shares one transaction struct between
  concurrent goroutines and collects errors instead of asserting inside them

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: mark failed keysend payments via markPaymentFailed

The SendKeysend failure path updated the transaction directly, which never
zeroed the fee reserve, recorded no failure reason, published no
nwc_payment_failed event, and had no guard against overwriting a
concurrently settled payment. Route it through markPaymentFailed like
SendPaymentSync, and allow MockLn keysends to fail so the path is testable.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-08 13:38:28 +07:00
Roland
6175489cb0
chore: remove unused argon2-wasm-esm dependency (#2508)
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-07 17:55:38 +07:00
Roland
bdce8fe8d2
fix: use scope constant in get_budget permission query (#2510)
Some checks are pending
Multiplatform Docker build & push / build (push) Waiting to run
Code quality - linting and typechecking / linting (push) Waiting to run
Backend testing with Postgres / test-postgres (push) Waiting to run
* fix: use scope constant in get_budget permission query

The get_budget controller filtered the app_permissions scope column with
models.PAY_INVOICE_METHOD, which only matched because the method and
scope constants share the same string value. Use
constants.PAY_INVOICE_SCOPE like every other scope lookup, and document
why the unchecked First result is safe.

Fixes #2503

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: return error from get_budget on unexpected permission query failure

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-07 12:39:07 +07:00
Roland
d94f6933f5
fix: remove avatar from lightning address QR (#2509)
The avatar overlay made the QR code hard to scan, especially for
short lightning addresses. Without center content the QR also drops
back to a lower error correction level, improving scannability.

Fixes #2507

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-07 11:20:01 +07:00
Alchemist
35d666d469
feat: filter transactions (#2464)
* feat: filter transactions

* fix: harden transaction filters

* refactor: use explicit nullable transaction filters with HideFailed polarity

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat: set transaction filters in a dialog from wallet actions menu

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat: filter transactions by search term and type

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: reject invalid transaction filters and reset page synchronously

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: parse complete minimum amount value in transactions filter dialog

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Roland Bewick <roland.bewick@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-07 10:52:14 +07:00
Josip
3b3e784fa6
fix: fallback to outgoing payments in Phoenixd LookupInvoice (#2447)
* fix: fallback to outgoing payments in Phoenixd LookupInvoice

LookupInvoice only queried /payments/incoming/{hash}, returning 404 for
outgoing payments. This caused all outgoing Lightning payments to remain
permanently stuck as PENDING in Alby Hub.

The fix tries incoming first (preserving existing behavior), then falls
back to listing outgoing payments and matching by paymentHash.

Fixes #2442

* fix: amount and fees in phoenix payment to transaction

---------

Co-authored-by: Roland Bewick <roland.bewick@gmail.com>
2026-08-06 17:24:10 +07:00
Roland
fbaff5d8a0
fix: show icon and proper name for lightning node backend on about page (#2501)
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-06 17:21:00 +07:00
Peter
355454a4cc
fix: Mandatory upgrade for bark SDK (#2502)
Some checks are pending
Multiplatform Docker build & push / build (push) Waiting to run
Code quality - linting and typechecking / linting (push) Waiting to run
Backend testing with Postgres / test-postgres (push) Waiting to run
chore: update bark bindings to v0.15.0

Moves from bark 0.4.0 to 0.6.0. The Ark server now requires protocol version 5
(hashlock clauses) to start a lightning receive, which only bark 0.6.0 sends, so
older clients are refused outright and cannot generate invoices.

No client changes needed: v0.15.0 only adds to the surface we use.
2026-08-06 10:43:41 +07:00
Roland
806dfd4e1b
chore: bump ldk node dependencies (#2498)
Some checks are pending
Multiplatform Docker build & push / build (push) Waiting to run
Code quality - linting and typechecking / linting (push) Waiting to run
Backend testing with Postgres / test-postgres (push) Waiting to run
- rust-lightning to 0.2.4
2026-08-05 15:51:25 +07:00
Roland
d3455eee7d
fix: explain API access is unavailable in the desktop app (#2499)
Creating a developer token in the Wails build failed with a confusing
"Unhandled route: POST /api/unlock" error, because the desktop app does
not expose an HTTP API for the token to be used against. Hide the token
creation form in the desktop build and show an explanatory message
instead.

Fixes #2471

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-05 15:26:40 +07:00
Roland
9971aa1ac8
fix: update bark icon (#2497)
Replace the bark.jpg icon with the new light and dark SVG icons.

Fixes #2446

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-05 15:08:03 +07:00
Roland
43d37d75d1
fix: bump go-nostr to fix duplicate relay connections (#2496)
Picks up getAlby/go-nostr#6, which shares relay connections in
SimplePool when dials fail, closes relay websockets on pool close,
and closes previous subscriptions before re-subscribing on CLOSED.

The shared per-relay-URL connect backoff is now enabled by default
in the fork, so no hub-side pool option is needed
(nostr.WithPenaltyBox is deprecated).

Fixes #2481

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-05 14:50:08 +07:00
Roland
8a9ba49807
chore: bump node version in dockerfile to 22 (#2495) 2026-08-05 14:29:40 +07:00
Roland
4484046ff7
fix: use async LDK event polling to avoid polling delay (#2494)
Switch from polling node.NextEvent() every second to node.NextEventAsync(),
which parks the goroutine until an event arrives without blocking an OS
thread or an LDK thread, as LDK is migrating to async event handling.

Guard event handling with a mutex held by Shutdown() so in-flight handlers
finish before the node is stopped and destroyed, and drop events that
arrive after shutdown starts (LDK redelivers unhandled events on startup).

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-04 23:14:30 +07:00
Roland
b051e5eb5f
fix: include payment hash when querying by payment request to ensure index is used (#2480) 2026-08-04 20:40:36 +07:00
dependabot[bot]
2bafad7a6c
build(deps): bump github.com/BoltzExchange/boltz-client/v2 from 2.12.0 to 2.12.5 (#2483)
build(deps): bump github.com/BoltzExchange/boltz-client/v2

Bumps [github.com/BoltzExchange/boltz-client/v2](https://github.com/BoltzExchange/boltz-client) from 2.12.0 to 2.12.5.
- [Release notes](https://github.com/BoltzExchange/boltz-client/releases)
- [Changelog](https://github.com/BoltzExchange/boltz-client/blob/master/CHANGELOG.md)
- [Commits](https://github.com/BoltzExchange/boltz-client/compare/v2.12.0...v2.12.5)

---
updated-dependencies:
- dependency-name: github.com/BoltzExchange/boltz-client/v2
  dependency-version: 2.12.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>
2026-08-04 20:39:06 +07:00
dependabot[bot]
8f9d6f73f3
build(deps): bump github.com/labstack/echo/v4 from 4.15.2 to 4.15.4 (#2460)
Bumps [github.com/labstack/echo/v4](https://github.com/labstack/echo) from 4.15.2 to 4.15.4.
- [Release notes](https://github.com/labstack/echo/releases)
- [Changelog](https://github.com/labstack/echo/blob/v4.15.4/CHANGELOG.md)
- [Commits](https://github.com/labstack/echo/compare/v4.15.2...v4.15.4)

---
updated-dependencies:
- dependency-name: github.com/labstack/echo/v4
  dependency-version: 4.15.4
  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>
2026-08-04 17:21:05 +07:00
dependabot[bot]
ec2ec911be
build(deps-dev): bump @commitlint/config-conventional from 20.5.0 to 21.2.0 in /frontend (#2487)
build(deps-dev): bump @commitlint/config-conventional in /frontend

Bumps [@commitlint/config-conventional](https://github.com/conventional-changelog/commitlint/tree/HEAD/@commitlint/config-conventional) from 20.5.0 to 21.2.0.
- [Release notes](https://github.com/conventional-changelog/commitlint/releases)
- [Changelog](https://github.com/conventional-changelog/commitlint/blob/master/@commitlint/config-conventional/CHANGELOG.md)
- [Commits](https://github.com/conventional-changelog/commitlint/commits/v21.2.0/@commitlint/config-conventional)

---
updated-dependencies:
- dependency-name: "@commitlint/config-conventional"
  dependency-version: 21.2.0
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-04 17:19:59 +07:00
Alchemist
816e0dda6e
feat: receive invoices to apps (#2466)
* feat: receive invoices to apps

* fix: handle cleared receive selector
2026-08-04 17:18:22 +07:00
saunter
417cb16d97
feat: refresh payment QR and status components (#2459)
* feat: refresh payment QR and status components

* fix: align payment success button spacing

* fix: invert payment QR colors in dark mode

* fix: address payment QR review feedback

* fix: flatten nested cards in payment review FixedFloat tiles

* chore: remove internal payment component review screen

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: keep QR codes dark-on-light in dark mode

Inverted QR codes are unreadable by many scanner apps (e.g. Phoenix).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: René Aaron <rene@getalby.com>
Co-authored-by: Roland Bewick <roland.bewick@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-04 17:08:45 +07:00
dependabot[bot]
5b49783478
build(deps): bump golang.org/x/crypto from 0.52.0 to 0.54.0 (#2484)
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.52.0 to 0.54.0.
- [Commits](https://github.com/golang/crypto/compare/v0.52.0...v0.54.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-version: 0.54.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>
2026-08-04 16:33:30 +07:00