Skip to content

Commit

Permalink
create invoice stub
Browse files Browse the repository at this point in the history
  • Loading branch information
ramin committed Mar 18, 2024
1 parent 481aebc commit 24e33d5
Show file tree
Hide file tree
Showing 5 changed files with 158 additions and 13 deletions.
57 changes: 57 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# go eclai

## what?

A simple API client for [Acinq's Eclair](https://github.com/ACINQ/eclair) [lightning node JSON API](https://acinq.github.io/eclair/#introduction)



### Examples

Some helpful examples are available in [the examples folder](./examples)

### Create Invoice




#### Watching Events

It is possible to listen for a handful of events that the node emits. This is done over websocket. Events that be subscribed to:

| Event Type | Description |
|---------------------------|---------------------------------------------------------------|
| `payment-received` | A payment has been received |
| `payment-relayed` | A payment has been successfully relayed |
| `payment-sent` | A payment has been successfully sent |
| `payment-settling-onchain`| A payment wasn't fulfilled and its HTLC is being redeemed on-chain |
| `payment-failed` | A payment failed |
| `channel-created` | A channel opening flow has started |
| `channel-opened` | A channel opening flow has completed |
| `channel-state-changed` | A channel state changed (e.g. going from offline to connected)|
| `channel-closed` | A channel has been closed |
| `onion-message-received` | An onion message was received |

To open a channel and watch for events

```go
client = client.WithBaseURL("http://localhost:8282") // if you are using polar for a local setup

channel, err := client.Subscribe()
if err != nil {
panic(err)
return
}

// example fo handling events
for message := range channel {
switch message.Type {
case eclair.ChannelOpened:
// handle channel opened event
case eclair.ChannelClosed:
// handle channel closed event
case eclair.PaymentReceived
// handle channel closed event
}
}
```
22 changes: 11 additions & 11 deletions events.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func ToString(kind eventType) string {
}

type Message struct {
Type string `json:"type"`
Type eventType `json:"type"`
Data interface{}
}

Expand Down Expand Up @@ -99,7 +99,7 @@ func UnmarshalEvent(data []byte) (*Message, error) {
return nil, err
}
return &Message{
Type: baseEvent.Type,
Type: ToEventType(baseEvent.Type),
Data: event,
}, nil
case "payment-relayed":
Expand All @@ -108,7 +108,7 @@ func UnmarshalEvent(data []byte) (*Message, error) {
return nil, err
}
return &Message{
Type: baseEvent.Type,
Type: ToEventType(baseEvent.Type),
Data: event,
}, nil

Expand All @@ -118,7 +118,7 @@ func UnmarshalEvent(data []byte) (*Message, error) {
return nil, err
}
return &Message{
Type: baseEvent.Type,
Type: ToEventType(baseEvent.Type),
Data: event,
}, nil

Expand All @@ -128,7 +128,7 @@ func UnmarshalEvent(data []byte) (*Message, error) {
return nil, err
}
return &Message{
Type: baseEvent.Type,
Type: ToEventType(baseEvent.Type),
Data: event,
}, nil

Expand All @@ -138,7 +138,7 @@ func UnmarshalEvent(data []byte) (*Message, error) {
return nil, err
}
return &Message{
Type: baseEvent.Type,
Type: ToEventType(baseEvent.Type),
Data: event,
}, nil

Expand All @@ -148,7 +148,7 @@ func UnmarshalEvent(data []byte) (*Message, error) {
return nil, err
}
return &Message{
Type: baseEvent.Type,
Type: ToEventType(baseEvent.Type),
Data: event,
}, nil

Expand All @@ -158,7 +158,7 @@ func UnmarshalEvent(data []byte) (*Message, error) {
return nil, err
}
return &Message{
Type: baseEvent.Type,
Type: ToEventType(baseEvent.Type),
Data: event,
}, nil

Expand All @@ -168,7 +168,7 @@ func UnmarshalEvent(data []byte) (*Message, error) {
return nil, err
}
return &Message{
Type: baseEvent.Type,
Type: ToEventType(baseEvent.Type),
Data: event,
}, nil

Expand All @@ -178,7 +178,7 @@ func UnmarshalEvent(data []byte) (*Message, error) {
return nil, err
}
return &Message{
Type: baseEvent.Type,
Type: ToEventType(baseEvent.Type),
Data: event,
}, nil

Expand All @@ -188,7 +188,7 @@ func UnmarshalEvent(data []byte) (*Message, error) {
return nil, err
}
return &Message{
Type: baseEvent.Type,
Type: ToEventType(baseEvent.Type),
Data: event,
}, nil

Expand Down
2 changes: 1 addition & 1 deletion events_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ func TestUnmarshalEvent(t *testing.T) {
name: "PaymentRelayedEvent",
data: []byte(`{"type":"payment-relayed","data":{"amount":200,"payment_hash":"def456"}}`),
expected: &Message{
Type: "payment-relayed",
Type: PaymentRelayed,
Data: PaymentRelayedEvent{
AmountIn: 200,
AmountOut: 100,
Expand Down
11 changes: 10 additions & 1 deletion examples/subscribe/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,19 @@ func main() {
channel, err := client.Subscribe()
if err != nil {
panic(err)
return
}

for message := range channel {
fmt.Println(message)
// handle messages here

switch message.Type {
case eclair.ChannelOpened:
// handle channel opened event
case eclair.ChannelClosed:
// handle channel closed event
case eclair.PaymentReceived:
// handle channel closed event
}
}
}
79 changes: 79 additions & 0 deletions invoice.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package eclair

import (
"bytes"
"encoding/json"
"fmt"
"io"
"mime/multipart"
)

const (
createPath = "/createinvoice"
)

type CreateInvoiceResponse struct {
Prefix string `json:"prefix"`
Timestamp int64 `json:"timestamp"`
NodeId string `json:"nodeId"`
Serialized string `json:"serialized"`
Description string `json:"description"`
PaymentHash string `json:"paymentHash"`
PaymentMetadata string `json:"paymentMetadata"`
Expiry int `json:"expiry"`
MinFinalCltvExpiry int `json:"minFinalCltvExpiry"`
Amount int `json:"amount"`
Features InvoiceFeatures `json:"features"`
RoutingInfo []interface{} `json:"routingInfo"`
}

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

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
}

err = w.WriteField("amountMsat", fmt.Sprintf("%d", c.Amount))
if err != nil {
return nil, err
}

w.Close()
return &b, nil
}

type InvoiceFeatures struct {
Activated map[string]string `json:"activated"`
Unknown []interface{} `json:"unknown"`
}

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

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

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

return &resp, nil
}

0 comments on commit 24e33d5

Please sign in to comment.