From ae30315d1687894bd1ef828cee234d80e0d224fd Mon Sep 17 00:00:00 2001 From: Chakib Benziane Date: Tue, 26 Mar 2019 22:01:54 +0100 Subject: [PATCH] Receive LN invoice on upload --- docker-compose.yml | 2 + ln/charge.go | 124 ++++++++++++++++++++++++++++++++++++++++ main.go | 5 +- storage/upload_ctrl.go | 23 +++++++- storage/upload_model.go | 1 - 5 files changed, 152 insertions(+), 3 deletions(-) create mode 100644 ln/charge.go diff --git a/docker-compose.yml b/docker-compose.yml index 278d045..61e8092 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -18,6 +18,8 @@ services: - DB_HOST=maria - DB_USER=bit4sat - DB_PASS=bit4sat + - LN_CHARGE_API=10.192.122.10:9112 + - LN_CHARGE_TOKEN=3emU3Fy8VasHCzMaMXHSVJYpQSqH3yXQj8N5cQFBbq3botrudJuR7zQkBBmFSbAmgXs9GD4j4U3J4R2sMfgqPo8q #deploy: #replicas: 1 diff --git a/ln/charge.go b/ln/charge.go new file mode 100644 index 0000000..0c46fb7 --- /dev/null +++ b/ln/charge.go @@ -0,0 +1,124 @@ +package ln + +import ( + "bytes" + "encoding/json" + "fmt" + "log" + "net" + "net/http" + "net/url" + "os" + "time" + + "github.com/gin-gonic/gin" +) + +const ( + CurMSat = iota + CurSat + CurUSD +) + +const ( + LNChargeAPIEnv = "LN_CHARGE_API" + LNChargeTokenEnv = "LN_CHARGE_TOKEN" + InfoEndpoint = "info" + InvoiceEndpoint = "invoice" +) + +var ( + LNCEndpoint string + LNChargeToken string +) + +type Charge struct { + client *http.Client +} + +func NewCharge() *Charge { + netTransport := &http.Transport{ + Dial: (&net.Dialer{ + Timeout: 5 * time.Second, + }).Dial, + TLSHandshakeTimeout: 5 * time.Second, + } + c := &http.Client{ + Timeout: time.Second * 10, + Transport: netTransport, + } + + return &Charge{ + client: c, + } +} + +func (c *Charge) Info() (gin.H, error) { + + result := make(gin.H) + resp, err := c.client.Get(getUrl(InfoEndpoint)) + if err != nil { + return nil, err + } + + jsonDec := json.NewDecoder(resp.Body) + jsonDec.Decode(&result) + + return result, nil +} + +func (c *Charge) Invoice(amount int, id string) (gin.H, error) { + + result := make(gin.H) + reqData := gin.H{ + "amount": 10, + "currency": "USD", + "description": fmt.Sprintf("bit4sat upload: %s", id), + } + + jsonEnc, err := json.Marshal(reqData) + if err != nil { + return nil, err + } + + resp, err := c.client.Post(getUrl(InvoiceEndpoint), + "application/json", + bytes.NewReader(jsonEnc)) + + if err != nil { + return nil, err + } + + result = make(gin.H) + jsonDec := json.NewDecoder(resp.Body) + jsonDec.Decode(&result) + + return result, nil +} + +func getUrl(endpoint string) string { + url, err := url.Parse(fmt.Sprintf("http://api-token:%s@%s/%s", + LNChargeToken, + LNCEndpoint, + endpoint)) + if err != nil { + log.Fatal(err) + } + + return url.String() + +} + +func init() { + var set bool + LNCEndpoint, set = os.LookupEnv(LNChargeAPIEnv) + if !set { + log.Fatalf("%s not set", LNChargeAPIEnv) + } + + LNChargeToken, set = os.LookupEnv(LNChargeTokenEnv) + if !set { + log.Fatalf("%s not set", LNChargeAPIEnv) + } + +} diff --git a/main.go b/main.go index 0b84327..5a46c6c 100644 --- a/main.go +++ b/main.go @@ -1,9 +1,12 @@ package main -import "git.sp4ke.com/sp4ke/bit4sat/db" +import ( + "git.sp4ke.com/sp4ke/bit4sat/db" +) func main() { defer db.DB.Sql.Close() + api := NewAPI() api.Run() diff --git a/storage/upload_ctrl.go b/storage/upload_ctrl.go index 630ea74..8bf4bd6 100644 --- a/storage/upload_ctrl.go +++ b/storage/upload_ctrl.go @@ -10,6 +10,7 @@ import ( "os" "git.sp4ke.com/sp4ke/bit4sat/db" + "git.sp4ke.com/sp4ke/bit4sat/ln" "git.sp4ke.com/sp4ke/bit4sat/utils" "github.com/gin-gonic/gin" "github.com/segmentio/ksuid" @@ -192,9 +193,29 @@ func (ctrl UploadCtrl) Upload(c *gin.Context) { return } + // Get a new lightning invoice + charge := ln.NewCharge() + + // New invoice for 10$ + invoice, err := charge.Invoice(10, id) + + //info, err := ln.Info() + if err != nil { + utils.JSONErrPriv(c, http.StatusInternalServerError, err) + return + } + + //c.JSON(http.StatusOK, gin.H{ + //"status": http.StatusOK, + //"result": fmt.Sprintf("%d files uploaded uploaded !", len(files)), + //}) + result := gin.H{ + "message": fmt.Sprintf("%d files uploaded uploaded !", len(files)), + "invoice": invoice, + } c.JSON(http.StatusOK, gin.H{ "status": http.StatusOK, - "result": fmt.Sprintf("%d files uploaded uploaded !", len(files)), + "result": result, }) } diff --git a/storage/upload_model.go b/storage/upload_model.go index 9219400..c66bd90 100644 --- a/storage/upload_model.go +++ b/storage/upload_model.go @@ -108,7 +108,6 @@ func CacheSetUploadStatus(id string, status int) error { // Returns true if id exists in DB func IdExists(id string) (exists bool, err error) { key := fmt.Sprintf("upload_status_%s", id) - log.Println("calling exists") err = DB.Redis.Do(radix.Cmd(&exists, "EXISTS", key))