diff --git a/cache/10118a51009b13b2592c87579e15e61e.json b/cache/10118a51009b13b2592c87579e15e61e.json index 2d5b3ba..c1b9204 100644 --- a/cache/10118a51009b13b2592c87579e15e61e.json +++ b/cache/10118a51009b13b2592c87579e15e61e.json @@ -1 +1 @@ -{"timestamp": 1733367496.996954, "result": "120"} \ No newline at end of file +{"timestamp": 1733371180.803243, "result": "120"} \ No newline at end of file diff --git a/cache/1ccff5c6f117409fea0c861aa44b8e62.json b/cache/1ccff5c6f117409fea0c861aa44b8e62.json index 0f03aad..fe2e1e5 100644 --- a/cache/1ccff5c6f117409fea0c861aa44b8e62.json +++ b/cache/1ccff5c6f117409fea0c861aa44b8e62.json @@ -1 +1 @@ -{"timestamp": 1733367305.82001, "result": 1.18} \ No newline at end of file +{"timestamp": 1733370947.4475856, "result": 1.19} \ No newline at end of file diff --git a/cache/29409a8a40dd2d547a7a44b8f6758f54.json b/cache/29409a8a40dd2d547a7a44b8f6758f54.json index 2be2c0d..2e88c24 100644 --- a/cache/29409a8a40dd2d547a7a44b8f6758f54.json +++ b/cache/29409a8a40dd2d547a7a44b8f6758f54.json @@ -1 +1 @@ -{"timestamp": 1733367305.1029575, "result": 4.18} \ No newline at end of file +{"timestamp": 1733370946.7141268, "result": 4.2} \ No newline at end of file diff --git a/cache/4104ed0427efe63d4ca0dead970a4391.json b/cache/4104ed0427efe63d4ca0dead970a4391.json index 00ef5cc..e8ecc7b 100644 --- a/cache/4104ed0427efe63d4ca0dead970a4391.json +++ b/cache/4104ed0427efe63d4ca0dead970a4391.json @@ -1 +1 @@ -{"timestamp": 1733367303.484976, "result": 248.08} \ No newline at end of file +{"timestamp": 1733370945.6919894, "result": 249.75} \ No newline at end of file diff --git a/cache/598f5dbf97fb0d45cbc6e1a5b0a3b575.json b/cache/598f5dbf97fb0d45cbc6e1a5b0a3b575.json index ffbe00e..fb8fb82 100644 --- a/cache/598f5dbf97fb0d45cbc6e1a5b0a3b575.json +++ b/cache/598f5dbf97fb0d45cbc6e1a5b0a3b575.json @@ -1 +1 @@ -{"timestamp": 1733367300.1864865, "result": 231.97} \ No newline at end of file +{"timestamp": 1733370941.0851188, "result": 234.61} \ No newline at end of file diff --git a/cache/6eec370e2713cfc84c84e1080b8a191a.json b/cache/6eec370e2713cfc84c84e1080b8a191a.json index 130faec..750de0b 100644 --- a/cache/6eec370e2713cfc84c84e1080b8a191a.json +++ b/cache/6eec370e2713cfc84c84e1080b8a191a.json @@ -1 +1 @@ -{"timestamp": 1733367298.2447531, "result": 120.0} \ No newline at end of file +{"timestamp": 1733370937.8074176, "result": 120.0} \ No newline at end of file diff --git a/cache/790b28a9a21cf694ad9577ef1072ac9e.json b/cache/790b28a9a21cf694ad9577ef1072ac9e.json index c62859e..85b7b8d 100644 --- a/cache/790b28a9a21cf694ad9577ef1072ac9e.json +++ b/cache/790b28a9a21cf694ad9577ef1072ac9e.json @@ -1 +1 @@ -{"timestamp": 1733365705.1888373, "result": 0.006517062} \ No newline at end of file +{"timestamp": 1733370648.2231722, "result": 0.006517062} \ No newline at end of file diff --git a/cache/94ac30c93587c50252ac382a8d02257f.json b/cache/94ac30c93587c50252ac382a8d02257f.json index ae276d0..a2ba15e 100644 --- a/cache/94ac30c93587c50252ac382a8d02257f.json +++ b/cache/94ac30c93587c50252ac382a8d02257f.json @@ -1 +1 @@ -{"timestamp": 1733367300.1870453, "result": 1.5117628721399998} \ No newline at end of file +{"timestamp": 1733370941.0857272, "result": 1.52896791582} \ No newline at end of file diff --git a/cache/a071d7bdda25c22e42ad7840f17c4b0e.json b/cache/a071d7bdda25c22e42ad7840f17c4b0e.json index 8b8a8fc..e765fda 100644 --- a/cache/a071d7bdda25c22e42ad7840f17c4b0e.json +++ b/cache/a071d7bdda25c22e42ad7840f17c4b0e.json @@ -1 +1 @@ -{"timestamp": 1733367301.6211267, "result": 1.001} \ No newline at end of file +{"timestamp": 1733370944.0799723, "result": 1.001} \ No newline at end of file diff --git a/cache/a0ee60913ba556f39d128e7d7249e788.json b/cache/a0ee60913ba556f39d128e7d7249e788.json index 9cf1b9f..77d0a65 100644 --- a/cache/a0ee60913ba556f39d128e7d7249e788.json +++ b/cache/a0ee60913ba556f39d128e7d7249e788.json @@ -1 +1 @@ -{"timestamp": 1733367305.106161, "result": [{"mint": "jupSoLaHXQiZZTSfEWMTRRgpnyFm8f6sZdosWBjx93v", "balance": 0.039815492, "price": 248.08, "value": 9.87742725536, "name": "Jupiter Staked SOL", "symbol": "jupsol"}, {"mint": "27G8MtK7VtTcCHkpASjSDdkWWYfoqT6ggEuKidVJidD4", "balance": 2.402337, "price": 4.18, "value": 10.04176866, "name": "Jupiter Perpetuals Liquidity Provider Token", "symbol": "jlp"}]} \ No newline at end of file +{"timestamp": 1733370946.7175624, "result": [{"mint": "jupSoLaHXQiZZTSfEWMTRRgpnyFm8f6sZdosWBjx93v", "balance": 0.039815492, "price": 249.75, "value": 9.943919127000001, "name": "Jupiter Staked SOL", "symbol": "jupsol"}, {"mint": "27G8MtK7VtTcCHkpASjSDdkWWYfoqT6ggEuKidVJidD4", "balance": 2.402337, "price": 4.2, "value": 10.0898154, "name": "Jupiter Perpetuals Liquidity Provider Token", "symbol": "jlp"}]} \ No newline at end of file diff --git a/cache/b81351778df9f812bbd75ee85a7a073e.json b/cache/b81351778df9f812bbd75ee85a7a073e.json index 1bba464..f1f200d 100644 --- a/cache/b81351778df9f812bbd75ee85a7a073e.json +++ b/cache/b81351778df9f812bbd75ee85a7a073e.json @@ -1 +1 @@ -{"timestamp": 1733367305.8206198, "result": 119.1529266475} \ No newline at end of file +{"timestamp": 1733370947.4478178, "result": 120.11282257281998} \ No newline at end of file diff --git a/cache/ccf2a009e56f1b05d471a55d9c9ea8ea.json b/cache/ccf2a009e56f1b05d471a55d9c9ea8ea.json index 7097bd8..bb86980 100644 --- a/cache/ccf2a009e56f1b05d471a55d9c9ea8ea.json +++ b/cache/ccf2a009e56f1b05d471a55d9c9ea8ea.json @@ -1 +1 @@ -{"timestamp": 1733367305.512328, "result": 82.815227} \ No newline at end of file +{"timestamp": 1733370947.155014, "result": 82.815227} \ No newline at end of file diff --git a/server.py b/server.py index 3f150fe..1db9dc6 100644 --- a/server.py +++ b/server.py @@ -124,7 +124,7 @@ def index(): pie_chart_data.append( ("ADA", cardanoBalance, f"Cardano: ${cardanoBalance}")) - return render_template("index.html", value=tokenValue, supply=tokenSupply, pie_chart=pie_chart_data, vault=vaultBalance) + return render_template("index.html", value=tokenValue, supply=tokenSupply, vault=vaultBalance) @app.route("/") @@ -334,7 +334,7 @@ def api_token(): token[t["symbol"].upper()]["amount"] = t["balance"] / supply token[t["symbol"].upper()]["value"] = t["price"] * t["balance"] / supply # Round value to 4 decimal places - token[t["symbol"].upper()]["value"] = round(token[t["symbol"].upper()]["value"], 4) + token[t["symbol"].upper()]["value"] = round(token[t["symbol"].upper()]["value"], 2) token[t["symbol"].upper()]["amount"] = round(token[t["symbol"].upper()]["amount"], 4) # Remove balance key @@ -344,13 +344,18 @@ def api_token(): token["ADA"] = { "name": "Cardano", - "amount": getCardanoBalance(vault_cardano_address) / supply, - "value": getCardanoValue(vault_cardano_address) / supply + "amount": round(getCardanoBalance(vault_cardano_address) / supply,4), + "value": round(getCardanoValue(vault_cardano_address) / supply,2) } if token["ADA"]["value"] < 0.01: token["ADA"]["amount"] = 0 token["ADA"]["value"] = 0 + # For each key add tooltip + for key in token: + token[key]["tooltip"] = f"{token[key]['amount']} {key} (${token[key]['value']})" + + token["total"] = { "name": "stWDBRN", "description": "stWDBRN total value (USD)", @@ -361,6 +366,60 @@ def api_token(): return jsonify(token) +@app.route("/api/v1/vault") +def api_vault(): + tokens = getTokens() + vaultBalance = getVaultBalance() + vaultBalance = "{:.2f}".format(vaultBalance) + + + vault = {} + vault["SOL"] = { + "name": "Solana", + "amount": round(getSolBalance(),4), + "value": round(getSolValue(),2) + } + if vault["SOL"]["value"] < 0.01: + vault["SOL"]["amount"] = 0 + vault["SOL"]["value"] = 0 + + vault["ADA"] = { + "name": "Cardano", + "amount": round(getCardanoBalance(vault_cardano_address),4), + "value": round(getCardanoValue(vault_cardano_address),2) + } + if vault["ADA"]["value"] < 0.01: + vault["ADA"]["amount"] = 0 + vault["ADA"]["value"] = 0 + + for t in tokens: + vault[t["symbol"].upper()] = t + if vault[t["symbol"].upper()]["value"] < 0.01: + vault[t["symbol"].upper()]["amount"] = 0 + vault[t["symbol"].upper()]["value"] = 0 + else: + vault[t["symbol"].upper()]["amount"] = t["balance"] + vault[t["symbol"].upper()]["value"] = t["price"] * t["balance"] + # Round value to 4 decimal places + vault[t["symbol"].upper()]["value"] = round(vault[t["symbol"].upper()]["value"], 2) + vault[t["symbol"].upper()]["amount"] = round(vault[t["symbol"].upper()]["amount"], 4) + + # Remove balance key + del vault[t["symbol"].upper()]["balance"] + + # For each key add tooltip + for key in vault: + vault[key]["tooltip"] = f"{vault[key]['amount']} {key} (${vault[key]['value']})" + + vault["total"] = { + "name": "Vault", + "description": "Total Vault value (USD)", + "value": vaultBalance + } + + return jsonify(vault) + + # endregion diff --git a/stWDBRN.bsdesign b/stWDBRN.bsdesign index 7c0d54d..2a92899 100644 Binary files a/stWDBRN.bsdesign and b/stWDBRN.bsdesign differ diff --git a/templates/assets/js/bs-init.js b/templates/assets/js/bs-init.js new file mode 100644 index 0000000..3c1498d --- /dev/null +++ b/templates/assets/js/bs-init.js @@ -0,0 +1,7 @@ +document.addEventListener('DOMContentLoaded', function() { + + var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bss-tooltip]')); + var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) { + return new bootstrap.Tooltip(tooltipTriggerEl); + }) +}, false); \ No newline at end of file diff --git a/templates/index.html b/templates/index.html index 4e6461c..86ed6b9 100644 --- a/templates/index.html +++ b/templates/index.html @@ -47,68 +47,178 @@
-

Current Vault Contents

+

Current Vault Contents

+
View on Coingecko + + async function fetchData(apiUrl) { + try { + const response = await fetch(apiUrl); + if (!response.ok) throw new Error('Failed to fetch data from API'); + return await response.json(); + } catch (error) { + console.error('Error fetching data:', error); + return null; + } + } + + function transformDataForChart(data) { + const chartData = []; + for (const token in data) { + if (token !== 'total') { + chartData.push([ + token, // Label for the chart + data[token].value, // Value for the chart + data[token].tooltip, // Tooltip for the chart + ]); + } + } + return chartData; + } + + async function drawChart() { + const apiUrl = '/api/v1/vault'; + const data = await fetchData(apiUrl); + + if (!data) return; // Exit if data fetch fails + + const chartDataTable = new google.visualization.DataTable(); + chartDataTable.addColumn('string', 'Token'); + chartDataTable.addColumn('number', 'Value'); + chartDataTable.addColumn({ type: 'string', role: 'tooltip', 'p': { 'html': false } }); + chartDataTable.addRows(transformDataForChart(data)); + + chart = new google.visualization.PieChart(document.getElementById('pie-chart')); + resizeAndDraw(chart, chartDataTable, options); + updateText(true); + populateTable(data); + } + + function updateText(isVault) { + let headerText = document.getElementById('chart-header'); + if (isVault) { + headerText.innerText = 'Current Vault Contents'; + } else { + headerText.innerText = 'Current Per Token Holding'; + } + } + + function populateTable(data) { + const tableContainer = document.getElementById('data-table'); + tableContainer.innerHTML = ''; // Clear previous table data + + // Create table elements + const table = document.createElement('table'); + table.style.margin = 'auto'; + table.style.borderCollapse = 'collapse'; + + const thead = document.createElement('thead'); + const tbody = document.createElement('tbody'); + + // Create table header + const headerRow = document.createElement('tr'); + ['Name', 'Amount', 'Value'].forEach(headerText => { + const th = document.createElement('th'); + th.textContent = headerText; + th.style.border = '1px solid #ccc'; + th.style.padding = '8px 20px'; + th.style.backgroundColor = '#333'; + th.style.color = 'white'; + headerRow.appendChild(th); + }); + thead.appendChild(headerRow); + + // Create table rows + for (const token in data) { + if (token !== 'total') { + const row = document.createElement('tr'); + + const nameCell = document.createElement('td'); + nameCell.textContent = data[token].name; + nameCell.style.border = '1px solid #ccc'; + nameCell.style.padding = '8px 20px'; + + const amountCell = document.createElement('td'); + amountCell.textContent = `${data[token].amount} ${token}`; + amountCell.style.border = '1px solid #ccc'; + amountCell.style.padding = '8px 20px'; + + const valueCell = document.createElement('td'); + valueCell.textContent = data[token].value; + valueCell.style.border = '1px solid #ccc'; + valueCell.style.padding = '8px 20px'; + + row.appendChild(nameCell); + row.appendChild(amountCell); + row.appendChild(valueCell); + tbody.appendChild(row); + } + } + table.appendChild(thead); + table.appendChild(tbody); + tableContainer.appendChild(table); + + } + + + async function toggleChart() { + isPerTokenView = !isPerTokenView; + const apiUrl = isPerTokenView ? '/api/v1/token' : '/api/v1/vault'; + const data = await fetchData(apiUrl); + + if (!data) return; // Exit if data fetch fails + + const chartDataTable = new google.visualization.DataTable(); + chartDataTable.addColumn('string', 'Token'); + chartDataTable.addColumn('number', 'Value'); + chartDataTable.addColumn({ type: 'string', role: 'tooltip', 'p': { 'html': false } }); + chartDataTable.addRows(transformDataForChart(data)); + + resizeAndDraw(chart, chartDataTable, options); + updateText(!isPerTokenView); + populateTable(data); + } + + function resizeAndDraw(chart, chartDataTable, options) { + function resizeChart() { + const width = window.innerWidth * 0.8; + const height = window.innerHeight * 0.5; + + const dynamicOptions = { ...options }; + if (width >= 700) { + dynamicOptions.width = width; + dynamicOptions.height = height; + } + + chart.draw(chartDataTable, dynamicOptions); + } + + resizeChart(); + window.addEventListener('resize', resizeChart); + } + + // Set button event listener + document.getElementById('chart-header').addEventListener('click', toggleChart); + }; + +
View on Coingecko
@@ -189,6 +299,7 @@ +