@fileverse-dev/formulajs 4.4.11-mod-66 → 4.4.11-mod-67

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
@@ -13116,15 +13116,19 @@ const SAFE_CHAIN_MAP = {
13116
13116
  };
13117
13117
 
13118
13118
  const ERROR_MESSAGES_FLAG = {
13119
- INVALID_API_KEY: '_INVALID_KEY',
13120
- RATE_LIMIT: '_RATE_LIMIT_REACHED',
13121
- DEFAULT: 'FETCH_ERROR',
13122
- MISSING_KEY: '_MISSING',
13123
- INVALID_CHAIN: '_INVALID_CHAIN',
13124
- INVALID_TYPE: '_INVALID_TYPE',
13125
- INVALID_ADDRESS: '_INVALID_ADDRESS',
13126
- INVALID_PARAM: '_INVALID_PARAM',
13127
- MAX_PAGE_LIMIT: 'Max page limit is 250'
13119
+ INVALID_API_KEY: 'INVALID_API_KEY',
13120
+ RATE_LIMIT: 'RATE_LIMIT',
13121
+ DEFAULT: 'DEFAULT',
13122
+ MISSING_KEY: 'MISSING_KEY',
13123
+ INVALID_CHAIN: 'INVALID_CHAIN',
13124
+ INVALID_TYPE: 'INVALID_TYPE',
13125
+ INVALID_ADDRESS: 'INVALID_ADDRESS',
13126
+ INVALID_PARAM: 'INVALID_PARAM',
13127
+ MAX_PAGE_LIMIT: 'MAX_PAGE_LIMIT',
13128
+ NETWORK_ERROR: 'NETWORK_ERROR',
13129
+ ENS: 'ENS',
13130
+ CUSTOM: 'CUSTOM',
13131
+ MISSING_PARAM: 'MISSING_PARAM'
13128
13132
  };
13129
13133
 
13130
13134
  const UTILITY = {
@@ -13132,16 +13136,16 @@ const UTILITY = {
13132
13136
  };
13133
13137
  const MAX_PAGE_LIMIT = 250;
13134
13138
 
13135
- const SERVICE_API_KEY = {
13136
- Etherscan: 'ETHERSCAN_API_KEY',
13137
- Coingecko: 'COINGECKO_API_KEY',
13138
- Safe: 'SAFE_API_KEY',
13139
- Basescan: 'BASESCAN_API_KEY',
13140
- Gnosisscan: 'GNOSIS_API_KEY',
13141
- Firefly: 'FIRE_FLY_API_KEY',
13142
- GnosisPay: 'GNOSIS_API_KEY',
13143
- Neynar: 'NEYNAR_API_KEY',
13144
- Defillama: 'DEFILLAMA_API_KEY'
13139
+ const SERVICES_API_KEY = {
13140
+ Etherscan: 'Etherscan',
13141
+ Coingecko: 'Coingecko',
13142
+ Safe: 'Safe',
13143
+ Basescan: 'Basescan',
13144
+ Gnosisscan: 'Gnosisscan',
13145
+ Firefly: 'Firefly',
13146
+ GnosisPay: 'GnosisPay',
13147
+ Neynar: 'Neynar',
13148
+ Defillama: 'Defillama'
13145
13149
  };
13146
13150
 
13147
13151
  const fromTimeStampToBlock = async (timestamp, chain, apiKey) => {
@@ -13154,6 +13158,10 @@ if(!timestamp || !chain || !apiKey) return
13154
13158
 
13155
13159
  };
13156
13160
 
13161
+ var fromTimestampToBlock = {
13162
+ fromTimeStampToBlock
13163
+ };
13164
+
13157
13165
  function toTimestamp(dateStr) {
13158
13166
  // Expecting format: "DD/MM/YYYY"
13159
13167
  const [day, month, year] = dateStr.split("/").map(Number);
@@ -13165,6 +13173,16 @@ const isAddress = (input) => {
13165
13173
  return (/^0x[a-fA-F0-9]{40}$/.test(input))
13166
13174
  };
13167
13175
 
13176
+ var isAddress$1 = {
13177
+ isAddress
13178
+ };
13179
+
13180
+ /* global document */
13181
+ /* global window */
13182
+ /* global ethers */
13183
+
13184
+
13185
+
13168
13186
  async function fromEnsNameToAddress(name) {
13169
13187
  if (typeof ethers === 'undefined') {
13170
13188
  await new Promise((resolve, reject) => {
@@ -13192,33 +13210,170 @@ async function fromEnsNameToAddress(name) {
13192
13210
  }
13193
13211
  }
13194
13212
 
13213
+ var fromEnsNameToAddress$1 = {
13214
+ fromEnsNameToAddress
13215
+ };
13216
+
13217
+ const errorMessageHandler = (errorFlag, input, functionName) => {
13218
+ if (!functionName) {
13219
+ const stack = new Error().stack?.split('\n')[2];
13220
+ const match = stack?.match(/at (.+?) \(/);
13221
+ const rawFnName = match?.[1];
13222
+ functionName = rawFnName?.split('.').pop() || '[unable to detect function name]';
13223
+ }
13224
+
13225
+ switch (errorFlag) {
13226
+ case ERROR_MESSAGES_FLAG.INVALID_ADDRESS:
13227
+ return {
13228
+ message: `${input} is not a supported address`,
13229
+ functionName,
13230
+ type: errorFlag
13231
+ }
13232
+
13233
+ case ERROR_MESSAGES_FLAG.INVALID_PARAM: {
13234
+ const key = Object.keys(input)[0];
13235
+ const value = input[key];
13236
+ return {
13237
+ message: `${value} is an invalid value for ${key}`,
13238
+ functionName,
13239
+ type: errorFlag
13240
+ }
13241
+ }
13242
+
13243
+ case ERROR_MESSAGES_FLAG.INVALID_CHAIN:
13244
+ return {
13245
+ message: `${input} is not a supported chain for this function `,
13246
+ functionName,
13247
+ type: errorFlag
13248
+ }
13249
+
13250
+ case ERROR_MESSAGES_FLAG.RATE_LIMIT:
13251
+ return {
13252
+ message: `Rate limit for ${input || functionName || 'this api'} has been reached`,
13253
+ functionName,
13254
+ type: errorFlag
13255
+ }
13256
+
13257
+ case ERROR_MESSAGES_FLAG.MISSING_KEY:
13258
+ return {
13259
+ message: `Api key for ${input || functionName || 'this api'} is missing`,
13260
+ functionName,
13261
+ type: errorFlag
13262
+ }
13263
+
13264
+ case ERROR_MESSAGES_FLAG.NETWORK_ERROR:
13265
+ if (input === 429) {
13266
+ return {
13267
+ message: `Rate limit for ${functionName || 'this function'} has been reached`,
13268
+ functionName,
13269
+ type: ERROR_MESSAGES_FLAG.RATE_LIMIT
13270
+ }
13271
+ }
13272
+ return {
13273
+ message: `Api failed with status code ${input}`,
13274
+ functionName,
13275
+ type: errorFlag
13276
+ }
13277
+
13278
+ case ERROR_MESSAGES_FLAG.MISSING_PARAM:
13279
+ return {
13280
+ message: `Missing param: ${input}`,
13281
+ functionName,
13282
+ type: errorFlag
13283
+ }
13284
+
13285
+ case ERROR_MESSAGES_FLAG.ENS:
13286
+ return {
13287
+ message: `${input} is not a supported ens name`,
13288
+ functionName,
13289
+ type: errorFlag
13290
+ }
13291
+
13292
+ case ERROR_MESSAGES_FLAG.CUSTOM:
13293
+ return {
13294
+ message: input.message,
13295
+ functionName,
13296
+ type: errorFlag,
13297
+ reason: input.reason || input.message
13298
+ }
13299
+
13300
+ case ERROR_MESSAGES_FLAG.MAX_PAGE_LIMIT:
13301
+ return {
13302
+ message: `Max page limit is ${MAX_PAGE_LIMIT}`,
13303
+ functionName,
13304
+ type: errorFlag
13305
+ }
13306
+
13307
+ case ERROR_MESSAGES_FLAG.INVALID_API_KEY:
13308
+ return {
13309
+ message: `${input}: Invalid API key`,
13310
+ functionName,
13311
+ type: errorFlag
13312
+ }
13313
+
13314
+ default:
13315
+ return {
13316
+ message: 'An unexpected error occured',
13317
+ functionName,
13318
+ type: errorFlag,
13319
+ reason: input
13320
+ }
13321
+ }
13322
+ };
13323
+
13324
+
13325
+
13326
+
13327
+
13328
+ const checkRequiredParams = (inputMap) => {
13329
+ for (const key in inputMap) {
13330
+ if (!inputMap[key]) {
13331
+ const stack = new Error().stack?.split('\n')[2];
13332
+
13333
+ const match = stack?.match(/at (.+?) \(/);
13334
+ const rawFnName = match?.[1];
13335
+ const parentFunctionName = rawFnName?.split('.').pop() || '[unable to detect function name]';
13336
+
13337
+ const paramName = key;
13338
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.MISSING_PARAM, paramName, parentFunctionName);
13339
+ }
13340
+ }
13341
+ };
13342
+
13195
13343
  async function handleScanRequest({
13196
- scanKey,
13197
- baseUrl,
13198
13344
  type,
13199
- chain,
13200
13345
  address,
13201
13346
  startDate,
13202
13347
  endDate,
13203
13348
  page = 1,
13204
- offset = 10
13349
+ offset = 10,
13350
+ apiKey,
13351
+ functionName,
13352
+ chainId,
13353
+ network
13205
13354
  }) {
13206
- const API_KEY = window.localStorage.getItem(scanKey);
13207
- if (!API_KEY) return `${scanKey}${ERROR_MESSAGES_FLAG.MISSING_KEY}`
13208
- if (API_KEY === 'xxxx') return `${scanKey}${ERROR_MESSAGES_FLAG.RATE_LIMIT}`
13209
- if (offset > MAX_PAGE_LIMIT) {
13210
- return ERROR_MESSAGES_FLAG.MAX_PAGE_LIMIT
13211
- }
13212
-
13213
- let chainId = CHAIN_ID_MAP[chain?.toLowerCase()];
13214
- if (!chainId) return `${scanKey}${ERROR_MESSAGES_FLAG.INVALID_CHAIN}`
13355
+ const API_INFO_MAP = {
13356
+ BASE: { url: 'https://api.basescan.org/api', apiKeyName: SERVICES_API_KEY.Basescan },
13357
+ ETHERSCAN: { url: 'https://api.etherscan.io/v2/api', apiKeyName: SERVICES_API_KEY.Etherscan },
13358
+ GNOSIS: { url: 'https://api.gnosisscan.io/api', apiKeyName: SERVICES_API_KEY.Gnosisscan }
13359
+ };
13215
13360
 
13216
- if (!isAddress(address)) {
13217
- address = await fromEnsNameToAddress(address);
13361
+ if (!isAddress$1.isAddress(address)) {
13362
+ const ensName = address;
13363
+ address = await fromEnsNameToAddress$1.fromEnsNameToAddress(address);
13364
+ if (!address) {
13365
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.ENS, ensName, functionName)
13366
+ }
13218
13367
  }
13219
13368
 
13220
- if (!address) {
13221
- return `${address}${ERROR_MESSAGES_FLAG.INVALID_PARAM}`
13369
+ const apiInfo = API_INFO_MAP[functionName];
13370
+ const baseUrl = apiInfo?.url;
13371
+
13372
+ if (!baseUrl) {
13373
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.CUSTOM, {
13374
+ message: 'Api not found',
13375
+ reason: ` Api not found for: ${functionName}`
13376
+ }, functionName)
13222
13377
  }
13223
13378
 
13224
13379
  const ACTION_MAP = {
@@ -13229,41 +13384,40 @@ async function handleScanRequest({
13229
13384
  };
13230
13385
 
13231
13386
  const action = ACTION_MAP[type];
13232
- if (!action) return `${scanKey}${ERROR_MESSAGES_FLAG.INVALID_TYPE}`
13233
-
13234
- if (scanKey === SERVICE_API_KEY.Basescan) chainId = 'base';
13235
- if (scanKey === SERVICE_API_KEY.Gnosisscan) chainId = 'gnosis';
13387
+ if (!action) return errorMessageHandler(ERROR_MESSAGES_FLAG.INVALID_PARAM, { type }, functionName)
13236
13388
 
13237
- let url = `${baseUrl}?chainid=${chainId}&module=account&action=${action}&apikey=${API_KEY}`;
13389
+ let url = `${baseUrl}?chainid=${chainId}&module=account&action=${action}&apikey=${apiKey}`;
13238
13390
 
13239
13391
  if (['all-txns', 'token-txns', 'nft-txns'].includes(type)) {
13240
- if (!address) return `${scanKey}${ERROR_MESSAGES_FLAG.INVALID_ADDRESS}`
13241
13392
  url += `&address=${address}&startblock=0&endblock=99999999&sort=asc`;
13242
13393
 
13243
13394
  if (!isNaN(startDate) && !isNaN(endDate)) {
13244
13395
  const [startBlock, endBlock] = await Promise.all([
13245
- fromTimeStampToBlock(toTimestamp(startDate), chain, API_KEY),
13246
- fromTimeStampToBlock(toTimestamp(endDate), chain, API_KEY)
13396
+ fromTimestampToBlock.fromTimeStampToBlock(toTimestamp(startDate), network, apiKey),
13397
+ fromTimestampToBlock.fromTimeStampToBlock(toTimestamp(endDate), network, apiKey)
13247
13398
  ]);
13248
- url += `&startblock=${startBlock}&endblock=${endBlock}`;
13399
+ url += `&startblock=${startBlock || '0'}&endblock=${endBlock || '99999999'}`;
13249
13400
  }
13250
13401
  url += `&page=${page}&offset=${offset}`;
13251
13402
  }
13252
13403
 
13253
13404
  try {
13254
13405
  const res = await fetch(url);
13255
- if (!res.ok) throw new Error(`HTTP error: ${res.status}`)
13406
+ if (!res.ok) {
13407
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.NETWORK_ERROR, res.status, functionName)
13408
+ }
13256
13409
  const json = await res.json();
13257
13410
 
13258
13411
  if (typeof json.result === 'string') {
13259
- if (json.result.includes('Invalid API Key')) return `${scanKey}${ERROR_MESSAGES_FLAG.INVALID_API_KEY}`
13260
- if (json.result.includes('Max rate limit reached')) return `${scanKey}${ERROR_MESSAGES_FLAG.RATE_LIMIT}`
13412
+ if (json.result.includes('Invalid API Key'))
13413
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.INVALID_API_KEY, apiInfo.apiKeyName, functionName)
13414
+ if (json.result.includes('Max rate limit reached'))
13415
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.RATE_LIMIT, apiInfo.apiKeyName, functionName)
13261
13416
  }
13262
13417
 
13263
13418
  return json.result
13264
13419
  } catch (err) {
13265
- console.error(`[${scanKey}]`, err);
13266
- return ERROR_MESSAGES_FLAG.DEFAULT
13420
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.DEFAULT, err, functionName)
13267
13421
  }
13268
13422
  }
13269
13423
 
@@ -13281,6 +13435,9 @@ const fromUsernameToFid = async (username, apiKey) => {
13281
13435
  const user = users.find(user => user.username === username);
13282
13436
  return user && user.fid || null;
13283
13437
  };
13438
+ var fromUsernameToFid$1 = {
13439
+ fromUsernameToFid
13440
+ };
13284
13441
 
13285
13442
  // remove nested structure from the response
13286
13443
  const removeNestedStructure = (json) => {
@@ -13295,13 +13452,22 @@ const removeNestedStructure = (json) => {
13295
13452
  });
13296
13453
  };
13297
13454
 
13455
+ /* global window */
13456
+
13298
13457
  async function FIREFLY() {
13299
13458
  const [platform, contentType, identifier, start = 0, end = 10] = argsToArray(arguments);
13459
+ const missingParamsError = checkRequiredParams({ platform, contentType, identifier });
13460
+
13461
+ if (missingParamsError) {
13462
+ return missingParamsError
13463
+ }
13464
+
13300
13465
  if (end > MAX_PAGE_LIMIT) {
13301
- return ERROR_MESSAGES_FLAG.MAX_PAGE_LIMIT
13466
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.MAX_PAGE_LIMIT)
13302
13467
  }
13303
- const API_KEY = window.localStorage.getItem(SERVICE_API_KEY.Firefly);
13304
- if (!API_KEY) return `${SERVICE_API_KEY.Firefly}${ERROR_MESSAGES_FLAG.MISSING_KEY}`
13468
+
13469
+ const API_KEY = window.localStorage.getItem(SERVICES_API_KEY.Firefly);
13470
+ if (!API_KEY) return errorMessageHandler(ERROR_MESSAGES_FLAG.MISSING_KEY, SERVICES_API_KEY.Firefly)
13305
13471
 
13306
13472
  const baseUrl = 'https://openapi.firefly.land/v1/fileverse/fetch';
13307
13473
  const headers = { 'x-api-key': API_KEY };
@@ -13317,10 +13483,14 @@ async function FIREFLY() {
13317
13483
  replies: 'lenspostid'
13318
13484
  }
13319
13485
  };
13320
-
13321
- const platformType = typeMap[platform]?.[contentType];
13322
- if (!platformType) return `${SERVICE_API_KEY.Firefly}${ERROR_MESSAGES_FLAG.INVALID_TYPE}`
13323
-
13486
+ const platformType = typeMap[platform];
13487
+ if (!platformType) {
13488
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.INVALID_PARAM, { platform })
13489
+ }
13490
+ const platformContentType = platformType[contentType];
13491
+ if (!platformContentType) {
13492
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.INVALID_PARAM, { contentType })
13493
+ }
13324
13494
  const query = identifier
13325
13495
  .split(',')
13326
13496
  .map((s) => s.trim())
@@ -13335,7 +13505,7 @@ async function FIREFLY() {
13335
13505
 
13336
13506
  try {
13337
13507
  const res = await fetch(url.toString(), { headers });
13338
- if (!res.ok) throw new Error(`HTTP ${res.status}`)
13508
+ if (!res.ok) return errorMessageHandler(ERROR_MESSAGES_FLAG.NETWORK_ERROR, res.status)
13339
13509
 
13340
13510
  const json = await res.json();
13341
13511
  if (!Array.isArray(json?.data)) return []
@@ -13351,19 +13521,21 @@ async function FIREFLY() {
13351
13521
  return flat
13352
13522
  })
13353
13523
  } catch (err) {
13354
- console.error('FIREFLY fetch error:', err);
13355
- return ERROR_MESSAGES_FLAG.DEFAULT
13524
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.DEFAULT, err)
13356
13525
  }
13357
13526
  }
13358
13527
 
13359
13528
  async function LENS() {
13360
13529
  const [contentType, identifier, start = 0, end = 10] = argsToArray(arguments);
13361
- const API_KEY = window.localStorage.getItem(SERVICE_API_KEY.Firefly);
13362
- if (!API_KEY) return `${SERVICE_API_KEY.Firefly}${ERROR_MESSAGES_FLAG.MISSING_KEY}`
13363
-
13530
+ const missingParamsError = checkRequiredParams({ contentType, identifier });
13531
+ if (missingParamsError) {
13532
+ return missingParamsError
13533
+ }
13364
13534
  if (end > MAX_PAGE_LIMIT) {
13365
- return ERROR_MESSAGES_FLAG.MAX_PAGE_LIMIT
13535
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.MAX_PAGE_LIMIT)
13366
13536
  }
13537
+ const API_KEY = window.localStorage.getItem(SERVICES_API_KEY.Firefly);
13538
+ if (!API_KEY) return errorMessageHandler(ERROR_MESSAGES_FLAG.MISSING_KEY, SERVICES_API_KEY.Firefly)
13367
13539
 
13368
13540
  const baseUrl = 'https://openapi.firefly.land/v1/fileverse/fetch';
13369
13541
  const headers = { 'x-api-key': API_KEY };
@@ -13372,10 +13544,10 @@ async function LENS() {
13372
13544
  posts: 'lensid',
13373
13545
  replies: 'lenspostid'
13374
13546
  };
13375
-
13376
- const platformType = typeMap[contentType];
13377
- if (!platformType) return `Lens: ${ERROR_MESSAGES_FLAG.INVALID_TYPE}`
13378
-
13547
+ const platformContentType = typeMap[contentType];
13548
+ if (!platformContentType) {
13549
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.INVALID_PARAM, { contentType })
13550
+ }
13379
13551
  const query = identifier
13380
13552
  .split(',')
13381
13553
  .map((s) => s.trim())
@@ -13384,13 +13556,15 @@ async function LENS() {
13384
13556
 
13385
13557
  const url = new URL(baseUrl);
13386
13558
  url.searchParams.set('query', query);
13387
- url.searchParams.set('type', platformType);
13559
+ url.searchParams.set('type', platformContentType);
13388
13560
  url.searchParams.set('start', String(start));
13389
13561
  url.searchParams.set('end', String(end));
13390
13562
 
13391
13563
  try {
13392
13564
  const res = await fetch(url.toString(), { headers });
13393
- if (!res.ok) throw new Error(`HTTP ${res.status}`)
13565
+ if (!res.ok) {
13566
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.NETWORK_ERROR, res.status)
13567
+ }
13394
13568
 
13395
13569
  const json = await res.json();
13396
13570
  if (!Array.isArray(json?.data)) return []
@@ -13406,18 +13580,21 @@ async function LENS() {
13406
13580
  return flat
13407
13581
  })
13408
13582
  } catch (err) {
13409
- console.error('LENS fetch error:', err);
13410
- return ERROR_MESSAGES_FLAG.DEFAULT
13583
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.DEFAULT, err)
13411
13584
  }
13412
13585
  }
13413
13586
 
13414
13587
  async function FARCASTER() {
13415
13588
  const [contentType, identifier, start = 0, end = 10] = argsToArray(arguments);
13416
- const API_KEY = window.localStorage.getItem(SERVICE_API_KEY.Firefly);
13417
- if (!API_KEY) return `${SERVICE_API_KEY.Firefly}${ERROR_MESSAGES_FLAG.MISSING_KEY}`
13589
+ const missingParamsError = checkRequiredParams({ contentType, identifier });
13590
+ if (missingParamsError) {
13591
+ return missingParamsError
13592
+ }
13418
13593
  if (end > MAX_PAGE_LIMIT) {
13419
- return ERROR_MESSAGES_FLAG.MAX_PAGE_LIMIT
13594
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.MAX_PAGE_LIMIT)
13420
13595
  }
13596
+ const API_KEY = window.localStorage.getItem(SERVICES_API_KEY.Firefly);
13597
+ if (!API_KEY) return errorMessageHandler(ERROR_MESSAGES_FLAG.MISSING_KEY, SERVICES_API_KEY.Firefly)
13421
13598
  const baseUrl = 'https://openapi.firefly.land/v1/fileverse/fetch';
13422
13599
  const headers = { 'x-api-key': API_KEY };
13423
13600
 
@@ -13427,9 +13604,10 @@ async function FARCASTER() {
13427
13604
  channels: 'farcasterchannels'
13428
13605
  };
13429
13606
 
13430
- const platformType = typeMap[contentType];
13431
- if (!platformType) return `Farcaster: ${ERROR_MESSAGES_FLAG.INVALID_TYPE}`
13432
-
13607
+ const platformContentType = typeMap[contentType];
13608
+ if (!platformContentType) {
13609
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.INVALID_PARAM, { contentType })
13610
+ }
13433
13611
  const query = identifier
13434
13612
  .split(',')
13435
13613
  .map((s) => s.trim())
@@ -13438,13 +13616,13 @@ async function FARCASTER() {
13438
13616
 
13439
13617
  const url = new URL(baseUrl);
13440
13618
  url.searchParams.set('query', query);
13441
- url.searchParams.set('type', platformType);
13619
+ url.searchParams.set('type', platformContentType);
13442
13620
  url.searchParams.set('start', String(start));
13443
13621
  url.searchParams.set('end', String(end));
13444
13622
 
13445
13623
  try {
13446
13624
  const res = await fetch(url.toString(), { headers });
13447
- if (!res.ok) throw new Error(`HTTP ${res.status}`)
13625
+ if (!res.ok) return errorMessageHandler(ERROR_MESSAGES_FLAG.NETWORK_ERROR, res.status)
13448
13626
 
13449
13627
  const json = await res.json();
13450
13628
  if (!Array.isArray(json?.data)) return []
@@ -13460,24 +13638,24 @@ async function FARCASTER() {
13460
13638
  return flat
13461
13639
  })
13462
13640
  } catch (err) {
13463
- console.error('Farcaster fetch error:', err);
13464
- return ERROR_MESSAGES_FLAG.DEFAULT
13641
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.DEFAULT, err)
13465
13642
  }
13466
13643
  }
13467
13644
 
13468
13645
  async function BLOCKSCOUT() {
13469
13646
  let [address, type, chain, startTimestamp, endTimestamp, page = 1, offset = 10] = argsToArray(arguments);
13647
+ const missingParamsError = checkRequiredParams({ address, type });
13648
+
13649
+ if (missingParamsError) {
13650
+ return missingParamsError
13651
+ }
13470
13652
  if (offset > MAX_PAGE_LIMIT) {
13471
- return ERROR_MESSAGES_FLAG.MAX_PAGE_LIMIT
13653
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.MAX_PAGE_LIMIT)
13472
13654
  }
13473
13655
  if (!chain) {
13474
13656
  chain = 'ethereum';
13475
13657
  }
13476
13658
 
13477
- if (!type) {
13478
- return 'TYPE_MISSING'
13479
- }
13480
-
13481
13659
  if (!startTimestamp) {
13482
13660
  const currentTimestamp = Date.now();
13483
13661
  startTimestamp = currentTimestamp - 30 * 24 * 60 * 60 * 1000;
@@ -13492,16 +13670,19 @@ async function BLOCKSCOUT() {
13492
13670
  endTimestamp = toTimestamp(endTimestamp);
13493
13671
  }
13494
13672
 
13495
- if (!isAddress(address)) {
13496
- address = await fromEnsNameToAddress(address);
13673
+ if (!isAddress$1.isAddress(address)) {
13674
+ const ensName = address;
13675
+ address = await fromEnsNameToAddress$1.fromEnsNameToAddress(address);
13676
+ if (!address) {
13677
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.ENS, ensName)
13678
+ }
13497
13679
  }
13680
+ const hostname = BLOCKSCOUT_CHAINS_MAP[chain];
13498
13681
 
13499
- if (!address) {
13500
- return `${address}${ERROR_MESSAGES_FLAG.INVALID_PARAM}`
13682
+ if (!hostname) {
13683
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.INVALID_CHAIN, chain)
13501
13684
  }
13502
13685
 
13503
- const hostname = BLOCKSCOUT_CHAINS_MAP[chain];
13504
-
13505
13686
  let requestUrl;
13506
13687
 
13507
13688
  switch (type) {
@@ -13515,22 +13696,26 @@ async function BLOCKSCOUT() {
13515
13696
  requestUrl = `${hostname}/api?module=account&action=tokenlist&address=${address}`;
13516
13697
  break
13517
13698
  default:
13518
- return 'INVALID_TYPE'
13699
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.INVALID_PARAM, { type })
13519
13700
  }
13520
13701
  try {
13521
13702
  const response = await fetch(requestUrl);
13522
13703
 
13523
13704
  if (!response.ok) {
13524
- throw new Error(`HTTP error! Status: ${response.status}`)
13705
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.NETWORK_ERROR, response.status)
13525
13706
  }
13526
13707
  const json = await response.json();
13527
-
13528
- console.log(json);
13529
13708
  if (json?.result?.includes('Invalid parameter(s)')) {
13530
- return `INVALID_REQUEST_PARAMS`
13709
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.CUSTOM, {
13710
+ message: 'Invalid parameters',
13711
+ reason: json.result
13712
+ })
13531
13713
  }
13532
13714
  if (json?.result?.includes('Not found')) {
13533
- return `ADDRESS_NOT_FOUND`
13715
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.CUSTOM, {
13716
+ message: 'Address information not found',
13717
+ reason: json.result
13718
+ })
13534
13719
  }
13535
13720
 
13536
13721
  if (type === 'stat') {
@@ -13550,52 +13735,75 @@ async function BLOCKSCOUT() {
13550
13735
  */
13551
13736
  return json.result
13552
13737
  } catch (error) {
13553
- return 'ERROR IN FETCHING'
13738
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.DEFAULT, error)
13554
13739
  }
13555
13740
  }
13556
13741
 
13557
13742
  async function BASE() {
13558
- const [type, chain, address, startDate, endDate, page, limit] = argsToArray(arguments);
13743
+ const [type, address, startDate, endDate, page, limit] = argsToArray(arguments);
13744
+ const missingParamsError = checkRequiredParams({ type, address });
13745
+
13746
+ if (missingParamsError) {
13747
+ return missingParamsError
13748
+ }
13749
+ const API_KEY = window.localStorage.getItem(SERVICES_API_KEY.Basescan);
13750
+ if (!API_KEY) return errorMessageHandler(ERROR_MESSAGES_FLAG.MISSING_KEY, SERVICES_API_KEY.Basescan)
13751
+ if (limit > MAX_PAGE_LIMIT) {
13752
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.MAX_PAGE_LIMIT)
13753
+ }
13559
13754
  return handleScanRequest({
13560
- scanKey: SERVICE_API_KEY.Basescan,
13561
- baseUrl: 'https://api.basescan.org/api',
13562
13755
  type,
13563
- chain,
13564
13756
  address,
13565
13757
  startDate,
13566
13758
  endDate,
13567
13759
  page,
13568
- offset: limit
13760
+ offset: limit,
13761
+ apiKey: API_KEY,
13762
+ functionName: 'BASE',
13763
+ chainId: CHAIN_ID_MAP.base,
13764
+ network: 'base'
13569
13765
  })
13570
13766
  }
13571
13767
  async function GNOSIS() {
13572
- const [type, chain, address, startDate, endDate, page, limit] = argsToArray(arguments);
13768
+ const [type, address, startDate, endDate, page, limit] = argsToArray(arguments);
13769
+ const missingParamsError = checkRequiredParams({ type, address });
13770
+
13771
+ if (missingParamsError) {
13772
+ return missingParamsError
13773
+ }
13774
+ const API_KEY = window.localStorage.getItem(SERVICES_API_KEY.Gnosisscan);
13775
+ if (!API_KEY) return errorMessageHandler(ERROR_MESSAGES_FLAG.MISSING_KEY, SERVICES_API_KEY.Gnosisscan)
13776
+ if (limit > MAX_PAGE_LIMIT) {
13777
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.MAX_PAGE_LIMIT)
13778
+ }
13573
13779
  return handleScanRequest({
13574
- scanKey: SERVICE_API_KEY.Gnosisscan,
13575
- baseUrl: 'https://api.gnosisscan.io/api',
13576
13780
  type,
13577
- chain,
13781
+ network: 'gnosis',
13578
13782
  address,
13579
13783
  startDate,
13580
13784
  endDate,
13581
13785
  page,
13582
- offset: limit
13786
+ apiKey: API_KEY,
13787
+ offset: limit,
13788
+ chainId: CHAIN_ID_MAP.gnosis,
13789
+ functionName: 'GNOSIS'
13583
13790
  })
13584
13791
  }
13585
13792
 
13586
13793
  async function NEYNAR() {
13587
13794
  const [username] = argsToArray(arguments);
13588
- const API_KEY = window.localStorage.getItem(SERVICE_API_KEY.Neynar);
13589
- if (!API_KEY) return `${SERVICE_API_KEY.Neynar}${ERROR_MESSAGES_FLAG.MISSING_KEY}`
13795
+ const missingParamsError = checkRequiredParams({ username });
13590
13796
 
13591
- if (!username) {
13592
- return `${SERVICE_API_KEY.Neynar}${ERROR_MESSAGES_FLAG.INVALID_PARAM}`
13797
+ if (missingParamsError) {
13798
+ return missingParamsError
13593
13799
  }
13800
+ const API_KEY = window.localStorage.getItem(SERVICES_API_KEY.Neynar);
13801
+ if (!API_KEY) return errorMessageHandler(ERROR_MESSAGES_FLAG.MISSING_KEY, SERVICES_API_KEY.Neynar)
13594
13802
 
13595
- const fid = await fromUsernameToFid(username, API_KEY);
13803
+ const fid = await fromUsernameToFid$1.fromUsernameToFid(username, API_KEY);
13596
13804
 
13597
13805
  if (!fid) {
13598
- return `${SERVICE_API_KEY.Neynar}${ERROR_MESSAGES_FLAG.INVALID_PARAM}`
13806
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.INVALID_PARAM, { username })
13599
13807
  }
13600
13808
 
13601
13809
  const url = `https://api.neynar.com/v2/farcaster/followers?fid=${fid}`;
@@ -13607,7 +13815,9 @@ async function NEYNAR() {
13607
13815
  'x-neynar-experimental': 'false'
13608
13816
  }
13609
13817
  });
13610
- if (!response.ok) throw new Error(`HTTP ${response.status}`)
13818
+ if (!response.ok) {
13819
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.NETWORK_ERROR, response.status)
13820
+ }
13611
13821
  const json = await response.json();
13612
13822
  if (!json?.users?.length) return []
13613
13823
 
@@ -13619,83 +13829,108 @@ async function NEYNAR() {
13619
13829
  city: user.profile?.location?.address?.city || ''
13620
13830
  }))
13621
13831
  } catch (err) {
13622
- console.error('NEYNAR_FETCH_FOLLOWERS error:', err);
13623
- return ERROR_MESSAGES_FLAG.DEFAULT
13624
- }
13625
- }
13626
- async function GNOSISPAY({ cardId, startDate, endDate, limit = 20, offset = 0 }) {
13627
- const apiKeyKey = SERVICE_API_KEY.GnosisPay;
13628
- const API_KEY = window.localStorage.getItem(apiKeyKey);
13629
- if (!API_KEY) return `${apiKeyKey}${ERROR_MESSAGES_FLAG.MISSING_KEY}`
13630
- if (!cardId) return `${apiKeyKey}${ERROR_MESSAGES_FLAG.INVALID_PARAM}`
13631
- if (limit > MAX_PAGE_LIMIT) {
13632
- return ERROR_MESSAGES_FLAG.MAX_PAGE_LIMIT
13633
- }
13634
-
13635
- const url = new URL(`https://api.gnosispay.com/cards/${cardId}/transactions`);
13636
- url.searchParams.set('limit', limit.toString());
13637
- url.searchParams.set('offset', offset.toString());
13832
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.DEFAULT, err)
13833
+ }
13834
+ }
13835
+ // export async function GNOSISPAY({
13836
+ // cardId,
13837
+ // startDate,
13838
+ // endDate,
13839
+ // limit = 20,
13840
+ // offset = 0,
13841
+ // }) {
13842
+ // const apiKeyKey = SERVICES_API_KEY.GnosisPay
13843
+ // const API_KEY = window.localStorage.getItem(apiKeyKey);
13844
+ // if (!API_KEY) return `${apiKeyKey}${ERROR_MESSAGES_FLAG.MISSING_KEY}`;
13845
+ // if (!cardId) return `${apiKeyKey}${ERROR_MESSAGES_FLAG.INVALID_PARAM}`;
13846
+ // if(limit > MAX_PAGE_LIMIT){
13847
+ // return ERROR_MESSAGES_FLAG.MAX_PAGE_LIMIT
13848
+ // }
13638
13849
 
13639
- if (!isNaN(toTimestamp(startDate))) {
13640
- url.searchParams.set('startDate', new Date(startDate * 1000).toISOString());
13641
- }
13850
+ // const url = new URL(`https://api.gnosispay.com/cards/${cardId}/transactions`);
13851
+ // url.searchParams.set('limit', limit.toString());
13852
+ // url.searchParams.set('offset', offset.toString());
13642
13853
 
13643
- if (!isNaN(toTimestamp(endDate))) {
13644
- url.searchParams.set('endDate', new Date(endDate * 1000).toISOString());
13645
- }
13854
+ // if (!isNaN(toTimestamp(startDate))) {
13855
+ // url.searchParams.set('startDate', new Date(startDate * 1000).toISOString());
13856
+ // }
13646
13857
 
13647
- try {
13648
- const res = await fetch(url.toString(), {
13649
- headers: {
13650
- Authorization: `Bearer ${API_KEY}`,
13651
- 'Content-Type': 'application/json'
13652
- }
13653
- });
13858
+ // if (!isNaN(toTimestamp(endDate))) {
13859
+ // url.searchParams.set('endDate', new Date(endDate * 1000).toISOString());
13860
+ // }
13654
13861
 
13655
- if (!res.ok) throw new Error(`HTTP error! Status: ${res.status}`)
13862
+ // try {
13863
+ // const res = await fetch(url.toString(), {
13864
+ // headers: {
13865
+ // Authorization: `Bearer ${API_KEY}`,
13866
+ // 'Content-Type': 'application/json',
13867
+ // },
13868
+ // });
13869
+
13870
+ // if (!res.ok) throw new Error(`HTTP error! Status: ${res.status}`);
13871
+
13872
+ // const json = await res.json();
13873
+
13874
+ // if (!Array.isArray(json)) return [];
13875
+
13876
+ // return json.map(tx => ({
13877
+ // createdAt: tx.createdAt,
13878
+ // clearedAt: tx.clearedAt,
13879
+ // country: tx.country,
13880
+ // merchant: tx.merchant,
13881
+ // billingAmount: tx.billingAmount,
13882
+ // billingCurrency: tx.billingCurrency,
13883
+ // transactionAmount: tx.transactionAmount,
13884
+ // transactionCurrency: tx.transactionCurrency,
13885
+ // transactionType: tx.transactionType,
13886
+ // kind: tx.kind,
13887
+ // status: tx.status || null,
13888
+ // mcc: tx.mcc,
13889
+ // }));
13890
+ // } catch (err) {
13891
+ // console.error('GNOSISPAY_CARD_TXNS error:', err);
13892
+ // return ERROR_MESSAGES_FLAG.DEFAULT;
13893
+ // }
13894
+ // }
13656
13895
 
13657
- const json = await res.json();
13896
+ async function ETHERSCAN(...args) {
13897
+ const [type, chain, address, startDate, endDate, page, limit] = args;
13898
+ const missingParamsError = checkRequiredParams({ type, address, chain });
13658
13899
 
13659
- if (!Array.isArray(json)) return []
13660
-
13661
- return json.map((tx) => ({
13662
- createdAt: tx.createdAt,
13663
- clearedAt: tx.clearedAt,
13664
- country: tx.country,
13665
- merchant: tx.merchant,
13666
- billingAmount: tx.billingAmount,
13667
- billingCurrency: tx.billingCurrency,
13668
- transactionAmount: tx.transactionAmount,
13669
- transactionCurrency: tx.transactionCurrency,
13670
- transactionType: tx.transactionType,
13671
- kind: tx.kind,
13672
- status: tx.status || null,
13673
- mcc: tx.mcc
13674
- }))
13675
- } catch (err) {
13676
- console.error('GNOSISPAY_CARD_TXNS error:', err);
13677
- return ERROR_MESSAGES_FLAG.DEFAULT
13900
+ if (missingParamsError) {
13901
+ return missingParamsError
13678
13902
  }
13679
- }
13680
13903
 
13681
- async function ETHERSCAN(...args) {
13682
- const [type, chain, address, startDate, endDate, page, limit] = args;
13904
+ const chainId = CHAIN_ID_MAP[chain];
13905
+
13906
+ if (!chainId?.toString()) {
13907
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.INVALID_CHAIN, chain)
13908
+ }
13909
+ const API_KEY = window.localStorage.getItem(SERVICES_API_KEY.Etherscan);
13910
+ if (!API_KEY) return errorMessageHandler(ERROR_MESSAGES_FLAG.MISSING_KEY, SERVICES_API_KEY.Etherscan)
13683
13911
  return handleScanRequest({
13684
- scanKey: SERVICE_API_KEY.Etherscan,
13685
- baseUrl: 'https://api.etherscan.io/v2/api',
13686
13912
  type,
13687
- chain,
13688
13913
  address,
13689
13914
  startDate,
13690
13915
  endDate,
13691
13916
  page,
13692
- offset: limit
13917
+ offset: limit,
13918
+ chainId,
13919
+ network: chain,
13920
+ functionName: 'ETHERSCAN',
13921
+ apiKey: API_KEY
13693
13922
  })
13694
13923
  }
13695
13924
 
13696
- async function COINGECKO(category, param1, param2) {
13697
- const API_KEY = window.localStorage.getItem(SERVICE_API_KEY.Coingecko);
13698
- if (!API_KEY) return `${SERVICE_API_KEY.Coingecko}${ERROR_MESSAGES_FLAG.MISSING_KEY}`
13925
+ async function COINGECKO() {
13926
+ const [category, param1, param2] = argsToArray(arguments);
13927
+ const missingParamsError = checkRequiredParams({ category, param1 });
13928
+
13929
+ if (missingParamsError) {
13930
+ return missingParamsError
13931
+ }
13932
+ const API_KEY = window.localStorage.getItem(SERVICES_API_KEY.Coingecko);
13933
+ if (!API_KEY) return errorMessageHandler(ERROR_MESSAGES_FLAG.MISSING_KEY, SERVICES_API_KEY.Coingecko)
13699
13934
 
13700
13935
  const headers = {
13701
13936
  accept: 'application/json',
@@ -13703,14 +13938,14 @@ async function COINGECKO(category, param1, param2) {
13703
13938
  };
13704
13939
 
13705
13940
  let url = '';
13706
- const lowerCategory = (category || '').toLowerCase();
13941
+ const lowerCategory = (category || '').toLowerCase?.();
13707
13942
 
13708
13943
  switch (lowerCategory) {
13709
13944
  case 'price': {
13710
13945
  const token = param1;
13711
13946
  const vsCurrencies = param2;
13712
13947
  if (!token) {
13713
- return `${SERVICE_API_KEY.Coingecko}${ERROR_MESSAGES_FLAG.INVALID_PARAM}`
13948
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.INVALID_PARAM, { param1 })
13714
13949
  }
13715
13950
  url = `https://api.coingecko.com/api/v3/simple/price?vs_currencies=${vsCurrencies ? vsCurrencies : 'usd'}&symbols=${token}`;
13716
13951
  break
@@ -13759,7 +13994,7 @@ async function COINGECKO(category, param1, param2) {
13759
13994
  }
13760
13995
 
13761
13996
  default:
13762
- return `${SERVICE_API_KEY.Coingecko}${ERROR_MESSAGES_FLAG.INVALID_PARAM}`
13997
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.INVALID_PARAM, { category })
13763
13998
  }
13764
13999
 
13765
14000
  try {
@@ -13768,12 +14003,10 @@ async function COINGECKO(category, param1, param2) {
13768
14003
 
13769
14004
  if (!response.ok) {
13770
14005
  const message = json?.status?.error_message || '';
13771
- if (response.status === 429) {
13772
- return `${SERVICE_API_KEY.Coingecko}${ERROR_MESSAGES_FLAG.RATE_LIMIT}`
13773
- }
13774
14006
  if (message.includes('API Key Missing')) {
13775
- return `${SERVICE_API_KEY.Coingecko}${ERROR_MESSAGES_FLAG.INVALID_API_KEY}`
14007
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.INVALID_API_KEY, SERVICES_API_KEY.Coingecko)
13776
14008
  }
14009
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.NETWORK_ERROR, response.status)
13777
14010
  }
13778
14011
 
13779
14012
  if (lowerCategory === 'price') {
@@ -13826,18 +14059,27 @@ async function COINGECKO(category, param1, param2) {
13826
14059
  return flat
13827
14060
  })
13828
14061
  } catch (error) {
13829
- console.error(error);
13830
- return ERROR_MESSAGES_FLAG.DEFAULT
14062
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.DEFAULT, error)
13831
14063
  }
13832
14064
  }
13833
14065
 
13834
14066
  async function EOA() {
13835
- const API_KEY = window.localStorage.getItem(SERVICE_API_KEY.Etherscan);
13836
- if (!API_KEY) return `${SERVICE_API_KEY.Etherscan}${ERROR_MESSAGES_FLAG.MISSING_KEY}`
13837
14067
  let [addresses, category, chains, startTime, endTime, page = 1, offset = 10] = argsToArray(arguments);
14068
+
14069
+ const optionalParams = category === 'balance' ? {} : {startTime, endTime};
14070
+
14071
+ const missingParamsError = checkRequiredParams({ addresses, category, chains, ...optionalParams });
14072
+
14073
+ if (missingParamsError) {
14074
+ return missingParamsError
14075
+ }
14076
+
13838
14077
  if (offset > MAX_PAGE_LIMIT) {
13839
- return ERROR_MESSAGES_FLAG.MAX_PAGE_LIMIT
14078
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.MAX_PAGE_LIMIT)
13840
14079
  }
14080
+
14081
+ const API_KEY = window.localStorage.getItem(SERVICES_API_KEY.Etherscan);
14082
+ if (!API_KEY) return errorMessageHandler(ERROR_MESSAGES_FLAG.MISSING_KEY, SERVICES_API_KEY.Etherscan)
13841
14083
  const INPUTS = addresses
13842
14084
  .split(',')
13843
14085
  .map((a) => a.trim())
@@ -13850,21 +14092,21 @@ async function EOA() {
13850
14092
  // Map: finalAddress => ENS name (if applicable)
13851
14093
  const ADDRESS_MAP = {};
13852
14094
  for (const input of INPUTS) {
13853
- if (isAddress(input)) {
14095
+ if (isAddress$1.isAddress(input)) {
13854
14096
  ADDRESS_MAP[input.toLowerCase()] = null; // it's a direct address
13855
14097
  } else {
13856
14098
  try {
13857
- const resolved = await fromEnsNameToAddress(input); // ENS -> address
14099
+ const resolved = await fromEnsNameToAddress$1.fromEnsNameToAddress(input); // ENS -> address
13858
14100
  if (resolved) ADDRESS_MAP[resolved.toLowerCase()] = input;
13859
14101
  } catch {
13860
- return `${input}${ERROR_MESSAGES_FLAG.INVALID_PARAM}`
14102
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.INVALID_PARAM, { addresses })
13861
14103
  }
13862
14104
  }
13863
14105
  }
13864
14106
  const ADDRS = Object.keys(ADDRESS_MAP);
13865
14107
  for (const chain of CHAINS) {
13866
14108
  const chainId = CHAIN_ID_MAP[chain];
13867
- if (!chainId) return ERROR_MESSAGES_FLAG.UNSUPPORTED_CHAIN
14109
+ if (!chainId) return errorMessageHandler(ERROR_MESSAGES_FLAG.INVALID_CHAIN, chain)
13868
14110
  if (category === 'balance') {
13869
14111
  for (let i = 0; i < ADDRS.length; i += 20) {
13870
14112
  const slice = ADDRS.slice(i, i + 20).join(',');
@@ -13873,8 +14115,8 @@ async function EOA() {
13873
14115
  `https://api.etherscan.io/v2/api?chainid=${chainId}` +
13874
14116
  `&module=account&action=${action}&address=${slice}` +
13875
14117
  `&page=${page}&offset=100&apikey=${API_KEY}`;
13876
- const data = await fetchJSON(url);
13877
- if (typeof data === 'string') return data
14118
+ const data = await fetchJSON(url, 'EOA');
14119
+ if (!Array.isArray(data)) return data
13878
14120
  data.forEach((tx) =>
13879
14121
  out.push({
13880
14122
  chain,
@@ -13887,16 +14129,22 @@ async function EOA() {
13887
14129
  continue
13888
14130
  }
13889
14131
  if (category === 'txns') {
13890
- const startBlock = await fromTimeStampToBlock(toTimestamp(startTime), chain, API_KEY);
13891
- const endBlock = await fromTimeStampToBlock(toTimestamp(endTime), chain, API_KEY);
14132
+ const startBlock = await fromTimestampToBlock.fromTimeStampToBlock(toTimestamp(startTime), chain, API_KEY);
14133
+ const endBlock = await fromTimestampToBlock.fromTimeStampToBlock(toTimestamp(endTime), chain, API_KEY);
14134
+ if (!startBlock?.toString()) {
14135
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.INVALID_PARAM, { startTime })
14136
+ }
14137
+ if (!endBlock?.toString()) {
14138
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.INVALID_PARAM, { endTime })
14139
+ }
13892
14140
  for (const addr of ADDRS) {
13893
14141
  const url =
13894
14142
  `https://api.etherscan.io/v2/api?chainid=${chainId}` +
13895
14143
  `&module=account&action=tokentx&address=${addr}` +
13896
14144
  `&startblock=${startBlock}&endblock=${endBlock}` +
13897
14145
  `&page=${page}&offset=${offset}&sort=asc&apikey=${API_KEY}`;
13898
- const data = await fetchJSON(url);
13899
- if (typeof data === 'string') return data
14146
+ const data = await fetchJSON(url, 'EOA');
14147
+ if (!Array.isArray(data)) return data
13900
14148
  data.forEach((tx) =>
13901
14149
  out.push({
13902
14150
  chain,
@@ -13908,29 +14156,35 @@ async function EOA() {
13908
14156
  }
13909
14157
  continue
13910
14158
  }
13911
- return ERROR_MESSAGES_FLAG.INVALID_CATEGORY
14159
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.INVALID_PARAM, { category })
13912
14160
  }
13913
14161
 
13914
14162
  return out
13915
14163
 
13916
- async function fetchJSON(url) {
14164
+ async function fetchJSON(url, fnName) {
13917
14165
  try {
13918
14166
  const res = await fetch(url);
13919
- if (!res.ok) return `HTTP_${res.status}`
14167
+ if (!res.ok) {
14168
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.NETWORK_ERROR, res.status, fnName)
14169
+ }
13920
14170
 
13921
14171
  const json = await res.json();
13922
14172
 
13923
14173
  if (json.result?.includes?.('Invalid API Key'))
13924
- return `${SERVICE_API_KEY.Etherscan}${ERROR_MESSAGES_FLAG.INVALID_API_KEY}`
14174
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.INVALID_API_KEY, SERVICES_API_KEY.Etherscan, fnName)
13925
14175
 
13926
14176
  if (json.result?.includes?.('Max rate limit reached'))
13927
- return `${SERVICE_API_KEY.Etherscan}${ERROR_MESSAGES_FLAG.RATE_LIMIT}`
14177
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.RATE_LIMIT, SERVICES_API_KEY.Etherscan, fnName)
13928
14178
 
13929
- if (json.status === '0' && json.message !== 'No transactions found') return ERROR_MESSAGES_FLAG.DEFAULT
14179
+ if (json.status === '0' && json.message !== 'No transactions found')
14180
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.CUSTOM, {
14181
+ message: 'Api Error',
14182
+ reason: json?.result || 'json.status === "0" && json.message !== "No transactions found"'
14183
+ }, fnName)
13930
14184
 
13931
14185
  return json.result
13932
- } catch {
13933
- return ERROR_MESSAGES_FLAG.DEFAULT
14186
+ } catch (err) {
14187
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.DEFAULT, err, fnName)
13934
14188
  }
13935
14189
  }
13936
14190
  }
@@ -13946,25 +14200,38 @@ async function FLVURL(token, vs_currencies) {
13946
14200
  async function SAFE() {
13947
14201
  let [address, utility, chain, limit = 10, offset = 0] = argsToArray(arguments);
13948
14202
 
13949
- if (typeof limit !== 'number' || limit < 0) return 'INVALID_LIMIT'
13950
- if (typeof offset !== 'number' || offset < 0) return 'INVALID_OFFSET'
13951
- if (utility !== 'txns') return 'UTILITY IS NOT SUPPORTED'
13952
- if (limit > MAX_PAGE_LIMIT) {
13953
- return ERROR_MESSAGES_FLAG.MAX_PAGE_LIMIT
14203
+ const missingParamsError = checkRequiredParams({ address, utility, chain });
14204
+
14205
+ if (missingParamsError) {
14206
+ return missingParamsError
13954
14207
  }
13955
14208
 
13956
- const apiKey = window.localStorage.getItem(SERVICE_API_KEY.Safe);
13957
- const chainIdentifier = SAFE_CHAIN_MAP[chain];
14209
+ if (offset > MAX_PAGE_LIMIT) {
14210
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.MAX_PAGE_LIMIT)
14211
+ }
14212
+
14213
+ const apiKey = window.localStorage.getItem(SERVICES_API_KEY.Safe);
13958
14214
 
13959
- if (!apiKey) return `${SERVICE_API_KEY.Safe}_MISSING`
13960
- if (!chainIdentifier) return 'CHAIN IS NOT SUPPORTED'
14215
+ if (!apiKey) return errorMessageHandler(ERROR_MESSAGES_FLAG.MISSING_KEY, SERVICES_API_KEY.Safe)
13961
14216
 
13962
- if (!isAddress(address)) {
13963
- address = await fromEnsNameToAddress(address);
14217
+ if (typeof limit !== 'number' || limit < 0) return errorMessageHandler(ERROR_MESSAGES_FLAG.INVALID_PARAM, { limit })
14218
+ if (typeof offset !== 'number' || offset < 0)
14219
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.INVALID_PARAM, { offset })
14220
+ if (utility !== 'txns') return errorMessageHandler(ERROR_MESSAGES_FLAG.INVALID_PARAM, { utility })
14221
+ if (limit > MAX_PAGE_LIMIT) {
14222
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.MAX_PAGE_LIMIT)
13964
14223
  }
13965
14224
 
13966
- if (!address) {
13967
- return `${address}${ERROR_MESSAGES_FLAG.INVALID_PARAM}`
14225
+ const chainIdentifier = SAFE_CHAIN_MAP[chain];
14226
+
14227
+ if (!chainIdentifier) return errorMessageHandler(ERROR_MESSAGES_FLAG.INVALID_CHAIN, chain)
14228
+
14229
+ if (!isAddress$1.isAddress(address)) {
14230
+ const ensName = address;
14231
+ address = await fromEnsNameToAddress$1.fromEnsNameToAddress(address);
14232
+ if (!address) {
14233
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.ENS, ensName)
14234
+ }
13968
14235
  }
13969
14236
 
13970
14237
  const url = `https://api.safe.global/tx-service/${chainIdentifier}/api/v2/safes/${address}/multisig-transactions?limit=${limit}&offset=${offset}`;
@@ -13974,23 +14241,29 @@ async function SAFE() {
13974
14241
  Authorization: `Bearer ${apiKey}`
13975
14242
  }
13976
14243
  });
13977
- if (!response.ok) throw new Error(`HTTP error! Status: ${response.status}`)
14244
+ if (!response.ok) {
14245
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.NETWORK_ERROR, response.status)
14246
+ }
13978
14247
  const json = await response.json();
13979
14248
  if (!Array.isArray(json.results)) {
13980
- return 'INVALID API RESPONSE'
14249
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.CUSTOM, { message: 'Invalid API response' })
13981
14250
  }
13982
14251
  // remove nested structure from the response
13983
14252
  return json.results.map(({ confirmations, dataDecoded, ...rest }) => rest)
13984
14253
  } catch (e) {
13985
- console.log(e);
13986
- return 'ERROR IN FETCHING'
14254
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.DEFAULT, e)
13987
14255
  }
13988
14256
  }
13989
14257
 
13990
14258
  async function DEFILLAMA() {
13991
14259
  let [category] = argsToArray(arguments);
13992
- const apiKey = window.localStorage.getItem(SERVICE_API_KEY.Defillama);
13993
- if (!apiKey) return `${SERVICE_API_KEY.Defillama}${ERROR_MESSAGES_FLAG.MISSING_KEY}`
14260
+ const missingParamsError = checkRequiredParams({ category });
14261
+
14262
+ if (missingParamsError) {
14263
+ return missingParamsError
14264
+ }
14265
+ const apiKey = window.localStorage.getItem(SERVICES_API_KEY.Defillama);
14266
+ if (!apiKey) return errorMessageHandler(ERROR_MESSAGES_FLAG.MISSING_KEY, SERVICES_API_KEY.Defillama)
13994
14267
  const categoryList = ['protocols', 'yields', 'dex', 'fees'];
13995
14268
  const categoryMap = {
13996
14269
  [categoryList[0]]: 'https://api.llama.fi/protocols',
@@ -14002,9 +14275,13 @@ async function DEFILLAMA() {
14002
14275
  };
14003
14276
  let url = categoryMap[category];
14004
14277
 
14278
+ if (!url) {
14279
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.INVALID_PARAM, { category })
14280
+ }
14281
+
14005
14282
  try {
14006
14283
  const response = await fetch(url);
14007
- if (!response.ok) throw new Error(`HTTP error! Status: ${response.status}`)
14284
+ if (!response.ok) return errorMessageHandler(ERROR_MESSAGES_FLAG.NETWORK_ERROR, response.status)
14008
14285
  let json = await response.json();
14009
14286
  switch (category) {
14010
14287
  case categoryList[0]: {
@@ -14029,38 +14306,59 @@ async function DEFILLAMA() {
14029
14306
 
14030
14307
  return removeNestedStructure(Array.isArray(json) ? json : [json])
14031
14308
  } catch (e) {
14032
- console.log(e);
14033
- return 'ERROR IN FETCHING'
14309
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.DEFAULT, e)
14034
14310
  }
14035
14311
  }
14036
14312
 
14037
14313
  async function UNISWAP() {
14038
14314
  const [graphType, category, param1, param2] = argsToArray(arguments);
14315
+ const missingParamsError = checkRequiredParams({ graphType, category, param1 });
14316
+
14317
+ if (missingParamsError) {
14318
+ return missingParamsError
14319
+ }
14039
14320
  const baseUrl = 'https://onchain-proxy.fileverse.io/third-party';
14040
14321
  try {
14041
14322
  const url = `${baseUrl}?service=uniswap&graphType=${graphType}&category=${category}&input1=${param1}&input2=${param2}`;
14042
14323
  const res = await fetch(url);
14043
- if (!res.ok) throw new Error(`HTTP ${res.status}`)
14324
+ if (!res.ok) {
14325
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.NETWORK_ERROR, res.status)
14326
+ }
14044
14327
  const json = await res.json();
14045
- return removeNestedStructure(json)
14328
+ if(Array.isArray(json)){
14329
+ return removeNestedStructure(json)
14330
+ } else {
14331
+ return json
14332
+ }
14333
+
14046
14334
  } catch (err) {
14047
- console.error('UNISWAP fetch error:', err);
14048
- return ERROR_MESSAGES_FLAG.DEFAULT
14335
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.DEFAULT, err)
14049
14336
  }
14050
14337
  }
14051
14338
 
14052
14339
  async function AAVE() {
14053
14340
  const [graphType, category, param1, param2] = argsToArray(arguments);
14341
+ const missingParamsError = checkRequiredParams({ graphType, category, param1 });
14342
+
14343
+ if (missingParamsError) {
14344
+ return missingParamsError
14345
+ }
14054
14346
  const baseUrl = 'https://onchain-proxy.fileverse.io/third-party';
14055
14347
  try {
14056
14348
  const url = `${baseUrl}?service=aave&graphType=${graphType}&category=${category}&input1=${param1}&input2=${param2}`;
14057
14349
  const res = await fetch(url);
14058
- if (!res.ok) throw new Error(`HTTP ${res.status}`)
14350
+ if (!res.ok) {
14351
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.NETWORK_ERROR, res.status)
14352
+ }
14059
14353
  const json = await res.json();
14060
- return removeNestedStructure(json)
14354
+ if(Array.isArray(json)){
14355
+ return removeNestedStructure(json)
14356
+ } else {
14357
+ return json
14358
+ }
14359
+
14061
14360
  } catch (err) {
14062
- console.error('AAVE fetch error:', err);
14063
- return ERROR_MESSAGES_FLAG.DEFAULT
14361
+ return errorMessageHandler(ERROR_MESSAGES_FLAG.DEFAULT, err)
14064
14362
  }
14065
14363
  }
14066
14364
 
@@ -14094,4 +14392,4 @@ function MYANIMELIST() {
14094
14392
 
14095
14393
  const utils = { errors, symbols, date };
14096
14394
 
14097
- export { AAVE, ABS, ACCRINT, ACOS, ACOSH, ACOT, ACOTH, AGGREGATE, AND, ARABIC, ARTEMIS, ASIN, ASINH, ATAN, ATAN2, ATANH, AVEDEV, AVERAGE, AVERAGEA, AVERAGEIF, AVERAGEIFS, BASE, BESSELI, BESSELJ, BESSELK, BESSELY, BETA, BETADIST, BETAINV, BIN2DEC, BIN2HEX, BIN2OCT, BINOM, BINOMDIST, BITAND, BITLSHIFT, BITOR, BITRSHIFT, BITXOR, BLOCKSCOUT, CEILING, CEILINGMATH, CEILINGPRECISE, CHAR, CHIDIST, CHIDISTRT, CHIINV, CHIINVRT, CHISQ, CHITEST, CHOOSE, CLEAN, CODE, COINGECKO, COLUMN, COLUMNS, COMBIN, COMBINA, COMPLEX, CONCAT, CONCATENATE, CONFIDENCE, CONVERT, CORREL, COS, COSH, COT, COTH, COUNT, COUNTA, COUNTBLANK, COUNTIF, COUNTIFS, COUPDAYS, COVAR, COVARIANCE, COVARIANCEP, COVARIANCES, CRITBINOM, CSC, CSCH, CUMIPMT, CUMPRINC, DATE, DATEDIF, DATEVALUE, DAVERAGE, DAY, DAYS, DAYS360, DB, DCOUNT, DCOUNTA, DDB, DEC2BIN, DEC2HEX, DEC2OCT, DECIMAL, DEFILLAMA, DEGREES, DELTA, DEVSQ, DGET, DISC, DMAX, DMIN, DOLLAR, DOLLARDE, DOLLARFR, DPRODUCT, DSTDEV, DSTDEVP, DSUM, DVAR, DVARP, EDATE, EFFECT, EOA, EOMONTH, ERF, ERFC, ERFCPRECISE, ERFPRECISE, ERROR, ETHERSCAN, EVEN, EXACT, EXP, EXPON, EXPONDIST, F, FACT, FACTDOUBLE, FALSE, FARCASTER, FDIST, FDISTRT, FIND, FINV, FINVRT, FIREFLY, FISHER, FISHERINV, FIXED, FLOOR, FLOORMATH, FLOORPRECISE, FLVURL, FORECAST, FREQUENCY, FTEST, FV, FVSCHEDULE, GAMMA, GAMMADIST, GAMMAINV, GAMMALN, GAMMALNPRECISE, GAUSS, GCD, GEOMEAN, GESTEP, GNOSIS, GNOSISPAY, GROWTH, HARMEAN, HEX2BIN, HEX2DEC, HEX2OCT, HLOOKUP, HOUR, HYPGEOM, HYPGEOMDIST, IF, IFERROR, IFNA, IFS, IMABS, IMAGINARY, IMARGUMENT, IMCONJUGATE, IMCOS, IMCOSH, IMCOT, IMCSC, IMCSCH, IMDIV, IMEXP, IMLN, IMLOG10, IMLOG2, IMPOWER, IMPRODUCT, IMREAL, IMSEC, IMSECH, IMSIN, IMSINH, IMSQRT, IMSUB, IMSUM, IMTAN, INDEX, INT, INTERCEPT, IPMT, IRR, ISBLANK, ISDATE, ISERR, ISERROR, ISEVEN, ISLOGICAL, ISNA, ISNONTEXT, ISNUMBER, ISO, ISODD, ISOWEEKNUM, ISPMT, ISTEXT, KURT, LARGE, LCM, LEFT, LEN, LENS, LINEST, LN, LOG, LOG10, LOGEST, LOGINV, LOGNORM, LOGNORMDIST, LOGNORMINV, LOOKUP, LOWER, MATCH, MAX, MAXA, MAXIFS, MEDIAN, MEERKAT, MID, MIN, MINA, MINIFS, MINUS$1 as MINUS, MINUTE, MIRR, MMULT, MOD, MODE, MODEMULT, MODESNGL, MONTH, MROUND, MULTINOMIAL, MUNIT, MYANIMELIST, N, NA, NEGBINOM, NEGBINOMDIST, NETWORKDAYS, NETWORKDAYSINTL, NETWORKDAYS_INTL, NEYNAR, NOMINAL, NORM, NORMDIST, NORMINV, NORMSDIST, NORMSINV, NOT, NOW, NPER, NPV, NUMBERVALUE, OCT2BIN, OCT2DEC, OCT2HEX, ODD, OR, PDURATION, PEARSON, PERCENTILE, PERCENTILEEXC, PERCENTILEINC, PERCENTRANK, PERCENTRANKEXC, PERCENTRANKINC, PERMUT, PERMUTATIONA, PHI, PI, PMT, PNL, POISSON, POISSONDIST, POLYMARKET, POWER, PPMT, PRICEDISC, PRIVACYPOOL, PROB, PRODUCT, PROPER, PV, QUARTILE, QUARTILEEXC, QUARTILEINC, QUOTIENT, RADIANS, RAND, RANDBETWEEN, RANK, RANKAVG, RANKEQ, RATE, REPLACE, REPT, RIGHT, ROMAN, ROTKI, ROUND, ROUNDDOWN, ROUNDUP, ROW, ROWS, RRI, RSQ, SAFE, SEARCH, SEC, SECH, SECOND, SERIESSUM, SIGN, SIN, SINH, SKEW, SKEWP, SLN, SLOPE, SMALL, SORT, SQRT, SQRTPI, STANDARDIZE, STDEV, STDEVA, STDEVP, STDEVPA, STDEVS, STEYX, SUBSTITUTE, SUBTOTAL, SUM, SUMIF, SUMIFS, SUMPRODUCT, SUMSQ, SUMX2MY2, SUMX2PY2, SUMXMY2, SWITCH, SYD, T, TALLY, TAN, TANH, TBILLEQ, TBILLPRICE, TBILLYIELD, TDIST, TDISTRT, TEXT, TEXTJOIN, TIME, TIMEVALUE, TINV, TODAY, TRANSPOSE, TREND, TRIM, TRIMMEAN, TRUE, TRUNC, TTEST, TYPE, UNICHAR, UNICODE, UNIQUE, UNISWAP, UPPER, VALUE, VAR, VARA, VARP, VARPA, VARS, VLOOKUP, WEEKDAY, WEEKNUM, WEIBULL, WEIBULLDIST, WORKDAY, WORKDAYINTL, WORKDAY_INTL, XIRR, XNPV, XOR, YEAR, YEARFRAC, Z, ZTEST, utils };
14395
+ export { AAVE, ABS, ACCRINT, ACOS, ACOSH, ACOT, ACOTH, AGGREGATE, AND, ARABIC, ARTEMIS, ASIN, ASINH, ATAN, ATAN2, ATANH, AVEDEV, AVERAGE, AVERAGEA, AVERAGEIF, AVERAGEIFS, BASE, BESSELI, BESSELJ, BESSELK, BESSELY, BETA, BETADIST, BETAINV, BIN2DEC, BIN2HEX, BIN2OCT, BINOM, BINOMDIST, BITAND, BITLSHIFT, BITOR, BITRSHIFT, BITXOR, BLOCKSCOUT, CEILING, CEILINGMATH, CEILINGPRECISE, CHAR, CHIDIST, CHIDISTRT, CHIINV, CHIINVRT, CHISQ, CHITEST, CHOOSE, CLEAN, CODE, COINGECKO, COLUMN, COLUMNS, COMBIN, COMBINA, COMPLEX, CONCAT, CONCATENATE, CONFIDENCE, CONVERT, CORREL, COS, COSH, COT, COTH, COUNT, COUNTA, COUNTBLANK, COUNTIF, COUNTIFS, COUPDAYS, COVAR, COVARIANCE, COVARIANCEP, COVARIANCES, CRITBINOM, CSC, CSCH, CUMIPMT, CUMPRINC, DATE, DATEDIF, DATEVALUE, DAVERAGE, DAY, DAYS, DAYS360, DB, DCOUNT, DCOUNTA, DDB, DEC2BIN, DEC2HEX, DEC2OCT, DECIMAL, DEFILLAMA, DEGREES, DELTA, DEVSQ, DGET, DISC, DMAX, DMIN, DOLLAR, DOLLARDE, DOLLARFR, DPRODUCT, DSTDEV, DSTDEVP, DSUM, DVAR, DVARP, EDATE, EFFECT, EOA, EOMONTH, ERF, ERFC, ERFCPRECISE, ERFPRECISE, ERROR, ETHERSCAN, EVEN, EXACT, EXP, EXPON, EXPONDIST, F, FACT, FACTDOUBLE, FALSE, FARCASTER, FDIST, FDISTRT, FIND, FINV, FINVRT, FIREFLY, FISHER, FISHERINV, FIXED, FLOOR, FLOORMATH, FLOORPRECISE, FLVURL, FORECAST, FREQUENCY, FTEST, FV, FVSCHEDULE, GAMMA, GAMMADIST, GAMMAINV, GAMMALN, GAMMALNPRECISE, GAUSS, GCD, GEOMEAN, GESTEP, GNOSIS, GROWTH, HARMEAN, HEX2BIN, HEX2DEC, HEX2OCT, HLOOKUP, HOUR, HYPGEOM, HYPGEOMDIST, IF, IFERROR, IFNA, IFS, IMABS, IMAGINARY, IMARGUMENT, IMCONJUGATE, IMCOS, IMCOSH, IMCOT, IMCSC, IMCSCH, IMDIV, IMEXP, IMLN, IMLOG10, IMLOG2, IMPOWER, IMPRODUCT, IMREAL, IMSEC, IMSECH, IMSIN, IMSINH, IMSQRT, IMSUB, IMSUM, IMTAN, INDEX, INT, INTERCEPT, IPMT, IRR, ISBLANK, ISDATE, ISERR, ISERROR, ISEVEN, ISLOGICAL, ISNA, ISNONTEXT, ISNUMBER, ISO, ISODD, ISOWEEKNUM, ISPMT, ISTEXT, KURT, LARGE, LCM, LEFT, LEN, LENS, LINEST, LN, LOG, LOG10, LOGEST, LOGINV, LOGNORM, LOGNORMDIST, LOGNORMINV, LOOKUP, LOWER, MATCH, MAX, MAXA, MAXIFS, MEDIAN, MEERKAT, MID, MIN, MINA, MINIFS, MINUS$1 as MINUS, MINUTE, MIRR, MMULT, MOD, MODE, MODEMULT, MODESNGL, MONTH, MROUND, MULTINOMIAL, MUNIT, MYANIMELIST, N, NA, NEGBINOM, NEGBINOMDIST, NETWORKDAYS, NETWORKDAYSINTL, NETWORKDAYS_INTL, NEYNAR, NOMINAL, NORM, NORMDIST, NORMINV, NORMSDIST, NORMSINV, NOT, NOW, NPER, NPV, NUMBERVALUE, OCT2BIN, OCT2DEC, OCT2HEX, ODD, OR, PDURATION, PEARSON, PERCENTILE, PERCENTILEEXC, PERCENTILEINC, PERCENTRANK, PERCENTRANKEXC, PERCENTRANKINC, PERMUT, PERMUTATIONA, PHI, PI, PMT, PNL, POISSON, POISSONDIST, POLYMARKET, POWER, PPMT, PRICEDISC, PRIVACYPOOL, PROB, PRODUCT, PROPER, PV, QUARTILE, QUARTILEEXC, QUARTILEINC, QUOTIENT, RADIANS, RAND, RANDBETWEEN, RANK, RANKAVG, RANKEQ, RATE, REPLACE, REPT, RIGHT, ROMAN, ROTKI, ROUND, ROUNDDOWN, ROUNDUP, ROW, ROWS, RRI, RSQ, SAFE, SEARCH, SEC, SECH, SECOND, SERIESSUM, SIGN, SIN, SINH, SKEW, SKEWP, SLN, SLOPE, SMALL, SORT, SQRT, SQRTPI, STANDARDIZE, STDEV, STDEVA, STDEVP, STDEVPA, STDEVS, STEYX, SUBSTITUTE, SUBTOTAL, SUM, SUMIF, SUMIFS, SUMPRODUCT, SUMSQ, SUMX2MY2, SUMX2PY2, SUMXMY2, SWITCH, SYD, T, TALLY, TAN, TANH, TBILLEQ, TBILLPRICE, TBILLYIELD, TDIST, TDISTRT, TEXT, TEXTJOIN, TIME, TIMEVALUE, TINV, TODAY, TRANSPOSE, TREND, TRIM, TRIMMEAN, TRUE, TRUNC, TTEST, TYPE, UNICHAR, UNICODE, UNIQUE, UNISWAP, UPPER, VALUE, VAR, VARA, VARP, VARPA, VARS, VLOOKUP, WEEKDAY, WEEKNUM, WEIBULL, WEIBULLDIST, WORKDAY, WORKDAYINTL, WORKDAY_INTL, XIRR, XNPV, XOR, YEAR, YEARFRAC, Z, ZTEST, utils };