@fileverse-dev/formulajs 4.4.11-mod-69 → 4.4.11-mod-68-patch-1

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/esm/index.mjs CHANGED
@@ -13142,15 +13142,126 @@ 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, apiKeyName, 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
- if(!timestamp || !chain || !apiKey) return
13147
- const chainId = CHAIN_ID_MAP[chain];
13148
- const url = `https://api.etherscan.io/v2/api?module=block&action=getblocknobytime&timestamp=${timestamp}&closest=before&apikey=${apiKey}&chainId=${chainId}`;
13149
- const res = await fetch(url);
13150
- const json = await res.json();
13151
- return parseInt(json.result);
13253
+ if (!timestamp || !chain || !apiKey) return
13254
+ const chainId = CHAIN_ID_MAP[chain];
13255
+ const url = `https://api.etherscan.io/v2/api?module=block&action=getblocknobytime&timestamp=${timestamp}&closest=before&apikey=${apiKey}&chainId=${chainId}`;
13256
+ const { URL: finalUrl, HEADERS } = getUrlAndHeaders(url);
13257
+ const res = await fetch(finalUrl, {
13258
+ method: 'GET',
13259
+ headers: HEADERS,
13260
+ });
13261
+ const json = await res.json();
13262
+ return parseInt(json.result);
13152
13263
 
13153
- };
13264
+ };
13154
13265
 
13155
13266
  var fromTimestampToBlock = {
13156
13267
  fromTimeStampToBlock
@@ -13287,14 +13398,13 @@ async function handleScanRequest({
13287
13398
  'all-txns': 'txlist',
13288
13399
  'token-txns': 'tokentx',
13289
13400
  'nft-txns': 'tokennfttx',
13290
- 'gas': 'gasoracle'
13401
+ gas: 'gastracker'
13291
13402
  };
13292
13403
 
13293
13404
  const action = ACTION_MAP[type];
13294
13405
  if (!action) throw new ValidationError(`Invalid type: ${type}`)
13295
13406
 
13296
- const module = action === 'gasoracle' ? 'gastracker' : 'account';
13297
- let url = `${baseUrl}?chainid=${chainId}&module=${module}&action=${action}&apikey=${apiKey}`;
13407
+ let url = `${baseUrl}?chainid=${chainId}&module=account&action=${action}&apikey=${apiKey}`;
13298
13408
 
13299
13409
  if (['all-txns', 'token-txns', 'nft-txns'].includes(type)) {
13300
13410
  url += `&address=${address}&startblock=0&endblock=99999999&sort=asc`;
@@ -13308,7 +13418,11 @@ async function handleScanRequest({
13308
13418
  }
13309
13419
  url += `&page=${page}&offset=${offset}`;
13310
13420
  }
13311
- const res = await fetch(url);
13421
+ const { URL: finalUrl, HEADERS } = getUrlAndHeaders({url, serviceName: 'Etherscan', headers: {}});
13422
+ const res = await fetch(finalUrl, {
13423
+ method: 'GET',
13424
+ headers: HEADERS,
13425
+ });
13312
13426
  if (!res.ok) {
13313
13427
  throw new NetworkError(apiInfo.apiKeyName, res.status)
13314
13428
  }
@@ -13327,14 +13441,19 @@ async function handleScanRequest({
13327
13441
  }
13328
13442
 
13329
13443
  const fromUsernameToFid = async (username, apiKey) => {
13330
- if(!username) return null
13444
+ if (!username) return null
13331
13445
  const url = `https://api.neynar.com/v2/farcaster/user/search/?q=${username}&limit=5`;
13332
- const res = await fetch(url, {
13333
- headers: {
13446
+ const { URL: finalUrl, HEADERS } = getUrlAndHeaders({
13447
+ url, serviceName: 'Neynar', headers: {
13334
13448
  'x-api-key': apiKey,
13335
13449
  'x-neynar-experimental': 'false'
13336
13450
  }
13337
13451
  });
13452
+
13453
+ const res = await fetch(finalUrl, {
13454
+ method: 'GET',
13455
+ headers: HEADERS,
13456
+ });
13338
13457
  const json = await res.json();
13339
13458
  const users = json.result ? json.result.users : [];
13340
13459
  const user = users.find(user => user.username === username);
@@ -17347,7 +17466,7 @@ const farcasterSchema = objectType({
17347
17466
  contentType: enumType(['posts', 'replies', 'channels']),
17348
17467
  identifier: stringType().nonempty(),
17349
17468
  start: numberType().int().nonnegative().default(0),
17350
- end: numberType().int().nonnegative().max(MAX_PAGE_LIMIT, {message: `"end" must be less than or equal to ${MAX_PAGE_LIMIT}`}).default(10),
17469
+ end: numberType().int().nonnegative().max(MAX_PAGE_LIMIT).default(10),
17351
17470
  });
17352
17471
 
17353
17472
  const lensSchema = objectType({
@@ -17355,7 +17474,7 @@ const lensSchema = objectType({
17355
17474
  contentType: enumType(['posts', 'replies']),
17356
17475
  identifier: stringType().nonempty(),
17357
17476
  start: numberType().int().nonnegative().default(0),
17358
- end: numberType().int().nonnegative().max(MAX_PAGE_LIMIT, {message: `"end" must be less than or equal to ${MAX_PAGE_LIMIT}`}).default(10),
17477
+ end: numberType().int().nonnegative().max(MAX_PAGE_LIMIT).default(10),
17359
17478
  });
17360
17479
 
17361
17480
  const fireflyParamsSchema = discriminatedUnionType('platform', [
@@ -17378,33 +17497,31 @@ const lensParamsSchema = objectType({
17378
17497
  contentType: enumType(['posts', 'replies']),
17379
17498
  identifier: stringType().nonempty(),
17380
17499
  start: numberType().int().nonnegative().default(0),
17381
- end: numberType().int().nonnegative().max(MAX_PAGE_LIMIT, {message: `"end" must be less than or equal to ${MAX_PAGE_LIMIT}`}).default(10),
17500
+ end: numberType().int().nonnegative().max(MAX_PAGE_LIMIT).default(10),
17382
17501
  });
17383
17502
 
17384
17503
  const farcasterParamsSchema = objectType({
17385
17504
  contentType: enumType(['posts', 'replies', 'channels']),
17386
17505
  identifier: stringType().nonempty(),
17387
17506
  start: numberType().int().nonnegative().default(0),
17388
- end: numberType().int().nonnegative().max(MAX_PAGE_LIMIT, {message: `"end" must be less than or equal to ${MAX_PAGE_LIMIT}`}).default(10),
17507
+ end: numberType().int().nonnegative().max(MAX_PAGE_LIMIT).default(10),
17389
17508
  });
17390
17509
 
17391
17510
  const dateStringToTimestamp = (val) => {
17392
- const [dd, mm, yyyy] = val.split('/');
17393
- const date = new Date(`${yyyy}-${mm.padStart(2, '0')}-${dd.padStart(2, '0')}`);
17394
- const timestamp = date.getTime();
17395
- return isNaN(timestamp) ? NaN : Math.floor(timestamp / 1000);
17511
+ const [mm, dd, yyyy] = val.split('/');
17512
+ return Math.floor(new Date(`${yyyy}-${mm}-${dd}`).getTime() / 1000);
17396
17513
  };
17397
17514
 
17398
17515
  /**
17399
- * Accepts either a UNIX timestamp number or a DD/MM/YYYY string,
17516
+ * Accepts either a UNIXtimestamp number or a MM/DD/YYYY string,
17400
17517
  * and always returns a nonnegative integer timestamp.
17401
17518
  */
17402
17519
  const dateOrTimestamp = preprocessType(
17403
17520
  (val) =>
17404
- typeof val === 'string' && /^\d{1,2}\/\d{1,2}\/\d{4}$/.test(val)
17521
+ typeof val === 'string' && /^\d{2}\/\d{2}\/\d{4}$/.test(val)
17405
17522
  ? dateStringToTimestamp(val)
17406
17523
  : val,
17407
- numberType({ invalid_type_error: 'Date must be a valid DD/MM/YYYY or timestamp' }).int('Date must be an integer timestamp').nonnegative('Date must be a nonnegative timestamp').refine((n) => !isNaN(n), { message: 'Invalid date format or value: expected DD/MM/YYYY' })
17524
+ numberType().int().nonnegative()
17408
17525
  );
17409
17526
 
17410
17527
  const blockscoutParamsSchema = objectType({
@@ -17414,7 +17531,7 @@ const blockscoutParamsSchema = objectType({
17414
17531
  startTimestamp: dateOrTimestamp.optional(),
17415
17532
  endTimestamp: dateOrTimestamp.optional(),
17416
17533
  page: numberType().int().nonnegative().default(1),
17417
- offset: numberType().int().nonnegative().max(MAX_PAGE_LIMIT, {message: `"offset" must be less than or equal to ${MAX_PAGE_LIMIT}`}).default(10),
17534
+ offset: numberType().int().nonnegative().max(MAX_PAGE_LIMIT).default(10),
17418
17535
  });
17419
17536
 
17420
17537
  const gasSchema$1 = objectType({
@@ -17422,7 +17539,7 @@ const gasSchema$1 = objectType({
17422
17539
  startDate: dateOrTimestamp.optional(),
17423
17540
  endDate: dateOrTimestamp.optional(),
17424
17541
  page: numberType().int().nonnegative().default(1),
17425
- limit: numberType().int().nonnegative().max(MAX_PAGE_LIMIT, {message: `"limit" must be less than or equal to ${MAX_PAGE_LIMIT}`}).default(10),
17542
+ limit: numberType().int().nonnegative().max(MAX_PAGE_LIMIT).default(10),
17426
17543
  });
17427
17544
 
17428
17545
  const txnSchema$1 = objectType({
@@ -17431,7 +17548,7 @@ const txnSchema$1 = objectType({
17431
17548
  startDate: dateOrTimestamp.optional(),
17432
17549
  endDate: dateOrTimestamp.optional(),
17433
17550
  page: numberType().int().nonnegative().default(1),
17434
- limit: numberType().int().nonnegative().max(MAX_PAGE_LIMIT, {message: `"limit" must be less than or equal to ${MAX_PAGE_LIMIT}`}).default(10),
17551
+ limit: numberType().int().nonnegative().max(MAX_PAGE_LIMIT).default(10),
17435
17552
  });
17436
17553
 
17437
17554
  const baseParamsSchema = discriminatedUnionType('type', [gasSchema$1, txnSchema$1]);
@@ -17441,7 +17558,7 @@ const gasSchema = objectType({
17441
17558
  startDate: dateOrTimestamp.optional(),
17442
17559
  endDate: dateOrTimestamp.optional(),
17443
17560
  page: numberType().int().nonnegative().default(1),
17444
- limit: numberType().int().nonnegative().max(MAX_PAGE_LIMIT, {message: `"limit" must be less than or equal to ${MAX_PAGE_LIMIT}`}).default(10),
17561
+ limit: numberType().int().nonnegative().max(MAX_PAGE_LIMIT).default(10),
17445
17562
  });
17446
17563
 
17447
17564
  const txnSchema = objectType({
@@ -17451,21 +17568,11 @@ const txnSchema = objectType({
17451
17568
  endDate: dateOrTimestamp.optional(),
17452
17569
  chain: enumType(['ethereum','base','gnosis']),
17453
17570
  page: numberType().int().nonnegative().default(1),
17454
- limit: numberType().int().nonnegative().max(MAX_PAGE_LIMIT, {message: `"limit" must be less than or equal to ${MAX_PAGE_LIMIT}`}).default(10),
17571
+ limit: numberType().int().nonnegative().max(MAX_PAGE_LIMIT).default(10),
17455
17572
  });
17456
17573
 
17457
17574
  const etherscanParamsSchema = discriminatedUnionType('type', [gasSchema, txnSchema]);
17458
17575
 
17459
- const allowedValues = ['1h', '24h', '7d'];
17460
- const param2Schema = stringType()
17461
- .refine((val) => {
17462
- const tokens = val.split(',').map((t) => t.trim().toLowerCase());
17463
- return tokens.some((token) =>
17464
- allowedValues.some((allowed) => token.includes(allowed))
17465
- );
17466
- }, {
17467
- message: "param2 must contain at least one of: '1h', '24h', '7d'",
17468
- }).optional();
17469
17576
  const priceSchema = objectType({
17470
17577
  category: literalType('price'),
17471
17578
  param1: stringType().nonempty(),
@@ -17475,13 +17582,13 @@ const marketEcosystems = ['all','base','meme','aiagents','bitcoin','ethereum','h
17475
17582
  const marketSchema = objectType({
17476
17583
  category: literalType('market'),
17477
17584
  param1: enumType(marketEcosystems),
17478
- param2: param2Schema,
17585
+ param2: enumType(['1h','24h','7d']).optional(),
17479
17586
  });
17480
17587
  const stablecoinsTypes = ['all','yield-bearing-stablecoins','crypto-backed-stablecoin'];
17481
17588
  const stablecoinsSchema = objectType({
17482
17589
  category: literalType('stablecoins'),
17483
17590
  param1: enumType(stablecoinsTypes),
17484
- param2: param2Schema,
17591
+ param2: enumType(['1h','24h','7d']).optional(),
17485
17592
  });
17486
17593
  const derivativesSchema = objectType({
17487
17594
  category: literalType('derivatives'),
@@ -17509,7 +17616,7 @@ const baseSchema = objectType({
17509
17616
  startTime: dateOrTimestamp.optional(),
17510
17617
  endTime: dateOrTimestamp.optional(),
17511
17618
  page: numberType().int().nonnegative().default(1),
17512
- offset: numberType().int().nonnegative().max(MAX_PAGE_LIMIT, {message: `"offset" must be less than or equal to ${MAX_PAGE_LIMIT}`}).default(10),
17619
+ offset: numberType().int().nonnegative().max(MAX_PAGE_LIMIT).default(10),
17513
17620
  });
17514
17621
 
17515
17622
  const eoaParamsSchema = preprocessType(
@@ -17538,7 +17645,7 @@ const safeParamsSchema = objectType({
17538
17645
  address: stringType().nonempty(),
17539
17646
  utility: literalType('txns'),
17540
17647
  chain: enumType(['ethereum','gnosis']),
17541
- limit: numberType().int().nonnegative().max(MAX_PAGE_LIMIT, {message: `"limit" must be less than or equal to ${MAX_PAGE_LIMIT}`}).default(10),
17648
+ limit: numberType().int().nonnegative().max(MAX_PAGE_LIMIT).default(10),
17542
17649
  offset: numberType().int().nonnegative().default(0),
17543
17650
  });
17544
17651
 
@@ -17574,9 +17681,9 @@ const aaveParamsSchema = objectType({
17574
17681
 
17575
17682
  async function FIREFLY() {
17576
17683
  try {
17577
- const [platform, contentType, identifier, start = 0, end = 10] = argsToArray(arguments);
17684
+ const [platform, contentType, identifier, start = 0, end = 10] = argsToArray(arguments);
17578
17685
 
17579
- validateParams(fireflyParamsSchema, {
17686
+ validateParams(fireflyParamsSchema, {
17580
17687
  platform,
17581
17688
  contentType,
17582
17689
  identifier,
@@ -17598,12 +17705,14 @@ validateParams(fireflyParamsSchema, {
17598
17705
  .filter(Boolean)
17599
17706
  .join(',')
17600
17707
  );
17601
- url.searchParams.set('type', fireFlyPlaformType[platform][contentType]);
17602
- url.searchParams.set('start', String(start));
17603
- url.searchParams.set('end', String(end));
17708
+ url.searchParams.set('type', fireFlyPlaformType[platform][contentType]);
17709
+ url.searchParams.set('start', String(start));
17710
+ url.searchParams.set('end', String(end));
17604
17711
 
17605
- const response = await fetch(url.toString(), {
17606
- headers: { 'x-api-key': apiKey }
17712
+ const { URL: finalUrl, HEADERS } = getUrlAndHeaders({ url: url.toString(), serviceName: 'Firefly', headers });
17713
+ const response = await fetch(finalUrl, {
17714
+ method: 'GET',
17715
+ headers: HEADERS,
17607
17716
  });
17608
17717
  if (!response.ok) {
17609
17718
  throw new NetworkError(SERVICES_API_KEY.Firefly, response.status)
@@ -17661,15 +17770,18 @@ async function LENS() {
17661
17770
  .join(',')
17662
17771
  );
17663
17772
  const typeMap = {
17664
- posts: 'lensid',
17773
+ posts: 'lensid',
17665
17774
  replies: 'lenspostid',
17666
17775
  };
17667
17776
  url.searchParams.set('type', typeMap[contentType]);
17668
17777
  url.searchParams.set('start', String(start));
17669
- url.searchParams.set('end', String(end));
17778
+ url.searchParams.set('end', String(end));
17670
17779
 
17671
- const response = await fetch(url.toString(), {
17672
- headers: { 'x-api-key': apiKey },
17780
+ const { URL: finalUrl, HEADERS } = getUrlAndHeaders({ url: url.toString(), serviceName: 'Firefly', headers });
17781
+
17782
+ const response = await fetch(finalUrl, {
17783
+ method: 'GET',
17784
+ headers: HEADERS,
17673
17785
  });
17674
17786
  if (!response.ok) {
17675
17787
  throw new NetworkError(SERVICES_API_KEY.Firefly, response.status)
@@ -17696,7 +17808,7 @@ async function FARCASTER() {
17696
17808
  try {
17697
17809
  const [contentType, identifier, start = 0, end = 10] =
17698
17810
  argsToArray(arguments);
17699
- validateParams(farcasterParamsSchema, {
17811
+ validateParams(farcasterParamsSchema, {
17700
17812
  contentType,
17701
17813
  identifier,
17702
17814
  start,
@@ -17722,16 +17834,19 @@ validateParams(farcasterParamsSchema, {
17722
17834
  .join(',')
17723
17835
  );
17724
17836
  const typeMap = {
17725
- posts: 'farcasterid',
17726
- replies: 'farcasterpostid',
17727
- channels: 'farcasterchannels',
17728
- };
17837
+ posts: 'farcasterid',
17838
+ replies: 'farcasterpostid',
17839
+ channels: 'farcasterchannels',
17840
+ };
17729
17841
  url.searchParams.set('type', typeMap[contentType]);
17730
17842
  url.searchParams.set('start', String(start));
17731
- url.searchParams.set('end', String(end));
17843
+ url.searchParams.set('end', String(end));
17844
+
17845
+ const { URL: finalUrl, HEADERS } = getUrlAndHeaders({ url: url.toString(), serviceName: 'Firefly', headers });
17732
17846
 
17733
- const response = await fetch(url.toString(), {
17734
- headers: { 'x-api-key': apiKey },
17847
+ const response = await fetch(finalUrl, {
17848
+ method: 'GET',
17849
+ headers: HEADERS,
17735
17850
  });
17736
17851
  if (!response.ok) {
17737
17852
  throw new NetworkError(
@@ -17840,12 +17955,12 @@ async function BLOCKSCOUT() {
17840
17955
  }
17841
17956
 
17842
17957
  async function BASE() {
17843
- try {
17958
+ try {
17844
17959
  const [type, address, startDate, endDate, page, limit] = argsToArray(arguments);
17845
- validateParams(baseParamsSchema, { type, address, startDate, endDate, page, limit });
17960
+ validateParams(baseParamsSchema, { type, address, startDate, endDate, page, limit });
17846
17961
  const API_KEY = window.localStorage.getItem(SERVICES_API_KEY.Basescan);
17847
17962
  if (!API_KEY) throw new MissingApiKeyError(SERVICES_API_KEY.Basescan)
17848
-
17963
+
17849
17964
  return await handleScanRequest({
17850
17965
  type,
17851
17966
  address,
@@ -17858,9 +17973,9 @@ try {
17858
17973
  chainId: CHAIN_ID_MAP.base,
17859
17974
  network: 'base'
17860
17975
  })
17861
- } catch (error) {
17862
- return errorMessageHandler(error, 'BASE')
17863
- }
17976
+ } catch (error) {
17977
+ return errorMessageHandler(error, 'BASE')
17978
+ }
17864
17979
  }
17865
17980
  async function GNOSIS() {
17866
17981
  try {
@@ -17901,9 +18016,9 @@ async function GNOSIS() {
17901
18016
 
17902
18017
  async function NEYNAR() {
17903
18018
  try {
17904
- const neynarParamsSchema = objectType({
17905
- username: stringType().nonempty()
17906
- });
18019
+ const neynarParamsSchema = objectType({
18020
+ username: stringType().nonempty()
18021
+ });
17907
18022
 
17908
18023
  const [username] = argsToArray(arguments);
17909
18024
 
@@ -17917,12 +18032,19 @@ async function NEYNAR() {
17917
18032
 
17918
18033
  const url = `https://api.neynar.com/v2/farcaster/followers?fid=${fid}`;
17919
18034
 
17920
- const response = await fetch(url, {
17921
- headers: {
17922
- 'x-api-key': apiKey,
17923
- 'x-neynar-experimental': 'false',
18035
+ const { URL: finalUrl, HEADERS } = getUrlAndHeaders({
18036
+ url: url.toString(), serviceName: 'Firefly', headers: {
18037
+ headers: {
18038
+ 'x-api-key': API_KEY,
18039
+ 'x-neynar-experimental': 'false'
18040
+ }
17924
18041
  }
17925
18042
  });
18043
+
18044
+ const response = await fetch(finalUrl, {
18045
+ method: 'GET',
18046
+ headers: HEADERS,
18047
+ });
17926
18048
  if (!response.ok) {
17927
18049
  throw new NetworkError(SERVICES_API_KEY.Neynar, response.status)
17928
18050
  }
@@ -18056,20 +18178,20 @@ async function COINGECKO() {
18056
18178
  break
18057
18179
  }
18058
18180
  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' };
18181
+ 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
18182
  const _category = map[param1] || '';
18061
18183
  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?`&category=${_category}`:''}${trend}`;
18184
+ 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
18185
  break
18064
18186
  }
18065
18187
  case 'stablecoins': {
18066
- const _category = param1==='all'? 'stablecoins' : param1;
18188
+ const _category = param1 === 'all' ? 'stablecoins' : param1;
18067
18189
  const trend = param2 ? `&price_change_percentage=${param2}` : '';
18068
18190
  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
18191
  break
18070
18192
  }
18071
18193
  case 'derivatives': {
18072
- url = (!param1 || param1==='all')
18194
+ url = (!param1 || param1 === 'all')
18073
18195
  ? 'https://api.coingecko.com/api/v3/derivatives'
18074
18196
  : `https://api.coingecko.com/api/v3/derivatives/exchanges/${param1}?include_tickers=all`;
18075
18197
  break
@@ -18084,17 +18206,17 @@ async function COINGECKO() {
18084
18206
  throw new NetworkError(SERVICES_API_KEY.Coingecko, res.status)
18085
18207
  }
18086
18208
 
18087
- if (category==='price') {
18209
+ if (category === 'price') {
18088
18210
  const out = {};
18089
18211
  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;
18212
+ for (const [cur, val] of Object.entries(prices))
18213
+ out[`${token.charAt(0).toUpperCase() + token.slice(1)}_${cur.toUpperCase()}`] = val;
18092
18214
  return [out]
18093
18215
  }
18094
18216
 
18095
18217
  const data = Array.isArray(json) ? json : [json];
18096
- return data.map(item=>{
18097
- const flat={};
18218
+ return data.map(item => {
18219
+ const flat = {};
18098
18220
  for (const [key, value] of Object.entries(item)) {
18099
18221
  if (typeof value !== 'object' || value === null) {
18100
18222
  flat[key] = value;
@@ -18102,12 +18224,13 @@ async function COINGECKO() {
18102
18224
  }
18103
18225
  return flat
18104
18226
  })
18105
- } catch(err) {
18106
- return errorMessageHandler(err,'COINGECKO')
18227
+ } catch (err) {
18228
+ return errorMessageHandler(err, 'COINGECKO')
18107
18229
  }
18108
18230
  }
18109
18231
 
18110
18232
  async function EOA() {
18233
+ console.log('EOA');
18111
18234
  try {
18112
18235
  const [addresses, category, chains, startTime, endTime, page = 1, offset = 10] =
18113
18236
  argsToArray(arguments);
@@ -18116,8 +18239,8 @@ async function EOA() {
18116
18239
  const apiKey = window.localStorage.getItem(SERVICES_API_KEY.Etherscan);
18117
18240
  if (!apiKey) throw new MissingApiKeyError(SERVICES_API_KEY.Etherscan)
18118
18241
 
18119
- const INPUTS = addresses.split(',').map(s=>s.trim()).filter(Boolean);
18120
- const CHAINS = chains.split(',').map(s=>s.trim()).filter(Boolean);
18242
+ const INPUTS = addresses.split(',').map(s => s.trim()).filter(Boolean);
18243
+ const CHAINS = chains.split(',').map(s => s.trim()).filter(Boolean);
18121
18244
 
18122
18245
  const ADDRESS_MAP = {};
18123
18246
  for (const inp of INPUTS) {
@@ -18134,7 +18257,12 @@ async function EOA() {
18134
18257
  const out = [];
18135
18258
 
18136
18259
  async function fetchJSON(url) {
18137
- const res = await fetch(url);
18260
+ const { URL: finalUrl, HEADERS } = getUrlAndHeaders({ url, serviceName: 'Etherscan', headers: {} });
18261
+ console.log('finalUrl', finalUrl, HEADERS);
18262
+ const res = await fetch(finalUrl, {
18263
+ method: 'GET',
18264
+ headers: HEADERS,
18265
+ });
18138
18266
  if (!res.ok) throw new NetworkError(SERVICES_API_KEY.Etherscan, res.status)
18139
18267
  const json = await res.json();
18140
18268
 
@@ -18152,15 +18280,15 @@ async function EOA() {
18152
18280
 
18153
18281
  if (category === 'balance') {
18154
18282
  // chunk 20
18155
- for (let i=0; i<ADDRS.length; i+=20) {
18156
- const slice = ADDRS.slice(i,i+20).join(',');
18283
+ for (let i = 0; i < ADDRS.length; i += 20) {
18284
+ const slice = ADDRS.slice(i, i + 20).join(',');
18157
18285
  const url =
18158
- `https://api.etherscan.io/v2/api?chainid=${chainId}`+
18159
- `&module=account&action=addresstokenbalance&address=${slice}`+
18286
+ `https://api.etherscan.io/v2/api?chainid=${chainId}` +
18287
+ `&module=account&action=addresstokenbalance&address=${slice}` +
18160
18288
  `&page=${page}&offset=${offset}&apikey=${apiKey}`;
18161
18289
  const data = await fetchJSON(url);
18162
18290
  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 }));
18291
+ data.forEach((item, idx) => out.push({ chain, address: ADDRS[i + idx], name: ADDRESS_MAP[ADDRS[i + idx]], ...item }));
18164
18292
  }
18165
18293
  } else {
18166
18294
  // txns
@@ -18170,9 +18298,9 @@ async function EOA() {
18170
18298
  if (!eb) throw new ValidationError(`Invalid endTime: ${endTime}`)
18171
18299
  for (const addr of ADDRS) {
18172
18300
  const url =
18173
- `https://api.etherscan.io/v2/api?chainid=${chainId}`+
18174
- `&module=account&action=tokentx&address=${addr}`+
18175
- `&startblock=${sb}&endblock=${eb}`+
18301
+ `https://api.etherscan.io/v2/api?chainid=${chainId}` +
18302
+ `&module=account&action=tokentx&address=${addr}` +
18303
+ `&startblock=${sb}&endblock=${eb}` +
18176
18304
  `&page=${page}&offset=${offset}&sort=asc&apikey=${apiKey}`;
18177
18305
  const data = await fetchJSON(url);
18178
18306
  if (!Array.isArray(data)) return data
@@ -18247,20 +18375,20 @@ async function DEFILLAMA() {
18247
18375
 
18248
18376
  switch (category) {
18249
18377
  case 'protocols':
18250
- json = Array.isArray(json) ? json.slice(0,500) : [];
18378
+ json = Array.isArray(json) ? json.slice(0, 500) : [];
18251
18379
  break
18252
18380
  case 'yields':
18253
- json = Array.isArray(json.data) ? json.data.slice(0,500) : [];
18381
+ json = Array.isArray(json.data) ? json.data.slice(0, 500) : [];
18254
18382
  break
18255
18383
  case 'dex':
18256
18384
  case 'fees':
18257
- json = Array.isArray(json.protocols) ? json.protocols.slice(0,500) : [];
18385
+ json = Array.isArray(json.protocols) ? json.protocols.slice(0, 500) : [];
18258
18386
  break
18259
18387
  }
18260
18388
 
18261
18389
  return (Array.isArray(json) ? json : [json]).map(item => {
18262
18390
  const out = {};
18263
- for (const [k,v] of Object.entries(item)) {
18391
+ for (const [k, v] of Object.entries(item)) {
18264
18392
  if (v === null || typeof v !== 'object') out[k] = v;
18265
18393
  }
18266
18394
  return out
@@ -18296,7 +18424,7 @@ async function UNISWAP() {
18296
18424
  // flatten nested
18297
18425
  return json.map(item => {
18298
18426
  const flat = {};
18299
- Object.entries(item).forEach(([k,v]) => {
18427
+ Object.entries(item).forEach(([k, v]) => {
18300
18428
  if (v === null || typeof v !== 'object') flat[k] = v;
18301
18429
  });
18302
18430
  return flat
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fileverse-dev/formulajs",
3
- "version": "4.4.11-mod-69",
3
+ "version": "4.4.11-mod-68-patch-1",
4
4
  "description": "JavaScript implementation of most Microsoft Excel formula functions",
5
5
  "author": "Formulajs",
6
6
  "publishConfig": {