@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/browser/formula.js +302 -382
- package/lib/browser/formula.min.js +2 -2
- package/lib/browser/formula.min.js.map +1 -1
- package/lib/cjs/index.cjs +104 -232
- package/lib/esm/crypto-constants.mjs +2 -2
- package/lib/esm/index.mjs +104 -232
- package/package.json +1 -1
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
|
-
|
|
13256
|
-
|
|
13257
|
-
|
|
13258
|
-
|
|
13259
|
-
|
|
13260
|
-
|
|
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×tamp=${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: '
|
|
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
|
-
|
|
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
|
|
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
|
|
13332
|
+
if(!username) return null
|
|
13447
13333
|
const url = `https://api.neynar.com/v2/farcaster/user/search/?q=${username}&limit=5`;
|
|
13448
|
-
const
|
|
13449
|
-
|
|
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 [
|
|
17514
|
-
|
|
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 UNIX
|
|
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:
|
|
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:
|
|
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
|
-
|
|
17579
|
+
const [platform, contentType, identifier, start = 0, end = 10] = argsToArray(arguments);
|
|
17687
17580
|
|
|
17688
|
-
|
|
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
|
-
|
|
17711
|
-
|
|
17712
|
-
|
|
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
|
|
17715
|
-
|
|
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:
|
|
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',
|
|
17671
|
+
url.searchParams.set('end', String(end));
|
|
17781
17672
|
|
|
17782
|
-
const
|
|
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
|
-
|
|
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
|
-
|
|
17840
|
-
|
|
17841
|
-
|
|
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',
|
|
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(
|
|
17850
|
-
|
|
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
|
-
|
|
17845
|
+
try {
|
|
17961
17846
|
const [type, address, startDate, endDate, page, limit] = argsToArray(arguments);
|
|
17962
|
-
|
|
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
|
-
|
|
17979
|
-
|
|
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
|
-
|
|
18022
|
-
|
|
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
|
|
18038
|
-
|
|
18039
|
-
|
|
18040
|
-
|
|
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:
|
|
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
|
|
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
|
|
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
|
|
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
|
|
18089
|
+
if (category==='price') {
|
|
18212
18090
|
const out = {};
|
|
18213
18091
|
for (const [token, prices] of Object.entries(json))
|
|
18214
|
-
for (const [cur,
|
|
18215
|
-
out[`${token.charAt(0).toUpperCase()
|
|
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
|
|
18230
|
-
return errorMessageHandler(err,
|
|
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
|
|
18245
|
-
const CHAINS = chains.split(',').map(s
|
|
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
|
|
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
|
|
18286
|
-
const slice = ADDRS.slice(i,
|
|
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
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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: `
|
|
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: `
|
|
296
|
+
example: `50`,
|
|
297
297
|
require: "o",
|
|
298
298
|
type: "number"
|
|
299
299
|
}
|