diff --git a/apps/tinycmc/ChangeLog b/apps/tinycmc/ChangeLog new file mode 100644 index 000000000..46fdd1b1e --- /dev/null +++ b/apps/tinycmc/ChangeLog @@ -0,0 +1,2 @@ +0.01: New App +0.02: Set API Key through Apploader \ No newline at end of file diff --git a/apps/tinycmc/README.md b/apps/tinycmc/README.md new file mode 100644 index 000000000..42cbdf203 --- /dev/null +++ b/apps/tinycmc/README.md @@ -0,0 +1,7 @@ +# Tiny Coinmarketcap +A simple app using Gadgedtbridge internet access to fetch current crypto prices from Coinmarketcap. +I'm providing a "free-tier" API Key. + +TO-DOs: +- [X] Add own API Key option +- [ ] Add settings for Currency conversion \ No newline at end of file diff --git a/apps/tinycmc/app-icon.js b/apps/tinycmc/app-icon.js new file mode 100644 index 000000000..0c8a0226b --- /dev/null +++ b/apps/tinycmc/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEw4kA/4ACBIP/o8242462/k8/gtytlz1s+r2/gv/q9Zpv/m+02pj/AH4AqgMRBhURAAQWGqPxqPwA4UoloABkoLCAIQhIiMQgUo29mtfr6WIBogxDFwNBAIeKwd8x2Mud8lUhBolQLoYABrERjurs/S7F329rs+i+I+EC4JRFxl+lUmvmGAIWKkJhGJ4lI01y2+3s4BB1s7s+o+MVMAhPEll7kd+uYBCvgBB7khyIRCL4cZiMS7YuCAAxnBSAsBJoWKl0sLYYBFluBL4iPCiuNsRdEAIlr3GBR4iQBJoMs7pdEAIjDBkK/ESAUY665BABNn7AvFkWBlEsXYoBFMAMlkPwC4UYRwOru5ZDMY+iitBF4MoPAOBxsjXoktAYMoYYcowOBwEokAXBiq+BL4eywWH2WHA4VrYAMViECgEgYAOIxhXDlF8k0oM4eDxrABkReBkEIj/y1ZVCsRjB2UnL4tYimCO4UBoOdlhdCveDAYMuYId8kq/DGIOI/Hyw6MDAA9t7FI/HwJAUBqOBll7X5WK+PxqK/DgMRimNsS7HAINm3DuBd4hfB+ONxhZEAIl8lVBL4YXCjLwB7eyLxFn7AvHJ4PxlS7BLo2OvmBqJfHAANC02yLotrs+iiMYB4IWCL4QgByMsvlzXYlz7UhLoIBBC4cADwMViNS7drFQNnAYXSFwZeDAAJPCyPxlEsFgIuClouBBoPxRwZgEGAMYwWI81n9sikA9CFwwwCKIWRyOFlEtlANEoAWGMIYyDisVCBAAHKYRjBqOAC6AyECqQA/AH4AJA==")) \ No newline at end of file diff --git a/apps/tinycmc/app.js b/apps/tinycmc/app.js new file mode 100644 index 000000000..07a56e494 --- /dev/null +++ b/apps/tinycmc/app.js @@ -0,0 +1,118 @@ +let settings = require("Storage").readJSON("tinycmc.json", 1); +const apiKey = settings.apikey || null; +const cmcBase = 'https://pro-api.coinmarketcap.com/'; +const version = ['v1', 'v2']; +const path = { + latest: '/cryptocurrency/listings/latest', + quote: '/cryptocurrency/quotes/latest' +}; +let page = 0; +function displayLatest(offset) { + g.clear(); + if (page === 0) { + E.showMessage('Getting Top 10'); + } else { + E.showMessage(`Getting Top ${offset} to ${offset + 9}`); + } + + const uri = offset ? `${cmcBase}${version[0]}${path.latest}?convert=EUR&limit=10&start=${offset}` : `${cmcBase}${version[0]}${path.latest}?convert=EUR&limit=10`; + Bangle.http(uri, + { + method: 'GET', + headers: { + "X-CMC_PRO_API_KEY": apiKey, + } + }).then(data=>{ + const result = JSON.parse(data.resp).data; + let menu = { + "" : { title : "-- Select --" }, + }; + //FIXME: Menu can also take an array of items, this would be easier to compose using map + result.forEach(listing => { + menu[listing.name] = { + title: `${listing.cmc_rank}: ${listing.symbol} ${Number(listing.quote.EUR.percent_change_24h).toFixed(3)}`, + onchange: function() { E.showMenu(); displayQuote(listing.symbol);} }; + }); + menu.Next = function() { + E.showMenu(); + g.clear(); + page = page + 1; + displayLatest((page * 10) + 1); + }; // remove the menu + menu.Exit = function() { + E.showMenu(); + g.clear(); + Bangle.showClock(); + }; // remove the menu + g.clear(); + E.showMenu(menu); + setWatch(() => { + g.clear(); + displayMenu(); + }, BTN, {edge:"rising", debounce:50, repeat:true}); +}).catch(error=>{ + console.log('Error'); + console.log(error); + E.showMessage(`${error}\nTo go back press BTN`); + setWatch(() => { + g.clear(); + displayMenu(); + }, BTN, {edge:"rising", debounce:50, repeat:true}); + }); +} + +function displayQuote(symb) { + g.clear(); + E.showMessage(`Getting latest for ${symb}`); + Bangle.http(`${cmcBase}${version[1]}${path.quote}?symbol=${symb}&convert=EUR`, + { + method: 'GET', + headers: { + "X-CMC_PRO_API_KEY": apiKey, + } + }).then(data=>{ + g.clear(); + const result = JSON.parse(data.resp).data[symb][0]; + E.showMessage(`#${result.cmc_rank}: ${result.symbol}\n${Number(result.quote.EUR.price).toFixed(2)}\n%24h: +${result.quote.EUR.percent_change_24h}`); + setWatch(() => { + g.clear(); + displayMenu(); + }, BTN, {edge:"rising", debounce:50, repeat:true}); +}).catch(error=>{ + E.showMessage(`${error}\nTo go back press BTN`); + setWatch(() => { + g.clear(); + displayMenu(); + }, BTN, {edge:"rising", debounce:50, repeat:true}); + }); +} + +function displayMenu() { + if (!apiKey) { + E.showMessage("Please provide a Coinmarketcap API Key"); + } else { + // Actually display the menu + E.showMenu({ + "" : { title : "-- Select --" }, // options + "Latest": function() { E.showMenu(); displayLatest(); }, + "BTC" : function() { E.showMenu(); displayQuote('BTC'); }, + "ETH" : function() { E.showMenu(); displayQuote('ETH'); }, + "XMR" : function() { E.showMenu(); displayQuote('XMR'); }, + "ADA" : function() { E.showMenu(); displayQuote('ADA'); }, + "DOGE" : function() { E.showMenu(); displayQuote('DOGE'); }, + "LTC" : function() { E.showMenu(); displayQuote('LTC'); }, + "Exit" : function() { + E.showMenu(); + g.clear(); + Bangle.showClock(); + }, // remove the menu + }); + } +} + +function main () { + displayMenu(); +} + +main (); diff --git a/apps/tinycmc/icon.png b/apps/tinycmc/icon.png new file mode 100644 index 000000000..2038315e0 Binary files /dev/null and b/apps/tinycmc/icon.png differ diff --git a/apps/tinycmc/interface.html b/apps/tinycmc/interface.html new file mode 100644 index 000000000..2a9e7824b --- /dev/null +++ b/apps/tinycmc/interface.html @@ -0,0 +1,63 @@ + +
+ + + +Go to https://coinmarketcap.com/api/ and sign up for a free account.
+ After registration you can login and obtain your personal API key.