diff --git a/.gitignore b/.gitignore
index 32f3e79..68d38d7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,5 @@ tmp
.vscode
build
.cache
+
+hardware-installer/
diff --git a/INSTALLER.md b/INSTALLER.md
index bcaff40..45658e1 100644
--- a/INSTALLER.md
+++ b/INSTALLER.md
@@ -4,17 +4,16 @@ LNPoS
## Free and open-source bitcoin point-of-sale
-
LNPoS includes:
-- LNPoS (for online LN payments, original project)
-- LNURLPoS (for offline LN payments, original project )
-- OnChain (for onchain payments)
-- LNURLATM (for making offline LN withdraw links).
+- Online PoS (for online LN payments, just connects to LNbits wallet over wifi)
+- Offline PoS (for offline LN payments, original project)
+- Onchain (for onchain payments, uses an bip39 xpub and also creates a mempool.space link for checking)
+- Offline ATM (for making offline LN withdraw links, original project)
-Original demo
+Video tutorial tutorial
-Video tutorial https://twitter.com/arcbtc/status/1585605023337168896
+Born here
Join our telegram group MakerBits
diff --git a/build.sh b/build.sh
old mode 100644
new mode 100755
diff --git a/config.js b/config.js
index 3e079ca..c3362c1 100644
--- a/config.js
+++ b/config.js
@@ -20,63 +20,61 @@ export const addressesAndFiles = [
export const configPath = "elements.json";
export const elements = [
{
- name: "config_lnurlpos",
- value: "",
- label: "LNURLPoS string from LNURLDevices extension",
- type: "text",
+ type: "heading",
+ label: "Offline PoS",
},
{
- name: "config_lnurlatm",
+ name: "config_offlinepos",
value: "",
- label: "LNURL ATM",
+ label: "String from the LNPoS extension",
type: "text",
},
{
- name: "config_password",
+ type: "heading",
+ label: "Offline ATM",
+ },
+ {
+ name: "config_offlineatm",
value: "",
- label: "Device Password",
+ label: "String from the FOSSA extension",
type: "text",
},
+ {
+ type: "heading",
+ label: "Onchain addresses",
+ },
{
name: "config_masterkey",
value: "",
- label: "Onchain Master Public Key",
+ label: "Onchain Extended Public Key",
type: "text",
},
{
- name: "config_server",
- value: "",
- label: "LNbits Server",
+ name: "config_mempool",
+ value: "https://mempool.space",
+ label: "Mempool.space Server, for creating a checking link",
type: "text",
},
{
- name: "config_invoice",
- value: "",
- label: "Wallet Invoice Key",
- type: "text",
+ type: "heading",
+ label: "Online PoS",
},
{
name: "config_lncurrency",
- value: "",
- label: "PoS Currency. ie: EUR",
+ value: "USD",
+ label: "PoS Currency. ie: GBP, EUR",
type: "text",
},
{
- name: "config_lnurlatmms",
- value: "",
- label: "Mempool.space Server",
+ name: "config_server",
+ value: "https://demo.lnbits.com",
+ label: "LNbits Server",
type: "text",
},
{
- name: "config_lnurlatmpin",
+ name: "config_invoice",
value: "",
- label: "LNURLATM pin String",
- type: "text",
- },
- {
- name: "config_decimalplaces",
- value: 2,
- label: "FIAT Decimal Places",
+ label: "Wallet Invoice Key",
type: "text",
},
{
@@ -91,4 +89,20 @@ export const elements = [
label: "WiFi Password",
type: "text",
},
+ {
+ type: "heading",
+ label: "Additional settings",
+ },
+ {
+ name: "config_securitypin",
+ value: "000000",
+ label: "Security pin for settings and ATM mode, 4-6 characters",
+ type: "text",
+ },
+ {
+ name: "config_fiatdecimalplaces",
+ value: 2,
+ label: "FIAT Decimal Places ie 2 for USD, 0 for YEN",
+ type: "text",
+ },
];
diff --git a/debug.sh b/debug.sh
old mode 100644
new mode 100755
diff --git a/lnpos/100_config.ino b/lnpos/100_config.ino
index 7f9c59e..c6c9d12 100644
--- a/lnpos/100_config.ino
+++ b/lnpos/100_config.ino
@@ -125,27 +125,27 @@ void readFiles()
return;
}
- lnurlPoS = getJsonValue(doc, "config_lnurlpos");
- lnurlATM = getJsonValue(doc, "config_lnurlatm");
+ offlinePoS = getJsonValue(doc, "config_offlinepos");
+ offlineATM = getJsonValue(doc, "config_offlineatm");
masterKey = getJsonValue(doc, "config_masterkey");
lnbitsServer = getJsonValue(doc, "config_server");
invoice = getJsonValue(doc, "config_invoice");
- lncurrency = getJsonValue(doc, "config_lncurrency");
- lnurlATMMS = getJsonValue(doc, "config_lnurlatmms");
- lnurlATMPin = getJsonValue(doc, "config_lnurlatmpin");
- decimalplaces = getJsonValue(doc, "config_decimalplaces");
+ lnCurrency = getJsonValue(doc, "config_lncurrency");
+ mempool = getJsonValue(doc, "config_mempool");
+ securityPin = getJsonValue(doc, "config_securitypin");
+ fiatDecimalPlaces = getJsonValue(doc, "config_fiatdecimalplaces");
ssid = getJsonValue(doc, "config_wifi_ssid");
password = getJsonValue(doc, "config_wifi_password");
}
////////LNURL PoS string/////////
- if (lnurlPoS != "null" || lnurlPoS != "")
+ if (offlinePoS != "null" || offlinePoS != "")
{
- baseURLPoS = getValue(lnurlPoS, ',', 0);
- secretPoS = getValue(lnurlPoS, ',', 1);
- currencyPoS = getValue(lnurlPoS, ',', 2);
+ baseURLPoS = getValue(offlinePoS, ',', 0);
+ secretPoS = getValue(offlinePoS, ',', 1);
+ currencyPoS = getValue(offlinePoS, ',', 2);
Serial.println("");
- Serial.println("lnurlPoS: " + lnurlPoS);
+ Serial.println("offlinePoS: " + offlinePoS);
Serial.println("baseURLPoS: " + baseURLPoS);
Serial.println("secretPoS: " + secretPoS);
Serial.println("currencyPoS: " + currencyPoS);
@@ -156,21 +156,21 @@ void readFiles()
}
else
{
- Serial.println("lnurlPoS not set");
+ Serial.println("offlinePoS not set");
}
////////LNURL ATM string/////////
- if (lnurlATM != "null" || lnurlATM != "")
+ if (offlineATM != "null" || offlineATM != "")
{
Serial.println("");
- Serial.println("lnurlATM: " + lnurlATM);
- baseURLATM = getValue(lnurlATM, ',', 0);
+ Serial.println("offlineATM: " + offlineATM);
+ baseURLATM = getValue(offlineATM, ',', 0);
// remove /api/v1.... and add /atm?lightning=
int apiPos = baseURLATM.indexOf("api");
baseUrlAtmPage = baseURLATM.substring(0, apiPos);
baseUrlAtmPage += "atm?lightning=";
- secretATM = getValue(lnurlATM, ',', 1);
- currencyATM = getValue(lnurlATM, ',', 2);
+ secretATM = getValue(offlineATM, ',', 1);
+ currencyATM = getValue(offlineATM, ',', 2);
Serial.println("baseUrlAtmPage: " + baseUrlAtmPage);
Serial.println("baseURLATM: " + baseURLATM);
Serial.println("secretATM: " + secretATM);
@@ -230,11 +230,11 @@ void readFiles()
}
/////////PoS Currency///////
- if (lncurrency != "null" || lncurrency != "")
+ if (lnCurrency != "null" || lnCurrency != "")
{
Serial.println("");
Serial.println("PoS currency used from memory");
- Serial.println("PoS currency: " + lncurrency);
+ Serial.println("PoS currency: " + lnCurrency);
}
else
{
@@ -242,11 +242,11 @@ void readFiles()
}
/////////mempool.space server///////
- if (lnurlATMMS != "null" || lnurlATMMS != "")
+ if (mempool != "null" || mempool != "")
{
Serial.println("");
Serial.println("mempool.space server used from memory");
- Serial.println("mempool.space server: " + lnurlATMMS);
+ Serial.println("mempool.space server: " + mempool);
}
else
{
@@ -254,24 +254,24 @@ void readFiles()
}
/////////mATM/Settings pin///////
- if (lnurlATMPin != "null" || lnurlATMPin != "")
+ if (securityPin != "null" || securityPin != "")
{
Serial.println("");
Serial.println("ATM/settings security pin used from memory");
- Serial.println("ATM/settings security pin: " + lnurlATMPin);
+ Serial.println("ATM/settings security pin: " + securityPin);
}
else
{
- lnurlATMPin = "878787";
+ securityPin = "878787";
Serial.println("ATM/Settings security pin not set using default");
}
/////////no. FIAT decimal places///////
- if (decimalplaces != "null" || decimalplaces != "")
+ if (fiatDecimalPlaces != "null" || fiatDecimalPlaces != "")
{
Serial.println("");
Serial.println("no. fiat decimal places used from memory");
- Serial.println("no. fiat decimal places: " + decimalplaces);
+ Serial.println("no. fiat decimal places: " + fiatDecimalPlaces);
}
else
{
diff --git a/lnpos/CHANGELOG.md b/lnpos/CHANGELOG.md
index c00f84e..117b617 100644
--- a/lnpos/CHANGELOG.md
+++ b/lnpos/CHANGELOG.md
@@ -1,6 +1,6 @@
0.1.4
======
-- Fix typo with logging 'lnurlATM' configuration to serial
+- Fix typo with logging 'offlineATM' configuration to serial
- Remove unused WebServer to reduce build time, file size and installation time
- Show a little "arrow" in front of the selected menu item to avoid ambiguity when only 2 menu items are present (or when the user is color blind)
- Make "USB" indicator blue so it looks better and is easier to distinguish
diff --git a/lnpos/lnpos.ino b/lnpos/lnpos.ino
index f15320f..4e0e5f0 100644
--- a/lnpos/lnpos.ino
+++ b/lnpos/lnpos.ino
@@ -28,25 +28,33 @@ fs::SPIFFSFS &FlashFS = SPIFFS;
bool format = false;
////////////////////////////////////////////////////////
-////////////LNPOS WILL LOOK FOR DETAILS SET/////////////
-////////OVER THE WEBINSTALLER CONFIG, HOWEVER///////////
///////////OPTIONALLY SET HARDCODED DETAILS/////////////
////////////////////////////////////////////////////////
+///////// OPTIONALLY SET HARDCODED SETTINGS ////////////
bool hardcoded = false; /// Set to true to hardcode
-String lnurlPoS = "https://demo.lnbits.com/lnpos/api/v1/lnurl/WTmei,BzzoY5wbgpym3eMdb9ueXr,USD";
-String lnurlATM = "https://demo.lnbits.com/fossa/api/v1/lnurl/W5xu4,XGg4BJ3xCh36JdMKm2kgDw,USD";
+/// FOR OFFLINE POS
+String offlinePoS = "https://demo.lnbits.com/lnpos/api/v1/lnurl/WTmei,BzzoY5wbgpym3eMdb9ueXr,USD";
+
+/// FOR OFFLINE ATM
+String offlineATM = "https://demo.lnbits.com/fossa/api/v1/lnurl/W5xu4,XGg4BJ3xCh36JdMKm2kgDw,USD";
+
+/// FOR GENERATING ONCHAIN ADDRESSES
String masterKey = "xpub6CJFgwcim8tPBJo2A6dS13kZxqbgtWKD3LKj1tyurWADbXbPyWo11exyotTSUY3cvhQy5Mfj8FSURgpXhc4L2UvQyaTMC36S49JnNJMmcWU";
+String mempool = "https://mempool.space";
+
+/// FOR ONLINE POS
String lnbitsServer = "https://demo.lnbits.com";
String invoice = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
-String lncurrency = "GBP";
-String lnurlATMMS = "https://mempool.space";
-String lnurlATMPin = "878787";
-String decimalplaces = "2";
+String lnCurrency = "GBP";
String ssid = "AlansBits";
String password = "ithurtswhenip";
+/// ADDITIONAL SETTINGS
+String securityPin = "878787"; // FOR SETTINGS AND ATM
+String fiatDecimalPlaces = "2"; // FOR OUR JAPANESE FREINDS
+
//////////////////////////////////////////////////
// variables
@@ -77,7 +85,7 @@ String amountToShow = "0";
String key_val;
String selection;
-const char menuItems[5][13] = {"LNPoS", "Offline PoS", "OnChain", "ATM", "Settings"};
+const char menuItems[5][13] = {"Online PoS", "Offline PoS", "OnChain", "ATM", "Settings"};
const char currencyItems[3][5] = {"sat", "USD", "EUR"};
char decimalplacesOutput[20];
int menuItemCheck[5] = {0, 0, 0, 0, 1};
@@ -151,11 +159,11 @@ bool isInteger(const char *str)
return true;
}
-void formatNumber(float number, int decimalplaces, char *output)
+void formatNumber(float number, int fiatDecimalPlaces, char *output)
{
- // Create a format string based on the decimalplaces
+ // Create a format string based on the fiatDecimalPlaces
char formatString[10];
- sprintf(formatString, "%%.%df", decimalplaces);
+ sprintf(formatString, "%%.%df", fiatDecimalPlaces);
// Use the format string to write the number to the output buffer
sprintf(output, formatString, number);
@@ -218,7 +226,7 @@ void loop()
{
noSats = "0";
dataIn = "0";
- formatNumber(0, decimalplaces.toInt(), decimalplacesOutput);
+ formatNumber(0, fiatDecimalPlaces.toInt(), decimalplacesOutput);
amountToShow = decimalplacesOutput;
unConfirmed = true;
key_val = "";
@@ -257,7 +265,7 @@ void loop()
menuLoop();
}
- if (selection == "LNPoS")
+ if (selection == "Online PoS")
{
lnMain();
}
@@ -297,15 +305,15 @@ void checkHardcoded()
{
if (!hardcoded)
{
- lnurlPoS = "";
- lnurlATM = "";
+ offlinePoS = "";
+ offlineATM = "";
masterKey = "";
lnbitsServer = "";
invoice = "";
- lncurrency = "";
- lnurlATMMS = "";
- lnurlATMPin = "";
- decimalplaces = "";
+ lnCurrency = "";
+ mempool = "";
+ securityPin = "";
+ fiatDecimalPlaces = "";
ssid = "";
password = "";
}
@@ -332,7 +340,7 @@ void accessPoint()
isATMMoneyPin(true);
}
- if (pinToShow.length() == lnurlATMPin.length() && pinToShow != lnurlATMPin)
+ if (pinToShow.length() == securityPin.length() && pinToShow != securityPin)
{
error(" WRONG PIN");
delay(1500);
@@ -341,9 +349,9 @@ void accessPoint()
dataIn = "";
isATMMoneyPin(true);
}
- else if (pinToShow == lnurlATMPin)
+ else if (pinToShow == securityPin)
{
- error(" SETTINGS", "HOLD 1 FOR USB", "");
+ error(" SETTINGS", "HOLD 1 FOR USB \nHOLD 2 TO RESET", "");
// start portal (any key pressed on startup)
int count = 0;
while (count < 10)
@@ -362,6 +370,10 @@ void accessPoint()
return;
}
}
+ if (key == '2')
+ {
+ ESP.restart();
+ }
}
}
else
@@ -424,7 +436,7 @@ void onchainMain()
{
while (unConfirmed)
{
- qrData = "https://" + lnurlATMMS + "/address/" + qrData;
+ qrData = mempool + "/address/" + qrData;
qrShowCodeOnchain(false, " *MENU");
while (unConfirmed)
@@ -454,7 +466,7 @@ void lnMain()
return;
}
- if (lncurrency == "" || lncurrency == "default")
+ if (lnCurrency == "" || lnCurrency == "default")
{
currencyLoop();
}
@@ -537,7 +549,7 @@ void lnMain()
{
noSats = "0";
dataIn = "0";
- formatNumber(0, decimalplaces.toInt(), decimalplacesOutput);
+ formatNumber(0, fiatDecimalPlaces.toInt(), decimalplacesOutput);
amountToShow = decimalplacesOutput;
unConfirmed = false;
timer = 5000;
@@ -557,7 +569,7 @@ void lnMain()
noSats = "0";
dataIn = "0";
- formatNumber(0, decimalplaces.toInt(), decimalplacesOutput);
+ formatNumber(0, fiatDecimalPlaces.toInt(), decimalplacesOutput);
amountToShow = decimalplacesOutput;
}
else
@@ -652,7 +664,7 @@ void lnurlATMMain()
isATMMoneyPin(true);
}
- if (pinToShow.length() == lnurlATMPin.length() && pinToShow != lnurlATMPin)
+ if (pinToShow.length() == securityPin.length() && pinToShow != securityPin)
{
error(" WRONG PIN");
delay(1500);
@@ -661,7 +673,7 @@ void lnurlATMMain()
dataIn = "";
isATMMoneyPin(true);
}
- else if (pinToShow == lnurlATMPin)
+ else if (pinToShow == securityPin)
{
isATMMoneyNumber(true);
inputs = "";
@@ -784,7 +796,7 @@ void isLNMoneyNumber(bool cleared)
tft.print(" - ENTER AMOUNT -");
tft.setTextSize(3);
tft.setCursor(0, 50);
- tft.println(String(lncurrency) + ": ");
+ tft.println(String(lnCurrency) + ": ");
tft.println("SAT: ");
tft.setCursor(0, 120);
tft.setTextSize(2);
@@ -792,8 +804,8 @@ void isLNMoneyNumber(bool cleared)
if (!cleared)
{
- amountToShowNumber = dataIn.toFloat() / pow(10, decimalplaces.toInt());
- formatNumber(amountToShowNumber, decimalplaces.toInt(), decimalplacesOutput);
+ amountToShowNumber = dataIn.toFloat() / pow(10, fiatDecimalPlaces.toInt());
+ formatNumber(amountToShowNumber, fiatDecimalPlaces.toInt(), decimalplacesOutput);
amountToShow = String(decimalplacesOutput);
noSats = String(converted * amountToShowNumber);
}
@@ -801,7 +813,7 @@ void isLNMoneyNumber(bool cleared)
{
noSats = "0";
dataIn = "0";
- formatNumber(0, decimalplaces.toInt(), decimalplacesOutput);
+ formatNumber(0, fiatDecimalPlaces.toInt(), decimalplacesOutput);
amountToShow = decimalplacesOutput;
}
@@ -831,14 +843,14 @@ void isLNURLMoneyNumber(bool cleared)
if (!cleared)
{
- amountToShowNumber = dataIn.toFloat() / pow(10, decimalplaces.toInt());
- formatNumber(amountToShowNumber, decimalplaces.toInt(), decimalplacesOutput);
+ amountToShowNumber = dataIn.toFloat() / pow(10, fiatDecimalPlaces.toInt());
+ formatNumber(amountToShowNumber, fiatDecimalPlaces.toInt(), decimalplacesOutput);
amountToShow = String(decimalplacesOutput);
}
else
{
dataIn = "0";
- formatNumber(0, decimalplaces.toInt(), decimalplacesOutput);
+ formatNumber(0, fiatDecimalPlaces.toInt(), decimalplacesOutput);
amountToShow = decimalplacesOutput;
}
@@ -864,14 +876,14 @@ void isATMMoneyNumber(bool cleared)
if (!cleared)
{
- amountToShowNumber = dataIn.toFloat() / pow(10, decimalplaces.toInt());
- formatNumber(amountToShowNumber, decimalplaces.toInt(), decimalplacesOutput);
+ amountToShowNumber = dataIn.toFloat() / pow(10, fiatDecimalPlaces.toInt());
+ formatNumber(amountToShowNumber, fiatDecimalPlaces.toInt(), decimalplacesOutput);
amountToShow = String(decimalplacesOutput);
}
else
{
dataIn = "0";
- formatNumber(0, decimalplaces.toInt(), decimalplacesOutput);
+ formatNumber(0, fiatDecimalPlaces.toInt(), decimalplacesOutput);
amountToShow = decimalplacesOutput;
}
@@ -1218,7 +1230,7 @@ void currencyLoop()
if (currencyItems[i] == currencyItems[currencyItemNo])
{
tft.setTextColor(TFT_GREEN, TFT_BLACK);
- lncurrency = currencyItems[i];
+ lnCurrency = currencyItems[i];
}
else
{
@@ -1352,7 +1364,7 @@ bool checkOnlineParams()
return false;
}
- const char *decimal = decimalplaces.c_str();
+ const char *decimal = fiatDecimalPlaces.c_str();
if (!isInteger(decimal))
{
error("WRONG DECIMAL");
@@ -1395,7 +1407,7 @@ bool checkOfflineParams()
return false;
}
- if (!isInteger(decimalplaces.c_str()))
+ if (!isInteger(fiatDecimalPlaces.c_str()))
{
error("WRONG DECIMAL");
delay(3000);
@@ -1419,7 +1431,7 @@ bool getSats()
}
const char *lnbitsServerChar = lnbitsServer.c_str();
const char *invoiceChar = invoice.c_str();
- const char *lncurrencyChar = lncurrency.c_str();
+ const char *lncurrencyChar = lnCurrency.c_str();
Serial.println("connecting to LNbits server " + lnbitsServer);
if (!client.connect(lnbitsServerChar, 443))
@@ -1428,26 +1440,33 @@ bool getSats()
return false;
}
- const String toPost = "{\"amount\" : 1, \"from\" :\"" + String(lncurrencyChar) + "\"}";
+ const String toPost = "{\"amount\" : 1, \"from_\" :\"" + String(lncurrencyChar) + "\", \"to\" : \"sat\"}";
const String url = "/api/v1/conversion";
client.print(String("POST ") + url + " HTTP/1.1\r\n" + "Host: " + String(lnbitsServerChar) + "\r\n" + "User-Agent: ESP32\r\n" + "X-Api-Key: " + String(invoiceChar) + " \r\n" + "Content-Type: application/json\r\n" + "Connection: close\r\n" + "Content-Length: " + toPost.length() + "\r\n" + "\r\n" + toPost + "\n");
+ // Skip response headers
while (client.connected())
{
- const String line = client.readStringUntil('\n');
+ String line = client.readStringUntil('\n');
if (line == "\r")
- {
break;
- }
}
- const String line = client.readString();
- StaticJsonDocument<150> doc;
- DeserializationError error = deserializeJson(doc, line);
- if (error)
+ // Read entire body
+ String payload;
+ while (client.available())
+ {
+ char c = client.read();
+ payload += c;
+ }
+
+ StaticJsonDocument<3000> doc;
+ DeserializationError jsonError = deserializeJson(doc, payload);
+
+ if (jsonError)
{
Serial.print("deserializeJson() failed: ");
- Serial.println(error.f_str());
+ Serial.println(jsonError.f_str());
return false;
}
@@ -1476,32 +1495,42 @@ bool getInvoice()
return false;
}
- const String toPost = "{\"out\": false,\"amount\" : " + String(noSats.toInt()) + ", \"memo\" :\"LNPoS-" + String(random(1, 1000)) + "\"}";
+ const String toPost = "{\"out\": false,\"amount\" : " + String(noSats.toInt()) + ", \"memo\" :\"Online PoS-" + String(random(1, 1000)) + "\"}";
const String url = "/api/v1/payments";
client.print(String("POST ") + url + " HTTP/1.1\r\n" + "Host: " + lnbitsServerChar + "\r\n" + "User-Agent: ESP32\r\n" + "X-Api-Key: " + invoiceChar + " \r\n" + "Content-Type: application/json\r\n" + "Connection: close\r\n" + "Content-Length: " + toPost.length() + "\r\n" + "\r\n" + toPost + "\n");
-
+ // Skip response headers
while (client.connected())
{
- const String line = client.readStringUntil('\n');
-
+ String line = client.readStringUntil('\n');
if (line == "\r")
- {
break;
- }
}
- const String line = client.readString();
- StaticJsonDocument<1000> doc;
- DeserializationError error = deserializeJson(doc, line);
- if (error)
+ // IMPORTANT, to skip "443\r\n
+ client.readStringUntil('\n');
+
+ // Read JSON payload
+ String payload;
+ while (client.connected())
+ {
+ String line = client.readStringUntil('\n');
+ if (line == "\r" || line.length() == 0)
+ break;
+ payload += line + "\n";
+ }
+
+ Serial.println(payload);
+ StaticJsonDocument<3000> doc;
+ DeserializationError jsonError = deserializeJson(doc, payload);
+ if (jsonError)
{
Serial.print("deserializeJson() failed: ");
- Serial.println(error.f_str());
+ Serial.println(jsonError.f_str());
return false;
}
const char *payment_hash = doc["checking_id"];
- const char *payment_request = doc["payment_request"];
+ const char *payment_request = doc["bolt11"];
qrData = payment_request;
dataId = payment_hash;
@@ -1525,24 +1554,28 @@ bool checkInvoice()
const String url = "/api/v1/payments/";
client.print(String("GET ") + url + dataId + " HTTP/1.1\r\n" + "Host: " + lnbitsServerChar + "\r\n" + "User-Agent: ESP32\r\n" + "Content-Type: application/json\r\n" + "Connection: close\r\n\r\n");
+ // Skip response headers
while (client.connected())
{
- const String line = client.readStringUntil('\n');
+ String line = client.readStringUntil('\n');
if (line == "\r")
- {
break;
- }
}
- const String line = client.readString();
- Serial.println(line);
- StaticJsonDocument<2000> doc;
+ // Read entire body
+ String payload;
+ while (client.available())
+ {
+ char c = client.read();
+ payload += c;
+ }
- DeserializationError error = deserializeJson(doc, line);
- if (error)
+ StaticJsonDocument<3000> doc;
+ DeserializationError jsonError = deserializeJson(doc, payload);
+ if (jsonError)
{
Serial.print("deserializeJson() failed: ");
- Serial.println(error.f_str());
+ Serial.println(jsonError.f_str());
return false;
}
if (doc["paid"])
@@ -1604,10 +1637,13 @@ bool makeLNURL()
String secret;
char hexbuffer[3];
- if (selection == "Offline PoS") {
+ if (selection == "Offline PoS")
+ {
preparedURL = baseURLPoS;
secret = secretPoS;
- } else {
+ }
+ else
+ {
// ATM
preparedURL = baseURLATM;
secret = secretATM;
@@ -1616,7 +1652,8 @@ bool makeLNURL()
int salt_length = 8;
unsigned char salt[salt_length];
- for (int i = 0; i < salt_length; i++) {
+ for (int i = 0; i < salt_length; i++)
+ {
salt[i] = random(0, 256);
}
@@ -1638,7 +1675,8 @@ bool makeLNURL()
size_t payload_len = payload.length();
int padding = 16 - (payload_len % 16);
payload_len += padding;
- for (int i = 0; i < padding; i++) {
+ for (int i = 0; i < padding; i++)
+ {
payload += String((char)padding);
}
@@ -1652,7 +1690,7 @@ bool makeLNURL()
memcpy(salted + 16, encrypted, payload_len);
preparedURL += "?p=";
- preparedURL += toBase64(salted, payload_len+16, BASE64_URLSAFE);
+ preparedURL += toBase64(salted, payload_len + 16, BASE64_URLSAFE);
Serial.println(preparedURL);
char Buf[200];
@@ -1888,17 +1926,19 @@ void printSleepAnimationFrame(String text, int wait)
}
//////////ENCRYPTION///////////////
-void encrypt(unsigned char* key, unsigned char* iv, int length, const char* plainText, unsigned char* outputBuffer){
+void encrypt(unsigned char *key, unsigned char *iv, int length, const char *plainText, unsigned char *outputBuffer)
+{
mbedtls_aes_context aes;
mbedtls_aes_init(&aes);
mbedtls_aes_setkey_enc(&aes, key, 256); // AES-256 requires a 32-byte key
- mbedtls_aes_crypt_cbc(&aes, MBEDTLS_AES_ENCRYPT, length, iv, (const unsigned char*)plainText, outputBuffer);
+ mbedtls_aes_crypt_cbc(&aes, MBEDTLS_AES_ENCRYPT, length, iv, (const unsigned char *)plainText, outputBuffer);
mbedtls_aes_free(&aes);
}
-void deriveKeyAndIV(const char* secret, unsigned char* salt, unsigned char* outputBuffer) {
+void deriveKeyAndIV(const char *secret, unsigned char *salt, unsigned char *outputBuffer)
+{
mbedtls_md5_context md5_ctx;
- unsigned char data[24]; // 16 bytes key + 8 bytes salt
+ unsigned char data[24]; // 16 bytes key + 8 bytes salt
unsigned char md5Output[16]; // 16 bytes for MD5 output
memcpy(data, secret, 16);
@@ -1914,7 +1954,8 @@ void deriveKeyAndIV(const char* secret, unsigned char* salt, unsigned char* outp
unsigned char data_md5[16 + 16 + 8]; // 16 bytes md5 output + 16 bytes key + 8 bytes salt
- for (int i = 16; i <= 48; i+=16) {
+ for (int i = 16; i <= 48; i += 16)
+ {
memcpy(data_md5, md5Output, 16);
memcpy(data_md5 + 16, data, 24);
mbedtls_md5_init(&md5_ctx);
@@ -1926,4 +1967,3 @@ void deriveKeyAndIV(const char* secret, unsigned char* salt, unsigned char* outp
mbedtls_md5_free(&md5_ctx);
}
-