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