Download the PHP package amashukov/lnd-client-php without Composer
On this page you can find all versions of the php package amashukov/lnd-client-php. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download amashukov/lnd-client-php
More information about amashukov/lnd-client-php
Files in amashukov/lnd-client-php
Package lnd-client-php
Short Description Typed LND (Lightning Network Daemon) REST client in pure PHP — invoices, payments, channel management and backups over any PSR-18 client, with millisatoshi amounts kept exact as bcmath numeric-strings.
License MIT
Homepage https://github.com/AndreyMashukov/lnd-client-php
Informations about the package lnd-client-php
amashukov/lnd-client-php
Typed LND (Lightning Network Daemon) REST client in pure PHP — invoices, payments, channel management and backups over any PSR-18 client, with millisatoshi amounts kept exact as bcmath numeric-strings.
An LND client in pure PHP speaking the node's REST gateway, built on any PSR-18 HTTP client. It covers the surface a custodial service actually needs: mint an invoice, watch it settle, pay a BOLT11, track that payment to a verdict, read channel and wallet balances, and drive channel lifecycle (open, close, fee policy, static backup) from an operator panel rather than lncli over ssh.
Features
- Millisatoshi arithmetic that cannot silently lose money —
Msatis a bcmath numeric-string value object. No floats anywhere;2100000000000000000msat survives a round trip that IEEE-754 would mangle. Sub-satoshi remainders are rejected loudly instead of being rounded away. - A timeout is not a failure —
sendPayment()raisesLndUnavailableExceptionwhen the node is unreachable or the call times out, andLnPaymentStatetreats every unrecognised or unknown state as unresolved. OnlySUCCEEDEDandFAILEDare terminal, so a caller can never mistake "I don't know yet" for "it failed" and pay twice. - Transport-agnostic — bring your own PSR-18 client and PSR-17 factories. The macaroon header, TLS pinning, retries and timeouts are middleware concerns of the host application, deliberately not baked in.
- Typed value objects —
LnInvoice,LnPayment,LnChannel,LnChannelBalance,LnWalletBalance,LnNodeInfo,LnChannelPoint,LnChannelBackup. They are total functions over wire data: a missing invoice becomes an absent instance, never an exception and nevernull. - Wire quirks handled — LND returns payment hashes and funding txids base64-encoded in some responses and hex in others; the VOs normalise both to lowercase hex. The
v2/routerstreaming endpoints wrap their payload in aresultenvelope, which is unwrapped transparently. - Zero framework coupling — no Symfony, no Laravel, no
App\namespace. PHPStan level 8 acrosssrcandtests.
Installation
Requires PHP >= 8.3 and ext-bcmath.
Usage
Paying an invoice, with a hard cap on routing fees:
Settling a payment safely
sendPayment() returning is not the end of the story, and neither is it throwing. The only
authority on whether money moved is trackPayment():
If sendPayment() throws LndUnavailableException, the HTLC may still be in flight. Treat that
as unresolved and let the next poll decide. Mapping it to failure and re-sending is how a
custodial service double-pays.
Channel operations
Backups
exportChannelBackup() returns the multi-channel static backup blob. It is the only artefact
that can recover funds from a lost node — and it is worthless if the recovered node is later
started from stale channel state. Store it off-box, encrypted and versioned; never run two
daemons against one state directory.
Value objects
| Class | Notes |
|---|---|
Msat |
Millisatoshi as a bcmath numeric-string. fromString / fromInt / fromSat / fromBtc / zero; add, sub (throws rather than going negative), mulBps, comparisons. toSat() throws on a sub-satoshi remainder. |
LnInvoice |
paymentHash (lowercase hex), bolt11, state, amountMsat, amountPaidMsat, expiresAt(), isExpiredAt(). LnInvoice::absent() for "no such invoice". |
LnPayment |
state, feeMsat (actual routing fee paid), failureReason, preimage. isInFlight() is true for anything not terminal, including unknown. |
LnChannel |
capacityMsat, localBalanceMsat, remoteBalanceMsat, active, pendingHtlcs, plus localShareBps() / inboundShareBps() for threshold alerts. |
LnChannelBalance, LnWalletBalance |
Off-chain and on-chain balances. |
LnNodeInfo |
alias, blockHeight, syncedToChain, isHealthy(). |
LnChannelPoint |
Funding txid + output index; renders as txid:index. |
LnChannelBackup |
The SCB blob and how many channels it covers. |
Exceptions
LndUnavailableException extends LndException, so one catch (LndException) covers both — but
the distinction matters: LndUnavailableException means transient, retry (transport failure or
HTTP 5xx), while a plain LndException carries an error the node itself reported, with
getLndCode().
Testing
Contract tests read recorded LND responses from tests/fixtures/*.json and assert the value
objects decode them exactly, so a change in the node's wire format fails a test rather than
surfacing as a wrong balance in production.
All versions of lnd-client-php with dependencies
ext-bcmath Version *
psr/clock Version ^1.0
psr/http-client Version ^1.0
psr/http-factory Version ^1.1
psr/http-message Version ^2.0