feat: Add LNBits multi currency price integration
This commit is contained in:
parent
3e54343da8
commit
19c877a254
12 changed files with 526 additions and 155 deletions
|
@ -46,8 +46,11 @@ std::string getCurrencyCode(char input)
|
|||
case CURRENCY_CAD:
|
||||
return CURRENCY_CODE_CAD;
|
||||
break;
|
||||
default:
|
||||
case CURRENCY_USD:
|
||||
return CURRENCY_CODE_USD;
|
||||
break;
|
||||
default:
|
||||
return CURRENCY_CODE_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -63,126 +66,172 @@ char getCurrencyChar(const std::string& input)
|
|||
return CURRENCY_AUD;
|
||||
else if (input == "CAD")
|
||||
return CURRENCY_CAD;
|
||||
else
|
||||
else if (input == "USD")
|
||||
return CURRENCY_USD; // Assuming USD is the default for unknown inputs
|
||||
else
|
||||
return ' ';
|
||||
}
|
||||
|
||||
std::array<std::string, NUM_SCREENS> parsePriceData(std::uint32_t price, char currencySymbol, bool useSuffixFormat, bool mowMode, bool shareDot)
|
||||
{
|
||||
std::array<std::string, NUM_SCREENS> ret;
|
||||
std::string priceString;
|
||||
if (std::to_string(price).length() >= NUM_SCREENS || useSuffixFormat)
|
||||
// Private helper methods
|
||||
namespace {
|
||||
std::array<std::string, NUM_SCREENS> formatPriceData(std::uint32_t price, char currencySymbol, const std::string& currencyCode, bool useSuffixFormat, bool mowMode, bool shareDot, bool useSymbol)
|
||||
{
|
||||
int numScreens = shareDot || mowMode ? NUM_SCREENS - 1 : NUM_SCREENS - 2;
|
||||
priceString = getCurrencySymbol(currencySymbol) + formatNumberWithSuffix(price, numScreens, mowMode);
|
||||
}
|
||||
else
|
||||
{
|
||||
priceString = getCurrencySymbol(currencySymbol) + std::to_string(price);
|
||||
}
|
||||
std::uint32_t firstIndex = 0;
|
||||
if ((shareDot && priceString.length() <= (NUM_SCREENS)) || priceString.length() < (NUM_SCREENS))
|
||||
{
|
||||
priceString.insert(priceString.begin(), NUM_SCREENS - priceString.length(), ' ');
|
||||
|
||||
if (mowMode)
|
||||
std::array<std::string, NUM_SCREENS> ret;
|
||||
std::string priceString;
|
||||
// If useSymbol is true, we're using the char version - use symbol as requested
|
||||
// If useSymbol is false, we're using the string version - only use symbol if it's a recognized currency
|
||||
bool shouldUseSymbol = useSymbol || (!useSymbol && currencySymbol != ' ');
|
||||
|
||||
if (std::to_string(price).length() >= NUM_SCREENS || useSuffixFormat)
|
||||
{
|
||||
ret[0] = "MOW/UNITS";
|
||||
int numScreens = shareDot || mowMode ? NUM_SCREENS - 1 : NUM_SCREENS - 2;
|
||||
if (shouldUseSymbol) {
|
||||
priceString = getCurrencySymbol(currencySymbol) + formatNumberWithSuffix(price, numScreens, mowMode);
|
||||
} else {
|
||||
priceString = formatNumberWithSuffix(price, numScreens, mowMode);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret[0] = "BTC/" + getCurrencyCode(currencySymbol);
|
||||
}
|
||||
|
||||
|
||||
firstIndex = 1;
|
||||
}
|
||||
|
||||
size_t dotPosition = priceString.find('.');
|
||||
|
||||
if (shareDot && dotPosition != std::string::npos && dotPosition > 0)
|
||||
{
|
||||
std::vector<std::string> tempArray;
|
||||
if (dotPosition != std::string::npos && dotPosition > 0)
|
||||
{
|
||||
for (size_t i = 0; i < priceString.length(); ++i)
|
||||
{
|
||||
if (i == dotPosition - 1)
|
||||
{
|
||||
tempArray.push_back(std::string(1, priceString[i]) + ".");
|
||||
++i; // Skip the dot in the next iteration
|
||||
}
|
||||
else
|
||||
{
|
||||
tempArray.push_back(std::string(1, priceString[i]));
|
||||
}
|
||||
}
|
||||
|
||||
// Copy from tempArray to ret
|
||||
for (std::uint32_t i = firstIndex; i < NUM_SCREENS && i - firstIndex < tempArray.size(); ++i)
|
||||
{
|
||||
ret[i] = tempArray[i - firstIndex];
|
||||
if (shouldUseSymbol) {
|
||||
priceString = getCurrencySymbol(currencySymbol) + std::to_string(price);
|
||||
} else {
|
||||
priceString = std::to_string(price);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (std::uint32_t i = firstIndex; i < NUM_SCREENS; i++)
|
||||
{
|
||||
ret[i] = std::string(1, priceString[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::array<std::string, NUM_SCREENS> parseSatsPerCurrency(std::uint32_t price,char currencySymbol, bool withSatsSymbol)
|
||||
{
|
||||
std::array<std::string, NUM_SCREENS> ret;
|
||||
std::string priceString = std::to_string(int(round(1 / float(price) * 10e7)));
|
||||
std::uint32_t firstIndex = 0;
|
||||
std::uint8_t insertSatSymbol = NUM_SCREENS - priceString.length() - 1;
|
||||
|
||||
if (priceString.length() < (NUM_SCREENS))
|
||||
{
|
||||
// Check if price is greater than 1 billion
|
||||
if (price >= 100000000)
|
||||
{
|
||||
double satsPerCurrency = (1.0 / static_cast<double>(price)) * 1e8; // Calculate satoshis
|
||||
std::ostringstream oss;
|
||||
oss << std::fixed << std::setprecision(3) << satsPerCurrency; // Format with 3 decimal places
|
||||
priceString = oss.str();
|
||||
}
|
||||
else
|
||||
{
|
||||
priceString = std::to_string(static_cast<int>(round(1.0 / static_cast<double>(price) * 1e8))); // Default formatting
|
||||
}
|
||||
|
||||
// Pad the string with spaces if necessary
|
||||
if (priceString.length() < NUM_SCREENS)
|
||||
std::uint32_t firstIndex = 0;
|
||||
if ((shareDot && priceString.length() <= (NUM_SCREENS)) || priceString.length() < (NUM_SCREENS))
|
||||
{
|
||||
priceString.insert(priceString.begin(), NUM_SCREENS - priceString.length(), ' ');
|
||||
|
||||
if (mowMode)
|
||||
{
|
||||
ret[0] = "MOW/UNITS";
|
||||
}
|
||||
else
|
||||
{
|
||||
ret[0] = "BTC/" + currencyCode;
|
||||
}
|
||||
|
||||
|
||||
firstIndex = 1;
|
||||
}
|
||||
|
||||
size_t dotPosition = priceString.find('.');
|
||||
|
||||
if (currencySymbol != CURRENCY_USD || price >= 100000000) // no time anymore when earlier than 1
|
||||
ret[0] = "SATS/" + getCurrencyCode(currencySymbol);
|
||||
else
|
||||
ret[0] = "MSCW/TIME";
|
||||
|
||||
firstIndex = 1;
|
||||
|
||||
for (std::uint32_t i = firstIndex; i < NUM_SCREENS; i++)
|
||||
if (shareDot && dotPosition != std::string::npos && dotPosition > 0)
|
||||
{
|
||||
ret[i] = priceString[i];
|
||||
std::vector<std::string> tempArray;
|
||||
if (dotPosition != std::string::npos && dotPosition > 0)
|
||||
{
|
||||
for (size_t i = 0; i < priceString.length(); ++i)
|
||||
{
|
||||
if (i == dotPosition - 1)
|
||||
{
|
||||
tempArray.push_back(std::string(1, priceString[i]) + ".");
|
||||
++i; // Skip the dot in the next iteration
|
||||
}
|
||||
else
|
||||
{
|
||||
tempArray.push_back(std::string(1, priceString[i]));
|
||||
}
|
||||
}
|
||||
|
||||
// Copy from tempArray to ret
|
||||
for (std::uint32_t i = firstIndex; i < NUM_SCREENS && i - firstIndex < tempArray.size(); ++i)
|
||||
{
|
||||
ret[i] = tempArray[i - firstIndex];
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (std::uint32_t i = firstIndex; i < NUM_SCREENS; i++)
|
||||
{
|
||||
ret[i] = std::string(1, priceString[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (withSatsSymbol)
|
||||
{
|
||||
ret[insertSatSymbol] = "STS";
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
return ret;
|
||||
|
||||
std::array<std::string, NUM_SCREENS> formatSatsPerCurrency(std::uint32_t price, char currencySymbol, const std::string& currencyCode, bool withSatsSymbol, bool alwaysShowSats)
|
||||
{
|
||||
std::array<std::string, NUM_SCREENS> ret;
|
||||
double satsPerCurrency = (1.0 / static_cast<double>(price)) * 1e8;
|
||||
std::string priceString;
|
||||
|
||||
// Handle values below 1 sat per currency with 3 decimal places
|
||||
if (satsPerCurrency < 1.0) {
|
||||
std::ostringstream oss;
|
||||
oss << std::fixed << std::setprecision(3) << satsPerCurrency;
|
||||
priceString = oss.str();
|
||||
}
|
||||
// // Check if price is greater than 1 billion (for displaying with 3 decimal places)
|
||||
// else if (price >= 100000000) {
|
||||
// std::ostringstream oss;
|
||||
// oss << std::fixed << std::setprecision(3) << satsPerCurrency;
|
||||
// priceString = oss.str();
|
||||
// }
|
||||
else {
|
||||
// Default formatting for integer values
|
||||
priceString = std::to_string(static_cast<int>(round(satsPerCurrency)));
|
||||
}
|
||||
|
||||
std::uint32_t firstIndex = 0;
|
||||
std::uint8_t insertSatSymbol = NUM_SCREENS - priceString.length() - 1;
|
||||
|
||||
if (priceString.length() < (NUM_SCREENS))
|
||||
{
|
||||
// Pad the string with spaces if necessary
|
||||
if (priceString.length() < NUM_SCREENS)
|
||||
{
|
||||
priceString.insert(priceString.begin(), NUM_SCREENS - priceString.length(), ' ');
|
||||
}
|
||||
|
||||
if (alwaysShowSats || currencySymbol != CURRENCY_USD || price >= 100000000) // no time anymore when earlier than 1
|
||||
ret[0] = "SATS/" + currencyCode;
|
||||
else
|
||||
ret[0] = "MSCW/TIME";
|
||||
|
||||
firstIndex = 1;
|
||||
|
||||
for (std::uint32_t i = firstIndex; i < NUM_SCREENS; i++)
|
||||
{
|
||||
ret[i] = priceString[i];
|
||||
}
|
||||
|
||||
if (withSatsSymbol)
|
||||
{
|
||||
ret[insertSatSymbol] = "STS";
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
// Updated public methods to use the helper methods
|
||||
std::array<std::string, NUM_SCREENS> parsePriceData(std::uint32_t price, char currencySymbol, bool useSuffixFormat, bool mowMode, bool shareDot)
|
||||
{
|
||||
// For char version, always use the currency symbol
|
||||
return formatPriceData(price, currencySymbol, getCurrencyCode(currencySymbol), useSuffixFormat, mowMode, shareDot, true);
|
||||
}
|
||||
|
||||
std::array<std::string, NUM_SCREENS> parsePriceData(std::uint32_t price, const std::string& currencyCode, bool useSuffixFormat, bool mowMode, bool shareDot)
|
||||
{
|
||||
// For string version, let formatPriceData decide whether to use symbol based on if it's a recognized currency
|
||||
char currencyChar = getCurrencyChar(currencyCode);
|
||||
return formatPriceData(price, currencyChar, currencyCode, useSuffixFormat, mowMode, shareDot, false);
|
||||
}
|
||||
|
||||
std::array<std::string, NUM_SCREENS> parseSatsPerCurrency(std::uint32_t price, char currencySymbol, bool withSatsSymbol)
|
||||
{
|
||||
return formatSatsPerCurrency(price, currencySymbol, getCurrencyCode(currencySymbol), withSatsSymbol, false);
|
||||
}
|
||||
|
||||
std::array<std::string, NUM_SCREENS> parseSatsPerCurrency(std::uint32_t price, const std::string& currencyCode, bool withSatsSymbol)
|
||||
{
|
||||
return formatSatsPerCurrency(price, getCurrencyChar(currencyCode), currencyCode, withSatsSymbol, true);
|
||||
}
|
||||
|
||||
std::array<std::string, NUM_SCREENS> parseBlockHeight(std::uint32_t blockHeight)
|
||||
|
@ -350,7 +399,12 @@ emscripten::val parseBlockHeightArray(std::uint32_t blockHeight)
|
|||
|
||||
emscripten::val parsePriceDataArray(std::uint32_t price, const std::string ¤cySymbol, bool useSuffixFormat = false, bool mowMode = false, bool shareDot = false)
|
||||
{
|
||||
return arrayToStringArray(parsePriceData(price, currencySymbol[0], useSuffixFormat, mowMode, shareDot));
|
||||
// Handle both single character and three-character currency codes
|
||||
if (currencySymbol.length() == 1) {
|
||||
return arrayToStringArray(parsePriceData(price, currencySymbol[0], useSuffixFormat, mowMode, shareDot));
|
||||
} else {
|
||||
return arrayToStringArray(parsePriceData(price, currencySymbol, useSuffixFormat, mowMode, shareDot));
|
||||
}
|
||||
}
|
||||
|
||||
emscripten::val parseHalvingCountdownArray(std::uint32_t blockHeight, bool asBlocks)
|
||||
|
@ -370,7 +424,12 @@ emscripten::val parseBlockFeesArray(std::uint16_t blockFees)
|
|||
|
||||
emscripten::val parseSatsPerCurrencyArray(std::uint32_t price, const std::string ¤cySymbol, bool withSatsSymbol)
|
||||
{
|
||||
return arrayToStringArray(parseSatsPerCurrency(price, currencySymbol[0], withSatsSymbol));
|
||||
// Handle both single character and three-character currency codes
|
||||
if (currencySymbol.length() == 1) {
|
||||
return arrayToStringArray(parseSatsPerCurrency(price, currencySymbol[0], withSatsSymbol));
|
||||
} else {
|
||||
return arrayToStringArray(parseSatsPerCurrency(price, currencySymbol, withSatsSymbol));
|
||||
}
|
||||
}
|
||||
|
||||
EMSCRIPTEN_BINDINGS(my_module)
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
#include <cmath>
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
#include "utils.hpp"
|
||||
|
||||
|
@ -19,9 +21,13 @@ const std::string CURRENCY_CODE_GBP = "GBP";
|
|||
const std::string CURRENCY_CODE_JPY = "JPY";
|
||||
const std::string CURRENCY_CODE_AUD = "AUD";
|
||||
const std::string CURRENCY_CODE_CAD = "CAD";
|
||||
const std::string CURRENCY_CODE_UNKNOWN = " ";
|
||||
|
||||
// Public methods
|
||||
std::array<std::string, NUM_SCREENS> parsePriceData(std::uint32_t price, char currency, bool useSuffixFormat = false, bool mowMode = false, bool shareDot = false);
|
||||
std::array<std::string, NUM_SCREENS> parsePriceData(std::uint32_t price, const std::string& currencyCode, bool useSuffixFormat = false, bool mowMode = false, bool shareDot = false);
|
||||
std::array<std::string, NUM_SCREENS> parseSatsPerCurrency(std::uint32_t price, char currencySymbol, bool withSatsSymbol);
|
||||
std::array<std::string, NUM_SCREENS> parseSatsPerCurrency(std::uint32_t price, const std::string& currencyCode, bool withSatsSymbol);
|
||||
std::array<std::string, NUM_SCREENS> parseBlockHeight(std::uint32_t blockHeight);
|
||||
std::array<std::string, NUM_SCREENS> parseHalvingCountdown(std::uint32_t blockHeight, bool asBlocks);
|
||||
std::array<std::string, NUM_SCREENS> parseMarketCap(std::uint32_t blockHeight, std::uint32_t price, char currencySymbol, bool bigChars);
|
||||
|
@ -29,4 +35,10 @@ std::array<std::string, NUM_SCREENS> parseBlockFees(std::uint16_t blockFees);
|
|||
|
||||
char getCurrencySymbol(char input);
|
||||
std::string getCurrencyCode(char input);
|
||||
char getCurrencyChar(const std::string& input);
|
||||
char getCurrencyChar(const std::string& input);
|
||||
|
||||
// Private helper methods
|
||||
namespace {
|
||||
std::array<std::string, NUM_SCREENS> formatPriceData(std::uint32_t price, char currencySymbol, const std::string& currencyCode, bool useSuffixFormat, bool mowMode, bool shareDot, bool useSymbol = true);
|
||||
std::array<std::string, NUM_SCREENS> formatSatsPerCurrency(std::uint32_t price, char currencySymbol, const std::string& currencyCode, bool withSatsSymbol, bool alwaysShowSats = false);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue