135 lines
3.7 KiB
C++
135 lines
3.7 KiB
C++
#include <iostream>
|
|
#include <string>
|
|
#include <curl/curl.h>
|
|
#include <boost/json.hpp>
|
|
#include <boost/json/src.hpp>
|
|
#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) {
|
|
curl_easy_setopt(curl, CURLOPT_URL, "https://api.coingecko.com/api/v3/simple/price?ids=solana&vs_currencies=usd");
|
|
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) {
|
|
boost::json::error_code ec;
|
|
auto parsed = boost::json::parse(readBuffer, ec);
|
|
if(!ec) {
|
|
auto& obj = parsed.as_object();
|
|
rate = obj["solana"].as_object()["usd"].as_double();
|
|
}
|
|
}
|
|
}
|
|
return rate;
|
|
}
|
|
|
|
void displayMenu(WINDOW *menu_win, int highlight, const std::string choices[], int n_choices) {
|
|
int x = 2, y = 2;
|
|
box(menu_win, 0, 0);
|
|
for(int i = 0; i < n_choices; ++i) {
|
|
if(highlight == i + 1) {
|
|
wattron(menu_win, A_REVERSE);
|
|
mvwprintw(menu_win, y, x, "%s", choices[i].c_str());
|
|
wattroff(menu_win, A_REVERSE);
|
|
} else
|
|
mvwprintw(menu_win, y, x, "%s", choices[i].c_str());
|
|
++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();
|
|
}
|
|
|
|
int main() {
|
|
initscr();
|
|
clear();
|
|
noecho();
|
|
cbreak();
|
|
|
|
int highlight = 1;
|
|
int choice = 0;
|
|
int c;
|
|
|
|
start_color();
|
|
init_pair(1, COLOR_CYAN, COLOR_BLACK);
|
|
|
|
WINDOW *menu_win = newwin(7, 60, 4, 4);
|
|
keypad(menu_win, TRUE);
|
|
mvprintw(0, 0, "Use arrow keys to go up and down, Press enter to select a choice");
|
|
refresh();
|
|
|
|
const std::string choices[] = { "Convert SOL to USD", "Convert USD to SOL", "Exit" };
|
|
int n_choices = sizeof(choices) / sizeof(std::string);
|
|
displayMenu(menu_win, highlight, choices, n_choices);
|
|
|
|
while(1) {
|
|
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;
|
|
}
|
|
double 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);
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
displayMenu(menu_win, highlight, choices, n_choices);
|
|
}
|
|
|
|
endwin();
|
|
return 0;
|
|
} |