@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/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
- 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&timestamp=${timestamp}&closest=before&apikey=${apiKey}&chainId=${chainId}`;
13151
- const res = await fetch(url);
13152
- const json = await res.json();
13153
- return parseInt(json.result);
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&timestamp=${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 res = await fetch(url);
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 res = await fetch(url, {
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
- const [platform, contentType, identifier, start = 0, end = 10] = argsToArray(arguments);
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
- url.searchParams.set('type', fireFlyPlaformType[platform][contentType]);
17604
- url.searchParams.set('start', String(start));
17605
- url.searchParams.set('end', String(end));
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 response = await fetch(url.toString(), {
17608
- headers: { 'x-api-key': apiKey }
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: 'lensid',
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', String(end));
17797
+ url.searchParams.set('end', String(end));
17672
17798
 
17673
- const response = await fetch(url.toString(), {
17674
- headers: { 'x-api-key': apiKey },
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
- posts: 'farcasterid',
17728
- replies: 'farcasterpostid',
17729
- channels: 'farcasterchannels',
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', String(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(url.toString(), {
17736
- headers: { 'x-api-key': apiKey },
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
- validateParams(baseParamsSchema, { type, address, startDate, endDate, page, limit });
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
- return errorMessageHandler(error, 'BASE')
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
- const neynarParamsSchema = objectType({
17907
- username: stringType().nonempty()
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 response = await fetch(url, {
17923
- headers: {
17924
- 'x-api-key': apiKey,
17925
- 'x-neynar-experimental': 'false',
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?`&category=${_category}`:''}${trend}`;
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(url, { headers });
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 res = await fetch(url);
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(url, { headers: { Authorization: `Bearer ${apiKey}` } });
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