Skip to content
This repository was archived by the owner on Feb 1, 2024. It is now read-only.

Commit fe19dcb

Browse files
authored
fix issue of fiat currency dropdown not updating correctly (closes #418) (#419)
* 1 - update selected value used in dropdown to match dropdown options by replacing with <api_key> * 2 - simplify fiat API dropdown options and augment URL only on client side * 3 - allow queryPrice to succeed by using the original feed_url
1 parent 222edd9 commit fe19dcb

4 files changed

Lines changed: 53 additions & 22 deletions

File tree

gui/backend/options_metadata.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ func (dob *dropdownOptionsBuilder) coinmarketcap(tickerCode string, currencyName
114114
}
115115

116116
func (dob *dropdownOptionsBuilder) currencylayer(tickerCode string, name string) *dropdownOptionsBuilder {
117-
value := fmt.Sprintf("http://apilayer.net/api/live?access_key=<api_key>&currencies=%s", tickerCode)
117+
value := tickerCode
118118
text := fmt.Sprintf("%s - %s", tickerCode, name)
119119
return dob._leaf(value, text)
120120
}

gui/web/src/components/molecules/Form/Form.js

Lines changed: 46 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@ import PriceFeedFormula from '../PriceFeedFormula/PriceFeedFormula';
2121
import Levels from '../Levels/Levels';
2222
import ErrorMessage from '../ErrorMessage/ErrorMessage';
2323
import newSecretKey from '../../../kelp-ops-api/newSecretKey';
24+
import fetchPrice from '../../../kelp-ops-api/fetchPrice';
2425
import SecretKey from '../SecretKey/SecretKey';
2526

2627
const fiatURLPrefix = "http://apilayer.net/api/live?access_key=";
2728
const fiatURLCurrencyParam = "&currencies=";
28-
const fiatAPIKeyPlaceholder = "<api_key>";
2929
const currencyLayerWebsite = "https://currencylayer.com/";
3030

3131
class Form extends Component {
@@ -60,7 +60,9 @@ class Form extends Component {
6060
this.addLevelError = this.addLevelError.bind(this);
6161
this.clearLevelError = this.clearLevelError.bind(this);
6262
this.makeNewFiatDataFeedURL = this.makeNewFiatDataFeedURL.bind(this);
63+
this.extractCurrencyCodeFromFiatURL = this.extractCurrencyCodeFromFiatURL.bind(this);
6364
this.updateFiatAPIKey = this.updateFiatAPIKey.bind(this);
65+
this.getConfigFeedURLTransformIfFiat = this.getConfigFeedURLTransformIfFiat.bind(this);
6466
this._emptyLevel = this._emptyLevel.bind(this);
6567
this._triggerUpdateLevels = this._triggerUpdateLevels.bind(this);
6668
this._fetchDotNotation = this._fetchDotNotation.bind(this);
@@ -69,6 +71,7 @@ class Form extends Component {
6971
this._asyncRequests = {};
7072
}
7173

74+
// _extractFiatAPIKey gets called when we load the config and we want to populate the fiat APIKey in the GUI
7275
_extractFiatAPIKey(props) {
7376
let url = null;
7477
if (props.configData.strategy_config.data_type_a === "fiat") {
@@ -89,6 +92,19 @@ class Form extends Component {
8992
return url.substring(fiatURLPrefix.length, url.indexOf(fiatURLCurrencyParam));
9093
}
9194

95+
// getConfigFeedURLTransformIfFiat is called when loading the config value for feed URLs
96+
// we want to load only the currencyCode
97+
getConfigFeedURLTransformIfFiat(ab) {
98+
let dataType = this.props.configData.strategy_config["data_type_" + ab]
99+
let feedUrl = this.props.configData.strategy_config["data_feed_" + ab + "_url"];
100+
101+
if (dataType === "fiat") {
102+
const currencyCode = this.extractCurrencyCodeFromFiatURL(feedUrl);
103+
return currencyCode;
104+
}
105+
return feedUrl;
106+
}
107+
92108
componentWillUnmount() {
93109
if (this._asyncRequests["secretKey"]) {
94110
delete this._asyncRequests["secretKey"];
@@ -200,9 +216,11 @@ class Form extends Component {
200216
feedUrlValue = feedUrlValue + "/" + newValues[2];
201217
}
202218

203-
// special handling for fiat feeds
219+
// when the users selects a new fiat feed currency, wrap the currencyCode (feedUrlValue) with the fiat URL format
220+
// so it can be saved in the config file which requires a URL.
221+
// This leaves the UI text in the dropdown unchanged
204222
if (dataTypeValue === "fiat") {
205-
feedUrlValue = feedUrlValue.replace(fiatAPIKeyPlaceholder, this.state.fiatAPIKey);
223+
feedUrlValue = this.makeNewFiatDataFeedURL(this.state.fiatAPIKey, feedUrlValue);
206224
}
207225

208226
let mergeUpdateInstructions = {};
@@ -329,19 +347,24 @@ class Form extends Component {
329347
});
330348
}
331349

332-
makeNewFiatDataFeedURL(apiKey, oldURL) {
333-
return fiatURLPrefix + apiKey + oldURL.substring(oldURL.indexOf(fiatURLCurrencyParam));
350+
makeNewFiatDataFeedURL(apiKey, currencyCode) {
351+
return fiatURLPrefix + apiKey + fiatURLCurrencyParam + currencyCode;
352+
}
353+
354+
extractCurrencyCodeFromFiatURL(url) {
355+
return url.substring(url.indexOf(fiatURLCurrencyParam) + fiatURLCurrencyParam.length);
334356
}
335357

358+
// updateFiatAPIKey is called when the user upates the fiat API key in the GUI
336359
updateFiatAPIKey(apiKey) {
337360
if (this.props.configData.strategy_config.data_type_a === "fiat") {
338-
const newValue = this.makeNewFiatDataFeedURL(apiKey, this.props.configData.strategy_config.data_feed_a_url);
339-
this.props.onChange("strategy_config.data_feed_a_url", {target: {value: newValue }});
361+
const newValue = this.makeNewFiatDataFeedURL(apiKey, this.extractCurrencyCodeFromFiatURL(this.props.configData.strategy_config.data_feed_a_url));
362+
this.props.onChange("strategy_config.data_feed_a_url", { target: { value: newValue } });
340363
}
341364

342365
if (this.props.configData.strategy_config.data_type_b === "fiat") {
343-
const newValue = this.makeNewFiatDataFeedURL(apiKey, this.props.configData.strategy_config.data_feed_b_url);
344-
this.props.onChange("strategy_config.data_feed_b_url", {target: {value: newValue }});
366+
const newValue = this.makeNewFiatDataFeedURL(apiKey, this.extractCurrencyCodeFromFiatURL(this.props.configData.strategy_config.data_feed_b_url));
367+
this.props.onChange("strategy_config.data_feed_b_url", { target: { value: newValue } });
345368
}
346369

347370
this.setState({
@@ -863,25 +886,35 @@ class Form extends Component {
863886
<FieldGroup groupTitle="Price Feed">
864887
<FieldItem>
865888
<PriceFeedAsset
866-
baseUrl={this.props.baseUrl}
867889
onChange={(newValues) => this.priceFeedAssetChangeHandler("a", newValues)}
868890
title={"Numerator: current price of base asset (" + this.props.configData.trader_config.asset_code_a + ")"}
869891
optionsMetadata={this.props.optionsMetadata}
870892
type={this.props.configData.strategy_config.data_type_a}
871-
feed_url={this.props.configData.strategy_config.data_feed_a_url}
893+
feed_url={this.getConfigFeedURLTransformIfFiat("a")}
894+
fetchPrice={fetchPrice.bind(
895+
this,
896+
this.props.baseUrl,
897+
this.props.configData.strategy_config.data_type_a,
898+
this.props.configData.strategy_config.data_feed_a_url,
899+
)}
872900
onLoadingPrice={() => this.setLoadingFormula()}
873901
onNewPrice={(newPrice) => this.updateFormulaPrice("numerator", newPrice)}
874902
readOnly={this.props.readOnly}
875903
/>
876904
</FieldItem>
877905
<FieldItem>
878906
<PriceFeedAsset
879-
baseUrl={this.props.baseUrl}
880907
onChange={(newValues) => this.priceFeedAssetChangeHandler("b", newValues)}
881908
title={"Denominator: current price of quote asset (" + this.props.configData.trader_config.asset_code_b + ")"}
882909
optionsMetadata={this.props.optionsMetadata}
883910
type={this.props.configData.strategy_config.data_type_b}
884-
feed_url={this.props.configData.strategy_config.data_feed_b_url}
911+
feed_url={this.getConfigFeedURLTransformIfFiat("b")}
912+
fetchPrice={fetchPrice.bind(
913+
this,
914+
this.props.baseUrl,
915+
this.props.configData.strategy_config.data_type_b,
916+
this.props.configData.strategy_config.data_feed_b_url,
917+
)}
885918
onLoadingPrice={() => this.setLoadingFormula()}
886919
onNewPrice={(newPrice) => this.updateFormulaPrice("denominator", newPrice)}
887920
readOnly={this.props.readOnly}

gui/web/src/components/molecules/PriceFeedAsset/PriceFeedAsset.js

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import styles from './PriceFeedAsset.module.scss';
44
import Label from '../../atoms/Label/Label';
55
import PriceFeedDisplay from '../PriceFeedDisplay/PriceFeedDisplay';
66
import PriceFeedSelector from '../PriceFeedSelector/PriceFeedSelector';
7-
import fetchPrice from '../../../kelp-ops-api/fetchPrice';
87
import LoadingAnimation from '../../atoms/LoadingAnimation/LoadingAnimation';
98

109
class PriceFeedAsset extends Component {
@@ -20,11 +19,11 @@ class PriceFeedAsset extends Component {
2019
}
2120

2221
static propTypes = {
23-
baseUrl: PropTypes.string,
2422
title: PropTypes.string,
2523
type: PropTypes.string,
2624
feed_url: PropTypes.string,
2725
onChange: PropTypes.func,
26+
fetchPrice: PropTypes.func,
2827
onLoadingPrice: PropTypes.func,
2928
onNewPrice: PropTypes.func,
3029
optionsMetadata: PropTypes.object,
@@ -37,7 +36,6 @@ class PriceFeedAsset extends Component {
3736

3837
componentDidUpdate(prevProps) {
3938
if (
40-
prevProps.baseUrl !== this.props.baseUrl ||
4139
prevProps.type !== this.props.type ||
4240
prevProps.feed_url !== this.props.feed_url
4341
) {
@@ -54,7 +52,7 @@ class PriceFeedAsset extends Component {
5452
this.props.onLoadingPrice();
5553

5654
var _this = this;
57-
let currentRequest = fetchPrice.bind(this, this.props.baseUrl, this.props.type, this.props.feed_url);
55+
let currentRequest = this.props.fetchPrice.bind(this);
5856
// we need to set the cached request to the current request so we always track the latest request we want processed
5957
this._asyncRequests["price"] = currentRequest;
6058
setTimeout(() => {

gui/web/src/components/molecules/PriceFeedSelector/PriceFeedSelector.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ class PriceFeedSelector extends Component {
6060
}
6161
selectedOption = selectedOption.subtype;
6262
}
63-
63+
6464
valuesToUpdate.push(curValue);
6565
i++;
6666
}
@@ -85,7 +85,7 @@ class PriceFeedSelector extends Component {
8585
type="string"
8686
onChange={(event) => this.changeHandler(idx, event)}
8787
readOnly={this.props.readOnly}
88-
/>
88+
/>
8989
</div>
9090
);
9191
} else if (metadata.type === "dropdown") {
@@ -98,7 +98,7 @@ class PriceFeedSelector extends Component {
9898
selected={value}
9999
onChange={(event) => this.changeHandler(idx, event)}
100100
readOnly={this.props.readOnly}
101-
/>
101+
/>
102102
</div>
103103
);
104104
}
@@ -124,7 +124,7 @@ class PriceFeedSelector extends Component {
124124
}
125125
secondComponent = this.renderComponentRecursive(idx + 1, selectedOption.subtype, innerValues);
126126
}
127-
127+
128128
return (
129129
<div className={grid.row}>
130130
{firstComponent}

0 commit comments

Comments
 (0)