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); } -