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

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,126 +13144,15 @@ 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, apiKeyName, 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
- 'Content-Type': 'application/json'
13250
- }
13251
- };
13252
- }
13253
-
13254
13147
  const fromTimeStampToBlock = async (timestamp, chain, apiKey) => {
13255
- if (!timestamp || !chain || !apiKey) return
13256
- const chainId = CHAIN_ID_MAP[chain];
13257
- const url = `https://api.etherscan.io/v2/api?module=block&action=getblocknobytime&timestamp=${timestamp}&closest=before&apikey=${apiKey}&chainId=${chainId}`;
13258
- const { URL: finalUrl, HEADERS } = getUrlAndHeaders(url);
13259
- const res = await fetch(finalUrl, {
13260
- method: 'GET',
13261
- headers: HEADERS,
13262
- });
13263
- const json = await res.json();
13264
- return parseInt(json.result);
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);
13265
13154
 
13266
- };
13155
+ };
13267
13156
 
13268
13157
  var fromTimestampToBlock = {
13269
13158
  fromTimeStampToBlock
@@ -13400,13 +13289,14 @@ async function handleScanRequest({
13400
13289
  'all-txns': 'txlist',
13401
13290
  'token-txns': 'tokentx',
13402
13291
  'nft-txns': 'tokennfttx',
13403
- gas: 'gastracker'
13292
+ 'gas': 'gasoracle'
13404
13293
  };
13405
13294
 
13406
13295
  const action = ACTION_MAP[type];
13407
13296
  if (!action) throw new ValidationError(`Invalid type: ${type}`)
13408
13297
 
13409
- let url = `${baseUrl}?chainid=${chainId}&module=account&action=${action}&apikey=${apiKey}`;
13298
+ const module = action === 'gasoracle' ? 'gastracker' : 'account';
13299
+ let url = `${baseUrl}?chainid=${chainId}&module=${module}&action=${action}&apikey=${apiKey}`;
13410
13300
 
13411
13301
  if (['all-txns', 'token-txns', 'nft-txns'].includes(type)) {
13412
13302
  url += `&address=${address}&startblock=0&endblock=99999999&sort=asc`;
@@ -13420,11 +13310,7 @@ async function handleScanRequest({
13420
13310
  }
13421
13311
  url += `&page=${page}&offset=${offset}`;
13422
13312
  }
13423
- const { URL: finalUrl, HEADERS } = getUrlAndHeaders({url, serviceName: 'Etherscan', headers: {}});
13424
- const res = await fetch(finalUrl, {
13425
- method: 'GET',
13426
- headers: HEADERS,
13427
- });
13313
+ const res = await fetch(url);
13428
13314
  if (!res.ok) {
13429
13315
  throw new NetworkError(apiInfo.apiKeyName, res.status)
13430
13316
  }
@@ -13439,23 +13325,18 @@ async function handleScanRequest({
13439
13325
  throw new RateLimitError(apiInfo.apiKeyName)
13440
13326
  }
13441
13327
 
13442
- return json.result
13328
+ return type === 'gas' ? [json.result] : json.result
13443
13329
  }
13444
13330
 
13445
13331
  const fromUsernameToFid = async (username, apiKey) => {
13446
- if (!username) return null
13332
+ if(!username) return null
13447
13333
  const url = `https://api.neynar.com/v2/farcaster/user/search/?q=${username}&limit=5`;
13448
- const { URL: finalUrl, HEADERS } = getUrlAndHeaders({
13449
- url, serviceName: 'Neynar', headers: {
13334
+ const res = await fetch(url, {
13335
+ headers: {
13450
13336
  'x-api-key': apiKey,
13451
13337
  'x-neynar-experimental': 'false'
13452
13338
  }
13453
13339
  });
13454
-
13455
- const res = await fetch(finalUrl, {
13456
- method: 'GET',
13457
- headers: HEADERS,
13458
- });
13459
13340
  const json = await res.json();
13460
13341
  const users = json.result ? json.result.users : [];
13461
13342
  const user = users.find(user => user.username === username);
@@ -17468,7 +17349,7 @@ const farcasterSchema = objectType({
17468
17349
  contentType: enumType(['posts', 'replies', 'channels']),
17469
17350
  identifier: stringType().nonempty(),
17470
17351
  start: numberType().int().nonnegative().default(0),
17471
- end: numberType().int().nonnegative().max(MAX_PAGE_LIMIT).default(10),
17352
+ end: numberType().int().nonnegative().max(MAX_PAGE_LIMIT, {message: `"end" must be less than or equal to ${MAX_PAGE_LIMIT}`}).default(10),
17472
17353
  });
17473
17354
 
17474
17355
  const lensSchema = objectType({
@@ -17476,7 +17357,7 @@ const lensSchema = objectType({
17476
17357
  contentType: enumType(['posts', 'replies']),
17477
17358
  identifier: stringType().nonempty(),
17478
17359
  start: numberType().int().nonnegative().default(0),
17479
- end: numberType().int().nonnegative().max(MAX_PAGE_LIMIT).default(10),
17360
+ end: numberType().int().nonnegative().max(MAX_PAGE_LIMIT, {message: `"end" must be less than or equal to ${MAX_PAGE_LIMIT}`}).default(10),
17480
17361
  });
17481
17362
 
17482
17363
  const fireflyParamsSchema = discriminatedUnionType('platform', [
@@ -17499,31 +17380,33 @@ const lensParamsSchema = objectType({
17499
17380
  contentType: enumType(['posts', 'replies']),
17500
17381
  identifier: stringType().nonempty(),
17501
17382
  start: numberType().int().nonnegative().default(0),
17502
- end: numberType().int().nonnegative().max(MAX_PAGE_LIMIT).default(10),
17383
+ end: numberType().int().nonnegative().max(MAX_PAGE_LIMIT, {message: `"end" must be less than or equal to ${MAX_PAGE_LIMIT}`}).default(10),
17503
17384
  });
17504
17385
 
17505
17386
  const farcasterParamsSchema = objectType({
17506
17387
  contentType: enumType(['posts', 'replies', 'channels']),
17507
17388
  identifier: stringType().nonempty(),
17508
17389
  start: numberType().int().nonnegative().default(0),
17509
- end: numberType().int().nonnegative().max(MAX_PAGE_LIMIT).default(10),
17390
+ end: numberType().int().nonnegative().max(MAX_PAGE_LIMIT, {message: `"end" must be less than or equal to ${MAX_PAGE_LIMIT}`}).default(10),
17510
17391
  });
17511
17392
 
17512
17393
  const dateStringToTimestamp = (val) => {
17513
- const [mm, dd, yyyy] = val.split('/');
17514
- return Math.floor(new Date(`${yyyy}-${mm}-${dd}`).getTime() / 1000);
17394
+ const [dd, mm, yyyy] = val.split('/');
17395
+ const date = new Date(`${yyyy}-${mm.padStart(2, '0')}-${dd.padStart(2, '0')}`);
17396
+ const timestamp = date.getTime();
17397
+ return isNaN(timestamp) ? NaN : Math.floor(timestamp / 1000);
17515
17398
  };
17516
17399
 
17517
17400
  /**
17518
- * Accepts either a UNIXtimestamp number or a MM/DD/YYYY string,
17401
+ * Accepts either a UNIX timestamp number or a DD/MM/YYYY string,
17519
17402
  * and always returns a nonnegative integer timestamp.
17520
17403
  */
17521
17404
  const dateOrTimestamp = preprocessType(
17522
17405
  (val) =>
17523
- typeof val === 'string' && /^\d{2}\/\d{2}\/\d{4}$/.test(val)
17406
+ typeof val === 'string' && /^\d{1,2}\/\d{1,2}\/\d{4}$/.test(val)
17524
17407
  ? dateStringToTimestamp(val)
17525
17408
  : val,
17526
- numberType().int().nonnegative()
17409
+ 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' })
17527
17410
  );
17528
17411
 
17529
17412
  const blockscoutParamsSchema = objectType({
@@ -17533,7 +17416,7 @@ const blockscoutParamsSchema = objectType({
17533
17416
  startTimestamp: dateOrTimestamp.optional(),
17534
17417
  endTimestamp: dateOrTimestamp.optional(),
17535
17418
  page: numberType().int().nonnegative().default(1),
17536
- offset: numberType().int().nonnegative().max(MAX_PAGE_LIMIT).default(10),
17419
+ offset: numberType().int().nonnegative().max(MAX_PAGE_LIMIT, {message: `"offset" must be less than or equal to ${MAX_PAGE_LIMIT}`}).default(10),
17537
17420
  });
17538
17421
 
17539
17422
  const gasSchema$1 = objectType({
@@ -17541,7 +17424,7 @@ const gasSchema$1 = objectType({
17541
17424
  startDate: dateOrTimestamp.optional(),
17542
17425
  endDate: dateOrTimestamp.optional(),
17543
17426
  page: numberType().int().nonnegative().default(1),
17544
- limit: numberType().int().nonnegative().max(MAX_PAGE_LIMIT).default(10),
17427
+ limit: numberType().int().nonnegative().max(MAX_PAGE_LIMIT, {message: `"limit" must be less than or equal to ${MAX_PAGE_LIMIT}`}).default(10),
17545
17428
  });
17546
17429
 
17547
17430
  const txnSchema$1 = objectType({
@@ -17550,7 +17433,7 @@ const txnSchema$1 = objectType({
17550
17433
  startDate: dateOrTimestamp.optional(),
17551
17434
  endDate: dateOrTimestamp.optional(),
17552
17435
  page: numberType().int().nonnegative().default(1),
17553
- limit: numberType().int().nonnegative().max(MAX_PAGE_LIMIT).default(10),
17436
+ limit: numberType().int().nonnegative().max(MAX_PAGE_LIMIT, {message: `"limit" must be less than or equal to ${MAX_PAGE_LIMIT}`}).default(10),
17554
17437
  });
17555
17438
 
17556
17439
  const baseParamsSchema = discriminatedUnionType('type', [gasSchema$1, txnSchema$1]);
@@ -17560,7 +17443,7 @@ const gasSchema = objectType({
17560
17443
  startDate: dateOrTimestamp.optional(),
17561
17444
  endDate: dateOrTimestamp.optional(),
17562
17445
  page: numberType().int().nonnegative().default(1),
17563
- limit: numberType().int().nonnegative().max(MAX_PAGE_LIMIT).default(10),
17446
+ limit: numberType().int().nonnegative().max(MAX_PAGE_LIMIT, {message: `"limit" must be less than or equal to ${MAX_PAGE_LIMIT}`}).default(10),
17564
17447
  });
17565
17448
 
17566
17449
  const txnSchema = objectType({
@@ -17570,11 +17453,21 @@ const txnSchema = objectType({
17570
17453
  endDate: dateOrTimestamp.optional(),
17571
17454
  chain: enumType(['ethereum','base','gnosis']),
17572
17455
  page: numberType().int().nonnegative().default(1),
17573
- limit: numberType().int().nonnegative().max(MAX_PAGE_LIMIT).default(10),
17456
+ limit: numberType().int().nonnegative().max(MAX_PAGE_LIMIT, {message: `"limit" must be less than or equal to ${MAX_PAGE_LIMIT}`}).default(10),
17574
17457
  });
17575
17458
 
17576
17459
  const etherscanParamsSchema = discriminatedUnionType('type', [gasSchema, txnSchema]);
17577
17460
 
17461
+ const allowedValues = ['1h', '24h', '7d'];
17462
+ const param2Schema = stringType()
17463
+ .refine((val) => {
17464
+ const tokens = val.split(',').map((t) => t.trim().toLowerCase());
17465
+ return tokens.some((token) =>
17466
+ allowedValues.some((allowed) => token.includes(allowed))
17467
+ );
17468
+ }, {
17469
+ message: "param2 must contain at least one of: '1h', '24h', '7d'",
17470
+ }).optional();
17578
17471
  const priceSchema = objectType({
17579
17472
  category: literalType('price'),
17580
17473
  param1: stringType().nonempty(),
@@ -17584,13 +17477,13 @@ const marketEcosystems = ['all','base','meme','aiagents','bitcoin','ethereum','h
17584
17477
  const marketSchema = objectType({
17585
17478
  category: literalType('market'),
17586
17479
  param1: enumType(marketEcosystems),
17587
- param2: enumType(['1h','24h','7d']).optional(),
17480
+ param2: param2Schema,
17588
17481
  });
17589
17482
  const stablecoinsTypes = ['all','yield-bearing-stablecoins','crypto-backed-stablecoin'];
17590
17483
  const stablecoinsSchema = objectType({
17591
17484
  category: literalType('stablecoins'),
17592
17485
  param1: enumType(stablecoinsTypes),
17593
- param2: enumType(['1h','24h','7d']).optional(),
17486
+ param2: param2Schema,
17594
17487
  });
17595
17488
  const derivativesSchema = objectType({
17596
17489
  category: literalType('derivatives'),
@@ -17618,7 +17511,7 @@ const baseSchema = objectType({
17618
17511
  startTime: dateOrTimestamp.optional(),
17619
17512
  endTime: dateOrTimestamp.optional(),
17620
17513
  page: numberType().int().nonnegative().default(1),
17621
- offset: numberType().int().nonnegative().max(MAX_PAGE_LIMIT).default(10),
17514
+ offset: numberType().int().nonnegative().max(MAX_PAGE_LIMIT, {message: `"offset" must be less than or equal to ${MAX_PAGE_LIMIT}`}).default(10),
17622
17515
  });
17623
17516
 
17624
17517
  const eoaParamsSchema = preprocessType(
@@ -17647,7 +17540,7 @@ const safeParamsSchema = objectType({
17647
17540
  address: stringType().nonempty(),
17648
17541
  utility: literalType('txns'),
17649
17542
  chain: enumType(['ethereum','gnosis']),
17650
- limit: numberType().int().nonnegative().max(MAX_PAGE_LIMIT).default(10),
17543
+ limit: numberType().int().nonnegative().max(MAX_PAGE_LIMIT, {message: `"limit" must be less than or equal to ${MAX_PAGE_LIMIT}`}).default(10),
17651
17544
  offset: numberType().int().nonnegative().default(0),
17652
17545
  });
17653
17546
 
@@ -17683,9 +17576,9 @@ const aaveParamsSchema = objectType({
17683
17576
 
17684
17577
  async function FIREFLY() {
17685
17578
  try {
17686
- const [platform, contentType, identifier, start = 0, end = 10] = argsToArray(arguments);
17579
+ const [platform, contentType, identifier, start = 0, end = 10] = argsToArray(arguments);
17687
17580
 
17688
- validateParams(fireflyParamsSchema, {
17581
+ validateParams(fireflyParamsSchema, {
17689
17582
  platform,
17690
17583
  contentType,
17691
17584
  identifier,
@@ -17707,14 +17600,12 @@ async function FIREFLY() {
17707
17600
  .filter(Boolean)
17708
17601
  .join(',')
17709
17602
  );
17710
- url.searchParams.set('type', fireFlyPlaformType[platform][contentType]);
17711
- url.searchParams.set('start', String(start));
17712
- url.searchParams.set('end', String(end));
17603
+ url.searchParams.set('type', fireFlyPlaformType[platform][contentType]);
17604
+ url.searchParams.set('start', String(start));
17605
+ url.searchParams.set('end', String(end));
17713
17606
 
17714
- const { URL: finalUrl, HEADERS } = getUrlAndHeaders({ url: url.toString(), serviceName: 'Firefly', headers });
17715
- const response = await fetch(finalUrl, {
17716
- method: 'GET',
17717
- headers: HEADERS,
17607
+ const response = await fetch(url.toString(), {
17608
+ headers: { 'x-api-key': apiKey }
17718
17609
  });
17719
17610
  if (!response.ok) {
17720
17611
  throw new NetworkError(SERVICES_API_KEY.Firefly, response.status)
@@ -17772,18 +17663,15 @@ async function LENS() {
17772
17663
  .join(',')
17773
17664
  );
17774
17665
  const typeMap = {
17775
- posts: 'lensid',
17666
+ posts: 'lensid',
17776
17667
  replies: 'lenspostid',
17777
17668
  };
17778
17669
  url.searchParams.set('type', typeMap[contentType]);
17779
17670
  url.searchParams.set('start', String(start));
17780
- url.searchParams.set('end', String(end));
17671
+ url.searchParams.set('end', String(end));
17781
17672
 
17782
- const { URL: finalUrl, HEADERS } = getUrlAndHeaders({ url: url.toString(), serviceName: 'Firefly', headers });
17783
-
17784
- const response = await fetch(finalUrl, {
17785
- method: 'GET',
17786
- headers: HEADERS,
17673
+ const response = await fetch(url.toString(), {
17674
+ headers: { 'x-api-key': apiKey },
17787
17675
  });
17788
17676
  if (!response.ok) {
17789
17677
  throw new NetworkError(SERVICES_API_KEY.Firefly, response.status)
@@ -17810,7 +17698,7 @@ async function FARCASTER() {
17810
17698
  try {
17811
17699
  const [contentType, identifier, start = 0, end = 10] =
17812
17700
  argsToArray(arguments);
17813
- validateParams(farcasterParamsSchema, {
17701
+ validateParams(farcasterParamsSchema, {
17814
17702
  contentType,
17815
17703
  identifier,
17816
17704
  start,
@@ -17836,19 +17724,16 @@ async function FARCASTER() {
17836
17724
  .join(',')
17837
17725
  );
17838
17726
  const typeMap = {
17839
- posts: 'farcasterid',
17840
- replies: 'farcasterpostid',
17841
- channels: 'farcasterchannels',
17842
- };
17727
+ posts: 'farcasterid',
17728
+ replies: 'farcasterpostid',
17729
+ channels: 'farcasterchannels',
17730
+ };
17843
17731
  url.searchParams.set('type', typeMap[contentType]);
17844
17732
  url.searchParams.set('start', String(start));
17845
- url.searchParams.set('end', String(end));
17846
-
17847
- const { URL: finalUrl, HEADERS } = getUrlAndHeaders({ url: url.toString(), serviceName: 'Firefly', headers });
17733
+ url.searchParams.set('end', String(end));
17848
17734
 
17849
- const response = await fetch(finalUrl, {
17850
- method: 'GET',
17851
- headers: HEADERS,
17735
+ const response = await fetch(url.toString(), {
17736
+ headers: { 'x-api-key': apiKey },
17852
17737
  });
17853
17738
  if (!response.ok) {
17854
17739
  throw new NetworkError(
@@ -17957,12 +17842,12 @@ async function BLOCKSCOUT() {
17957
17842
  }
17958
17843
 
17959
17844
  async function BASE() {
17960
- try {
17845
+ try {
17961
17846
  const [type, address, startDate, endDate, page, limit] = argsToArray(arguments);
17962
- validateParams(baseParamsSchema, { type, address, startDate, endDate, page, limit });
17847
+ validateParams(baseParamsSchema, { type, address, startDate, endDate, page, limit });
17963
17848
  const API_KEY = window.localStorage.getItem(SERVICES_API_KEY.Basescan);
17964
17849
  if (!API_KEY) throw new MissingApiKeyError(SERVICES_API_KEY.Basescan)
17965
-
17850
+
17966
17851
  return await handleScanRequest({
17967
17852
  type,
17968
17853
  address,
@@ -17975,9 +17860,9 @@ async function BASE() {
17975
17860
  chainId: CHAIN_ID_MAP.base,
17976
17861
  network: 'base'
17977
17862
  })
17978
- } catch (error) {
17979
- return errorMessageHandler(error, 'BASE')
17980
- }
17863
+ } catch (error) {
17864
+ return errorMessageHandler(error, 'BASE')
17865
+ }
17981
17866
  }
17982
17867
  async function GNOSIS() {
17983
17868
  try {
@@ -18018,9 +17903,9 @@ async function GNOSIS() {
18018
17903
 
18019
17904
  async function NEYNAR() {
18020
17905
  try {
18021
- const neynarParamsSchema = objectType({
18022
- username: stringType().nonempty()
18023
- });
17906
+ const neynarParamsSchema = objectType({
17907
+ username: stringType().nonempty()
17908
+ });
18024
17909
 
18025
17910
  const [username] = argsToArray(arguments);
18026
17911
 
@@ -18034,19 +17919,12 @@ async function NEYNAR() {
18034
17919
 
18035
17920
  const url = `https://api.neynar.com/v2/farcaster/followers?fid=${fid}`;
18036
17921
 
18037
- const { URL: finalUrl, HEADERS } = getUrlAndHeaders({
18038
- url: url.toString(), serviceName: 'Firefly', headers: {
18039
- headers: {
18040
- 'x-api-key': API_KEY,
18041
- 'x-neynar-experimental': 'false'
18042
- }
17922
+ const response = await fetch(url, {
17923
+ headers: {
17924
+ 'x-api-key': apiKey,
17925
+ 'x-neynar-experimental': 'false',
18043
17926
  }
18044
17927
  });
18045
-
18046
- const response = await fetch(finalUrl, {
18047
- method: 'GET',
18048
- headers: HEADERS,
18049
- });
18050
17928
  if (!response.ok) {
18051
17929
  throw new NetworkError(SERVICES_API_KEY.Neynar, response.status)
18052
17930
  }
@@ -18180,20 +18058,20 @@ async function COINGECKO() {
18180
18058
  break
18181
18059
  }
18182
18060
  case 'market': {
18183
- 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' };
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' };
18184
18062
  const _category = map[param1] || '';
18185
18063
  const trend = param2 ? `&price_change_percentage=${param2}` : '';
18186
- url = `https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&include_tokens=top&page=1&per_page=100${_category ? `&category=${_category}` : ''}${trend}`;
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}`;
18187
18065
  break
18188
18066
  }
18189
18067
  case 'stablecoins': {
18190
- const _category = param1 === 'all' ? 'stablecoins' : param1;
18068
+ const _category = param1==='all'? 'stablecoins' : param1;
18191
18069
  const trend = param2 ? `&price_change_percentage=${param2}` : '';
18192
18070
  url = `https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&category=${_category}&order=market_cap_desc&page=1&per_page=100${trend}`;
18193
18071
  break
18194
18072
  }
18195
18073
  case 'derivatives': {
18196
- url = (!param1 || param1 === 'all')
18074
+ url = (!param1 || param1==='all')
18197
18075
  ? 'https://api.coingecko.com/api/v3/derivatives'
18198
18076
  : `https://api.coingecko.com/api/v3/derivatives/exchanges/${param1}?include_tickers=all`;
18199
18077
  break
@@ -18208,17 +18086,17 @@ async function COINGECKO() {
18208
18086
  throw new NetworkError(SERVICES_API_KEY.Coingecko, res.status)
18209
18087
  }
18210
18088
 
18211
- if (category === 'price') {
18089
+ if (category==='price') {
18212
18090
  const out = {};
18213
18091
  for (const [token, prices] of Object.entries(json))
18214
- for (const [cur, val] of Object.entries(prices))
18215
- out[`${token.charAt(0).toUpperCase() + token.slice(1)}_${cur.toUpperCase()}`] = val;
18092
+ for (const [cur,val] of Object.entries(prices))
18093
+ out[`${token.charAt(0).toUpperCase()+token.slice(1)}_${cur.toUpperCase()}`]=val;
18216
18094
  return [out]
18217
18095
  }
18218
18096
 
18219
18097
  const data = Array.isArray(json) ? json : [json];
18220
- return data.map(item => {
18221
- const flat = {};
18098
+ return data.map(item=>{
18099
+ const flat={};
18222
18100
  for (const [key, value] of Object.entries(item)) {
18223
18101
  if (typeof value !== 'object' || value === null) {
18224
18102
  flat[key] = value;
@@ -18226,13 +18104,12 @@ async function COINGECKO() {
18226
18104
  }
18227
18105
  return flat
18228
18106
  })
18229
- } catch (err) {
18230
- return errorMessageHandler(err, 'COINGECKO')
18107
+ } catch(err) {
18108
+ return errorMessageHandler(err,'COINGECKO')
18231
18109
  }
18232
18110
  }
18233
18111
 
18234
18112
  async function EOA() {
18235
- console.log('EOA');
18236
18113
  try {
18237
18114
  const [addresses, category, chains, startTime, endTime, page = 1, offset = 10] =
18238
18115
  argsToArray(arguments);
@@ -18241,8 +18118,8 @@ async function EOA() {
18241
18118
  const apiKey = window.localStorage.getItem(SERVICES_API_KEY.Etherscan);
18242
18119
  if (!apiKey) throw new MissingApiKeyError(SERVICES_API_KEY.Etherscan)
18243
18120
 
18244
- const INPUTS = addresses.split(',').map(s => s.trim()).filter(Boolean);
18245
- const CHAINS = chains.split(',').map(s => s.trim()).filter(Boolean);
18121
+ const INPUTS = addresses.split(',').map(s=>s.trim()).filter(Boolean);
18122
+ const CHAINS = chains.split(',').map(s=>s.trim()).filter(Boolean);
18246
18123
 
18247
18124
  const ADDRESS_MAP = {};
18248
18125
  for (const inp of INPUTS) {
@@ -18259,12 +18136,7 @@ async function EOA() {
18259
18136
  const out = [];
18260
18137
 
18261
18138
  async function fetchJSON(url) {
18262
- const { URL: finalUrl, HEADERS } = getUrlAndHeaders({ url, serviceName: 'Etherscan', headers: {} });
18263
- console.log('finalUrl', finalUrl, HEADERS);
18264
- const res = await fetch(finalUrl, {
18265
- method: 'GET',
18266
- headers: HEADERS,
18267
- });
18139
+ const res = await fetch(url);
18268
18140
  if (!res.ok) throw new NetworkError(SERVICES_API_KEY.Etherscan, res.status)
18269
18141
  const json = await res.json();
18270
18142
 
@@ -18282,15 +18154,15 @@ async function EOA() {
18282
18154
 
18283
18155
  if (category === 'balance') {
18284
18156
  // chunk 20
18285
- for (let i = 0; i < ADDRS.length; i += 20) {
18286
- const slice = ADDRS.slice(i, i + 20).join(',');
18157
+ for (let i=0; i<ADDRS.length; i+=20) {
18158
+ const slice = ADDRS.slice(i,i+20).join(',');
18287
18159
  const url =
18288
- `https://api.etherscan.io/v2/api?chainid=${chainId}` +
18289
- `&module=account&action=addresstokenbalance&address=${slice}` +
18160
+ `https://api.etherscan.io/v2/api?chainid=${chainId}`+
18161
+ `&module=account&action=addresstokenbalance&address=${slice}`+
18290
18162
  `&page=${page}&offset=${offset}&apikey=${apiKey}`;
18291
18163
  const data = await fetchJSON(url);
18292
18164
  if (!Array.isArray(data)) return data
18293
- data.forEach((item, idx) => out.push({ chain, address: ADDRS[i + idx], name: ADDRESS_MAP[ADDRS[i + idx]], ...item }));
18165
+ data.forEach((item, idx) => out.push({ chain, address: ADDRS[i+idx], name: ADDRESS_MAP[ADDRS[i+idx]], ...item }));
18294
18166
  }
18295
18167
  } else {
18296
18168
  // txns
@@ -18300,9 +18172,9 @@ async function EOA() {
18300
18172
  if (!eb) throw new ValidationError(`Invalid endTime: ${endTime}`)
18301
18173
  for (const addr of ADDRS) {
18302
18174
  const url =
18303
- `https://api.etherscan.io/v2/api?chainid=${chainId}` +
18304
- `&module=account&action=tokentx&address=${addr}` +
18305
- `&startblock=${sb}&endblock=${eb}` +
18175
+ `https://api.etherscan.io/v2/api?chainid=${chainId}`+
18176
+ `&module=account&action=tokentx&address=${addr}`+
18177
+ `&startblock=${sb}&endblock=${eb}`+
18306
18178
  `&page=${page}&offset=${offset}&sort=asc&apikey=${apiKey}`;
18307
18179
  const data = await fetchJSON(url);
18308
18180
  if (!Array.isArray(data)) return data
@@ -18377,20 +18249,20 @@ async function DEFILLAMA() {
18377
18249
 
18378
18250
  switch (category) {
18379
18251
  case 'protocols':
18380
- json = Array.isArray(json) ? json.slice(0, 500) : [];
18252
+ json = Array.isArray(json) ? json.slice(0,500) : [];
18381
18253
  break
18382
18254
  case 'yields':
18383
- json = Array.isArray(json.data) ? json.data.slice(0, 500) : [];
18255
+ json = Array.isArray(json.data) ? json.data.slice(0,500) : [];
18384
18256
  break
18385
18257
  case 'dex':
18386
18258
  case 'fees':
18387
- json = Array.isArray(json.protocols) ? json.protocols.slice(0, 500) : [];
18259
+ json = Array.isArray(json.protocols) ? json.protocols.slice(0,500) : [];
18388
18260
  break
18389
18261
  }
18390
18262
 
18391
18263
  return (Array.isArray(json) ? json : [json]).map(item => {
18392
18264
  const out = {};
18393
- for (const [k, v] of Object.entries(item)) {
18265
+ for (const [k,v] of Object.entries(item)) {
18394
18266
  if (v === null || typeof v !== 'object') out[k] = v;
18395
18267
  }
18396
18268
  return out
@@ -18426,7 +18298,7 @@ async function UNISWAP() {
18426
18298
  // flatten nested
18427
18299
  return json.map(item => {
18428
18300
  const flat = {};
18429
- Object.entries(item).forEach(([k, v]) => {
18301
+ Object.entries(item).forEach(([k,v]) => {
18430
18302
  if (v === null || typeof v !== 'object') flat[k] = v;
18431
18303
  });
18432
18304
  return flat
@@ -286,14 +286,14 @@ If "derivatives": exchange name (e.g., "binance_futures", "hyperliquid", "weex-f
286
286
  {
287
287
  name: "page",
288
288
  detail: "Page number for paginated transaction results. Applies only to 'txns', 'token-txns', and 'nft-txns'.",
289
- example: `"1"`,
289
+ example: `1`,
290
290
  require: "o",
291
291
  type: "number"
292
292
  },
293
293
  {
294
294
  name: "offset",
295
295
  detail: "Number of results per page (limit). Applies only to 'txns', 'token-txns', and 'nft-txns'.",
296
- example: `"50"`,
296
+ example: `50`,
297
297
  require: "o",
298
298
  type: "number"
299
299
  }