solanaprice-cli/main.cpp

179 lines
5.5 KiB
C++
Raw Normal View History

2024-04-10 04:12:51 -04:00
#include <iostream>
#include <string>
#include <curl/curl.h>
#include <ncurses.h>
static size_t WriteCallback(void *contents, size_t size, size_t nmemb, std::string *userp) {
userp->append(static_cast<char*>(contents), size * nmemb);
return size * nmemb;
}
double getConversionRate() {
CURL *curl;
CURLcode res;
std::string readBuffer;
double rate = 0.0;
curl = curl_easy_init();
if(curl) {
2024-05-29 03:37:12 -04:00
curl_easy_setopt(curl, CURLOPT_URL, "https://api.diadata.org/v1/assetQuotation/Solana/0x0000000000000000000000000000000000000000");
2024-04-10 04:12:51 -04:00
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
if(res == CURLE_OK) {
2024-05-29 03:37:12 -04:00
std::size_t pricePos = readBuffer.find("\"Price\":");
if (pricePos != std::string::npos) {
std::size_t start = readBuffer.find(':', pricePos) + 1;
std::size_t end = readBuffer.find_first_of(",}", start);
2024-04-10 04:49:57 -04:00
if(start < end) {
2024-05-29 03:37:12 -04:00
std::string priceValue = readBuffer.substr(start, end - start);
priceValue.erase(0, priceValue.find_first_not_of(" \n\r\t"));
priceValue.erase(priceValue.find_last_not_of(" \n\r\t") + 1);
2024-04-10 04:49:57 -04:00
try {
2024-05-29 03:37:12 -04:00
rate = std::stod(priceValue);
2024-04-10 04:49:57 -04:00
} catch (const std::invalid_argument& ia) {
std::cerr << "Invalid argument: " << ia.what() << '\n';
} catch (const std::out_of_range& oor) {
std::cerr << "Out of Range error: " << oor.what() << '\n';
}
}
} else {
2024-05-29 03:37:12 -04:00
std::cerr << "Price not found in response." << std::endl;
2024-04-10 04:12:51 -04:00
}
2024-04-10 04:49:57 -04:00
} else {
std::cerr << "CURL failed with error code: " << res << std::endl;
2024-04-10 04:12:51 -04:00
}
}
return rate;
}
2024-04-10 04:31:29 -04:00
void displayMenu(WINDOW *menu_win, int highlight, const std::string choices[], int n_choices, double solRate) {
2024-04-10 04:12:51 -04:00
int x = 2, y = 2;
box(menu_win, 0, 0);
if(solRate == 0.0) {
mvwprintw(menu_win, 1, 1, "Fetching SOL price...");
} else {
mvwprintw(menu_win, 1, 1, "1 SOL = $%.2f ", solRate);
}
2024-04-10 04:12:51 -04:00
for(int i = 0; i < n_choices; ++i) {
if(highlight == i + 1) {
wattron(menu_win, A_REVERSE);
2024-04-10 04:31:29 -04:00
mvwprintw(menu_win, y + 1, x, "%s", choices[i].c_str());
2024-04-10 04:12:51 -04:00
wattroff(menu_win, A_REVERSE);
} else
2024-04-10 04:31:29 -04:00
mvwprintw(menu_win, y + 1, x, "%s", choices[i].c_str());
2024-04-10 04:12:51 -04:00
++y;
}
wrefresh(menu_win);
}
void processChoice(int choice, double rate) {
echo();
if (choice == 1) {
printw("Enter amount in SOL: ");
double sol;
scanw("%lf", &sol);
printw("%.2f SOL is approximately %.2f USD.\n", sol, sol * rate);
} else if (choice == 2) {
printw("Enter amount in USD: ");
double usd;
scanw("%lf", &usd);
printw("%.2f USD is approximately %.2f SOL.\n", usd, usd / rate);
}
noecho();
}
2024-05-29 03:37:12 -04:00
int main(int argc, char *argv[]) {
bool standardMode = false;
if (argc > 1 && std::string(argv[1]) == "-standard") {
standardMode = true;
}
double rate = getConversionRate();
if (standardMode) {
if (rate == 0.0) {
std::cerr << "Failed to fetch conversion rate. Please try again later.\n";
} else {
std::cout << "Solana is Currently $" << rate << std::endl;
}
return 0;
}
2024-04-10 04:12:51 -04:00
initscr();
clear();
noecho();
cbreak();
start_color();
init_pair(1, COLOR_CYAN, COLOR_BLACK);
WINDOW *menu_win = newwin(7, 60, 4, 4);
keypad(menu_win, TRUE);
refresh();
2024-04-10 04:31:29 -04:00
const std::string choices[] = {"Convert SOL to USD", "Convert USD to SOL", "Exit"};
2024-04-10 04:12:51 -04:00
int n_choices = sizeof(choices) / sizeof(std::string);
2024-04-10 04:31:29 -04:00
int highlight = 1;
bool needsFetch = true;
2024-04-10 04:31:29 -04:00
displayMenu(menu_win, highlight, choices, n_choices, rate);
int choice = 0;
int c;
2024-04-10 04:12:51 -04:00
while(1) {
if (needsFetch) {
refresh();
rate = getConversionRate();
needsFetch = false;
clear();
displayMenu(menu_win, highlight, choices, n_choices, rate);
}
2024-04-10 04:31:29 -04:00
c = wgetch(menu_win);
switch(c) {
case KEY_UP:
if(highlight == 1)
highlight = n_choices;
else
--highlight;
break;
case KEY_DOWN:
if(highlight == n_choices)
highlight = 1;
else
++highlight;
break;
case 10: {
choice = highlight;
clear();
refresh();
if (choice == 3) {
endwin();
return 0;
}
rate = getConversionRate();
if (rate == 0.0) {
printw("Failed to fetch conversion rate. Please try again later.\n");
} else {
processChoice(choice, rate);
}
printw("Press any key to return to the menu.");
getch();
clear();
displayMenu(menu_win, highlight, choices, n_choices, rate);
break;
2024-04-10 04:12:51 -04:00
}
2024-04-10 04:31:29 -04:00
default:
break;
2024-04-10 04:12:51 -04:00
}
2024-04-10 04:31:29 -04:00
displayMenu(menu_win, highlight, choices, n_choices, rate);
2024-04-10 04:12:51 -04:00
}
endwin();
return 0;
2024-05-29 03:37:12 -04:00
}