Skip to content

Releases: ArkLabsHQ/lnurl-server

v0.5.0

Choose a tag to compare

@github-actions github-actions released this 21 Oct 09:41
f039788

Added

  • @arkade-os/lnurl-client 0.8.0: the glue a wallet otherwise writes itself — createLocalStorageLnurlWatermarkStore(key?) from /browser is the cursor backend createLnurlPaymentRepository needs beside the IndexedDB record store: one JSON map of ${baseUrl}|${lightningAddress} cursors under key, where a map that cannot be read counts as empty so the next sync replays rather than skips. lnurlActivityResolver and sentActivityResolver await their getter on every prepare, so () => repository.all() passes straight in. arkadeLnurl().sessionLnurl() returns the LNURL a nameless claim will serve, before the claim lands. chainName(chainId) names a CAIP-2 chain as the BTCPay LNURLVerify plugin does. It also adds integration helpers: createLocalStorageLnurlSentPaymentStore(key?) in /browser backs createLnurlSendTracker, and tracker.subscribe(listener) fires after each write that landed. syncPayments and receiver.sync() take a signal that stops fetching and writing. lnurlActivity(activity) reads a tagged activity row back typed, with LNURL_ACTIVITY_KIND / SENT_ACTIVITY_KIND exported. LnurlAddressErrorCode types LnurlError.code for address endpoints, held to the server's codes by a type-level test. For payers, lnurlPayableRanges(payRequest) gives the sendable ranges and whether an amount fits, and firstQuote(options) with isLnurlRail falls back from a rail that cannot quote. For token receive, tokenOptionAccepts applies an option's bounds and requestTokenQuote requests, checks and normalizes a quote with a minimum lifetime. Receiver discovery moves into the facade: owned({ refresh: true }) re-binds the current destinations only on active aliases the server lists as bound elsewhere, or on every alias where the server does not say; claim, owned and upgrade run one at a time per identity and server across facades; a signal passed to owned or claim rejects with its reason and stops further writes; addresses() and domain read without side effects; bootstrapReceiver passes refresh and signal through.
  • The owner's address list reports where each address pays — GET /lnurl/address adds arkadeAddress, claimPublicKey and boardingAddress (null until bound), so a client re-binds only an alias whose destination moved.

Changed

  • arkadeLnurl().owned() returns only an active address; it no longer falls back to a revoked one when nothing else is owned. It also waits for a claim, owned or upgrade still running for the same identity and server, and an object typed as ArkadeLnurl now needs domain and addresses().

Removed

  • HD Lightning-address receiving — the server learnt each receiver's branch xpub and allocated its indexes itself, so it is gone rather than deprecated: the hd body of POST /lnurl/address/:handle/arkade (a body carrying only hd gets the same 400 as one missing arkadeAddress), GET /lnurl/address/:handle/arkade/allocations, and in @arkade-os/lnurl-client the /hd entry, listHdAllocations, Receiver.allocations(), the hd option of registerArkadeIdentity and arkadeLnurl, the HdReceiveConfig, HdReceiveAllocation and HdReceiveAllocationPage types and the @scure/bip32 dependency. Migration 27 drops the HD tables and the addresses.hd_receive column, allocation history included. An address registered in HD mode has no Arkade destination until its owner binds a static one again with arkadeAddress and claimPublicKey; rotating means re-binding, which owned({ refresh: true }) already does.

Fixed

  • API docs (public and admin) load again: Redoc is pinned to v2.5.4, since latest now serves the 3.x ES-module bundle, which a classic script tag cannot run.

v0.4.0

Choose a tag to compare

@github-actions github-actions released this 19 Oct 12:58
634e8b0

Added

  • Share token quote URI/memo validation and normalization, receive-rail limits and destination checks, receiver bootstrap orchestration, and an optional IndexedDB backend through the LNURL client. The demo uses the shared startup, bounds and token payment helpers.
  • Add reusable LNURL client payment repositories with injected record/cursor backends and a reset write gate, pending receiver confirmations, and Arkade send tracking with resume and reset cancellation. The demo wallet shares the package confirmation loop. Batched verification now honors the client's injected fetch transport.
  • HD Lightning-address receiving — register a dedicated public branch instead of a fixed Arkade identity. Every callback reserves a fresh payout address and claim key, including offline invoices, with durable counters and owner-only allocation history for recovery. HD receivers refuse static registration and fallback; existing static receivers keep their behavior. Migration 26 retains allocation snapshots across configuration changes. The client adds /hd branch-export and contract-recovery helpers; applications must watch and shield the resulting payouts.
  • @arkade-os/lnurl-client 0.7.0: pay in a unit — requestInvoice(payRequest, { unit: "USD", amount: 500 }) pays $5.00 to a receiver that advertises units: amount is in the unit's smallest denomination, the answer's paymentQuote must be for exactly that amount and unit, and the invoice must be for the quoted millisats. The payment router takes the same as unitAmount beside raw, and arkadeLnurl().options() accepts a UnitAmount in place of sats; the lnurl rails price it on arkade or lightning and record it as lnurlQuoteMeta(quote).quote. SentPayment, synced received payments and both activity resolvers carry quote, shown as requested ("5.00 USD"). parseUnitAmount/formatUnitAmount convert typed decimals. Breaking: RequestInvoiceOptions is now sats or unit, so { amountSat, unit } no longer compiles; it never worked, since the amount went out in millisats labelled as the unit and the quoted invoice was then refused.
  • Quoted payments keep their unit amount — a callback priced in a LUD-XX unit records { amount, unit, decimals } on its settlement (migration 25), returned as quote by the owner's payments sync and shown in the admin Settlements view.
  • Unit quotes on the arkade and onchain destination rails — unit was refused there; only token-deposit rails, which quote their own payment, still refuse it. The demo wallet's send screen offers a target's units beside sats.
  • Solvers listed by pointer, with their markets read over Nostr — a registry index's solvers, and any pasted or file card carrying a discovery_pubkey and relays, are resolved on every refresh from the signed card each solver publishes over Nostr (kind 38859, d = the network); a card that passes every check replaces that solver's listed markets. To allow a solver the registry does not list, paste its signed pointer — a card with no markets, from cli card --pointer on intent-solver — in the Solvers tab. Unreadable relays leave discovery as it was, with a warning.
  • Price feeds for units quoting (QUOTE_UNITS) — the LUD-XX paymentQuote seam finally has a provider: each listed unit is priced from its own JSON feed (QUOTE_<CODE>_FEED_URL, QUOTE_<CODE>_DECIMALS, and QUOTE_<CODE>_PRICE_PATH unless the URL is Binance or CoinGecko), the feed contract intent-solver's asset markets use, with exact decimal math and the msat amount rounded up. Feeds refresh every QUOTE_REFRESH_MS (60 s) in the background; a unit more than three intervals stale is neither advertised nor quoted, and /health reports it as the optional priceFeeds check. Session LNURLs now advertise and quote units too, and priceFeedQuotes is exported for createServer embedders. Unset, nothing changes. With DB_PATH, units are also editable at runtime from the admin UI's Quotes tab and /admin/api/quote-units (migration 24 adds quote_units): an admin unit replaces the env unit of the same code, a feed must answer before it is saved, and admin-entered feed URLs are fetched through an SSRF guard that refuses private, loopback and link-local hosts.
  • @arkade-os/lnurl-client 0.6.0 — small receive-wallet and payment-router interfaces replace concrete SDK classes, with optional router injection and isolated SDK RC compatibility checks. The optional SDK peer now requires >=0.5.0-rc.0; callers explicitly typing returned routers as the SDK's PaymentRouter should use LnurlPaymentRouter instead. The main entry point remains SDK-free.
  • Optional CAIP-19 identifiers for BTC payment options and network-checked callback aliases, preserving bare rail selectors and token deposit options.
  • Compiler-generated v3 covenant destinations with permissionless batch renewal, separate fee funding, and durable successor tracking. Existing v1/v2 funded addresses retain their original construction.
  • Token deposits through FixedFloat (mainnet only) — with FIXEDFLOAT_API_KEY and FIXEDFLOAT_API_SECRET set, an address with an Arkade identity advertises one paymentOptions entry per stablecoin network (ff-usdtarbitrum, ff-usdcsol, ff-usdttrc, … — USDT and USDC on Ethereum, Arbitrum, Base, Optimism, Polygon, Avalanche, Solana and Tron), each with type set to its CAIP-2 namespace, a CAIP-19 asset, a unit naming a units[] entry, and provider: "FixedFloat". The callback creates the corridor swap's hold invoice and a fixed-rate FixedFloat order paying it, and answers the deposit address, an EIP-681 or Solana Pay paymentURI (none on Tron), and a paymentQuote in the token's base units whose expiresAt is the payer's deadline: the earlier of FixedFloat's deadline and the corridor invoice's less FIXEDFLOAT_SETTLE_MARGIN_SECONDS (600 s), refused when that leaves under FIXEDFLOAT_MIN_PAY_WINDOW_SECONDS (300 s). There is no top-level expiresAt on these answers. Settlement is the corridor's alone; verify then reports the payer's deposit txid as paymentReference. The server never holds or refunds the payer's tokens: a late or wrong deposit is resolved with FixedFloat. Known risk: FixedFloat may keep an order open past our deadline, and a payer who deposits in that gap may find the invoice dead and is not paid out; FixedFloat then holds the tokens in its emergency/refund flow. Expired orders stay watched until the TTL, so such a deposit is logged and shown in the admin view. It refuses to start with FixedFloat keys on any network but bitcoin, without a file-backed DB_PATH, or without offline receive. Every FixedFloat call shares one budget kept 25 units under FixedFloat's 250 a minute. The callback answers 429 past it, past FIXEDFLOAT_ORDERS_PER_IP token callbacks from one IP (10 per 10 minutes), past FIXEDFLOAT_MAX_OPEN_ORDERS_PER_ADDRESS unfunded orders for one receiver (5), or past FIXEDFLOAT_MAX_OPEN_ORDERS in all (20). Each token callback also spends one of the 30 callbacks a minute per IP that the offline Lightning and Arkade destination callbacks share, a limit with no setting, so a burst of them can refuse the same IP's other callbacks for the rest of that minute. After an HTTP 429 from FixedFloat, or five errors in a row, all FixedFloat calls pause for two minutes and the options read available: false. Two unroutable-invoice answers (304) in a row close one receiver's token callbacks for ten minutes. Migration 18 adds the ff_orders table; the admin rails and settlements views show the rail and each order (never its token).
  • FIXEDFLOAT_SIMULATE=true — an in-process stand-in for test networks (refused on bitcoin and with real keys) that answers the same shapes under ffsim- ids, provider: "Simulated", on testnet chains, so wallet and checkout UIs can be exercised without real tokens. It takes no deposit.
  • @arkade-os/lnurl-client 0.5.0: token options — PaymentOption gains asset, unit and provider; a destination result now carries paymentURI (always sent, previously dropped), paymentQuote, paymentDestinationTag, expiresAt and provider. tokenOptions(payRequest) parses token options exactly as the BTCPay LNURLVerify plugin does, and requestInvoice on one checks the answer as the plugin does: the option asked for, an address on the token's chain, and a whole amount of the token.
  • The admin Settlements view links each destination to its explorer and copies it whole on click — an Arkade destination opens in the Arkade explorer and an on-chain one in mempool, for the network solver discovery reports (no link while discovery is off). Clicking the shortened value copies the full destination, or a Lightning row's payment hash.
  • verifiable on every advertised payment option — whether that option's callback answers carry a LUD-21 verify URL, proposed for LUD-XX (lnurl/luds#303). Until now a payer that must detect settlement, such as a merchant backend, learnt that only by requesting a destination, and lnurl-server's onchain option never has one: every checkout cost a refused request, a settlement row and a slot of the per-IP destination budget. Lightning is true; arkade is true only while per-payment covenant destinations serve it, since the static-address fallback identifies no payment; onchain is false. An address served without server caps states nothing, because absent means unknown. @arkade-os/lnurl-client 0.4.5 types it as PaymentOption.verifiable.
  • lnurlQuoteMeta(quote) and the LnurlQuoteMeta type (@arkade-os/lnurl-client/arkade) — what an lnurl rail records on its quote (target, via, verify, verifyBatch), readable without casting quote.meta.lnurl. Undefined for a quote no lnurl rail made.
  • SentPayment.verify / verifyBatch — the receiver-confirmation URLs a send's quote carried, so an app can resume a confirmation that ...
Read more

v0.3.4

Choose a tag to compare

@github-actions github-actions released this 14 Sep 15:00
4ad7fd3

Fixed

  • The served spec omitted the health endpoints — GET /livez and GET /readyz (with its { status, components, reason? } body and the 503 it answers while unready) were registered by src/server.ts but absent from src/openapi.ts, so neither the Redoc page nor /openapi.json mentioned the probes an orchestrator uses. Both are now documented.
  • The public spec under-described the SSE session contract — POST /lnurl/session now documents the optional { token } body that makes a session reconnectable, the 400 / 409 / 429 rejections returned before the stream opens, and the error stream event. The LUD-16 callback's bolt11 branch now includes the paymentOption: "lightning" echo, and the Arkade-identity route's 400 describes both of its invalid-input cases.
  • The admin spec was thinner than the code on solver cards and API keys — PUT /solver-cards/{id} had no request body at all, and the PUT/PATCH/DELETE responses omitted the 400/404 failures the routes return; GET /solver-cards and the mutation responses now carry the persisted card shape. API-key responses include the createdAt / lastUsedAt fields the repo returns. (Path and method coverage itself was audited against the router and already complete — the docs/spec meta endpoints stay undocumented by design.)

Added

  • A route/spec drift guard (test/openapi-routes.test.ts) — builds the real apps with createServer and createAdminServer, walks the Express 5 router stacks, and asserts both that every registered method+path pair is documented in the matching spec and that every documented operation is registered, with an explicit allowlist for the docs/spec meta endpoints (GET /, GET /openapi.json, admin GET /docs). It also fetches both specs through the real HTTP apps, so a spec that no longer serialises fails the suite too.

v0.3.3

Choose a tag to compare

@github-actions github-actions released this 14 Sep 14:15
7499faf

Added

  • Request tracing (TRACE_REQUESTS=1, default off) — one structured completion line per request through the existing logger, on both the public and admin servers, including unmatched routes Express answers with a 404, so an operator behind a reverse proxy can tell "no request arrived" from "a request arrived and matched nothing". The line carries method, path, Host, response status, duration in ms, the X-Request-Id the app attaches, and the X-Forwarded-For / X-Forwarded-Proto / X-Real-Ip headers. With the flag on, startup also logs the resolved public config (base URL, ports, admin bind, trustProxy, Arkade network and indexer URL, discovery sources/candidates and readiness). Off, no lines are added.

Fixed

  • The OpenAPI spec claimed 0.2.6 on every release since 0.3.0 — src/openapi.ts hardcoded info.version, so /openapi.json on the 0.3.2 image still reported 0.2.6, and the admin spec, which sources its version from the public spec, inherited it. The version now lives in one literal (src/version.ts) used by both specs and the startup log, and a test pins it to package.json so a release that updates only one of the two fails CI. The arkade-lnurl listening on … line now carries the version, so docker logs tells an operator which build is running without probing a route.

v0.3.2

Choose a tag to compare

@github-actions github-actions released this 14 Sep 10:23
f0879f1

Fixed

  • Offline receive matched none of the registry's corridor cards — solver selection queried the market set by exact leg id (arkade:<network>/slip44:<slip> / bolt11:<network>/slip44:<slip>), but the published registry indexes its corridor cards in the legacy v0 shape (base_asset.id: "btc" + quote_corridor: "lightning"), whose leg keys render as arkade:btc/lightning:btc. selectMarkets compares leg keys as strings, so the two never met and every offline receive answered no solver card supports a N sat lightning receive. Selection now delegates to solverLightningRendezvous, which accepts both id forms and also rejects a market whose base leg is not BTC — a check the corridor test alone cannot make. The runner-up candidates are still returned in ranked order, so per-quote solver failover is unchanged; the emulator x-only key is now a required argument, since the covenant commits to it. A regression test pins the registry's live short-id shape.

v0.3.1

Choose a tag to compare

@github-actions github-actions released this 14 Sep 09:41
5d6d61a

Fixed

  • Covclaimd-optional offline receive — OFFLINE_SELF_CLAIM=true with OFFLINE_EMULATOR_URL no longer requires COVCLAIMD_URL. The RFQ omits the optional claim_packet and the solver funds anyway, waiting for this server's own covenant claim; OFFLINE_COVENANT_DESTINATIONS likewise needs only ARK_SERVER_URL + OFFLINE_EMULATOR_URL.

v0.3.0

Choose a tag to compare

@github-actions github-actions released this 14 Sep 07:50
108f619

Changed

  • Latest SDKs — @arkade-os/sdk 0.4.68 → 0.4.72 (@arkade-os/solver-discovery stays at 0.2.4, already latest). The offline-receive corridor client moves off the vendored src/vendor/arkade-swap/ copy onto the published @arkade-os/swap@0.0.18, which now ships the lightning:BTC -> arkade:BTC receive corridors. Adapts to the SDK's watch-only contract events (isContractVtxoEvent gate in src/covenant-watcher.ts).

Added

  • Production runtime and card-only solver discovery — uses @arkade-os/solver-discovery across multiple registries, cached indexes, startup cards, and cards pasted into the admin UI. Direct SOLVER_URL / pubkey / relay configuration is removed. Accepted offline swaps atomically persist solver and VHTLC recovery state for restart-safe polling/self-claim. Adds liveness/readiness endpoints, resource caps, redacted structured logs, graceful shutdown, a non-root image, reference Compose deployment, and an operations runbook.
  • Self-claim (OFFLINE_SELF_CLAIM, default off) — the server can push the solver-funded lockup's nonInteractiveClaim leaf itself, while the covenant and emulator still constrain payment to the user's registered address. Claims skip underfunded lockups, are safe to retry, and never block status polling. Versioned VHTLC reconstruction data is now persisted atomically with accepted swaps, so self-claim resumes after restart.
  • Per-payment Arkade destinations (OFFLINE_COVENANT_DESTINATIONS, default off) — the arkade rail handed every payer the same registered address, so concurrent payments were indistinguishable on the wire and the watcher correlated them by amount and arrival window; two payments of the same amount could not be told apart at all, and a greedy first-fit could let an older, smaller record consume a larger one's payment. With the flag set each callback derives its own address (src/covenant-destination.ts) and the script becomes the identifier: a VTXO there belongs to exactly one record, so src/covenant-watcher.ts settles it on the contract event instead of guessing (the arrival window, the 15s skew and the oldest-first assignment all drop away; the amount check stays, since an under-payment must not flip settled). src/arkade-watcher.ts skips these records and keeps correlating the static-address rail only, where amount and arrival time remain all there is. The address is three Taproot leaves — condition(H(P)) + operator + a cosigner key committing to enforcePayTo(static address); user + operator; and user alone after a CSV (OFFLINE_COVENANT_RECOVERY_DELAY_SECONDS, default 86528 — BIP68 counts seconds in 512s units, so 24h exactly is not expressible). Only the first carries H(P), so a fresh preimage moves the address while the covenant bytes stay fixed, and the preimage is not a secret: the covenant means anyone holding it can only pay the user, which is why the two recovery leaves are keyed to the user and need neither P nor this server. A sweeper (src/covenant-sweeper.ts) moves each funded destination on to the static address, so the receiving wallet sees an ordinary arrival and needs to know nothing about the covenant. Costs one extra Arkade transaction per payment and a dependency on the emulator co-signing the sweep; requires OFFLINE_EMULATOR_URL, COVCLAIMD_URL and ARK_SERVER_URL, all checked at startup rather than when a payer is already holding an address. Derivation failure at request time falls back to the static address — ambiguous again for that payment, which beats refusing to be paid. Tracking, watching and spending are the SDK's: the covenant is registered as a contract type (src/covenant-contract.ts) so ContractManager owns its lifecycle — a subscription instead of a poll, awaiting-funds demoting itself once a payment lands, and getSpendablePaths choosing the leaf. Adds migration 007 (covenant_script with a unique index) as the join key; everything else about a covenant lives in the SDK's own ark_contracts.
  • ClaimPacket TLV codec (src/claim-packet.ts) — encode/decode for the Arkade extension packet body covclaimd matches on (type 0x04; TLVs 0x01 ciphertext, 0x02 arkade_script, 0x03 covclaimd_pub_key), transcribed from covclaimd's pkg/preimage/packet.go. Groundwork for the non-interactive claim path in which the funder stamps the packet into the lockup's funding transaction instead of revealing it to covclaimd over HTTP (arkade-os/intent-solver#46); Wired behind OFFLINE_STAMP_CLAIM_PACKET (default off): with it set, the callback sends 0x01 ciphertext + 0x03 covclaimd_pub_key instead of the bare ciphertext, so the solver stamps the packet on chain and the covclaimd is ours to choose rather than something both sides must have been configured with. Off by default because a solver predating that PR forwards the packet as a ciphertext, cannot decrypt it, and the swap funds and refunds.
  • LUD-21 (verify) — LNURL-pay callback responses now carry a verify URL, and a new GET /lnurl/verify/:paymentHash lets payers poll settlement status ({ status, settled, preimage, pr }). Because this server is a relay with no Lightning node, wallets report settlement via the new authenticated POST /lnurl/session/:id/settled with { preimage } — the server checks sha256(preimage) against a payment hash the session issued (decoded locally from the bolt11, no new dependency) before flipping the record to settled. Settlement records live in a new settlements table (migration 003) when DB_PATH is set, or in an in-memory store with a VERIFY_TTL_MS (default 24h) lifetime otherwise, so a payer can still poll verify after the wallet disconnects. Available on both the ephemeral LNURL and the LN-address (LUD-16) flows.
  • Offline receive (opt-in) — with solver cards plus COVCLAIMD_URL and ARK_SERVER_URL, an LN address can register an Arkade receive identity and receive while its wallet is offline. The server obtains a Nostr RFQ through the ranked card candidates, returns the verified hold invoice, and tracks the pinned solver through LUD-21 settlement without holding user keys or funds.
  • Payment options (LUD-XX, paymentOptions) — an LN address with a registered Arkade identity now advertises paymentOptions: [lightning, arkade] in its LUD-06 payRequest. A payer selects a rail with ?paymentOption=<id>: lightning (or absent) keeps the existing BOLT11 / offline-swap flow; arkade returns the user's Arkade address as a paymentDestination (direct receive, no swap) plus a verify URL that reports the non-pr LUD-21 shape ({ settled, paymentOption, paymentDestination, paymentReference }). Unknown/unavailable options return { status: "ERROR", reason: "Unsupported paymentOption" }. Settlement records carry the option + destination + agreed amount (migration 006, incl. amount_msat so the future watcher can correlate observed payments). Because the payer pays the Arkade address directly, the server isn't in the payment path, so arkade settled flips only when the server-side Arkade watcher observes the payment — which ships in this same release, below. The resolver is a small registry (src/payment-options.ts) so future rails/assets slot in.
  • Payment quote (LUD-XX, paymentQuote) — when a QuoteProvider is injected, the LN-address payRequest advertises units (e.g. USD), and a callback with ?unit=<code> (optionally &receiveUnit=) is quoted: the provider converts the unit amount to the effective msat amount used for the bolt11 / offline swap, and the response echoes paymentQuote ({ requested, payment, receive?, fees? }). This server has no rate oracle, so without a provider units is omitted and any unit= request returns Unsupported unit. Framework only — real rate sourcing, assets, and swap-backed quotes plug in behind QuoteProvider (src/quote-provider.ts). Applies to the amount-denominated Lightning path (relay + offline swap); quoting the arkade destination rail is a follow-up.
  • Arkade settlement watcher — when ARK_SERVER_URL is set, a background poller watches the Arkade indexer for payments to destination-rail records (paymentOptions: arkade) and flips verify to settled: true with paymentReference = the observed Arkade txid. Matching is by destination script + agreed amount (amount_msat, never under-paid) + arrival window; each observed VTXO settles at most one record, oldest first. Correlation fuzziness (an unrelated same-amount payment in the same window) is inherent to reference-less address payments and is documented in the README.
  • Solver discovery — SOLVER_REGISTRY_URLS, a startup card file, and admin-pasted cards merge into one atomically refreshed, fee-ranked discovery snapshot with bounded registry caching.
  • Admin settlements view — GET /admin/api/settlements (filter: settled, option, limit) lists LUD-21 settlement records (relay invoices, offline corridor swaps, destination-rail payments) newest-first, never exposing preimages or invoices; plus a Settlements tab in the admin SPA with a 5s live poll.

Security

  • Patched express's transitive dependencies — path-to-regexp 8.3.0 → 8.4.2 (high severity), qs 6.15.0 → 6.16.0, and body-parser 2.2.2 → 2.3.0, which between them clear every advisory open against code this server actually ships. Lockfile only: express 5.2.1 is already the newest release, and the ranges it and router declare already allowed the patched versions, so nothing in package.json changed. The advisories left open after this are all dev-only (vite, postcss, nanoid, esbuild, and the form-data under supertest) and none reach the published image, whose final stage installs --prod and copies only dist.

v0.2.6

Choose a tag to compare

@github-actions github-actions released this 04 Jun 18:45
1e0daac

Added

  • Admin API documentation — a dedicated OpenAPI/Swagger spec for the admin API, served on the admin port at GET /admin/api/docs (Redoc page) and GET /admin/api/openapi.json. Documents every admin endpoint (domains, addresses, API keys, blacklist, sessions, settings) with request/response shapes and error codes. The admin SPA nav gained an "API Docs ↗" link. The spec's version is sourced from the public spec so the two can't drift. (Kept separate from the public spec by design — the admin API runs on the loopback-bound admin port behind your auth proxy.)

v0.2.5

Choose a tag to compare

@github-actions github-actions released this 04 Jun 13:11
8b07518

Fixed

  • The OpenAPI/Swagger docs (served at /) only listed the original four relay endpoints — the public endpoints added in 0.2.0 were never documented, so the page looked unchanged across releases despite the version bump. Documented the missing public endpoints: POST /lnurl/address (register/claim), GET /lnurl/address (list own), DELETE /lnurl/address/{username} (revoke own), and the LUD-16 GET /.well-known/lnurlp/{username} + /callback routes, with request/response shapes and error codes. (The admin API stays out of the public spec by design — it runs on the separate admin port.)

v0.2.4

Choose a tag to compare

@github-actions github-actions released this 04 Jun 12:57
8b37be9

Added

  • Admin Sessions tab: a live view of every connected wallet (the in-memory SSE session map, polled every 5s), joined to the addresses table so each connection shows the LN address(es) it belongs to. Per session: bound addresses, reusable-vs-ephemeral type, connected-since, client IP (as seen through trust proxy), invoices issued (+ last-issued time), and the in-flight payer request (amount + how long it's been waiting). A Disconnect action force-closes a session (POST /admin/api/sessions/:id/disconnect). The session token is never exposed. The Dashboard gains a "Live sessions" count.