Skip to content

Commit

Permalink
handlers for invoices
Browse files Browse the repository at this point in the history
  • Loading branch information
ramin committed Mar 18, 2024
1 parent 37b14e5 commit b86fefb
Show file tree
Hide file tree
Showing 3 changed files with 167 additions and 40 deletions.
34 changes: 34 additions & 0 deletions examples/invoices/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package main

import (
"fmt"

eclair "github.com/edobtc/go-eclair"
)

func main() {
client := eclair.NewClient()
client = client.WithBaseURL("http://localhost:8282")
client.Debug = true

resp, err := client.CreateInvoice(eclair.CreateInvoiceRequest{
Description: "test4",
Amount: 10000,
})

if err != nil {
fmt.Println(err)
return
}

dresp, err := client.DeleteInvoice(eclair.DeleteInvoiceRequest{
PaymentHash: resp.PaymentHash,
})

if err != nil {
fmt.Println(err)
}

fmt.Println(dresp.Message)

}
146 changes: 125 additions & 21 deletions invoice.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
package eclair

import (
"bytes"
"encoding/json"
"fmt"
"io"
"mime/multipart"
"net/url"
"strconv"
"strings"
)

const (
createPath = "/createinvoice"
deletePath = "/deleteinvoice"
payInvoice = "/payinvoice"
)

type CreateInvoiceResponse struct {
Expand All @@ -28,29 +31,39 @@ type CreateInvoiceResponse struct {
}

type CreateInvoiceRequest struct {
Description string `json:"description"`
DescriptionHash string `json:"descriptionHash"`
Expiry int `json:"expireIn"`
Description string `json:"description,omitempty"`
DescriptionHash string `json:"descriptionHash,omitempty"`
Expiry int `json:"expireIn,omitempty"`
Amount int `json:"amountMsat"`
FallbackAddress string `json:"fallbackAddress"`
PaymentPreimage string `json:"paymentPreimage"`
FallbackAddress string `json:"fallbackAddress,omitempty"`
PaymentPreimage string `json:"paymentPreimage,omitempty"`
}

func (c *CreateInvoiceRequest) ToBuffer() (io.ReadWriter, error) {
var b bytes.Buffer
w := multipart.NewWriter(&b)
err := w.WriteField("description", c.Description)
if err != nil {
return nil, err
func (c *CreateInvoiceRequest) FormData() (io.Reader, error) {
formData := url.Values{}

if c.Description != "" {
formData.Set("description", c.Description)
}

err = w.WriteField("amountMsat", fmt.Sprintf("%d", c.Amount))
if err != nil {
return nil, err
if c.DescriptionHash != "" {
formData.Set("descriptionHash", c.DescriptionHash)
}
if c.Expiry != 0 {
formData.Set("expireIn", strconv.Itoa(c.Expiry))
}
if c.FallbackAddress != "" {
formData.Set("fallbackAddress", c.FallbackAddress)
}
if c.PaymentPreimage != "" {
formData.Set("paymentPreimage", c.PaymentPreimage)
}

if c.Amount != 0 {
formData.Set("amountMsat", fmt.Sprintf("%d", c.Amount))
}

w.Close()
return &b, nil
return strings.NewReader(formData.Encode()), nil
}

type InvoiceFeatures struct {
Expand All @@ -60,20 +73,111 @@ type InvoiceFeatures struct {

func (c *Client) CreateInvoice(settings CreateInvoiceRequest) (*CreateInvoiceResponse, error) {
resp := CreateInvoiceResponse{}
body, err := settings.ToBuffer()
data, err := settings.FormData()
if err != nil {
return nil, err
}

data, err := c.Post(createPath, &body, nil)
r, err := c.Post(createPath, data, nil)
if err != nil {
return nil, err
}

err = json.Unmarshal(data, &resp)
err = json.Unmarshal(r, &resp)
if err != nil {
return nil, err
}

return &resp, nil
}

type DeleteInvoiceResponse struct {
Message string `json:"message"`
}

type DeleteInvoiceRequest struct {
PaymentHash string `json:"paymentHash"`
}

func (c *DeleteInvoiceRequest) FormData() (io.Reader, error) {
formData := url.Values{}
formData.Set("paymentHash", c.PaymentHash)
return strings.NewReader(formData.Encode()), nil
}

func (c *Client) DeleteInvoice(settings DeleteInvoiceRequest) (*DeleteInvoiceResponse, error) {

data, err := settings.FormData()
if err != nil {
return nil, err
}

r, err := c.Post(deletePath, data, nil)
if err != nil {
return nil, err
}

return &DeleteInvoiceResponse{
Message: string(r),
}, nil
}

type PayInvoiceRequest struct {
Invoice string `json:"invoice,omitempty"`
AmountMsat int `json:"amountMsat"`
MaxAttempts int `json:"maxAttempts"`
MaxFeeFlatSat int `json:"maxFeeFlatSat"`
MaxFeePct int `json:"maxFeePct"`
ExternalId string `json:"externalId"`
PathFindingExperimentName string `json:"pathFindingExperimentName"`
Blocking bool `json:"blocking"`
}

type PayInvoiceResponse struct {
Message string `json:"message"`
}

func (c *PayInvoiceRequest) FormData() (io.Reader, error) {
formData := url.Values{}

if c.Invoice != "" {
formData.Set("invoice", c.Invoice)
}
if c.AmountMsat != 0 {
formData.Set("amountMsat", strconv.Itoa(c.AmountMsat))
}
if c.MaxAttempts != 0 {
formData.Set("maxAttempts", strconv.Itoa(c.MaxAttempts))
}
if c.MaxFeeFlatSat != 0 {
formData.Set("maxFeeFlatSat", strconv.Itoa(c.MaxFeeFlatSat))
}
if c.MaxFeePct != 0 {
formData.Set("maxFeePct", strconv.Itoa(c.MaxFeePct))
}
if c.ExternalId != "" {
formData.Set("externalId", c.ExternalId)
}
if c.PathFindingExperimentName != "" {
formData.Set("pathFindingExperimentName", c.PathFindingExperimentName)
}
formData.Set("blocking", strconv.FormatBool(c.Blocking))

return strings.NewReader(formData.Encode()), nil
}

func (c *Client) PayInvoice(settings PayInvoiceRequest) (*PayInvoiceResponse, error) {
data, err := settings.FormData()
if err != nil {
return nil, err
}

r, err := c.Post(payInvoice, data, nil)
if err != nil {
return nil, err
}

return &PayInvoiceResponse{
Message: string(r),
}, nil
}
27 changes: 8 additions & 19 deletions request.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package eclair

import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
Expand All @@ -13,22 +11,17 @@ func (c *Client) Get(path string, response interface{}) ([]byte, error) {
return c.Request(http.MethodGet, path, nil, response)
}

func (c *Client) Post(path string, body interface{}, response interface{}) ([]byte, error) {
return c.Request(http.MethodPost, path, body, response)
func (c *Client) Post(path string, data io.Reader, response interface{}) ([]byte, error) {
return c.Request(http.MethodPost, path, data, response)
}
func (c *Client) Request(method, path string, body interface{}, response interface{}) ([]byte, error) {
reqBody, err := json.Marshal(body)
if err != nil {
return nil, err
}

func (c *Client) Request(method, path string, data io.Reader, response interface{}) ([]byte, error) {
path = strings.TrimPrefix(path, "/")
url := strings.TrimSuffix(c.BaseURL, "/") + "/" + path

req, err := http.NewRequest(
method,
url,
bytes.NewBuffer(reqBody),
data,
)
if err != nil {
return nil, err
Expand All @@ -49,18 +42,14 @@ func (c *Client) Request(method, path string, body interface{}, response interfa
}
defer resp.Body.Close()

if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
}

data, err := io.ReadAll(resp.Body)
d, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}

if c.Debug {
fmt.Println(string(data))
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf(string(d))
}

return data, nil
return d, nil
}

0 comments on commit b86fefb

Please sign in to comment.