BTC$68,420▲ 0.82% / ETH$3,841▼ 0.31% / LTC$94.05▲ 1.14% / SOL$221.60▲ 3.02% / USDT·TRC20$1.0000 / USDC·ERC20$0.9999 / XMR$168.42▼ 0.18% / TON$6.02▲ 0.47% / XRP$2.41▼ 0.09% / GAS·ETH18 gwei / Indicative prices · illustrative ticker / No-KYC · non-pooled · 0.4% flat / BTC$68,420▲ 0.82% / ETH$3,841▼ 0.31% / LTC$94.05▲ 1.14% / SOL$221.60▲ 3.02% / USDT·TRC20$1.0000 / USDC·ERC20$0.9999 / XMR$168.42▼ 0.18% / TON$6.02▲ 0.47% / XRP$2.41▼ 0.09% / GAS·ETH18 gwei / Indicative prices · illustrative ticker / No-KYC · non-pooled · 0.4% flat
OrbChain
UTC 18:47:02 Get started →
§ Product · 2026-04-20

Shipping Lightning without
running an LSP.

Every crypto payment gateway either ships Lightning or apologizes for not shipping it. We shipped it. We also didn't add a single 24/7 on-call shift to do so. Here's the architecture, the tradeoffs we made, and the one thing we still depend on a vendor for.

The two ways to ship LN

Lightning for a payment gateway is really two problems: run a node, and manage liquidity. Most competitors solve problem one by self-hosting LND on a VPS and problem two by running an LSP (Liquidity Service Provider) or by buying inbound liquidity from one. Both add operational load — force-closes at 3am, channel monitoring, watchtowers, backups — to a team that mostly wants to ship product.

The alternative is Lightning-as-a-service. Voltage runs the LND node; our code speaks gRPC to it with our macaroons; our keys hold our sats. It's not custodial — Voltage can't spend our funds — but it is a managed node. They handle 24/7 uptime, watchtowers, backups, upgrades. We pay a flat monthly fee (~$25 at our current tier) and treat the node as a dependency, the same way we treat Infura for Ethereum.

Invoices + payouts

Accepting Lightning is simple once the node is up. We expose a LightningProvider interface with createInvoice, subscribeInvoices, payInvoice, and decodeInvoice. The Voltage-backed implementation wraps ln-service. A mock implementation handles every unit test so our CI never touches a real node.

Invoice settlement is atomic — a Lightning payment either completes or it doesn't, no "2 of 6 confirmations" middle state. That simplifies our deposit pipeline: we set confirmBTC_LN = 0 in the config and recordDeposit credits the merchant on the first SETTLED event from subscribeInvoices. Idempotency falls out naturally — paymentHash is the unique key.

Payouts work the same way, just inverted. A BOLT11 in, a signed payInvoice out, the preimage stored on the Payout row as proof-of-payment. Lightning Addresses ([email protected]) get resolved to BOLT11s via LNURL-pay at payout time.

The liquidity problem

You can't spend Lightning sats you don't have in outbound channels. You can't receive Lightning sats without inbound capacity. An LSP is what most gateways use to rent both. We don't want to operate one, but we still need to solve the problem.

Our answer: Boltz submarine swaps. Boltz is a stateless REST API for LN ↔ on-chain BTC swaps, backed by HTLCs (so the swap is trustless — if the counterparty fails, the refund path recovers your funds on-chain). When our outbound Lightning liquidity drops below a threshold, a worker triggers a swap: we send on-chain BTC to Boltz, they route a Lightning payment back to us, our channel gets filled. Same mechanism in the other direction when inbound capacity runs low.

The decision engine is ~80 lines. It reads channel balance, computes the direction and amount, and executes through our existing SwapVenue abstraction (the one we already use for ChangeNOW). Hard caps: 0.02 BTC per swap, 0.2 BTC per 24h rolling window, 30-minute post-fail cooldown per direction.

What we're still on the hook for

  • Opening the first channel. Voltage's Flow 2.0 LSP gives us inbound liquidity at node setup. This is a one-time op per tier upgrade.
  • Channel topology. Our outbound channel peers matter — not all routes are cheap. We document peer selection in our ops runbook.
  • Watching for force-closes. Voltage's watchtower handles the honest case. We alert on channel-count deltas so we see anomalies quickly.
  • Rebalance caps. Boltz has had downtime. The 30-minute cooldown prevents a retry loop from burning sats during an outage.

What we deliberately don't ship

  • BOLT12 offers. Wallet support was still sparse in early 2026. We'll revisit when Phoenix, Zeus, and Wallet of Satoshi all support receiving them.
  • Multi-path payment tuning. LND does MPP automatically; we don't expose knobs for it.
  • Our own LSP. Running an LSP is a business, not a feature. If we ever need one, we'd spin it up as a separate entity.

Shipping cadence

The stack above went from empty directory to live-on-testnet in four focused passes (PL-T1..T4 in our v2.4 roadmap). Mainnet canary is 30 days at a 0.05 BTC channel cap before we raise the ceiling. If you're a merchant who wants to be an early mainnet canary partner, we pay for the channel.

§ Keep reading

Related posts.

Hand-picked
Same rails, next questions