@fileverse-dev/formulajs 4.4.11-mod-77 → 4.4.11-mod-79
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/browser/formula.js +590 -527
- package/lib/browser/formula.min.js +2 -2
- package/lib/browser/formula.min.js.map +1 -1
- package/lib/cjs/index.cjs +229 -105
- package/lib/esm/index.mjs +229 -105
- package/package.json +1 -1
package/lib/esm/index.mjs
CHANGED
|
@@ -13130,6 +13130,7 @@ const UTILITY = {
|
|
|
13130
13130
|
};
|
|
13131
13131
|
const MAX_PAGE_LIMIT = 250;
|
|
13132
13132
|
|
|
13133
|
+
// if data block need API key
|
|
13133
13134
|
const SERVICES_API_KEY = {
|
|
13134
13135
|
Etherscan: 'Etherscan',
|
|
13135
13136
|
Coingecko: 'Coingecko',
|
|
@@ -13142,27 +13143,6 @@ const SERVICES_API_KEY = {
|
|
|
13142
13143
|
Defillama: 'Defillama'
|
|
13143
13144
|
};
|
|
13144
13145
|
|
|
13145
|
-
const fromTimeStampToBlock = async (timestamp, chain, apiKey) => {
|
|
13146
|
-
if(!timestamp || !chain || !apiKey) return
|
|
13147
|
-
const chainId = CHAIN_ID_MAP[chain];
|
|
13148
|
-
const url = `https://api.etherscan.io/v2/api?module=block&action=getblocknobytime×tamp=${timestamp}&closest=before&apikey=${apiKey}&chainId=${chainId}`;
|
|
13149
|
-
const res = await fetch(url);
|
|
13150
|
-
const json = await res.json();
|
|
13151
|
-
return parseInt(json.result);
|
|
13152
|
-
|
|
13153
|
-
};
|
|
13154
|
-
|
|
13155
|
-
var fromTimestampToBlock = {
|
|
13156
|
-
fromTimeStampToBlock
|
|
13157
|
-
};
|
|
13158
|
-
|
|
13159
|
-
function toTimestamp(dateStr) {
|
|
13160
|
-
// Expecting format: "DD/MM/YYYY"
|
|
13161
|
-
const [day, month, year] = dateStr.split("/").map(Number);
|
|
13162
|
-
const date = new Date(year, month - 1, day);
|
|
13163
|
-
return Math.floor(date.getTime() / 1000); // Unix timestamp in seconds
|
|
13164
|
-
}
|
|
13165
|
-
|
|
13166
13146
|
class ValidationError extends Error {
|
|
13167
13147
|
constructor(message) {
|
|
13168
13148
|
super(message);
|
|
@@ -13207,6 +13187,138 @@ class InvalidApiKeyError extends Error {
|
|
|
13207
13187
|
}
|
|
13208
13188
|
}
|
|
13209
13189
|
|
|
13190
|
+
const fileverseProxyUrl = `${process?.env?.NEXT_PUBLIC_PROXY_BASE_URL}/proxy`;
|
|
13191
|
+
// Proxy map configuration
|
|
13192
|
+
const PROXY_MAP = {
|
|
13193
|
+
Etherscan: {
|
|
13194
|
+
url: fileverseProxyUrl,
|
|
13195
|
+
removeParams: ['apikey']
|
|
13196
|
+
},
|
|
13197
|
+
Basescan: {
|
|
13198
|
+
url: fileverseProxyUrl,
|
|
13199
|
+
removeParams: ['apikey']
|
|
13200
|
+
},
|
|
13201
|
+
Gnosisscan: {
|
|
13202
|
+
url: fileverseProxyUrl,
|
|
13203
|
+
removeParams: ['apikey']
|
|
13204
|
+
},
|
|
13205
|
+
Coingecko: {
|
|
13206
|
+
url: fileverseProxyUrl,
|
|
13207
|
+
removeParams: ['apikey']
|
|
13208
|
+
},
|
|
13209
|
+
Firefly: {
|
|
13210
|
+
url: fileverseProxyUrl,
|
|
13211
|
+
removeParams: ['apikey']
|
|
13212
|
+
},
|
|
13213
|
+
Neynar: {
|
|
13214
|
+
url: fileverseProxyUrl,
|
|
13215
|
+
removeParams: ['api_key']
|
|
13216
|
+
},
|
|
13217
|
+
Safe: {
|
|
13218
|
+
url: fileverseProxyUrl,
|
|
13219
|
+
removeParams: ['api_key']
|
|
13220
|
+
},
|
|
13221
|
+
Defillama: {
|
|
13222
|
+
url: fileverseProxyUrl,
|
|
13223
|
+
removeParams: ['api_key']
|
|
13224
|
+
},
|
|
13225
|
+
GnosisPay: {
|
|
13226
|
+
url: fileverseProxyUrl,
|
|
13227
|
+
removeParams: ['api_key']
|
|
13228
|
+
},
|
|
13229
|
+
// Add more services as needed. It can be direct url instead of ENV variable
|
|
13230
|
+
// ANOTHER_SERVICE: "https://another-proxy-url.com"
|
|
13231
|
+
};
|
|
13232
|
+
|
|
13233
|
+
/**
|
|
13234
|
+
* Removes specified parameters from a URL
|
|
13235
|
+
* @param {string} url - The original URL
|
|
13236
|
+
* @param {string[]} paramsToRemove - Array of parameter names to remove
|
|
13237
|
+
* @returns {string} URL with specified parameters removed
|
|
13238
|
+
*/
|
|
13239
|
+
function removeUrlParams(url, paramsToRemove) {
|
|
13240
|
+
if (!paramsToRemove || paramsToRemove.length === 0) {
|
|
13241
|
+
return url;
|
|
13242
|
+
}
|
|
13243
|
+
|
|
13244
|
+
const urlObj = new URL(url);
|
|
13245
|
+
|
|
13246
|
+
paramsToRemove.forEach(param => {
|
|
13247
|
+
if (urlObj.searchParams.has(param)) {
|
|
13248
|
+
urlObj.searchParams.delete(param);
|
|
13249
|
+
}
|
|
13250
|
+
});
|
|
13251
|
+
|
|
13252
|
+
return urlObj.toString();
|
|
13253
|
+
}
|
|
13254
|
+
|
|
13255
|
+
/**
|
|
13256
|
+
* Handles URL routing through proxy or direct API calls
|
|
13257
|
+
* @param {string} url - The original API URL
|
|
13258
|
+
* @param {string} serviceName - [OPTIONAL] The name of the service (e.g., 'EOA')
|
|
13259
|
+
* @param {object} headers - [OPTIONAL] The name of the service (e.g., 'EOA')
|
|
13260
|
+
* @returns {Object} Object containing URL and HEADERS for the fetch request
|
|
13261
|
+
*/
|
|
13262
|
+
function getUrlAndHeaders({ url, serviceName, headers = {} }) {
|
|
13263
|
+
// Check if proxy is enabled in localStorage
|
|
13264
|
+
const apiKeyLS = window.localStorage.getItem(SERVICES_API_KEY[serviceName]);
|
|
13265
|
+
const isProxyModeEnabledValue = apiKeyLS === 'DEFAULT_PROXY_MODE';
|
|
13266
|
+
|
|
13267
|
+
// Check if proxy URL exists for this service
|
|
13268
|
+
const proxyConfig = PROXY_MAP[serviceName];
|
|
13269
|
+
|
|
13270
|
+
if (!proxyConfig && SERVICES_API_KEY[serviceName] && (!apiKeyLS || apiKeyLS === '')) {
|
|
13271
|
+
throw new MissingApiKeyError(SERVICES_API_KEY[serviceName])
|
|
13272
|
+
}
|
|
13273
|
+
|
|
13274
|
+
// If proxy mode is enabled AND proxy URL exists for this service
|
|
13275
|
+
if ((isProxyModeEnabledValue || !apiKeyLS || apiKeyLS === '') && proxyConfig) {
|
|
13276
|
+
// Remove specified parameters from the target URL
|
|
13277
|
+
const cleanedUrl = removeUrlParams(url, proxyConfig.removeParams);
|
|
13278
|
+
|
|
13279
|
+
return {
|
|
13280
|
+
URL: proxyConfig.url,
|
|
13281
|
+
HEADERS: {
|
|
13282
|
+
'target-url': cleanedUrl,
|
|
13283
|
+
method: 'GET',
|
|
13284
|
+
'Content-Type': 'application/json'
|
|
13285
|
+
}
|
|
13286
|
+
};
|
|
13287
|
+
}
|
|
13288
|
+
|
|
13289
|
+
return {
|
|
13290
|
+
URL: url,
|
|
13291
|
+
HEADERS: {
|
|
13292
|
+
...headers,
|
|
13293
|
+
}
|
|
13294
|
+
};
|
|
13295
|
+
}
|
|
13296
|
+
|
|
13297
|
+
const fromTimeStampToBlock = async (timestamp, chain, apiKey) => {
|
|
13298
|
+
if (!timestamp || !chain) return
|
|
13299
|
+
const chainId = CHAIN_ID_MAP[chain];
|
|
13300
|
+
const url = `https://api.etherscan.io/v2/api?module=block&action=getblocknobytime×tamp=${timestamp}&closest=before&apikey=${apiKey}&chainId=${chainId}`;
|
|
13301
|
+
const { URL: finalUrl, HEADERS } = getUrlAndHeaders({ url, serviceName: 'Etherscan', headers: {} });
|
|
13302
|
+
const res = await fetch(finalUrl, {
|
|
13303
|
+
method: 'GET',
|
|
13304
|
+
headers: HEADERS,
|
|
13305
|
+
});
|
|
13306
|
+
const json = await res.json();
|
|
13307
|
+
return parseInt(json.result);
|
|
13308
|
+
|
|
13309
|
+
};
|
|
13310
|
+
|
|
13311
|
+
var fromTimestampToBlock = {
|
|
13312
|
+
fromTimeStampToBlock
|
|
13313
|
+
};
|
|
13314
|
+
|
|
13315
|
+
function toTimestamp(dateStr) {
|
|
13316
|
+
// Expecting format: "DD/MM/YYYY"
|
|
13317
|
+
const [day, month, year] = dateStr.split("/").map(Number);
|
|
13318
|
+
const date = new Date(year, month - 1, day);
|
|
13319
|
+
return Math.floor(date.getTime() / 1000); // Unix timestamp in seconds
|
|
13320
|
+
}
|
|
13321
|
+
|
|
13210
13322
|
const isAddress = (input) => {
|
|
13211
13323
|
return (/^0x[a-fA-F0-9]{40}$/.test(input))
|
|
13212
13324
|
};
|
|
@@ -13311,7 +13423,11 @@ async function handleScanRequest({
|
|
|
13311
13423
|
}
|
|
13312
13424
|
url += `&page=${page}&offset=${offset}`;
|
|
13313
13425
|
}
|
|
13314
|
-
const
|
|
13426
|
+
const { URL: finalUrl, HEADERS } = getUrlAndHeaders({url, serviceName: apiInfo.apiKeyName, headers: {}});
|
|
13427
|
+
const res = await fetch(finalUrl, {
|
|
13428
|
+
method: 'GET',
|
|
13429
|
+
headers: HEADERS,
|
|
13430
|
+
});
|
|
13315
13431
|
if (!res.ok) {
|
|
13316
13432
|
throw new NetworkError(apiInfo.apiKeyName, res.status)
|
|
13317
13433
|
}
|
|
@@ -13330,14 +13446,19 @@ async function handleScanRequest({
|
|
|
13330
13446
|
}
|
|
13331
13447
|
|
|
13332
13448
|
const fromUsernameToFid = async (username, apiKey) => {
|
|
13333
|
-
if(!username) return null
|
|
13449
|
+
if (!username) return null
|
|
13334
13450
|
const url = `https://api.neynar.com/v2/farcaster/user/search/?q=${username}&limit=5`;
|
|
13335
|
-
const
|
|
13336
|
-
headers: {
|
|
13451
|
+
const { URL: finalUrl, HEADERS } = getUrlAndHeaders({
|
|
13452
|
+
url, serviceName: 'Neynar', headers: {
|
|
13337
13453
|
'x-api-key': apiKey,
|
|
13338
13454
|
'x-neynar-experimental': 'false'
|
|
13339
13455
|
}
|
|
13340
13456
|
});
|
|
13457
|
+
|
|
13458
|
+
const res = await fetch(finalUrl, {
|
|
13459
|
+
method: 'GET',
|
|
13460
|
+
headers: HEADERS,
|
|
13461
|
+
});
|
|
13341
13462
|
const json = await res.json();
|
|
13342
13463
|
const users = json.result ? json.result.users : [];
|
|
13343
13464
|
const user = users.find(user => user.username === username);
|
|
@@ -17577,9 +17698,9 @@ const aaveParamsSchema = objectType({
|
|
|
17577
17698
|
|
|
17578
17699
|
async function FIREFLY() {
|
|
17579
17700
|
try {
|
|
17580
|
-
|
|
17701
|
+
const [platform, contentType, identifier, start = 0, end = 10] = argsToArray(arguments);
|
|
17581
17702
|
|
|
17582
|
-
validateParams(fireflyParamsSchema, {
|
|
17703
|
+
validateParams(fireflyParamsSchema, {
|
|
17583
17704
|
platform,
|
|
17584
17705
|
contentType,
|
|
17585
17706
|
identifier,
|
|
@@ -17588,9 +17709,6 @@ validateParams(fireflyParamsSchema, {
|
|
|
17588
17709
|
});
|
|
17589
17710
|
|
|
17590
17711
|
const apiKey = window.localStorage.getItem(SERVICES_API_KEY.Firefly);
|
|
17591
|
-
if (!apiKey) {
|
|
17592
|
-
throw new MissingApiKeyError(SERVICES_API_KEY.Firefly)
|
|
17593
|
-
}
|
|
17594
17712
|
|
|
17595
17713
|
const url = new URL('https://openapi.firefly.land/v1/fileverse/fetch');
|
|
17596
17714
|
url.searchParams
|
|
@@ -17601,12 +17719,14 @@ validateParams(fireflyParamsSchema, {
|
|
|
17601
17719
|
.filter(Boolean)
|
|
17602
17720
|
.join(',')
|
|
17603
17721
|
);
|
|
17604
|
-
|
|
17605
|
-
|
|
17606
|
-
|
|
17722
|
+
url.searchParams.set('type', fireFlyPlaformType[platform][contentType]);
|
|
17723
|
+
url.searchParams.set('start', String(start));
|
|
17724
|
+
url.searchParams.set('end', String(end));
|
|
17607
17725
|
|
|
17608
|
-
const
|
|
17609
|
-
|
|
17726
|
+
const { URL: finalUrl, HEADERS } = getUrlAndHeaders({ url: url.toString(), serviceName: 'Firefly', headers: { 'x-api-key': apiKey } });
|
|
17727
|
+
const response = await fetch(finalUrl, {
|
|
17728
|
+
method: 'GET',
|
|
17729
|
+
headers: HEADERS,
|
|
17610
17730
|
});
|
|
17611
17731
|
if (!response.ok) {
|
|
17612
17732
|
throw new NetworkError(SERVICES_API_KEY.Firefly, response.status)
|
|
@@ -17648,9 +17768,6 @@ async function LENS() {
|
|
|
17648
17768
|
const apiKey = window.localStorage.getItem(
|
|
17649
17769
|
SERVICES_API_KEY.Firefly
|
|
17650
17770
|
);
|
|
17651
|
-
if (!apiKey) {
|
|
17652
|
-
throw new MissingApiKeyError(SERVICES_API_KEY.Firefly)
|
|
17653
|
-
}
|
|
17654
17771
|
|
|
17655
17772
|
const url = new URL(
|
|
17656
17773
|
'https://openapi.firefly.land/v1/fileverse/fetch'
|
|
@@ -17664,15 +17781,18 @@ async function LENS() {
|
|
|
17664
17781
|
.join(',')
|
|
17665
17782
|
);
|
|
17666
17783
|
const typeMap = {
|
|
17667
|
-
posts:
|
|
17784
|
+
posts: 'lensid',
|
|
17668
17785
|
replies: 'lenspostid',
|
|
17669
17786
|
};
|
|
17670
17787
|
url.searchParams.set('type', typeMap[contentType]);
|
|
17671
17788
|
url.searchParams.set('start', String(start));
|
|
17672
|
-
url.searchParams.set('end',
|
|
17789
|
+
url.searchParams.set('end', String(end));
|
|
17790
|
+
|
|
17791
|
+
const { URL: finalUrl, HEADERS } = getUrlAndHeaders({ url: url.toString(), serviceName: 'Firefly', headers: { 'x-api-key': apiKey } });
|
|
17673
17792
|
|
|
17674
|
-
const response = await fetch(
|
|
17675
|
-
|
|
17793
|
+
const response = await fetch(finalUrl, {
|
|
17794
|
+
method: 'GET',
|
|
17795
|
+
headers: HEADERS,
|
|
17676
17796
|
});
|
|
17677
17797
|
if (!response.ok) {
|
|
17678
17798
|
throw new NetworkError(SERVICES_API_KEY.Firefly, response.status)
|
|
@@ -17699,7 +17819,7 @@ async function FARCASTER() {
|
|
|
17699
17819
|
try {
|
|
17700
17820
|
const [contentType, identifier, start = 0, end = 10] =
|
|
17701
17821
|
argsToArray(arguments);
|
|
17702
|
-
validateParams(farcasterParamsSchema, {
|
|
17822
|
+
validateParams(farcasterParamsSchema, {
|
|
17703
17823
|
contentType,
|
|
17704
17824
|
identifier,
|
|
17705
17825
|
start,
|
|
@@ -17709,9 +17829,6 @@ validateParams(farcasterParamsSchema, {
|
|
|
17709
17829
|
const apiKey = window.localStorage.getItem(
|
|
17710
17830
|
SERVICES_API_KEY.Firefly
|
|
17711
17831
|
);
|
|
17712
|
-
if (!apiKey) {
|
|
17713
|
-
throw new MissingApiKeyError(SERVICES_API_KEY.Firefly)
|
|
17714
|
-
}
|
|
17715
17832
|
|
|
17716
17833
|
const url = new URL(
|
|
17717
17834
|
'https://openapi.firefly.land/v1/fileverse/fetch'
|
|
@@ -17725,16 +17842,19 @@ validateParams(farcasterParamsSchema, {
|
|
|
17725
17842
|
.join(',')
|
|
17726
17843
|
);
|
|
17727
17844
|
const typeMap = {
|
|
17728
|
-
|
|
17729
|
-
|
|
17730
|
-
|
|
17731
|
-
};
|
|
17845
|
+
posts: 'farcasterid',
|
|
17846
|
+
replies: 'farcasterpostid',
|
|
17847
|
+
channels: 'farcasterchannels',
|
|
17848
|
+
};
|
|
17732
17849
|
url.searchParams.set('type', typeMap[contentType]);
|
|
17733
17850
|
url.searchParams.set('start', String(start));
|
|
17734
|
-
url.searchParams.set('end',
|
|
17851
|
+
url.searchParams.set('end', String(end));
|
|
17735
17852
|
|
|
17736
|
-
const
|
|
17737
|
-
|
|
17853
|
+
const { URL: finalUrl, HEADERS } = getUrlAndHeaders({ url: url.toString(), serviceName: 'Firefly', headers: { 'x-api-key': apiKey } });
|
|
17854
|
+
|
|
17855
|
+
const response = await fetch(finalUrl, {
|
|
17856
|
+
method: 'GET',
|
|
17857
|
+
headers: HEADERS,
|
|
17738
17858
|
});
|
|
17739
17859
|
if (!response.ok) {
|
|
17740
17860
|
throw new NetworkError(
|
|
@@ -17836,12 +17956,11 @@ async function BLOCKSCOUT() {
|
|
|
17836
17956
|
}
|
|
17837
17957
|
|
|
17838
17958
|
async function BASE() {
|
|
17839
|
-
try {
|
|
17959
|
+
try {
|
|
17840
17960
|
const [type, address, startDate, endDate, page, limit] = argsToArray(arguments);
|
|
17841
|
-
|
|
17961
|
+
validateParams(baseParamsSchema, { type, address, startDate, endDate, page, limit });
|
|
17842
17962
|
const API_KEY = window.localStorage.getItem(SERVICES_API_KEY.Basescan);
|
|
17843
|
-
|
|
17844
|
-
|
|
17963
|
+
|
|
17845
17964
|
return await handleScanRequest({
|
|
17846
17965
|
type,
|
|
17847
17966
|
address,
|
|
@@ -17854,9 +17973,9 @@ try {
|
|
|
17854
17973
|
chainId: CHAIN_ID_MAP.base,
|
|
17855
17974
|
network: 'base'
|
|
17856
17975
|
})
|
|
17857
|
-
} catch (error) {
|
|
17858
|
-
|
|
17859
|
-
}
|
|
17976
|
+
} catch (error) {
|
|
17977
|
+
return errorMessageHandler(error, 'BASE')
|
|
17978
|
+
}
|
|
17860
17979
|
}
|
|
17861
17980
|
async function GNOSIS() {
|
|
17862
17981
|
try {
|
|
@@ -17876,7 +17995,6 @@ async function GNOSIS() {
|
|
|
17876
17995
|
const apiKey = window.localStorage.getItem(
|
|
17877
17996
|
SERVICES_API_KEY.Gnosisscan
|
|
17878
17997
|
);
|
|
17879
|
-
if (!apiKey) throw new MissingApiKeyError(SERVICES_API_KEY.Gnosisscan)
|
|
17880
17998
|
|
|
17881
17999
|
return await handleScanRequest({
|
|
17882
18000
|
type,
|
|
@@ -17897,27 +18015,33 @@ async function GNOSIS() {
|
|
|
17897
18015
|
|
|
17898
18016
|
async function NEYNAR() {
|
|
17899
18017
|
try {
|
|
17900
|
-
|
|
17901
|
-
|
|
17902
|
-
});
|
|
18018
|
+
const neynarParamsSchema = objectType({
|
|
18019
|
+
username: stringType().nonempty()
|
|
18020
|
+
});
|
|
17903
18021
|
|
|
17904
18022
|
const [username] = argsToArray(arguments);
|
|
17905
18023
|
|
|
17906
18024
|
validateParams(neynarParamsSchema, { username });
|
|
17907
18025
|
|
|
17908
18026
|
const apiKey = window.localStorage.getItem(SERVICES_API_KEY.Neynar);
|
|
17909
|
-
if (!apiKey) throw new MissingApiKeyError(SERVICES_API_KEY.Neynar)
|
|
17910
18027
|
|
|
17911
18028
|
const fid = await fromUsernameToFid$1.fromUsernameToFid(username, apiKey);
|
|
17912
18029
|
if (!fid) throw new ValidationError(`Invalid username: ${username}`)
|
|
17913
18030
|
|
|
17914
18031
|
const url = `https://api.neynar.com/v2/farcaster/followers?fid=${fid}`;
|
|
17915
18032
|
|
|
17916
|
-
const
|
|
17917
|
-
|
|
17918
|
-
|
|
17919
|
-
|
|
17920
|
-
|
|
18033
|
+
const { URL: finalUrl, HEADERS } = getUrlAndHeaders({
|
|
18034
|
+
url: url.toString(), serviceName: 'Neynar',
|
|
18035
|
+
headers: {
|
|
18036
|
+
'x-api-key': apiKey,
|
|
18037
|
+
'x-neynar-experimental': 'false'
|
|
18038
|
+
}
|
|
18039
|
+
|
|
18040
|
+
});
|
|
18041
|
+
|
|
18042
|
+
const response = await fetch(finalUrl, {
|
|
18043
|
+
method: 'GET',
|
|
18044
|
+
headers: HEADERS,
|
|
17921
18045
|
});
|
|
17922
18046
|
if (!response.ok) {
|
|
17923
18047
|
throw new NetworkError(SERVICES_API_KEY.Neynar, response.status)
|
|
@@ -18012,7 +18136,6 @@ async function ETHERSCAN() {
|
|
|
18012
18136
|
if (!chainId) throw new ValidationError(`Invalid chain: ${chain}`)
|
|
18013
18137
|
|
|
18014
18138
|
const apiKey = window.localStorage.getItem(SERVICES_API_KEY.Etherscan);
|
|
18015
|
-
if (!apiKey) throw new MissingApiKeyError(SERVICES_API_KEY.Etherscan)
|
|
18016
18139
|
|
|
18017
18140
|
return await handleScanRequest({
|
|
18018
18141
|
type,
|
|
@@ -18038,7 +18161,6 @@ async function COINGECKO() {
|
|
|
18038
18161
|
validateParams(coingeckoParamsSchema, { category, param1, param2 });
|
|
18039
18162
|
|
|
18040
18163
|
const apiKey = window.localStorage.getItem(SERVICES_API_KEY.Coingecko);
|
|
18041
|
-
if (!apiKey) throw new MissingApiKeyError(SERVICES_API_KEY.Coingecko)
|
|
18042
18164
|
|
|
18043
18165
|
const headers = {
|
|
18044
18166
|
accept: 'application/json',
|
|
@@ -18052,27 +18174,28 @@ async function COINGECKO() {
|
|
|
18052
18174
|
break
|
|
18053
18175
|
}
|
|
18054
18176
|
case 'market': {
|
|
18055
|
-
const map = { all:'', base:'base-ecosystem', meme:'meme-token', aiagents:'ai-agents', bitcoin:'bitcoin-ecosystem', ethereum:'ethereum-ecosystem', hyperliquid:'hyperliquid-ecosystem', pump:'pump-ecosystem', solana:'solana-ecosystem' };
|
|
18177
|
+
const map = { all: '', base: 'base-ecosystem', meme: 'meme-token', aiagents: 'ai-agents', bitcoin: 'bitcoin-ecosystem', ethereum: 'ethereum-ecosystem', hyperliquid: 'hyperliquid-ecosystem', pump: 'pump-ecosystem', solana: 'solana-ecosystem' };
|
|
18056
18178
|
const _category = map[param1] || '';
|
|
18057
18179
|
const trend = param2 ? `&price_change_percentage=${param2}` : '';
|
|
18058
|
-
url = `https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&include_tokens=top&page=1&per_page=100${_category
|
|
18180
|
+
url = `https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&include_tokens=top&page=1&per_page=100${_category ? `&category=${_category}` : ''}${trend}`;
|
|
18059
18181
|
break
|
|
18060
18182
|
}
|
|
18061
18183
|
case 'stablecoins': {
|
|
18062
|
-
const _category = param1==='all'? 'stablecoins' : param1;
|
|
18184
|
+
const _category = param1 === 'all' ? 'stablecoins' : param1;
|
|
18063
18185
|
const trend = param2 ? `&price_change_percentage=${param2}` : '';
|
|
18064
18186
|
url = `https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&category=${_category}&order=market_cap_desc&page=1&per_page=100${trend}`;
|
|
18065
18187
|
break
|
|
18066
18188
|
}
|
|
18067
18189
|
case 'derivatives': {
|
|
18068
|
-
url = (!param1 || param1==='all')
|
|
18190
|
+
url = (!param1 || param1 === 'all')
|
|
18069
18191
|
? 'https://api.coingecko.com/api/v3/derivatives'
|
|
18070
18192
|
: `https://api.coingecko.com/api/v3/derivatives/exchanges/${param1}?include_tickers=all`;
|
|
18071
18193
|
break
|
|
18072
18194
|
}
|
|
18073
18195
|
}
|
|
18196
|
+
const {URL: finalUrl, HEADERS} = getUrlAndHeaders({url, serviceName: 'Coingecko', headers});
|
|
18074
18197
|
|
|
18075
|
-
const res = await fetch(
|
|
18198
|
+
const res = await fetch(finalUrl, { headers: HEADERS });
|
|
18076
18199
|
const json = await res.json();
|
|
18077
18200
|
if (!res.ok) {
|
|
18078
18201
|
const msg = json?.status?.error_message || '';
|
|
@@ -18080,17 +18203,17 @@ async function COINGECKO() {
|
|
|
18080
18203
|
throw new NetworkError(SERVICES_API_KEY.Coingecko, res.status)
|
|
18081
18204
|
}
|
|
18082
18205
|
|
|
18083
|
-
if (category==='price') {
|
|
18206
|
+
if (category === 'price') {
|
|
18084
18207
|
const out = {};
|
|
18085
18208
|
for (const [token, prices] of Object.entries(json))
|
|
18086
|
-
for (const [cur,val] of Object.entries(prices))
|
|
18087
|
-
out[`${token.charAt(0).toUpperCase()+token.slice(1)}_${cur.toUpperCase()}`]=val;
|
|
18209
|
+
for (const [cur, val] of Object.entries(prices))
|
|
18210
|
+
out[`${token.charAt(0).toUpperCase() + token.slice(1)}_${cur.toUpperCase()}`] = val;
|
|
18088
18211
|
return [out]
|
|
18089
18212
|
}
|
|
18090
18213
|
|
|
18091
18214
|
const data = Array.isArray(json) ? json : [json];
|
|
18092
|
-
return data.map(item=>{
|
|
18093
|
-
const flat={};
|
|
18215
|
+
return data.map(item => {
|
|
18216
|
+
const flat = {};
|
|
18094
18217
|
for (const [key, value] of Object.entries(item)) {
|
|
18095
18218
|
if (typeof value !== 'object' || value === null) {
|
|
18096
18219
|
flat[key] = value;
|
|
@@ -18098,8 +18221,8 @@ async function COINGECKO() {
|
|
|
18098
18221
|
}
|
|
18099
18222
|
return flat
|
|
18100
18223
|
})
|
|
18101
|
-
} catch(err) {
|
|
18102
|
-
return errorMessageHandler(err,'COINGECKO')
|
|
18224
|
+
} catch (err) {
|
|
18225
|
+
return errorMessageHandler(err, 'COINGECKO')
|
|
18103
18226
|
}
|
|
18104
18227
|
}
|
|
18105
18228
|
|
|
@@ -18110,10 +18233,9 @@ async function EOA() {
|
|
|
18110
18233
|
validateParams(eoaParamsSchema, { addresses, category, chains, startTime, endTime, page, offset });
|
|
18111
18234
|
|
|
18112
18235
|
const apiKey = window.localStorage.getItem(SERVICES_API_KEY.Etherscan);
|
|
18113
|
-
if (!apiKey) throw new MissingApiKeyError(SERVICES_API_KEY.Etherscan)
|
|
18114
18236
|
|
|
18115
|
-
const INPUTS = addresses.split(',').map(s=>s.trim()).filter(Boolean);
|
|
18116
|
-
const CHAINS = chains.split(',').map(s=>s.trim()).filter(Boolean);
|
|
18237
|
+
const INPUTS = addresses.split(',').map(s => s.trim()).filter(Boolean);
|
|
18238
|
+
const CHAINS = chains.split(',').map(s => s.trim()).filter(Boolean);
|
|
18117
18239
|
|
|
18118
18240
|
const ADDRESS_MAP = {};
|
|
18119
18241
|
for (const inp of INPUTS) {
|
|
@@ -18128,7 +18250,11 @@ async function EOA() {
|
|
|
18128
18250
|
const out = [];
|
|
18129
18251
|
|
|
18130
18252
|
async function fetchJSON(url) {
|
|
18131
|
-
const
|
|
18253
|
+
const { URL: finalUrl, HEADERS } = getUrlAndHeaders({ url, serviceName: 'Etherscan', headers: {} });
|
|
18254
|
+
const res = await fetch(finalUrl, {
|
|
18255
|
+
method: 'GET',
|
|
18256
|
+
headers: HEADERS,
|
|
18257
|
+
});
|
|
18132
18258
|
if (!res.ok) throw new NetworkError(SERVICES_API_KEY.Etherscan, res.status)
|
|
18133
18259
|
const json = await res.json();
|
|
18134
18260
|
|
|
@@ -18146,15 +18272,15 @@ async function EOA() {
|
|
|
18146
18272
|
|
|
18147
18273
|
if (category === 'balance') {
|
|
18148
18274
|
// chunk 20
|
|
18149
|
-
for (let i=0; i<ADDRS.length; i+=20) {
|
|
18150
|
-
const slice = ADDRS.slice(i,i+20).join(',');
|
|
18275
|
+
for (let i = 0; i < ADDRS.length; i += 20) {
|
|
18276
|
+
const slice = ADDRS.slice(i, i + 20).join(',');
|
|
18151
18277
|
const url =
|
|
18152
|
-
`https://api.etherscan.io/v2/api?chainid=${chainId}
|
|
18153
|
-
`&module=account&action=addresstokenbalance&address=${slice}
|
|
18278
|
+
`https://api.etherscan.io/v2/api?chainid=${chainId}` +
|
|
18279
|
+
`&module=account&action=addresstokenbalance&address=${slice}` +
|
|
18154
18280
|
`&page=${page}&offset=${offset}&apikey=${apiKey}`;
|
|
18155
18281
|
const data = await fetchJSON(url);
|
|
18156
18282
|
if (!Array.isArray(data)) return data
|
|
18157
|
-
data.forEach((item, idx) => out.push({ chain, address: ADDRS[i+idx], name: ADDRESS_MAP[ADDRS[i+idx]], ...item }));
|
|
18283
|
+
data.forEach((item, idx) => out.push({ chain, address: ADDRS[i + idx], name: ADDRESS_MAP[ADDRS[i + idx]], ...item }));
|
|
18158
18284
|
}
|
|
18159
18285
|
} else {
|
|
18160
18286
|
// txns
|
|
@@ -18164,9 +18290,9 @@ async function EOA() {
|
|
|
18164
18290
|
if (!eb) throw new ValidationError(`Invalid endTime: ${endTime}`)
|
|
18165
18291
|
for (const addr of ADDRS) {
|
|
18166
18292
|
const url =
|
|
18167
|
-
`https://api.etherscan.io/v2/api?chainid=${chainId}
|
|
18168
|
-
`&module=account&action=tokentx&address=${addr}
|
|
18169
|
-
`&startblock=${sb}&endblock=${eb}
|
|
18293
|
+
`https://api.etherscan.io/v2/api?chainid=${chainId}` +
|
|
18294
|
+
`&module=account&action=tokentx&address=${addr}` +
|
|
18295
|
+
`&startblock=${sb}&endblock=${eb}` +
|
|
18170
18296
|
`&page=${page}&offset=${offset}&sort=asc&apikey=${apiKey}`;
|
|
18171
18297
|
const data = await fetchJSON(url);
|
|
18172
18298
|
if (!Array.isArray(data)) return data
|
|
@@ -18195,7 +18321,6 @@ async function SAFE() {
|
|
|
18195
18321
|
validateParams(safeParamsSchema, { address, utility, chain, limit, offset });
|
|
18196
18322
|
|
|
18197
18323
|
const apiKey = window.localStorage.getItem(SERVICES_API_KEY.Safe);
|
|
18198
|
-
if (!apiKey) throw new MissingApiKeyError(SERVICES_API_KEY.Safe)
|
|
18199
18324
|
|
|
18200
18325
|
const chainId = SAFE_CHAIN_MAP[chain];
|
|
18201
18326
|
if (!chainId) throw new ValidationError(`Invalid chain: ${chain}`)
|
|
@@ -18208,8 +18333,8 @@ async function SAFE() {
|
|
|
18208
18333
|
|
|
18209
18334
|
const url = `https://api.safe.global/tx-service/${chainId}/api/v2/safes/${resolved}/multisig-transactions?limit=${limit}&offset=${offset}`;
|
|
18210
18335
|
|
|
18211
|
-
|
|
18212
|
-
const res = await fetch(
|
|
18336
|
+
const { URL: finalUrl, HEADERS } = getUrlAndHeaders({ url, serviceName: 'Etherscan', headers: { Authorization: `Bearer ${apiKey}` } });
|
|
18337
|
+
const res = await fetch(finalUrl, { headers: HEADERS });
|
|
18213
18338
|
if (!res.ok) throw new NetworkError(SERVICES_API_KEY.Safe, res.status)
|
|
18214
18339
|
const json = await res.json();
|
|
18215
18340
|
|
|
@@ -18230,7 +18355,6 @@ async function DEFILLAMA() {
|
|
|
18230
18355
|
const [category] = argsToArray(arguments);
|
|
18231
18356
|
validateParams(defillamaParamsSchema, { category });
|
|
18232
18357
|
const apiKey = window.localStorage.getItem(SERVICES_API_KEY.Defillama);
|
|
18233
|
-
if (!apiKey) throw new MissingApiKeyError(SERVICES_API_KEY.Defillama)
|
|
18234
18358
|
const url = CATEGORY_URLS[category];
|
|
18235
18359
|
if (!url) throw new ValidationError(`Invalid category: ${category}`)
|
|
18236
18360
|
const res = await fetch(url);
|
|
@@ -18239,20 +18363,20 @@ async function DEFILLAMA() {
|
|
|
18239
18363
|
|
|
18240
18364
|
switch (category) {
|
|
18241
18365
|
case 'protocols':
|
|
18242
|
-
json = Array.isArray(json) ? json.slice(0,500) : [];
|
|
18366
|
+
json = Array.isArray(json) ? json.slice(0, 500) : [];
|
|
18243
18367
|
break
|
|
18244
18368
|
case 'yields':
|
|
18245
|
-
json = Array.isArray(json.data) ? json.data.slice(0,500) : [];
|
|
18369
|
+
json = Array.isArray(json.data) ? json.data.slice(0, 500) : [];
|
|
18246
18370
|
break
|
|
18247
18371
|
case 'dex':
|
|
18248
18372
|
case 'fees':
|
|
18249
|
-
json = Array.isArray(json.protocols) ? json.protocols.slice(0,500) : [];
|
|
18373
|
+
json = Array.isArray(json.protocols) ? json.protocols.slice(0, 500) : [];
|
|
18250
18374
|
break
|
|
18251
18375
|
}
|
|
18252
18376
|
|
|
18253
18377
|
return (Array.isArray(json) ? json : [json]).map(item => {
|
|
18254
18378
|
const out = {};
|
|
18255
|
-
for (const [k,v] of Object.entries(item)) {
|
|
18379
|
+
for (const [k, v] of Object.entries(item)) {
|
|
18256
18380
|
if (v === null || typeof v !== 'object') out[k] = v;
|
|
18257
18381
|
}
|
|
18258
18382
|
return out
|
|
@@ -18288,7 +18412,7 @@ async function UNISWAP() {
|
|
|
18288
18412
|
// flatten nested
|
|
18289
18413
|
return json.map(item => {
|
|
18290
18414
|
const flat = {};
|
|
18291
|
-
Object.entries(item).forEach(([k,v]) => {
|
|
18415
|
+
Object.entries(item).forEach(([k, v]) => {
|
|
18292
18416
|
if (v === null || typeof v !== 'object') flat[k] = v;
|
|
18293
18417
|
});
|
|
18294
18418
|
return flat
|