All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog and this project adheres to Semantic Versioning.
- Fixed: When using the Echo middleware the invoice response status code was 200 OK instead of 402 Payment Required (issue #30)
- Fixed: When using the Echo middleware error responses (including the invoice) were wrapped in JSON instead of just text (issue #30)
- Fixed: GoDoc for
storage.NewBoltClient(...)
contained usage suggestions that would lead to the possibility of clients cheating with reusing preimages
- Fixed: Performance decreased when using Lightning Charge and the amount of invoices in the Lightning Charge server increased (issue #28)
- Fixed: Since the introduction of the
ln.Invoice
struct the whole struct was logged instead of just the invoice string
Note: The following breaking changes don't affect normal users of the package, but only those who use their own implementations of our interfaces.
- Changed: The struct
ln.Invoice
now has a fieldImplDepID string
which is required by the middlewares. It's an LN node implementation dependent ID (e.g. payment hash for lnd, some random string for Lightning Charge). (Required for issue #28.) - Changed:
wall.LNclient
now requires the methodCheckInvoice(string) (bool, error)
to accept the LN node implementation dependent ID instead of the preimage hash as parameter. (Required for issue #28.)
- Added: Support for c-lightning with Lightning Charge (issue #6)
- Note: The current implementation's performance decreases when the amount of invoices in the Lightning Charge server increases. This will be fixed in an upcoming release.
- Added: Package
pay
(issue #20)- Interface
pay.LNclient
- Abstraction of a Lightning Network node client for paying LN invoices. Enables developers to write their own implementations if the provided ones aren't enough. - Struct
pay.Client
- Replacement for a standard Gohttp.Client
- Factory function
NewClient(httpClient *http.Client, lnClient LNclient) Client
-httpClient
can be passed asnil
, leading tohttp.DefaultClient
being used - Method
Do(req *http.Request) (*http.Response, error)
- Meant to be used as equivalent to the same Gohttp.Client
method, but handles the Lightning Network payment in the background. - Method
Get(url string) (*http.Response, error)
- A convenience method for theDo(...)
method, also an equivalent to the same Gohttp.Client
method (regarding its usage)
- Factory function
- Example client in
examples/client/main.go
-
Note: Currently only
ln.LNDclient
can be used in the client, because Lightning Charge doesn't support sending payments (and maybe never will)
- Interface
- Added: Method
Pay(invoice string) (string, error)
forln.LNDclient
- Implements the newpay.LNclient
interface, so that theLNDclient
can be used as parameter in thepay.NewClient(...)
function. (Issue #20) - Fixed: A client could cheat in multiple ways, for example use a preimage for a request to endpoint A while the invoice was for endpoint B, with B being cheaper than A. Or if the LN node is used for other purposes as well, a client could send any preimage that might be for a totally different invoice, not related to the API at all. (Issue #16)
- Fixed: Some info logs were logged to
stderr
instead ofstdout
- Changed: The preimage in the
X-Preimage
header must now be hex encoded instead of Base64 encoded. The hex encoded representation is the typical representation, as used by "lncli listpayments", Eclair on Android and bolt11 payment request decoders like https://lndecode.com. Base64 was used previously because "lncli listinvoices" uses that encoding. (Issue #8) - Changed: Interface
wall.StorageClient
and thus all its implementations in thestorage
package were significantly changed. The methods are now completely independent of any ln-paywall specifics, withSet(...)
andGet(...)
just setting and retrieving any arbitraryinterface{}
to/from the storage. (Required for issue #16.) - Changed: The method
GenerateInvoice(int64, string) (string, error)
in the interfacewall.LNclient
was changed to return aln.Invoice
object, which makes it much easier to access the preimage hash (a.k.a. payment hash), instead of having to decode the invoice. (Useful for issue #16, in which the preimage hash is required as key in the storage.)
Warning: This release contains a lot of renamings and refactorings, so your code will most definitely break. But it paves the way to upcoming features and makes some things easier, like automated testing.
- Added: Package-level documentation
- Improved: In case of an invalid preimage the error response is much more detailed now. It differentiates between several reasons why the preimage is invalid. Additionally more cases of invalid requests are detected now, so a proper
400 Bad Request
is returned instead of a500 Internal Server Error
. (Issue #11) - Improved: Increased performance when creating multiple middleware instances, because the LN client implementation can now be passed into the middleware factory function and be reused across multiple middleware instances. Previously the LN client was created internally, and a new instance was created with every middleware instance.
- Not measured, but probably a bit lower memory consumption and a bit less traffic. Probably not much regarding speed.
- Fixed: Wrong spelling in an error message
- Changed: Renamed package from
pay
towall
- this enables us to create a package calledpay
for client-side payments to the paywall in the future - Changed: Moved all storage implementations to the new package
storage
- Changed: Moved
LNDoptions
andDefaultLNDoptions
to the from thewall
(formerpay
) package to theln
package- This leads to the same kind of separation and loose coupling as with the storages
- Changed: All middleware factory functions now take a
LNclient
as second parameter instead ofLNDoptions
- Added:
pay.NewEchoMiddleware(...)
- A middleware factory function for Echo (issue #2) - Added: Bolt DB client (issue #3)
- Struct
pay.BoltClient
- Implements theStorageClient
interface - Factory function
NewBoltClient(...)
- Struct
pay.BoltOptions
- Options for theBoltClient
- Var
pay.DefaultBoltOptions
- aBoltOptions
object with default values
- Struct
- Added:
pay.LNclient
- An abstraction of a client that connects to a Lightning Network node implementation (like lnd, c-lightning and eclair) - Added:
ln.LNDclient
- Implements thepay.LNclient
interface (issue #4)- Factory function
ln.NewLNDclient(...)
- Factory function
- Improved: Increased middleware performance by reusing the gRPC connection to the lnd backend (issue #4)
- With the same setup (local Gin web service,
pay.GoMap
as storage client, remote lnd, same hardware) it took about 100ms per request before, and takes about 25ms per request now. Measured from the arrival of the initial request until the sending of the response with the Lightning invoice (as logged by Gin).
- With the same setup (local Gin web service,
- Fixed: Success log message mentioned "HandlerFunc" in all middlewares despite it not always being a HandlerFunc
- Fixed: A wrong HTTP status code was used in responses when an internal error occurred (
400 Bad Request
instead of500 Internal Server Error
)
Package pay
:
- Changed: Renamed
pay.InvoiceOptions.Amount
topay.InvoiceOptions.Price
to avoid misunderstandings
Package ln
(none of these changes should affect anyone, because this package is meant to be used only internally):
- Removed:
ln.NewLightningClient(...)
- Not required anymore after adding the much more usableln.NewLNDclient(...)
. - Changed:
ln.GenerateInvoice(...)
from being a function to being a method ofln.LNDclient
and removed all lnd connection-related parameters which are part of theLNDclient
. (issue #4) - Changed
ln.CheckInvoice(...)
from being a function to being a method ofln.LNDclient
and removed all lnd connection-related parameters which are part of theLNDclient
. (issue #4)
- Added: Interface
pay.StorageClient
- an abstraction for multiple storage clients, which allows you to write your own storage client for storing the preimages that have already been used as payment proof in a request (issue #1)- Methods
WasUsed(string) (bool, error)
andSetUsed(string) error
- Methods
- Added: Struct
pay.RedisClient
- implements theStorageClient
interface (issue #1)- Factory function
NewRedisClient(...)
- Factory function
- Added: Var
pay.DefaultRedisOptions
- aRedisOptions
object with default values - Added: Struct
pay.GoMap
- implements theStorageClient
interface (issue #1)- Factory function
NewGoMap()
- Factory function
- Improved: Increased middleware performance and decreased load on the connected lnd when invalid requests with the
x-preimage
header are received (invalid because the preimage was already used) - Instead of first getting a corresponding invoice for a preimage from the lnd and then checking if the preimage was used already, the order of these operations was switched, because then, if the preimage was already used, no request to lnd needs to be made anymore. - Improved: All fields of the struct
pay.RedisOptions
are now optional
Package pay
:
- Changed:
pay.NewHandlerFuncMiddleware(...)
,pay.NewHandlerMiddleware(...)
andpay.NewGinMiddleware(...)
now take aln.StorageClient
instead of a*redis.Client
as parameter (issue #1)
Package ln
(none of these changes should affect anyone, because this package is meant to be used only internally):
- Changed:
ln.CheckPreimage(...)
was renamed toln.CheckInvoice(...)
and doesn't check the storage anymore. Theln
methods are supposed to just handle lightning related things and nothing else. - Removed: Package
lnrpc
- Instead of using our own generated lnd gRPC Go file, import the one from Lightning Labs.
Initial release after working on the project during the "Chainhack 3" Blockchain hackathon.