diff --git a/src/connectors/kujira/kujira.config.ts b/src/connectors/kujira/kujira.config.ts index fd1a0d67f0..fdc3f9bdef 100644 --- a/src/connectors/kujira/kujira.config.ts +++ b/src/connectors/kujira/kujira.config.ts @@ -126,6 +126,7 @@ export namespace KujiraConfig { priceUrl: configManager.get('kujira.coinGecko.priceUrl') || 'https://api.coingecko.com/api/v3/simple/price?ids={targets}&vs_currencies=usd', + apiKeys: configManager.get('kujira.coinGecko.apiKeys') || [''], }, }; } diff --git a/src/connectors/kujira/kujira.ts b/src/connectors/kujira/kujira.ts index d7fb75a034..1baa31c7b5 100644 --- a/src/connectors/kujira/kujira.ts +++ b/src/connectors/kujira/kujira.ts @@ -785,13 +785,17 @@ export class Kujira { ): Promise { const output = IMap().asMutable(); - const url = config.coinGecko.coinsUrl; + const apiKeys = config.coinGecko.apiKeys; + const randomIndex = Math.floor(Math.random() * apiKeys.length); + const apiKey = apiKeys[randomIndex]; + + const finalUrl = config.coinGecko.coinsUrl.replace('{apiKey}', apiKey); const result: any = ( await runWithRetryAndTimeout( axios, axios.get, - [url], + [finalUrl], config.retry.all.maxNumberOfRetries, 0 ) @@ -1029,10 +1033,17 @@ export class Kujira { if (!coinGeckoBaseTokenId || !coinGeckoQuoteTokenId) { result = {}; } else { - const finalUrl = config.coinGecko.priceUrl.replace( - '{targets}', - coinGeckoBaseTokenId.concat(',').concat(coinGeckoQuoteTokenId) - ); + const coinGeckoIds = coinGeckoBaseTokenId + .concat(',') + .concat(coinGeckoQuoteTokenId); + + const apiKeys = config.coinGecko.apiKeys; + const randomIndex = Math.floor(Math.random() * apiKeys.length); + const apiKey = apiKeys[randomIndex]; + + const finalUrl = config.coinGecko.priceUrl + .replace('{apiKey}', apiKey) + .replace('{targets}', coinGeckoIds); result = ( await runWithRetryAndTimeout( @@ -1124,11 +1135,16 @@ export class Kujira { const coinGeckoIds = kujiraSymbolsToCoinGeckoIdsMap .valueSeq() .toArray() + .filter((id: any) => id && id.trim() !== '') .join(','); - const finalUrl = getNotNullOrThrowError<{ priceUrl: string }>( - config.coinGecko - ).priceUrl.replace('{targets}', coinGeckoIds); + const apiKeys = config.coinGecko.apiKeys; + const randomIndex = Math.floor(Math.random() * apiKeys.length); + const apiKey = apiKeys[randomIndex]; + + const finalUrl = config.coinGecko.priceUrl + .replace('{apiKey}', apiKey) + .replace('{targets}', coinGeckoIds); const result: any = ( await runWithRetryAndTimeout( diff --git a/src/services/schema/kujira-schema.json b/src/services/schema/kujira-schema.json index 0f40ca41c9..23e89d3b1c 100644 --- a/src/services/schema/kujira-schema.json +++ b/src/services/schema/kujira-schema.json @@ -196,7 +196,8 @@ "type": "object", "required": [ "coinsUrl", - "priceUrl" + "priceUrl", + "apiKeys" ], "properties": { "coinsUrl": { @@ -210,7 +211,13 @@ "string", "null" ] - } + }, + "apiKeys": { + "type": [ + "array", + "null" + ] + } } }, "transactions": { diff --git a/src/templates/kujira.yml b/src/templates/kujira.yml index c08c3575a2..9966cda9ca 100644 --- a/src/templates/kujira.yml +++ b/src/templates/kujira.yml @@ -71,8 +71,9 @@ tickers: # orderBookVolumeWeightedAveragePrice: # lastFilledOrder: coinGecko: - coinsUrl: 'https://api.coingecko.com/api/v3/coins/list?x_cg_demo_api_key=' - priceUrl: "https://api.coingecko.com/api/v3/simple/price?vs_currencies=usd&x_cg_demo_api_key=&ids={targets}" + coinsUrl: 'https://api.coingecko.com/api/v3/coins/list?x_cg_demo_api_key={apiKey}' + priceUrl: "https://api.coingecko.com/api/v3/simple/price?vs_currencies=usd&x_cg_demo_api_key={apiKey}&ids={targets}" + apiKeys: [""] # If you don't have any use null transactions: merge: createOrders: true