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