@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/esm/index.mjs
CHANGED
|
@@ -13142,15 +13142,130 @@ 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
|
+
}
|
|
13248
|
+
};
|
|
13249
|
+
}
|
|
13250
|
+
|
|
13145
13251
|
const fromTimeStampToBlock = async (timestamp, chain, apiKey) => {
|
|
13146
|
-
|
|
13147
|
-
|
|
13148
|
-
|
|
13149
|
-
|
|
13150
|
-
|
|
13151
|
-
|
|
13252
|
+
console.log('fromTimeStampToBlock', timestamp, chain, apiKey);
|
|
13253
|
+
if (!timestamp || !chain || !apiKey) return
|
|
13254
|
+
const chainId = CHAIN_ID_MAP[chain];
|
|
13255
|
+
console.log('chainId', chainId);
|
|
13256
|
+
const url = `https://api.etherscan.io/v2/api?module=block&action=getblocknobytime×tamp=${timestamp}&closest=before&apikey=${apiKey}&chainId=${chainId}`;
|
|
13257
|
+
console.log('url', url, getUrlAndHeaders);
|
|
13258
|
+
const { URL: finalUrl, HEADERS } = getUrlAndHeaders({ url, serviceName: 'Etherscan', headers: {} });
|
|
13259
|
+
console.log('finalUrl', finalUrl, HEADERS);
|
|
13260
|
+
const res = await fetch(finalUrl, {
|
|
13261
|
+
method: 'GET',
|
|
13262
|
+
headers: HEADERS,
|
|
13263
|
+
});
|
|
13264
|
+
console.log('res', res, finalUrl, HEADERS);
|
|
13265
|
+
const json = await res.json();
|
|
13266
|
+
return parseInt(json.result);
|
|
13152
13267
|
|
|
13153
|
-
|
|
13268
|
+
};
|
|
13154
13269
|
|
|
13155
13270
|
var fromTimestampToBlock = {
|
|
13156
13271
|
fromTimeStampToBlock
|
|
@@ -13308,7 +13423,11 @@ async function handleScanRequest({
|
|
|
13308
13423
|
}
|
|
13309
13424
|
url += `&page=${page}&offset=${offset}`;
|
|
13310
13425
|
}
|
|
13311
|
-
const
|
|
13426
|
+
const { URL: finalUrl, HEADERS } = getUrlAndHeaders({url, serviceName: 'Etherscan', headers: {}});
|
|
13427
|
+
const res = await fetch(finalUrl, {
|
|
13428
|
+
method: 'GET',
|
|
13429
|
+
headers: HEADERS,
|
|
13430
|
+
});
|
|
13312
13431
|
if (!res.ok) {
|
|
13313
13432
|
throw new NetworkError(apiInfo.apiKeyName, res.status)
|
|
13314
13433
|
}
|
|
@@ -13327,14 +13446,19 @@ async function handleScanRequest({
|
|
|
13327
13446
|
}
|
|
13328
13447
|
|
|
13329
13448
|
const fromUsernameToFid = async (username, apiKey) => {
|
|
13330
|
-
if(!username) return null
|
|
13449
|
+
if (!username) return null
|
|
13331
13450
|
const url = `https://api.neynar.com/v2/farcaster/user/search/?q=${username}&limit=5`;
|
|
13332
|
-
const
|
|
13333
|
-
headers: {
|
|
13451
|
+
const { URL: finalUrl, HEADERS } = getUrlAndHeaders({
|
|
13452
|
+
url, serviceName: 'Neynar', headers: {
|
|
13334
13453
|
'x-api-key': apiKey,
|
|
13335
13454
|
'x-neynar-experimental': 'false'
|
|
13336
13455
|
}
|
|
13337
13456
|
});
|
|
13457
|
+
|
|
13458
|
+
const res = await fetch(finalUrl, {
|
|
13459
|
+
method: 'GET',
|
|
13460
|
+
headers: HEADERS,
|
|
13461
|
+
});
|
|
13338
13462
|
const json = await res.json();
|
|
13339
13463
|
const users = json.result ? json.result.users : [];
|
|
13340
13464
|
const user = users.find(user => user.username === username);
|
|
@@ -17574,9 +17698,9 @@ const aaveParamsSchema = objectType({
|
|
|
17574
17698
|
|
|
17575
17699
|
async function FIREFLY() {
|
|
17576
17700
|
try {
|
|
17577
|
-
|
|
17701
|
+
const [platform, contentType, identifier, start = 0, end = 10] = argsToArray(arguments);
|
|
17578
17702
|
|
|
17579
|
-
validateParams(fireflyParamsSchema, {
|
|
17703
|
+
validateParams(fireflyParamsSchema, {
|
|
17580
17704
|
platform,
|
|
17581
17705
|
contentType,
|
|
17582
17706
|
identifier,
|
|
@@ -17598,12 +17722,14 @@ validateParams(fireflyParamsSchema, {
|
|
|
17598
17722
|
.filter(Boolean)
|
|
17599
17723
|
.join(',')
|
|
17600
17724
|
);
|
|
17601
|
-
|
|
17602
|
-
|
|
17603
|
-
|
|
17725
|
+
url.searchParams.set('type', fireFlyPlaformType[platform][contentType]);
|
|
17726
|
+
url.searchParams.set('start', String(start));
|
|
17727
|
+
url.searchParams.set('end', String(end));
|
|
17604
17728
|
|
|
17605
|
-
const
|
|
17606
|
-
|
|
17729
|
+
const { URL: finalUrl, HEADERS } = getUrlAndHeaders({ url: url.toString(), serviceName: 'Firefly', headers: { 'x-api-key': apiKey } });
|
|
17730
|
+
const response = await fetch(finalUrl, {
|
|
17731
|
+
method: 'GET',
|
|
17732
|
+
headers: HEADERS,
|
|
17607
17733
|
});
|
|
17608
17734
|
if (!response.ok) {
|
|
17609
17735
|
throw new NetworkError(SERVICES_API_KEY.Firefly, response.status)
|
|
@@ -17661,15 +17787,18 @@ async function LENS() {
|
|
|
17661
17787
|
.join(',')
|
|
17662
17788
|
);
|
|
17663
17789
|
const typeMap = {
|
|
17664
|
-
posts:
|
|
17790
|
+
posts: 'lensid',
|
|
17665
17791
|
replies: 'lenspostid',
|
|
17666
17792
|
};
|
|
17667
17793
|
url.searchParams.set('type', typeMap[contentType]);
|
|
17668
17794
|
url.searchParams.set('start', String(start));
|
|
17669
|
-
url.searchParams.set('end',
|
|
17795
|
+
url.searchParams.set('end', String(end));
|
|
17670
17796
|
|
|
17671
|
-
const
|
|
17672
|
-
|
|
17797
|
+
const { URL: finalUrl, HEADERS } = getUrlAndHeaders({ url: url.toString(), serviceName: 'Firefly', headers: { 'x-api-key': apiKey } });
|
|
17798
|
+
|
|
17799
|
+
const response = await fetch(finalUrl, {
|
|
17800
|
+
method: 'GET',
|
|
17801
|
+
headers: HEADERS,
|
|
17673
17802
|
});
|
|
17674
17803
|
if (!response.ok) {
|
|
17675
17804
|
throw new NetworkError(SERVICES_API_KEY.Firefly, response.status)
|
|
@@ -17696,7 +17825,7 @@ async function FARCASTER() {
|
|
|
17696
17825
|
try {
|
|
17697
17826
|
const [contentType, identifier, start = 0, end = 10] =
|
|
17698
17827
|
argsToArray(arguments);
|
|
17699
|
-
validateParams(farcasterParamsSchema, {
|
|
17828
|
+
validateParams(farcasterParamsSchema, {
|
|
17700
17829
|
contentType,
|
|
17701
17830
|
identifier,
|
|
17702
17831
|
start,
|
|
@@ -17722,16 +17851,19 @@ validateParams(farcasterParamsSchema, {
|
|
|
17722
17851
|
.join(',')
|
|
17723
17852
|
);
|
|
17724
17853
|
const typeMap = {
|
|
17725
|
-
|
|
17726
|
-
|
|
17727
|
-
|
|
17728
|
-
};
|
|
17854
|
+
posts: 'farcasterid',
|
|
17855
|
+
replies: 'farcasterpostid',
|
|
17856
|
+
channels: 'farcasterchannels',
|
|
17857
|
+
};
|
|
17729
17858
|
url.searchParams.set('type', typeMap[contentType]);
|
|
17730
17859
|
url.searchParams.set('start', String(start));
|
|
17731
|
-
url.searchParams.set('end',
|
|
17860
|
+
url.searchParams.set('end', String(end));
|
|
17861
|
+
|
|
17862
|
+
const { URL: finalUrl, HEADERS } = getUrlAndHeaders({ url: url.toString(), serviceName: 'Firefly', headers: { 'x-api-key': apiKey } });
|
|
17732
17863
|
|
|
17733
|
-
const response = await fetch(
|
|
17734
|
-
|
|
17864
|
+
const response = await fetch(finalUrl, {
|
|
17865
|
+
method: 'GET',
|
|
17866
|
+
headers: HEADERS,
|
|
17735
17867
|
});
|
|
17736
17868
|
if (!response.ok) {
|
|
17737
17869
|
throw new NetworkError(
|
|
@@ -17840,12 +17972,12 @@ async function BLOCKSCOUT() {
|
|
|
17840
17972
|
}
|
|
17841
17973
|
|
|
17842
17974
|
async function BASE() {
|
|
17843
|
-
try {
|
|
17975
|
+
try {
|
|
17844
17976
|
const [type, address, startDate, endDate, page, limit] = argsToArray(arguments);
|
|
17845
|
-
|
|
17977
|
+
validateParams(baseParamsSchema, { type, address, startDate, endDate, page, limit });
|
|
17846
17978
|
const API_KEY = window.localStorage.getItem(SERVICES_API_KEY.Basescan);
|
|
17847
17979
|
if (!API_KEY) throw new MissingApiKeyError(SERVICES_API_KEY.Basescan)
|
|
17848
|
-
|
|
17980
|
+
|
|
17849
17981
|
return await handleScanRequest({
|
|
17850
17982
|
type,
|
|
17851
17983
|
address,
|
|
@@ -17858,9 +17990,9 @@ try {
|
|
|
17858
17990
|
chainId: CHAIN_ID_MAP.base,
|
|
17859
17991
|
network: 'base'
|
|
17860
17992
|
})
|
|
17861
|
-
} catch (error) {
|
|
17862
|
-
|
|
17863
|
-
}
|
|
17993
|
+
} catch (error) {
|
|
17994
|
+
return errorMessageHandler(error, 'BASE')
|
|
17995
|
+
}
|
|
17864
17996
|
}
|
|
17865
17997
|
async function GNOSIS() {
|
|
17866
17998
|
try {
|
|
@@ -17901,9 +18033,9 @@ async function GNOSIS() {
|
|
|
17901
18033
|
|
|
17902
18034
|
async function NEYNAR() {
|
|
17903
18035
|
try {
|
|
17904
|
-
|
|
17905
|
-
|
|
17906
|
-
});
|
|
18036
|
+
const neynarParamsSchema = objectType({
|
|
18037
|
+
username: stringType().nonempty()
|
|
18038
|
+
});
|
|
17907
18039
|
|
|
17908
18040
|
const [username] = argsToArray(arguments);
|
|
17909
18041
|
|
|
@@ -17917,11 +18049,18 @@ async function NEYNAR() {
|
|
|
17917
18049
|
|
|
17918
18050
|
const url = `https://api.neynar.com/v2/farcaster/followers?fid=${fid}`;
|
|
17919
18051
|
|
|
17920
|
-
const
|
|
17921
|
-
|
|
17922
|
-
|
|
17923
|
-
|
|
17924
|
-
|
|
18052
|
+
const { URL: finalUrl, HEADERS } = getUrlAndHeaders({
|
|
18053
|
+
url: url.toString(), serviceName: 'Firefly',
|
|
18054
|
+
headers: {
|
|
18055
|
+
'x-api-key': apiKey,
|
|
18056
|
+
'x-neynar-experimental': 'false'
|
|
18057
|
+
}
|
|
18058
|
+
|
|
18059
|
+
});
|
|
18060
|
+
|
|
18061
|
+
const response = await fetch(finalUrl, {
|
|
18062
|
+
method: 'GET',
|
|
18063
|
+
headers: HEADERS,
|
|
17925
18064
|
});
|
|
17926
18065
|
if (!response.ok) {
|
|
17927
18066
|
throw new NetworkError(SERVICES_API_KEY.Neynar, response.status)
|
|
@@ -18056,27 +18195,28 @@ async function COINGECKO() {
|
|
|
18056
18195
|
break
|
|
18057
18196
|
}
|
|
18058
18197
|
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' };
|
|
18198
|
+
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
18199
|
const _category = map[param1] || '';
|
|
18061
18200
|
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
|
|
18201
|
+
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
18202
|
break
|
|
18064
18203
|
}
|
|
18065
18204
|
case 'stablecoins': {
|
|
18066
|
-
const _category = param1==='all'? 'stablecoins' : param1;
|
|
18205
|
+
const _category = param1 === 'all' ? 'stablecoins' : param1;
|
|
18067
18206
|
const trend = param2 ? `&price_change_percentage=${param2}` : '';
|
|
18068
18207
|
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
18208
|
break
|
|
18070
18209
|
}
|
|
18071
18210
|
case 'derivatives': {
|
|
18072
|
-
url = (!param1 || param1==='all')
|
|
18211
|
+
url = (!param1 || param1 === 'all')
|
|
18073
18212
|
? 'https://api.coingecko.com/api/v3/derivatives'
|
|
18074
18213
|
: `https://api.coingecko.com/api/v3/derivatives/exchanges/${param1}?include_tickers=all`;
|
|
18075
18214
|
break
|
|
18076
18215
|
}
|
|
18077
18216
|
}
|
|
18217
|
+
const {URL: finalUrl, HEADERS} = getUrlAndHeaders({url, serviceName: 'Coingecko', headers});
|
|
18078
18218
|
|
|
18079
|
-
const res = await fetch(
|
|
18219
|
+
const res = await fetch(finalUrl, { headers: HEADERS });
|
|
18080
18220
|
const json = await res.json();
|
|
18081
18221
|
if (!res.ok) {
|
|
18082
18222
|
const msg = json?.status?.error_message || '';
|
|
@@ -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