Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
137 changes: 137 additions & 0 deletions LNPay.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
/**
* LNPay Payment Connector
*
* @author Tim Kijewski <bootstrapbandit7@gmail.com>
*
*/

#include <String.h>
#include <ArduinoJson.h>
#include <WiFiClientSecure.h>
#include <HTTPClient.h>

#include "PaymentConnector.h"

//API Setup
String api_key = "<public_api_key>"; // Can be found here: https://lnpay.co/dashboard/integrations
String wallet_key = "<wallet_access_key>"; // Can be found here: https://lnpay.co/dashboard/advanced-wallets


//Endpoint Setup
String api_endpoint = "https://lnpay.co/v1";
String invoice_create_endpoint = "/wallet/" + wallet_key + "/invoice";
String invoice_check_endpoint = "/lntx/{{tx_id}}"; //append LNTX ID to the end (e.g. /user/lntx/lntx_mfEKSse22)

//HTTP client
HTTPClient http;


//Constructor
PaymentConnector::PaymentConnector (String currency_pair) {
_currency_pair = currency_pair;
}


/**
* PaymentConnector::createRequest
*
* @param String method - GET,POST
* @param String path - REST path to be appended to api_endpoint
* @param String data - string of data for POST requests
*
* @return String - response data from request
*
*/
String PaymentConnector::createRequest(String method,String path, String data)
{
String payload;
int httpCode;

Serial.println("PaymentConnector::createRequest BEGIN-------");
Serial.println("METHOD:" + method);
Serial.println("URL:" + api_endpoint + path);
Serial.println("DATA:" + data);

http.begin(api_endpoint + path); //Getting fancy to response size
http.addHeader("Content-Type","application/json");
http.addHeader("X-Api-Key",api_key);

if (method.equals("POST"))
httpCode = http.POST(data); //Make the request
else if (method.equals("GET")) {
httpCode = http.GET(); //Make the request
} else {
Serial.println("This HTTP method usage is not defined");
}

if (httpCode > 0) { //Check for the returning code
payload = http.getString();
Serial.println("RESPONSE:" + payload);
} else {
Serial.println("Error on HTTP request");
}
http.end(); //Free the resources
Serial.println("PaymentConnector::createRequest END--------");

return payload;
}


/**
* PaymentConnector::createInvoice
*
* @param int num_satoshis - number of satoshis for invoice
* @param String memo - Memo for invoice
*
* @return createInvoiceResponse - object containing both a payment_request AND an ID for lookup
*
*/
createInvoiceResponse PaymentConnector::createInvoice(int num_satoshis, String memo) {
String toPost = "{ \"num_satoshis\" : " + (String) num_satoshis +", \"memo\" :\""+ memo + String(random(1,1000)) + "\"}";

String payload = PaymentConnector::createRequest((String)"POST",invoice_create_endpoint,toPost);

const size_t capacity = JSON_OBJECT_SIZE(2) + 500;
DynamicJsonDocument doc(capacity);
deserializeJson(doc, payload);
Serial.println(payload);

const char* payment_request = doc["payment_request"];
const char* id = doc["id"];
String payreq = (String) payment_request;
String lntx_id = (String) id;
Serial.println(payreq);
Serial.println(lntx_id);

createInvoiceResponse cir;

cir.payment_request = payreq;
cir.payment_id = lntx_id;

return cir;
}

/**
* PaymentConnector::checkIfPaymentIsSettled
*
* @param String id - provided from the PaymentConnector::createInvoice call to check if settled
*
* @return int - 1 or 0 depending on settled
*
*/
int PaymentConnector::checkIfPaymentIsSettled(String id) {
invoice_check_endpoint.replace("{{tx_id}}",id);
String payload = PaymentConnector::createRequest((String)"GET",invoice_check_endpoint);

const size_t capacity = JSON_OBJECT_SIZE(2) + 500;
DynamicJsonDocument doc(capacity);
deserializeJson(doc, payload);

const char* settled = doc["settled"];
int settledInt = (int) settled;
if (settledInt == 1){
return 1;
} else{
return 0;
}
}
29 changes: 29 additions & 0 deletions PaymentConnector.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* createInvoiceResponse
*
* @param String payment_request - Payment request to be saved from the createInvoice request
* @param String payment_id - to be used to poll for invoice settled or not
*
*
*/
class createInvoiceResponse {
public:
String payment_request;
String payment_id;
};

/**
* PaymentConnector
*
* Skeleton for functions required to make a PaymentConnector
*
*/
class PaymentConnector {
public:
PaymentConnector(String currency_pair);
createInvoiceResponse createInvoice(int num_satoshis, String memo);
int checkIfPaymentIsSettled(String id);
String createRequest(String method, String path, String data = "");
private:
String _currency_pair;
};
42 changes: 42 additions & 0 deletions main.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#include <M5Stack.h>
#include <WiFiClientSecure.h>
#include "PaymentConnector.h"

PaymentConnector lnpay("BTCUSD");

void setup() {
Serial.begin(115200);
M5.begin();
Wire.begin();
WiFi.begin("SSID", "PASSWORD");
int i = 0;
while (WiFi.status() != WL_CONNECTED) {
if(i >= 5){
M5.Lcd.fillScreen(BLACK);
M5.Lcd.setCursor(55, 80);
M5.Lcd.setTextSize(2);
M5.Lcd.setTextColor(TFT_RED);
M5.Lcd.println("WIFI NOT CONNECTED");
}
i++;
}




}

void loop() {
// put your main code here, to run repeatedly:


//createInvoiceResponse resp = lnpay.createInvoice(20,"Memo!");

int settled = 0;
while (!settled) {
settled = lnpay.checkIfPaymentIsSettled(resp.payment_id);
Serial.println("SETTLED:" + settled);
delay(1000);
}

}