@fileverse-dev/formulajs 4.4.11-mod-71 → 4.4.11-mod-68-patch-9
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 +440 -287
- package/lib/browser/formula.min.js +2 -2
- package/lib/browser/formula.min.js.map +1 -1
- package/lib/cjs/index.cjs +228 -74
- package/lib/esm/index.mjs +228 -74
- package/package.json +1 -1
package/lib/cjs/index.cjs
CHANGED
|
@@ -13144,15 +13144,130 @@ const SERVICES_API_KEY = {
|
|
|
13144
13144
|
Defillama: 'Defillama'
|
|
13145
13145
|
};
|
|
13146
13146
|
|
|
13147
|
+
// Proxy map configuration
|
|
13148
|
+
const PROXY_MAP = {
|
|
13149
|
+
Etherscan: {
|
|
13150
|
+
url: "https://staging-api-proxy-ca4268d7d581.herokuapp.com/proxy",
|
|
13151
|
+
removeParams: ['apikey']
|
|
13152
|
+
},
|
|
13153
|
+
Basescan: {
|
|
13154
|
+
url: "https://staging-api-proxy-ca4268d7d581.herokuapp.com/proxy",
|
|
13155
|
+
removeParams: ['apikey']
|
|
13156
|
+
},
|
|
13157
|
+
Gnosisscan: {
|
|
13158
|
+
url: "https://staging-api-proxy-ca4268d7d581.herokuapp.com/proxy",
|
|
13159
|
+
removeParams: ['apikey']
|
|
13160
|
+
},
|
|
13161
|
+
Coingecko: {
|
|
13162
|
+
url: "https://staging-api-proxy-ca4268d7d581.herokuapp.com/proxy",
|
|
13163
|
+
removeParams: ['apikey']
|
|
13164
|
+
},
|
|
13165
|
+
Firefly: {
|
|
13166
|
+
url: "https://staging-api-proxy-ca4268d7d581.herokuapp.com/proxy",
|
|
13167
|
+
removeParams: ['apikey']
|
|
13168
|
+
},
|
|
13169
|
+
Neynar: {
|
|
13170
|
+
url: "https://staging-api-proxy-ca4268d7d581.herokuapp.com/proxy",
|
|
13171
|
+
removeParams: ['api_key']
|
|
13172
|
+
},
|
|
13173
|
+
Safe: {
|
|
13174
|
+
url: "https://staging-api-proxy-ca4268d7d581.herokuapp.com/proxy",
|
|
13175
|
+
removeParams: ['api_key']
|
|
13176
|
+
},
|
|
13177
|
+
Defillama: {
|
|
13178
|
+
url: "https://staging-api-proxy-ca4268d7d581.herokuapp.com/proxy",
|
|
13179
|
+
removeParams: ['api_key']
|
|
13180
|
+
},
|
|
13181
|
+
GnosisPay: {
|
|
13182
|
+
url: "https://staging-api-proxy-ca4268d7d581.herokuapp.com/proxy",
|
|
13183
|
+
removeParams: ['api_key']
|
|
13184
|
+
},
|
|
13185
|
+
// Add more services as needed. It can be direct url instead of ENV variable
|
|
13186
|
+
// ANOTHER_SERVICE: "https://another-proxy-url.com"
|
|
13187
|
+
};
|
|
13188
|
+
|
|
13189
|
+
/**
|
|
13190
|
+
* Removes specified parameters from a URL
|
|
13191
|
+
* @param {string} url - The original URL
|
|
13192
|
+
* @param {string[]} paramsToRemove - Array of parameter names to remove
|
|
13193
|
+
* @returns {string} URL with specified parameters removed
|
|
13194
|
+
*/
|
|
13195
|
+
function removeUrlParams(url, paramsToRemove) {
|
|
13196
|
+
if (!paramsToRemove || paramsToRemove.length === 0) {
|
|
13197
|
+
return url;
|
|
13198
|
+
}
|
|
13199
|
+
|
|
13200
|
+
const urlObj = new URL(url);
|
|
13201
|
+
|
|
13202
|
+
paramsToRemove.forEach(param => {
|
|
13203
|
+
if (urlObj.searchParams.has(param)) {
|
|
13204
|
+
urlObj.searchParams.delete(param);
|
|
13205
|
+
}
|
|
13206
|
+
});
|
|
13207
|
+
|
|
13208
|
+
return urlObj.toString();
|
|
13209
|
+
}
|
|
13210
|
+
|
|
13211
|
+
/**
|
|
13212
|
+
* Handles URL routing through proxy or direct API calls
|
|
13213
|
+
* @param {string} url - The original API URL
|
|
13214
|
+
* @param {string} serviceName - The name of the service (e.g., 'EOA')
|
|
13215
|
+
* @param {string} headers - The name of the service (e.g., 'EOA')
|
|
13216
|
+
* @returns {Object} Object containing URL and HEADERS for the fetch request
|
|
13217
|
+
*/
|
|
13218
|
+
function getUrlAndHeaders({ url, serviceName, headers = {} }) {
|
|
13219
|
+
console.log('getUrlAndHeaders new modified function from formulajs', url, serviceName);
|
|
13220
|
+
// Check if proxy is enabled in localStorage
|
|
13221
|
+
const apiKeyLS = window.localStorage.getItem(SERVICES_API_KEY[serviceName]);
|
|
13222
|
+
const isProxyModeEnabledValue = apiKeyLS === 'DEFAULT_PROXY_MODE';
|
|
13223
|
+
|
|
13224
|
+
// Check if proxy URL exists for this service
|
|
13225
|
+
const proxyConfig = PROXY_MAP[serviceName];
|
|
13226
|
+
|
|
13227
|
+
// If proxy mode is enabled AND proxy URL exists for this service
|
|
13228
|
+
if (isProxyModeEnabledValue && proxyConfig && serviceName && SERVICES_API_KEY[serviceName]) {
|
|
13229
|
+
console.log('isProxyModeEnabledValue', isProxyModeEnabledValue);
|
|
13230
|
+
// Remove specified parameters from the target URL
|
|
13231
|
+
const cleanedUrl = removeUrlParams(url, proxyConfig.removeParams);
|
|
13232
|
+
|
|
13233
|
+
return {
|
|
13234
|
+
URL: proxyConfig.url,
|
|
13235
|
+
HEADERS: {
|
|
13236
|
+
'target-url': cleanedUrl,
|
|
13237
|
+
method: 'GET',
|
|
13238
|
+
'Content-Type': 'application/json'
|
|
13239
|
+
}
|
|
13240
|
+
};
|
|
13241
|
+
}
|
|
13242
|
+
|
|
13243
|
+
|
|
13244
|
+
return {
|
|
13245
|
+
URL: url,
|
|
13246
|
+
HEADERS: {
|
|
13247
|
+
...headers,
|
|
13248
|
+
method: 'GET',
|
|
13249
|
+
}
|
|
13250
|
+
};
|
|
13251
|
+
}
|
|
13252
|
+
|
|
13147
13253
|
const fromTimeStampToBlock = async (timestamp, chain, apiKey) => {
|
|
13148
|
-
|
|
13149
|
-
|
|
13150
|
-
|
|
13151
|
-
|
|
13152
|
-
|
|
13153
|
-
|
|
13254
|
+
console.log('fromTimeStampToBlock', timestamp, chain, apiKey);
|
|
13255
|
+
if (!timestamp || !chain || !apiKey) return
|
|
13256
|
+
const chainId = CHAIN_ID_MAP[chain];
|
|
13257
|
+
console.log('chainId', chainId);
|
|
13258
|
+
const url = `https://api.etherscan.io/v2/api?module=block&action=getblocknobytime×tamp=${timestamp}&closest=before&apikey=${apiKey}&chainId=${chainId}`;
|
|
13259
|
+
console.log('url', url, getUrlAndHeaders);
|
|
13260
|
+
const { URL: finalUrl, HEADERS } = getUrlAndHeaders({ url, serviceName: 'Etherscan', headers: {} });
|
|
13261
|
+
console.log('finalUrl', finalUrl, HEADERS);
|
|
13262
|
+
const res = await fetch(finalUrl, {
|
|
13263
|
+
method: 'GET',
|
|
13264
|
+
headers: HEADERS,
|
|
13265
|
+
});
|
|
13266
|
+
console.log('res', res, finalUrl, HEADERS);
|
|
13267
|
+
const json = await res.json();
|
|
13268
|
+
return parseInt(json.result);
|
|
13154
13269
|
|
|
13155
|
-
|
|
13270
|
+
};
|
|
13156
13271
|
|
|
13157
13272
|
var fromTimestampToBlock = {
|
|
13158
13273
|
fromTimeStampToBlock
|
|
@@ -13310,7 +13425,11 @@ async function handleScanRequest({
|
|
|
13310
13425
|
}
|
|
13311
13426
|
url += `&page=${page}&offset=${offset}`;
|
|
13312
13427
|
}
|
|
13313
|
-
const
|
|
13428
|
+
const { URL: finalUrl, HEADERS } = getUrlAndHeaders({url, serviceName: 'Etherscan', headers: {}});
|
|
13429
|
+
const res = await fetch(finalUrl, {
|
|
13430
|
+
method: 'GET',
|
|
13431
|
+
headers: HEADERS,
|
|
13432
|
+
});
|
|
13314
13433
|
if (!res.ok) {
|
|
13315
13434
|
throw new NetworkError(apiInfo.apiKeyName, res.status)
|
|
13316
13435
|
}
|
|
@@ -13329,14 +13448,19 @@ async function handleScanRequest({
|
|
|
13329
13448
|
}
|
|
13330
13449
|
|
|
13331
13450
|
const fromUsernameToFid = async (username, apiKey) => {
|
|
13332
|
-
if(!username) return null
|
|
13451
|
+
if (!username) return null
|
|
13333
13452
|
const url = `https://api.neynar.com/v2/farcaster/user/search/?q=${username}&limit=5`;
|
|
13334
|
-
const
|
|
13335
|
-
headers: {
|
|
13453
|
+
const { URL: finalUrl, HEADERS } = getUrlAndHeaders({
|
|
13454
|
+
url, serviceName: 'Neynar', headers: {
|
|
13336
13455
|
'x-api-key': apiKey,
|
|
13337
13456
|
'x-neynar-experimental': 'false'
|
|
13338
13457
|
}
|
|
13339
13458
|
});
|
|
13459
|
+
|
|
13460
|
+
const res = await fetch(finalUrl, {
|
|
13461
|
+
method: 'GET',
|
|
13462
|
+
headers: HEADERS,
|
|
13463
|
+
});
|
|
13340
13464
|
const json = await res.json();
|
|
13341
13465
|
const users = json.result ? json.result.users : [];
|
|
13342
13466
|
const user = users.find(user => user.username === username);
|
|
@@ -17576,9 +17700,9 @@ const aaveParamsSchema = objectType({
|
|
|
17576
17700
|
|
|
17577
17701
|
async function FIREFLY() {
|
|
17578
17702
|
try {
|
|
17579
|
-
|
|
17703
|
+
const [platform, contentType, identifier, start = 0, end = 10] = argsToArray(arguments);
|
|
17580
17704
|
|
|
17581
|
-
validateParams(fireflyParamsSchema, {
|
|
17705
|
+
validateParams(fireflyParamsSchema, {
|
|
17582
17706
|
platform,
|
|
17583
17707
|
contentType,
|
|
17584
17708
|
identifier,
|
|
@@ -17600,12 +17724,14 @@ validateParams(fireflyParamsSchema, {
|
|
|
17600
17724
|
.filter(Boolean)
|
|
17601
17725
|
.join(',')
|
|
17602
17726
|
);
|
|
17603
|
-
|
|
17604
|
-
|
|
17605
|
-
|
|
17727
|
+
url.searchParams.set('type', fireFlyPlaformType[platform][contentType]);
|
|
17728
|
+
url.searchParams.set('start', String(start));
|
|
17729
|
+
url.searchParams.set('end', String(end));
|
|
17606
17730
|
|
|
17607
|
-
const
|
|
17608
|
-
|
|
17731
|
+
const { URL: finalUrl, HEADERS } = getUrlAndHeaders({ url: url.toString(), serviceName: 'Firefly', headers: { 'x-api-key': apiKey } });
|
|
17732
|
+
const response = await fetch(finalUrl, {
|
|
17733
|
+
method: 'GET',
|
|
17734
|
+
headers: HEADERS,
|
|
17609
17735
|
});
|
|
17610
17736
|
if (!response.ok) {
|
|
17611
17737
|
throw new NetworkError(SERVICES_API_KEY.Firefly, response.status)
|
|
@@ -17663,15 +17789,18 @@ async function LENS() {
|
|
|
17663
17789
|
.join(',')
|
|
17664
17790
|
);
|
|
17665
17791
|
const typeMap = {
|
|
17666
|
-
posts:
|
|
17792
|
+
posts: 'lensid',
|
|
17667
17793
|
replies: 'lenspostid',
|
|
17668
17794
|
};
|
|
17669
17795
|
url.searchParams.set('type', typeMap[contentType]);
|
|
17670
17796
|
url.searchParams.set('start', String(start));
|
|
17671
|
-
url.searchParams.set('end',
|
|
17797
|
+
url.searchParams.set('end', String(end));
|
|
17672
17798
|
|
|
17673
|
-
const
|
|
17674
|
-
|
|
17799
|
+
const { URL: finalUrl, HEADERS } = getUrlAndHeaders({ url: url.toString(), serviceName: 'Firefly', headers: { 'x-api-key': apiKey } });
|
|
17800
|
+
|
|
17801
|
+
const response = await fetch(finalUrl, {
|
|
17802
|
+
method: 'GET',
|
|
17803
|
+
headers: HEADERS,
|
|
17675
17804
|
});
|
|
17676
17805
|
if (!response.ok) {
|
|
17677
17806
|
throw new NetworkError(SERVICES_API_KEY.Firefly, response.status)
|
|
@@ -17698,7 +17827,7 @@ async function FARCASTER() {
|
|
|
17698
17827
|
try {
|
|
17699
17828
|
const [contentType, identifier, start = 0, end = 10] =
|
|
17700
17829
|
argsToArray(arguments);
|
|
17701
|
-
validateParams(farcasterParamsSchema, {
|
|
17830
|
+
validateParams(farcasterParamsSchema, {
|
|
17702
17831
|
contentType,
|
|
17703
17832
|
identifier,
|
|
17704
17833
|
start,
|
|
@@ -17724,16 +17853,19 @@ validateParams(farcasterParamsSchema, {
|
|
|
17724
17853
|
.join(',')
|
|
17725
17854
|
);
|
|
17726
17855
|
const typeMap = {
|
|
17727
|
-
|
|
17728
|
-
|
|
17729
|
-
|
|
17730
|
-
};
|
|
17856
|
+
posts: 'farcasterid',
|
|
17857
|
+
replies: 'farcasterpostid',
|
|
17858
|
+
channels: 'farcasterchannels',
|
|
17859
|
+
};
|
|
17731
17860
|
url.searchParams.set('type', typeMap[contentType]);
|
|
17732
17861
|
url.searchParams.set('start', String(start));
|
|
17733
|
-
url.searchParams.set('end',
|
|
17862
|
+
url.searchParams.set('end', String(end));
|
|
17863
|
+
|
|
17864
|
+
const { URL: finalUrl, HEADERS } = getUrlAndHeaders({ url: url.toString(), serviceName: 'Firefly', headers: { 'x-api-key': apiKey } });
|
|
17734
17865
|
|
|
17735
|
-
const response = await fetch(
|
|
17736
|
-
|
|
17866
|
+
const response = await fetch(finalUrl, {
|
|
17867
|
+
method: 'GET',
|
|
17868
|
+
headers: HEADERS,
|
|
17737
17869
|
});
|
|
17738
17870
|
if (!response.ok) {
|
|
17739
17871
|
throw new NetworkError(
|
|
@@ -17842,12 +17974,12 @@ async function BLOCKSCOUT() {
|
|
|
17842
17974
|
}
|
|
17843
17975
|
|
|
17844
17976
|
async function BASE() {
|
|
17845
|
-
try {
|
|
17977
|
+
try {
|
|
17846
17978
|
const [type, address, startDate, endDate, page, limit] = argsToArray(arguments);
|
|
17847
|
-
|
|
17979
|
+
validateParams(baseParamsSchema, { type, address, startDate, endDate, page, limit });
|
|
17848
17980
|
const API_KEY = window.localStorage.getItem(SERVICES_API_KEY.Basescan);
|
|
17849
17981
|
if (!API_KEY) throw new MissingApiKeyError(SERVICES_API_KEY.Basescan)
|
|
17850
|
-
|
|
17982
|
+
|
|
17851
17983
|
return await handleScanRequest({
|
|
17852
17984
|
type,
|
|
17853
17985
|
address,
|
|
@@ -17860,9 +17992,9 @@ try {
|
|
|
17860
17992
|
chainId: CHAIN_ID_MAP.base,
|
|
17861
17993
|
network: 'base'
|
|
17862
17994
|
})
|
|
17863
|
-
} catch (error) {
|
|
17864
|
-
|
|
17865
|
-
}
|
|
17995
|
+
} catch (error) {
|
|
17996
|
+
return errorMessageHandler(error, 'BASE')
|
|
17997
|
+
}
|
|
17866
17998
|
}
|
|
17867
17999
|
async function GNOSIS() {
|
|
17868
18000
|
try {
|
|
@@ -17903,9 +18035,9 @@ async function GNOSIS() {
|
|
|
17903
18035
|
|
|
17904
18036
|
async function NEYNAR() {
|
|
17905
18037
|
try {
|
|
17906
|
-
|
|
17907
|
-
|
|
17908
|
-
});
|
|
18038
|
+
const neynarParamsSchema = objectType({
|
|
18039
|
+
username: stringType().nonempty()
|
|
18040
|
+
});
|
|
17909
18041
|
|
|
17910
18042
|
const [username] = argsToArray(arguments);
|
|
17911
18043
|
|
|
@@ -17919,11 +18051,18 @@ async function NEYNAR() {
|
|
|
17919
18051
|
|
|
17920
18052
|
const url = `https://api.neynar.com/v2/farcaster/followers?fid=${fid}`;
|
|
17921
18053
|
|
|
17922
|
-
const
|
|
17923
|
-
|
|
17924
|
-
|
|
17925
|
-
|
|
17926
|
-
|
|
18054
|
+
const { URL: finalUrl, HEADERS } = getUrlAndHeaders({
|
|
18055
|
+
url: url.toString(), serviceName: 'Firefly',
|
|
18056
|
+
headers: {
|
|
18057
|
+
'x-api-key': apiKey,
|
|
18058
|
+
'x-neynar-experimental': 'false'
|
|
18059
|
+
}
|
|
18060
|
+
|
|
18061
|
+
});
|
|
18062
|
+
|
|
18063
|
+
const response = await fetch(finalUrl, {
|
|
18064
|
+
method: 'GET',
|
|
18065
|
+
headers: HEADERS,
|
|
17927
18066
|
});
|
|
17928
18067
|
if (!response.ok) {
|
|
17929
18068
|
throw new NetworkError(SERVICES_API_KEY.Neynar, response.status)
|
|
@@ -18058,27 +18197,28 @@ async function COINGECKO() {
|
|
|
18058
18197
|
break
|
|
18059
18198
|
}
|
|
18060
18199
|
case 'market': {
|
|
18061
|
-
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' };
|
|
18200
|
+
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' };
|
|
18062
18201
|
const _category = map[param1] || '';
|
|
18063
18202
|
const trend = param2 ? `&price_change_percentage=${param2}` : '';
|
|
18064
|
-
url = `https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&include_tokens=top&page=1&per_page=100${_category
|
|
18203
|
+
url = `https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&include_tokens=top&page=1&per_page=100${_category ? `&category=${_category}` : ''}${trend}`;
|
|
18065
18204
|
break
|
|
18066
18205
|
}
|
|
18067
18206
|
case 'stablecoins': {
|
|
18068
|
-
const _category = param1==='all'? 'stablecoins' : param1;
|
|
18207
|
+
const _category = param1 === 'all' ? 'stablecoins' : param1;
|
|
18069
18208
|
const trend = param2 ? `&price_change_percentage=${param2}` : '';
|
|
18070
18209
|
url = `https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&category=${_category}&order=market_cap_desc&page=1&per_page=100${trend}`;
|
|
18071
18210
|
break
|
|
18072
18211
|
}
|
|
18073
18212
|
case 'derivatives': {
|
|
18074
|
-
url = (!param1 || param1==='all')
|
|
18213
|
+
url = (!param1 || param1 === 'all')
|
|
18075
18214
|
? 'https://api.coingecko.com/api/v3/derivatives'
|
|
18076
18215
|
: `https://api.coingecko.com/api/v3/derivatives/exchanges/${param1}?include_tickers=all`;
|
|
18077
18216
|
break
|
|
18078
18217
|
}
|
|
18079
18218
|
}
|
|
18219
|
+
const {URL: finalUrl, HEADERS} = getUrlAndHeaders({url, serviceName: 'Coingecko', headers});
|
|
18080
18220
|
|
|
18081
|
-
const res = await fetch(
|
|
18221
|
+
const res = await fetch(finalUrl, { headers: HEADERS });
|
|
18082
18222
|
const json = await res.json();
|
|
18083
18223
|
if (!res.ok) {
|
|
18084
18224
|
const msg = json?.status?.error_message || '';
|
|
@@ -18086,17 +18226,17 @@ async function COINGECKO() {
|
|
|
18086
18226
|
throw new NetworkError(SERVICES_API_KEY.Coingecko, res.status)
|
|
18087
18227
|
}
|
|
18088
18228
|
|
|
18089
|
-
if (category==='price') {
|
|
18229
|
+
if (category === 'price') {
|
|
18090
18230
|
const out = {};
|
|
18091
18231
|
for (const [token, prices] of Object.entries(json))
|
|
18092
|
-
for (const [cur,val] of Object.entries(prices))
|
|
18093
|
-
out[`${token.charAt(0).toUpperCase()+token.slice(1)}_${cur.toUpperCase()}`]=val;
|
|
18232
|
+
for (const [cur, val] of Object.entries(prices))
|
|
18233
|
+
out[`${token.charAt(0).toUpperCase() + token.slice(1)}_${cur.toUpperCase()}`] = val;
|
|
18094
18234
|
return [out]
|
|
18095
18235
|
}
|
|
18096
18236
|
|
|
18097
18237
|
const data = Array.isArray(json) ? json : [json];
|
|
18098
|
-
return data.map(item=>{
|
|
18099
|
-
const flat={};
|
|
18238
|
+
return data.map(item => {
|
|
18239
|
+
const flat = {};
|
|
18100
18240
|
for (const [key, value] of Object.entries(item)) {
|
|
18101
18241
|
if (typeof value !== 'object' || value === null) {
|
|
18102
18242
|
flat[key] = value;
|
|
@@ -18104,22 +18244,24 @@ async function COINGECKO() {
|
|
|
18104
18244
|
}
|
|
18105
18245
|
return flat
|
|
18106
18246
|
})
|
|
18107
|
-
} catch(err) {
|
|
18108
|
-
return errorMessageHandler(err,'COINGECKO')
|
|
18247
|
+
} catch (err) {
|
|
18248
|
+
return errorMessageHandler(err, 'COINGECKO')
|
|
18109
18249
|
}
|
|
18110
18250
|
}
|
|
18111
18251
|
|
|
18112
18252
|
async function EOA() {
|
|
18253
|
+
console.log('EOA');
|
|
18113
18254
|
try {
|
|
18114
18255
|
const [addresses, category, chains, startTime, endTime, page = 1, offset = 10] =
|
|
18115
18256
|
argsToArray(arguments);
|
|
18116
18257
|
validateParams(eoaParamsSchema, { addresses, category, chains, startTime, endTime, page, offset });
|
|
18117
18258
|
|
|
18118
18259
|
const apiKey = window.localStorage.getItem(SERVICES_API_KEY.Etherscan);
|
|
18260
|
+
console.log('apiKey', apiKey);
|
|
18119
18261
|
if (!apiKey) throw new MissingApiKeyError(SERVICES_API_KEY.Etherscan)
|
|
18120
18262
|
|
|
18121
|
-
const INPUTS = addresses.split(',').map(s=>s.trim()).filter(Boolean);
|
|
18122
|
-
const CHAINS = chains.split(',').map(s=>s.trim()).filter(Boolean);
|
|
18263
|
+
const INPUTS = addresses.split(',').map(s => s.trim()).filter(Boolean);
|
|
18264
|
+
const CHAINS = chains.split(',').map(s => s.trim()).filter(Boolean);
|
|
18123
18265
|
|
|
18124
18266
|
const ADDRESS_MAP = {};
|
|
18125
18267
|
for (const inp of INPUTS) {
|
|
@@ -18133,10 +18275,16 @@ async function EOA() {
|
|
|
18133
18275
|
}
|
|
18134
18276
|
}
|
|
18135
18277
|
const ADDRS = Object.keys(ADDRESS_MAP);
|
|
18278
|
+
console.log('ADDRS', ADDRS);
|
|
18136
18279
|
const out = [];
|
|
18137
18280
|
|
|
18138
18281
|
async function fetchJSON(url) {
|
|
18139
|
-
const
|
|
18282
|
+
const { URL: finalUrl, HEADERS } = getUrlAndHeaders({ url, serviceName: 'Etherscan', headers: {} });
|
|
18283
|
+
console.log('finalUrl', finalUrl, HEADERS);
|
|
18284
|
+
const res = await fetch(finalUrl, {
|
|
18285
|
+
method: 'GET',
|
|
18286
|
+
headers: HEADERS,
|
|
18287
|
+
});
|
|
18140
18288
|
if (!res.ok) throw new NetworkError(SERVICES_API_KEY.Etherscan, res.status)
|
|
18141
18289
|
const json = await res.json();
|
|
18142
18290
|
|
|
@@ -18149,32 +18297,38 @@ async function EOA() {
|
|
|
18149
18297
|
|
|
18150
18298
|
|
|
18151
18299
|
for (const chain of CHAINS) {
|
|
18300
|
+
console.log('chain', chain);
|
|
18152
18301
|
const chainId = CHAIN_ID_MAP[chain];
|
|
18153
18302
|
if (!chainId) throw new ValidationError(`Invalid chain: ${chain}`)
|
|
18303
|
+
console.log('chain', chain);
|
|
18304
|
+
|
|
18154
18305
|
|
|
18155
18306
|
if (category === 'balance') {
|
|
18307
|
+
console.log('balance');
|
|
18156
18308
|
// chunk 20
|
|
18157
|
-
for (let i=0; i<ADDRS.length; i+=20) {
|
|
18158
|
-
const slice = ADDRS.slice(i,i+20).join(',');
|
|
18309
|
+
for (let i = 0; i < ADDRS.length; i += 20) {
|
|
18310
|
+
const slice = ADDRS.slice(i, i + 20).join(',');
|
|
18159
18311
|
const url =
|
|
18160
|
-
`https://api.etherscan.io/v2/api?chainid=${chainId}
|
|
18161
|
-
`&module=account&action=addresstokenbalance&address=${slice}
|
|
18312
|
+
`https://api.etherscan.io/v2/api?chainid=${chainId}` +
|
|
18313
|
+
`&module=account&action=addresstokenbalance&address=${slice}` +
|
|
18162
18314
|
`&page=${page}&offset=${offset}&apikey=${apiKey}`;
|
|
18163
18315
|
const data = await fetchJSON(url);
|
|
18164
18316
|
if (!Array.isArray(data)) return data
|
|
18165
|
-
data.forEach((item, idx) => out.push({ chain, address: ADDRS[i+idx], name: ADDRESS_MAP[ADDRS[i+idx]], ...item }));
|
|
18317
|
+
data.forEach((item, idx) => out.push({ chain, address: ADDRS[i + idx], name: ADDRESS_MAP[ADDRS[i + idx]], ...item }));
|
|
18166
18318
|
}
|
|
18167
18319
|
} else {
|
|
18168
18320
|
// txns
|
|
18321
|
+
console.log('startTime', startTime, 'endTime', endTime, chain, apiKey);
|
|
18169
18322
|
const sb = await fromTimestampToBlock.fromTimeStampToBlock(toTimestamp(startTime), chain, apiKey);
|
|
18170
18323
|
const eb = await fromTimestampToBlock.fromTimeStampToBlock(toTimestamp(endTime), chain, apiKey);
|
|
18324
|
+
console.log('sb', sb, 'eb', eb);
|
|
18171
18325
|
if (!sb) throw new ValidationError(`Invalid startTime: ${startTime}`)
|
|
18172
18326
|
if (!eb) throw new ValidationError(`Invalid endTime: ${endTime}`)
|
|
18173
18327
|
for (const addr of ADDRS) {
|
|
18174
18328
|
const url =
|
|
18175
|
-
`https://api.etherscan.io/v2/api?chainid=${chainId}
|
|
18176
|
-
`&module=account&action=tokentx&address=${addr}
|
|
18177
|
-
`&startblock=${sb}&endblock=${eb}
|
|
18329
|
+
`https://api.etherscan.io/v2/api?chainid=${chainId}` +
|
|
18330
|
+
`&module=account&action=tokentx&address=${addr}` +
|
|
18331
|
+
`&startblock=${sb}&endblock=${eb}` +
|
|
18178
18332
|
`&page=${page}&offset=${offset}&sort=asc&apikey=${apiKey}`;
|
|
18179
18333
|
const data = await fetchJSON(url);
|
|
18180
18334
|
if (!Array.isArray(data)) return data
|
|
@@ -18218,8 +18372,8 @@ async function SAFE() {
|
|
|
18218
18372
|
|
|
18219
18373
|
const url = `https://api.safe.global/tx-service/${chainId}/api/v2/safes/${resolved}/multisig-transactions?limit=${limit}&offset=${offset}`;
|
|
18220
18374
|
|
|
18221
|
-
|
|
18222
|
-
const res = await fetch(
|
|
18375
|
+
const { URL: finalUrl, HEADERS } = getUrlAndHeaders({ url, serviceName: 'Etherscan', headers: { Authorization: `Bearer ${apiKey}` } });
|
|
18376
|
+
const res = await fetch(finalUrl, { headers: HEADERS });
|
|
18223
18377
|
if (!res.ok) throw new NetworkError(SERVICES_API_KEY.Safe, res.status)
|
|
18224
18378
|
const json = await res.json();
|
|
18225
18379
|
|
|
@@ -18249,20 +18403,20 @@ async function DEFILLAMA() {
|
|
|
18249
18403
|
|
|
18250
18404
|
switch (category) {
|
|
18251
18405
|
case 'protocols':
|
|
18252
|
-
json = Array.isArray(json) ? json.slice(0,500) : [];
|
|
18406
|
+
json = Array.isArray(json) ? json.slice(0, 500) : [];
|
|
18253
18407
|
break
|
|
18254
18408
|
case 'yields':
|
|
18255
|
-
json = Array.isArray(json.data) ? json.data.slice(0,500) : [];
|
|
18409
|
+
json = Array.isArray(json.data) ? json.data.slice(0, 500) : [];
|
|
18256
18410
|
break
|
|
18257
18411
|
case 'dex':
|
|
18258
18412
|
case 'fees':
|
|
18259
|
-
json = Array.isArray(json.protocols) ? json.protocols.slice(0,500) : [];
|
|
18413
|
+
json = Array.isArray(json.protocols) ? json.protocols.slice(0, 500) : [];
|
|
18260
18414
|
break
|
|
18261
18415
|
}
|
|
18262
18416
|
|
|
18263
18417
|
return (Array.isArray(json) ? json : [json]).map(item => {
|
|
18264
18418
|
const out = {};
|
|
18265
|
-
for (const [k,v] of Object.entries(item)) {
|
|
18419
|
+
for (const [k, v] of Object.entries(item)) {
|
|
18266
18420
|
if (v === null || typeof v !== 'object') out[k] = v;
|
|
18267
18421
|
}
|
|
18268
18422
|
return out
|
|
@@ -18298,7 +18452,7 @@ async function UNISWAP() {
|
|
|
18298
18452
|
// flatten nested
|
|
18299
18453
|
return json.map(item => {
|
|
18300
18454
|
const flat = {};
|
|
18301
|
-
Object.entries(item).forEach(([k,v]) => {
|
|
18455
|
+
Object.entries(item).forEach(([k, v]) => {
|
|
18302
18456
|
if (v === null || typeof v !== 'object') flat[k] = v;
|
|
18303
18457
|
});
|
|
18304
18458
|
return flat
|