Skip to content

Commit c090f6c

Browse files
committed
Add more fiat currencies
1 parent 48393db commit c090f6c

File tree

2 files changed

+75
-63
lines changed

2 files changed

+75
-63
lines changed

main.qml

Lines changed: 33 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -102,23 +102,24 @@ ApplicationWindow {
102102

103103
// fiat price conversion
104104
property real fiatPrice: 0
105-
property var fiatPriceAPIs: {
106-
return {
107-
"kraken": {
108-
"xmrusd": "https://api.kraken.com/0/public/Ticker?pair=XMRUSD",
109-
"xmreur": "https://api.kraken.com/0/public/Ticker?pair=XMREUR"
110-
},
111-
"coingecko": {
112-
"xmrusd": "https://api.coingecko.com/api/v3/simple/price?ids=monero&vs_currencies=usd",
113-
"xmreur": "https://api.coingecko.com/api/v3/simple/price?ids=monero&vs_currencies=eur"
114-
},
115-
"cryptocompare": {
116-
"xmrusd": "https://min-api.cryptocompare.com/data/price?fsym=XMR&tsyms=USD",
117-
"xmreur": "https://min-api.cryptocompare.com/data/price?fsym=XMR&tsyms=EUR",
118-
}
119-
}
120-
}
121105

106+
// {provider name: {ticker: price_api_url}}
107+
// API response schema depends on the provider
108+
property var fiatCurrencies: ["usd", "eur", "aed", "ars", "aud", "bdt", "bhd", "brl", "cad", "chf", "clp", "cny", "czk", "gbp", "hkd",
109+
"huf", "idr", "ils", "inr", "jpy", "krw", "kwd", "lkr", "mmk", "mxn", "myr", "ngn", "nok", "nzd", "php",
110+
"pkr", "pln", "rub", "sar", "sek", "sgd", "thb", "try", "twd", "uah", "vef", "vnd", "zar", "xau"];
111+
property var fiatPriceAPIs: fiatCurrencies.reduce(function(obj, x) {
112+
const key = `xmr${x}`; // e.g. xmrusd
113+
if (x === "usd" || x === "eur") {
114+
// Kraken only supports XMRUSD and XMREUR
115+
obj["kraken"][key] = `https://api.kraken.com/0/public/Ticker?pair=XMR${x}`;
116+
}
117+
obj["coingecko"][key] = `https://api.coingecko.com/api/v3/simple/price?ids=monero&vs_currencies=${x}`;
118+
obj["cryptocompare"][key] = `https://min-api.cryptocompare.com/data/price?fsym=XMR&tsyms=${x}`;
119+
return obj;
120+
}, {"kraken": {}, "coingecko": {}, "cryptocompare": {}})
121+
// if the user is using Kraken, the following is used if the user wants non USD/EUR
122+
property string fiatPriceBackupProvider: "coingecko"
122123
// true if wallet ever synchronized
123124
property bool walletInitialized : false
124125

@@ -137,7 +138,7 @@ ApplicationWindow {
137138
passwordDialog.onAcceptedCallback = function() {
138139
if(walletPassword === passwordDialog.password)
139140
passwordDialog.close();
140-
else
141+
else
141142
passwordDialog.showError(qsTr("Wrong password") + translationManager.emptyString);
142143
}
143144
passwordDialog.open(usefulName(persistentSettings.wallet_path));
@@ -1029,11 +1030,9 @@ ApplicationWindow {
10291030
var isReserveProof = signature.indexOf("ReserveProofV") === 0;
10301031
if (address.length > 0 && !isReserveProof) {
10311032
result = currentWallet.checkTxProof(txid, address, message, signature);
1032-
}
1033-
else if (isReserveProof) {
1033+
} else if (isReserveProof) {
10341034
result = currentWallet.checkReserveProof(address, message, signature);
1035-
}
1036-
else {
1035+
} else {
10371036
result = currentWallet.checkSpendProof(txid, message, signature);
10381037
}
10391038
var results = result.split("|");
@@ -1065,7 +1064,7 @@ ApplicationWindow {
10651064
informationPopup.title = qsTr("Payment proof check") + translationManager.emptyString;
10661065
informationPopup.icon = good ? StandardIcon.Information : StandardIcon.Critical;
10671066
informationPopup.text = good ? qsTr("Good signature") : qsTr("Bad signature");
1068-
}
1067+
}
10691068
else if (isReserveProof && results[0] === "true") {
10701069
var good = results[1] === "true";
10711070
informationPopup.title = qsTr("Reserve proof check") + translationManager.emptyString;
@@ -1152,19 +1151,21 @@ ApplicationWindow {
11521151
appWindow.fiatApiError("Kraken API has error(s)");
11531152
return;
11541153
}
1155-
1156-
var key = currency === "xmreur" ? "XXMRZEUR" : "XXMRZUSD";
1154+
// i.e. xmr[a-z]+ -> XXMRZ[A-Z]+
1155+
var key = `XXMRZ${currency.substring(3).toUpperCase()}`;
11571156
var ticker = resp.result[key]["c"][0];
11581157
return ticker;
11591158
} else if(url.startsWith("https://api.coingecko.com/api/v3/")){
1160-
var key = currency === "xmreur" ? "eur" : "usd";
1159+
// i.e. xmr[a-z]+ -> [a-z]+
1160+
var key = currency.substring(3);
11611161
if(!resp.hasOwnProperty("monero") || !resp["monero"].hasOwnProperty(key)){
11621162
appWindow.fiatApiError("Coingecko API has error(s)");
11631163
return;
11641164
}
11651165
return resp["monero"][key];
11661166
} else if(url.startsWith("https://min-api.cryptocompare.com/data/")){
1167-
var key = currency === "xmreur" ? "EUR" : "USD";
1167+
// i.e. xmr[a-z]+ -> [A-Z]+
1168+
var key = currency.substring(3).toUpperCase();
11681169
if(!resp.hasOwnProperty(key)){
11691170
appWindow.fiatApiError("cryptocompare API has error(s)");
11701171
return;
@@ -1235,23 +1236,20 @@ ApplicationWindow {
12351236
var provider = appWindow.fiatPriceAPIs[userProvider];
12361237
var userCurrency = persistentSettings.fiatPriceCurrency;
12371238
if(!provider.hasOwnProperty(userCurrency)){
1238-
appWindow.fiatApiError("currency \"" + userCurrency + "\" not implemented");
1239+
appWindow.fiatApiError("currency \"" + userCurrency + "\"is not supported by provider \"" + userProvider + "\"");
12391240
}
12401241

12411242
var url = provider[userCurrency];
12421243
network.getJSON(url, fiatApiJsonReceived);
12431244
}
12441245

12451246
function fiatApiCurrencySymbol() {
1246-
switch (persistentSettings.fiatPriceCurrency) {
1247-
case "xmrusd":
1248-
return "USD";
1249-
case "xmreur":
1250-
return "EUR";
1251-
default:
1252-
console.error("unsupported currency", persistentSettings.fiatPriceCurrency);
1253-
return "UNSUPPORTED";
1247+
let currency = persistentSettings.fiatPriceCurrency.substring(3);
1248+
if (fiatCurrencies.indexOf(currency) !== -1) {
1249+
return currency.toUpperCase();
12541250
}
1251+
console.error("unsupported currency", persistentSettings.fiatPriceCurrency);
1252+
return "UNSUPPORTED";
12551253
}
12561254

12571255
function fiatApiConvertToFiat(amount) {

pages/settings/SettingsLayout.qml

Lines changed: 42 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
// Copyright (c) 2014-2018, The Monero Project
2-
//
2+
//
33
// All rights reserved.
4-
//
4+
//
55
// Redistribution and use in source and binary forms, with or without modification, are
66
// permitted provided that the following conditions are met:
7-
//
7+
//
88
// 1. Redistributions of source code must retain the above copyright notice, this list of
99
// conditions and the following disclaimer.
10-
//
10+
//
1111
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
1212
// of conditions and the following disclaimer in the documentation and/or other
1313
// materials provided with the distribution.
14-
//
14+
//
1515
// 3. Neither the name of the copyright holder nor the names of its contributors may be
1616
// used to endorse or promote products derived from this software without specific
1717
// prior written permission.
18-
//
18+
//
1919
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
2020
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
2121
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
@@ -91,7 +91,7 @@ Rectangle {
9191
MoneroComponents.Style.blackTheme = !MoneroComponents.Style.blackTheme;
9292
}
9393
}
94-
94+
9595
MoneroComponents.CheckBox {
9696
checked: persistentSettings.askPasswordBeforeSending
9797
text: qsTr("Ask for password before sending a transaction") + translationManager.emptyString
@@ -190,9 +190,21 @@ Rectangle {
190190
labelFontSize: 14
191191
dataModel: fiatPriceProvidersModel
192192
onChanged: {
193-
var obj = dataModel.get(currentIndex);
194-
persistentSettings.fiatPriceProvider = obj.data;
195-
193+
var newProvider = dataModel.get(currentIndex).data;
194+
var providerCurrencies = appWindow.fiatPriceAPIs[newProvider];
195+
// ONLY when the user changes the provider should the currency list also update
196+
// This way, since Kraken is the default, users can see ALL supported currencies
197+
fiatPriceCurrencyModel.clear();
198+
appWindow.fiatCurrencies.forEach(el => {
199+
if (`xmr${el}` in providerCurrencies) fiatPriceCurrencyModel.append({ data: `xmr${el}`, column1: el.toUpperCase()})
200+
});
201+
// if fiatPriceCurrency is not supported by the new provider, use first available currency
202+
if (!(persistentSettings.fiatPriceCurrency in providerCurrencies)) {
203+
persistentSettings.fiatPriceCurrency = Object.keys(providerCurrencies)[0];
204+
fiatPriceCurrencyDropdown.currentIndex = 0;
205+
}
206+
persistentSettings.fiatPriceProvider = newProvider;
207+
// refresh price after validating that the fiat currency is provided by the provider
196208
if(persistentSettings.fiatPriceEnabled)
197209
appWindow.fiatApiRefresh();
198210
}
@@ -203,12 +215,18 @@ Rectangle {
203215
Layout.maximumWidth: 100
204216
labelText: qsTr("Currency") + translationManager.emptyString
205217
labelFontSize: 14
206-
currentIndex: persistentSettings.fiatPriceCurrency === "xmrusd" ? 0 : 1
218+
currentIndex: appWindow.fiatCurrencies.indexOf(persistentSettings.fiatPriceCurrency.substring(3))
207219
dataModel: fiatPriceCurrencyModel
208220
onChanged: {
209-
var obj = dataModel.get(currentIndex);
210-
persistentSettings.fiatPriceCurrency = obj.data;
211-
221+
var newCurrency = dataModel.get(currentIndex).data;
222+
if (!(newCurrency in appWindow.fiatPriceAPIs[persistentSettings.fiatPriceProvider])) {
223+
// this occurs if a fiat currency other than EUR/USD is selected and provider is Kraken
224+
// so use appWindow.fiatPriceBackupProvider instead
225+
let backupIdx = Object.keys(appWindow.fiatPriceAPIs).indexOf(appWindow.fiatPriceBackupProvider);
226+
fiatPriceProviderDropDown.currentIndex = backupIdx;
227+
persistentSettings.fiatPriceProvider = appWindow.fiatPriceBackupProvider;
228+
}
229+
persistentSettings.fiatPriceCurrency = newCurrency;
212230
if(persistentSettings.fiatPriceEnabled)
213231
appWindow.fiatApiRefresh();
214232
}
@@ -290,34 +308,30 @@ Rectangle {
290308

291309
ListModel {
292310
id: fiatPriceCurrencyModel
293-
ListElement {
294-
data: "xmrusd"
295-
column1: "USD"
296-
}
297-
ListElement {
298-
data: "xmreur"
299-
column1: "EUR"
311+
Component.onCompleted: {
312+
// populate with fiat currencies
313+
appWindow.fiatCurrencies.forEach(el => {
314+
fiatPriceCurrencyModel.append({ data: `xmr${el}`, column1: el.toUpperCase()});
315+
});
300316
}
301317
}
302318

303319
Component.onCompleted: {
304-
// Dynamically fill fiatPrice dropdown based on `appWindow.fiatPriceAPIs`
320+
// Dynamically fill fiatPrice dropdowns based on `appWindow.fiatPriceAPIs`
305321
var apis = appWindow.fiatPriceAPIs;
306322
fiatPriceProvidersModel.clear();
307-
308323
var i = 0;
309-
for (var api in apis){
310-
if (!apis.hasOwnProperty(api))
324+
for (var apiProvider in apis){
325+
if (!apis.hasOwnProperty(apiProvider))
311326
continue;
312327

313-
fiatPriceProvidersModel.append({"column1": Utils.capitalize(api), "data": api});
328+
fiatPriceProvidersModel.append({data: apiProvider, column1: Utils.capitalize(apiProvider)});
314329

315-
if(api === persistentSettings.fiatPriceProvider)
330+
if(apiProvider === persistentSettings.fiatPriceProvider)
316331
fiatPriceProviderDropDown.currentIndex = i;
317332
i += 1;
318333
}
319334

320335
console.log('SettingsLayout loaded');
321336
}
322337
}
323-

0 commit comments

Comments
 (0)