-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.js
183 lines (143 loc) · 5.67 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
// eslint-disable-next-line import/no-unresolved
import got from 'got';
import getPackageUserAgent from 'package-user-agent';
const providers = {
cmc: {
apiKeyRequired: true,
baseUrl: 'https://pro-api.coinmarketcap.com/v1/cryptocurrency/quotes/latest?symbol=BTC'
},
coingecko: {
apiKeyRequired: false,
baseUrl: 'https://api.coingecko.com/api/v3/simple/price?ids=bitcoin'
}
};
let apiKey = '';
let selectedProvider = 'coingecko';
const packageUserAgent = await getPackageUserAgent();
export async function getSupportedCurrencies() {
// Check if the api key is needed for the selected provider
if (providers[selectedProvider].apiKeyRequired && !apiKey) {
throw new Error('`apiKey` needs to be set if using CoinMarketCap. Call `.setApiKey()` with your API key before calling other functions.');
}
if (selectedProvider === 'cmc') {
try {
const jsonResponse = await got(`https://pro-api.coinmarketcap.com/v1/fiat/map?CMC_PRO_API_KEY=${apiKey}`).json();
// Check if there are errors in the API response
if (jsonResponse.status && jsonResponse.status.error_code !== 0) {
throw new Error(`Failed to retrieve supported currencies: ${jsonResponse.status.error_message}`);
}
if (!jsonResponse.data) {
throw new Error('Failed to retrieve supported currencies');
}
return jsonResponse.data;
} catch {
// If not able to parse JSON or get the supported currencies
throw new Error('Failed to retrieve supported currencies');
}
}
// Default to CoinGecko
try {
const supportedCurrenciesResponse = await got('https://api.coingecko.com/api/v3/simple/supported_vs_currencies').json();
if (!Array.isArray(supportedCurrenciesResponse)) {
// eslint-disable-next-line unicorn/prefer-type-error
throw new Error('Failed to retrieve supported currencies');
}
return supportedCurrenciesResponse;
} catch {
// If not able to parse JSON or get the supported currencies
throw new Error('Failed to retrieve supported currencies');
}
}
async function sendHttpRequest(urlParameters = '') {
// Check if the api key is needed for the selected provider
if (providers[selectedProvider].apiKeyRequired && !apiKey) {
throw new Error('`apiKey` needs to be set if using CoinMarketCap. Call `.setApiKey()` with your API key before calling other functions.');
}
const {baseUrl} = providers[selectedProvider];
const url = `${baseUrl}${urlParameters}&CMC_PRO_API_KEY=${apiKey}`;
try {
const jsonResponse = await got(url, {headers: packageUserAgent}).json();
// Check if there are errors in the API response
if (jsonResponse.status && jsonResponse.status.error_code !== 0) {
throw new Error(`Error occurred while retrieving Bitcoin value: ${jsonResponse.status.error_message}`);
}
return jsonResponse.data.BTC;
} catch {
// If not able to parse JSON or get the first parsed value
throw new Error('Failed to retrieve Bitcoin value');
}
}
export function setProvider(provider) {
if (!Object.keys(providers).includes(provider)) {
throw new Error('`provider` needs to be one of `cmc` and `coingecko`');
}
selectedProvider = provider;
}
export function setApiKey(newApiKey) {
// Check if the API key is provided
if (!newApiKey) {
throw new Error('You need to provide an API key.');
}
// Check that the type of `apiKey` is `string`
if (typeof newApiKey !== 'string') {
throw new TypeError('`apiKey` should be of type `string`');
}
apiKey = newApiKey;
}
export default async function btcValue(currencyCode = 'USD') {
let urlParameters = '';
// Check that the type of `currencyCode` is `string`
if (typeof currencyCode !== 'string') {
throw new TypeError('`currencyCode` should be of type `string`');
}
// Ensure the currency code is uppercase
currencyCode = currencyCode.toUpperCase();
let currencyValue;
if (selectedProvider === 'cmc') {
if (currencyCode !== 'USD') {
urlParameters += `&convert=${currencyCode}`;
}
const response = await sendHttpRequest(urlParameters);
// Set the `currencyValue` to the value for the specified currency
currencyValue = response.quote[currencyCode].price;
if (!currencyValue) {
throw new Error('Failed to retrieve Bitcoin value');
}
} else {
// Default to CoinGecko
try {
const jsonResponse = await got(`${providers[selectedProvider].baseUrl}&vs_currencies=${currencyCode}&precision=full`).json();
if (!jsonResponse.bitcoin || !jsonResponse.bitcoin[currencyCode.toLowerCase()]) {
throw new Error('Failed to retrieve Bitcoin value');
}
currencyValue = jsonResponse.bitcoin[currencyCode.toLowerCase()];
} catch {
throw new Error('Failed to retrieve Bitcoin value');
}
}
return Number(currencyValue);
}
async function getPercentageChangeLastTime(type) {
if (selectedProvider === 'cmc') {
const response = await sendHttpRequest();
if (!response.quote || !response.quote.USD || (response.quote && !response.quote.USD[`percent_change_${type}`])) {
throw new Error('Failed to retrieve percentage change');
}
return Number.parseFloat(response.quote.USD[`percent_change_${type}`]);
}
// Default to CoinGecko
const jsonResponse = await got(`https://api.coingecko.com/api/v3/coins/markets?ids=bitcoin&vs_currency=usd&price_change_percentage=${type}`).json();
if (!jsonResponse[0] || !jsonResponse[0][`price_change_percentage_${type}_in_currency`]) {
throw new Error('Failed to retrieve percentage change');
}
return Number.parseFloat(jsonResponse[0][`price_change_percentage_${type}_in_currency`]);
}
export async function getPercentageChangeLastHour() {
return getPercentageChangeLastTime('1h');
}
export async function getPercentageChangeLastDay() {
return getPercentageChangeLastTime('24h');
}
export async function getPercentageChangeLastWeek() {
return getPercentageChangeLastTime('7d');
}