@fileverse-dev/formulajs 4.4.11-mod-68-patch-7 → 4.4.11-mod-71
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 +333 -429
- package/lib/browser/formula.min.js +2 -2
- package/lib/browser/formula.min.js.map +1 -1
- package/lib/cjs/index.cjs +104 -245
- package/lib/esm/crypto-constants.mjs +2 -2
- package/lib/esm/index.mjs +104 -245
- package/package.json +1 -1
package/lib/cjs/index.cjs
CHANGED
|
@@ -13144,131 +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, 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
|
-
const { URL: finalUrl, HEADERS } = getUrlAndHeaders({ url, serviceName: 'Etherscan', headers: {} });
|
|
13262
|
-
console.log('finalUrl', finalUrl, HEADERS);
|
|
13263
|
-
const res = await fetch(finalUrl, {
|
|
13264
|
-
method: 'GET',
|
|
13265
|
-
headers: HEADERS,
|
|
13266
|
-
});
|
|
13267
|
-
console.log('res', res, finalUrl, HEADERS);
|
|
13268
|
-
const json = await res.json();
|
|
13269
|
-
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);
|
|
13270
13154
|
|
|
13271
|
-
};
|
|
13155
|
+
};
|
|
13272
13156
|
|
|
13273
13157
|
var fromTimestampToBlock = {
|
|
13274
13158
|
fromTimeStampToBlock
|
|
@@ -13405,13 +13289,14 @@ async function handleScanRequest({
|
|
|
13405
13289
|
'all-txns': 'txlist',
|
|
13406
13290
|
'token-txns': 'tokentx',
|
|
13407
13291
|
'nft-txns': 'tokennfttx',
|
|
13408
|
-
gas: '
|
|
13292
|
+
'gas': 'gasoracle'
|
|
13409
13293
|
};
|
|
13410
13294
|
|
|
13411
13295
|
const action = ACTION_MAP[type];
|
|
13412
13296
|
if (!action) throw new ValidationError(`Invalid type: ${type}`)
|
|
13413
13297
|
|
|
13414
|
-
|
|
13298
|
+
const module = action === 'gasoracle' ? 'gastracker' : 'account';
|
|
13299
|
+
let url = `${baseUrl}?chainid=${chainId}&module=${module}&action=${action}&apikey=${apiKey}`;
|
|
13415
13300
|
|
|
13416
13301
|
if (['all-txns', 'token-txns', 'nft-txns'].includes(type)) {
|
|
13417
13302
|
url += `&address=${address}&startblock=0&endblock=99999999&sort=asc`;
|
|
@@ -13425,11 +13310,7 @@ async function handleScanRequest({
|
|
|
13425
13310
|
}
|
|
13426
13311
|
url += `&page=${page}&offset=${offset}`;
|
|
13427
13312
|
}
|
|
13428
|
-
const
|
|
13429
|
-
const res = await fetch(finalUrl, {
|
|
13430
|
-
method: 'GET',
|
|
13431
|
-
headers: HEADERS,
|
|
13432
|
-
});
|
|
13313
|
+
const res = await fetch(url);
|
|
13433
13314
|
if (!res.ok) {
|
|
13434
13315
|
throw new NetworkError(apiInfo.apiKeyName, res.status)
|
|
13435
13316
|
}
|
|
@@ -13444,23 +13325,18 @@ async function handleScanRequest({
|
|
|
13444
13325
|
throw new RateLimitError(apiInfo.apiKeyName)
|
|
13445
13326
|
}
|
|
13446
13327
|
|
|
13447
|
-
return json.result
|
|
13328
|
+
return type === 'gas' && !Array.isArray(json.result) ? [json.result] : json.result
|
|
13448
13329
|
}
|
|
13449
13330
|
|
|
13450
13331
|
const fromUsernameToFid = async (username, apiKey) => {
|
|
13451
|
-
if
|
|
13332
|
+
if(!username) return null
|
|
13452
13333
|
const url = `https://api.neynar.com/v2/farcaster/user/search/?q=${username}&limit=5`;
|
|
13453
|
-
const
|
|
13454
|
-
|
|
13334
|
+
const res = await fetch(url, {
|
|
13335
|
+
headers: {
|
|
13455
13336
|
'x-api-key': apiKey,
|
|
13456
13337
|
'x-neynar-experimental': 'false'
|
|
13457
13338
|
}
|
|
13458
13339
|
});
|
|
13459
|
-
|
|
13460
|
-
const res = await fetch(finalUrl, {
|
|
13461
|
-
method: 'GET',
|
|
13462
|
-
headers: HEADERS,
|
|
13463
|
-
});
|
|
13464
13340
|
const json = await res.json();
|
|
13465
13341
|
const users = json.result ? json.result.users : [];
|
|
13466
13342
|
const user = users.find(user => user.username === username);
|
|
@@ -17473,7 +17349,7 @@ const farcasterSchema = objectType({
|
|
|
17473
17349
|
contentType: enumType(['posts', 'replies', 'channels']),
|
|
17474
17350
|
identifier: stringType().nonempty(),
|
|
17475
17351
|
start: numberType().int().nonnegative().default(0),
|
|
17476
|
-
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),
|
|
17477
17353
|
});
|
|
17478
17354
|
|
|
17479
17355
|
const lensSchema = objectType({
|
|
@@ -17481,7 +17357,7 @@ const lensSchema = objectType({
|
|
|
17481
17357
|
contentType: enumType(['posts', 'replies']),
|
|
17482
17358
|
identifier: stringType().nonempty(),
|
|
17483
17359
|
start: numberType().int().nonnegative().default(0),
|
|
17484
|
-
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),
|
|
17485
17361
|
});
|
|
17486
17362
|
|
|
17487
17363
|
const fireflyParamsSchema = discriminatedUnionType('platform', [
|
|
@@ -17504,31 +17380,33 @@ const lensParamsSchema = objectType({
|
|
|
17504
17380
|
contentType: enumType(['posts', 'replies']),
|
|
17505
17381
|
identifier: stringType().nonempty(),
|
|
17506
17382
|
start: numberType().int().nonnegative().default(0),
|
|
17507
|
-
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),
|
|
17508
17384
|
});
|
|
17509
17385
|
|
|
17510
17386
|
const farcasterParamsSchema = objectType({
|
|
17511
17387
|
contentType: enumType(['posts', 'replies', 'channels']),
|
|
17512
17388
|
identifier: stringType().nonempty(),
|
|
17513
17389
|
start: numberType().int().nonnegative().default(0),
|
|
17514
|
-
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),
|
|
17515
17391
|
});
|
|
17516
17392
|
|
|
17517
17393
|
const dateStringToTimestamp = (val) => {
|
|
17518
|
-
const [
|
|
17519
|
-
|
|
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);
|
|
17520
17398
|
};
|
|
17521
17399
|
|
|
17522
17400
|
/**
|
|
17523
|
-
* Accepts either a UNIX
|
|
17401
|
+
* Accepts either a UNIX timestamp number or a DD/MM/YYYY string,
|
|
17524
17402
|
* and always returns a nonnegative integer timestamp.
|
|
17525
17403
|
*/
|
|
17526
17404
|
const dateOrTimestamp = preprocessType(
|
|
17527
17405
|
(val) =>
|
|
17528
|
-
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)
|
|
17529
17407
|
? dateStringToTimestamp(val)
|
|
17530
17408
|
: val,
|
|
17531
|
-
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' })
|
|
17532
17410
|
);
|
|
17533
17411
|
|
|
17534
17412
|
const blockscoutParamsSchema = objectType({
|
|
@@ -17538,7 +17416,7 @@ const blockscoutParamsSchema = objectType({
|
|
|
17538
17416
|
startTimestamp: dateOrTimestamp.optional(),
|
|
17539
17417
|
endTimestamp: dateOrTimestamp.optional(),
|
|
17540
17418
|
page: numberType().int().nonnegative().default(1),
|
|
17541
|
-
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),
|
|
17542
17420
|
});
|
|
17543
17421
|
|
|
17544
17422
|
const gasSchema$1 = objectType({
|
|
@@ -17546,7 +17424,7 @@ const gasSchema$1 = objectType({
|
|
|
17546
17424
|
startDate: dateOrTimestamp.optional(),
|
|
17547
17425
|
endDate: dateOrTimestamp.optional(),
|
|
17548
17426
|
page: numberType().int().nonnegative().default(1),
|
|
17549
|
-
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),
|
|
17550
17428
|
});
|
|
17551
17429
|
|
|
17552
17430
|
const txnSchema$1 = objectType({
|
|
@@ -17555,7 +17433,7 @@ const txnSchema$1 = objectType({
|
|
|
17555
17433
|
startDate: dateOrTimestamp.optional(),
|
|
17556
17434
|
endDate: dateOrTimestamp.optional(),
|
|
17557
17435
|
page: numberType().int().nonnegative().default(1),
|
|
17558
|
-
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),
|
|
17559
17437
|
});
|
|
17560
17438
|
|
|
17561
17439
|
const baseParamsSchema = discriminatedUnionType('type', [gasSchema$1, txnSchema$1]);
|
|
@@ -17565,7 +17443,7 @@ const gasSchema = objectType({
|
|
|
17565
17443
|
startDate: dateOrTimestamp.optional(),
|
|
17566
17444
|
endDate: dateOrTimestamp.optional(),
|
|
17567
17445
|
page: numberType().int().nonnegative().default(1),
|
|
17568
|
-
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),
|
|
17569
17447
|
});
|
|
17570
17448
|
|
|
17571
17449
|
const txnSchema = objectType({
|
|
@@ -17575,11 +17453,21 @@ const txnSchema = objectType({
|
|
|
17575
17453
|
endDate: dateOrTimestamp.optional(),
|
|
17576
17454
|
chain: enumType(['ethereum','base','gnosis']),
|
|
17577
17455
|
page: numberType().int().nonnegative().default(1),
|
|
17578
|
-
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),
|
|
17579
17457
|
});
|
|
17580
17458
|
|
|
17581
17459
|
const etherscanParamsSchema = discriminatedUnionType('type', [gasSchema, txnSchema]);
|
|
17582
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();
|
|
17583
17471
|
const priceSchema = objectType({
|
|
17584
17472
|
category: literalType('price'),
|
|
17585
17473
|
param1: stringType().nonempty(),
|
|
@@ -17589,13 +17477,13 @@ const marketEcosystems = ['all','base','meme','aiagents','bitcoin','ethereum','h
|
|
|
17589
17477
|
const marketSchema = objectType({
|
|
17590
17478
|
category: literalType('market'),
|
|
17591
17479
|
param1: enumType(marketEcosystems),
|
|
17592
|
-
param2:
|
|
17480
|
+
param2: param2Schema,
|
|
17593
17481
|
});
|
|
17594
17482
|
const stablecoinsTypes = ['all','yield-bearing-stablecoins','crypto-backed-stablecoin'];
|
|
17595
17483
|
const stablecoinsSchema = objectType({
|
|
17596
17484
|
category: literalType('stablecoins'),
|
|
17597
17485
|
param1: enumType(stablecoinsTypes),
|
|
17598
|
-
param2:
|
|
17486
|
+
param2: param2Schema,
|
|
17599
17487
|
});
|
|
17600
17488
|
const derivativesSchema = objectType({
|
|
17601
17489
|
category: literalType('derivatives'),
|
|
@@ -17623,7 +17511,7 @@ const baseSchema = objectType({
|
|
|
17623
17511
|
startTime: dateOrTimestamp.optional(),
|
|
17624
17512
|
endTime: dateOrTimestamp.optional(),
|
|
17625
17513
|
page: numberType().int().nonnegative().default(1),
|
|
17626
|
-
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),
|
|
17627
17515
|
});
|
|
17628
17516
|
|
|
17629
17517
|
const eoaParamsSchema = preprocessType(
|
|
@@ -17652,7 +17540,7 @@ const safeParamsSchema = objectType({
|
|
|
17652
17540
|
address: stringType().nonempty(),
|
|
17653
17541
|
utility: literalType('txns'),
|
|
17654
17542
|
chain: enumType(['ethereum','gnosis']),
|
|
17655
|
-
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),
|
|
17656
17544
|
offset: numberType().int().nonnegative().default(0),
|
|
17657
17545
|
});
|
|
17658
17546
|
|
|
@@ -17688,9 +17576,9 @@ const aaveParamsSchema = objectType({
|
|
|
17688
17576
|
|
|
17689
17577
|
async function FIREFLY() {
|
|
17690
17578
|
try {
|
|
17691
|
-
|
|
17579
|
+
const [platform, contentType, identifier, start = 0, end = 10] = argsToArray(arguments);
|
|
17692
17580
|
|
|
17693
|
-
|
|
17581
|
+
validateParams(fireflyParamsSchema, {
|
|
17694
17582
|
platform,
|
|
17695
17583
|
contentType,
|
|
17696
17584
|
identifier,
|
|
@@ -17712,14 +17600,12 @@ async function FIREFLY() {
|
|
|
17712
17600
|
.filter(Boolean)
|
|
17713
17601
|
.join(',')
|
|
17714
17602
|
);
|
|
17715
|
-
|
|
17716
|
-
|
|
17717
|
-
|
|
17603
|
+
url.searchParams.set('type', fireFlyPlaformType[platform][contentType]);
|
|
17604
|
+
url.searchParams.set('start', String(start));
|
|
17605
|
+
url.searchParams.set('end', String(end));
|
|
17718
17606
|
|
|
17719
|
-
const
|
|
17720
|
-
|
|
17721
|
-
method: 'GET',
|
|
17722
|
-
headers: HEADERS,
|
|
17607
|
+
const response = await fetch(url.toString(), {
|
|
17608
|
+
headers: { 'x-api-key': apiKey }
|
|
17723
17609
|
});
|
|
17724
17610
|
if (!response.ok) {
|
|
17725
17611
|
throw new NetworkError(SERVICES_API_KEY.Firefly, response.status)
|
|
@@ -17777,18 +17663,15 @@ async function LENS() {
|
|
|
17777
17663
|
.join(',')
|
|
17778
17664
|
);
|
|
17779
17665
|
const typeMap = {
|
|
17780
|
-
posts:
|
|
17666
|
+
posts: 'lensid',
|
|
17781
17667
|
replies: 'lenspostid',
|
|
17782
17668
|
};
|
|
17783
17669
|
url.searchParams.set('type', typeMap[contentType]);
|
|
17784
17670
|
url.searchParams.set('start', String(start));
|
|
17785
|
-
url.searchParams.set('end',
|
|
17671
|
+
url.searchParams.set('end', String(end));
|
|
17786
17672
|
|
|
17787
|
-
const
|
|
17788
|
-
|
|
17789
|
-
const response = await fetch(finalUrl, {
|
|
17790
|
-
method: 'GET',
|
|
17791
|
-
headers: HEADERS,
|
|
17673
|
+
const response = await fetch(url.toString(), {
|
|
17674
|
+
headers: { 'x-api-key': apiKey },
|
|
17792
17675
|
});
|
|
17793
17676
|
if (!response.ok) {
|
|
17794
17677
|
throw new NetworkError(SERVICES_API_KEY.Firefly, response.status)
|
|
@@ -17815,7 +17698,7 @@ async function FARCASTER() {
|
|
|
17815
17698
|
try {
|
|
17816
17699
|
const [contentType, identifier, start = 0, end = 10] =
|
|
17817
17700
|
argsToArray(arguments);
|
|
17818
|
-
|
|
17701
|
+
validateParams(farcasterParamsSchema, {
|
|
17819
17702
|
contentType,
|
|
17820
17703
|
identifier,
|
|
17821
17704
|
start,
|
|
@@ -17841,19 +17724,16 @@ async function FARCASTER() {
|
|
|
17841
17724
|
.join(',')
|
|
17842
17725
|
);
|
|
17843
17726
|
const typeMap = {
|
|
17844
|
-
|
|
17845
|
-
|
|
17846
|
-
|
|
17847
|
-
|
|
17727
|
+
posts: 'farcasterid',
|
|
17728
|
+
replies: 'farcasterpostid',
|
|
17729
|
+
channels: 'farcasterchannels',
|
|
17730
|
+
};
|
|
17848
17731
|
url.searchParams.set('type', typeMap[contentType]);
|
|
17849
17732
|
url.searchParams.set('start', String(start));
|
|
17850
|
-
url.searchParams.set('end',
|
|
17851
|
-
|
|
17852
|
-
const { URL: finalUrl, HEADERS } = getUrlAndHeaders({ url: url.toString(), serviceName: 'Firefly', headers });
|
|
17733
|
+
url.searchParams.set('end', String(end));
|
|
17853
17734
|
|
|
17854
|
-
const response = await fetch(
|
|
17855
|
-
|
|
17856
|
-
headers: HEADERS,
|
|
17735
|
+
const response = await fetch(url.toString(), {
|
|
17736
|
+
headers: { 'x-api-key': apiKey },
|
|
17857
17737
|
});
|
|
17858
17738
|
if (!response.ok) {
|
|
17859
17739
|
throw new NetworkError(
|
|
@@ -17962,12 +17842,12 @@ async function BLOCKSCOUT() {
|
|
|
17962
17842
|
}
|
|
17963
17843
|
|
|
17964
17844
|
async function BASE() {
|
|
17965
|
-
|
|
17845
|
+
try {
|
|
17966
17846
|
const [type, address, startDate, endDate, page, limit] = argsToArray(arguments);
|
|
17967
|
-
|
|
17847
|
+
validateParams(baseParamsSchema, { type, address, startDate, endDate, page, limit });
|
|
17968
17848
|
const API_KEY = window.localStorage.getItem(SERVICES_API_KEY.Basescan);
|
|
17969
17849
|
if (!API_KEY) throw new MissingApiKeyError(SERVICES_API_KEY.Basescan)
|
|
17970
|
-
|
|
17850
|
+
|
|
17971
17851
|
return await handleScanRequest({
|
|
17972
17852
|
type,
|
|
17973
17853
|
address,
|
|
@@ -17980,9 +17860,9 @@ async function BASE() {
|
|
|
17980
17860
|
chainId: CHAIN_ID_MAP.base,
|
|
17981
17861
|
network: 'base'
|
|
17982
17862
|
})
|
|
17983
|
-
|
|
17984
|
-
|
|
17985
|
-
|
|
17863
|
+
} catch (error) {
|
|
17864
|
+
return errorMessageHandler(error, 'BASE')
|
|
17865
|
+
}
|
|
17986
17866
|
}
|
|
17987
17867
|
async function GNOSIS() {
|
|
17988
17868
|
try {
|
|
@@ -18023,9 +17903,9 @@ async function GNOSIS() {
|
|
|
18023
17903
|
|
|
18024
17904
|
async function NEYNAR() {
|
|
18025
17905
|
try {
|
|
18026
|
-
|
|
18027
|
-
|
|
18028
|
-
|
|
17906
|
+
const neynarParamsSchema = objectType({
|
|
17907
|
+
username: stringType().nonempty()
|
|
17908
|
+
});
|
|
18029
17909
|
|
|
18030
17910
|
const [username] = argsToArray(arguments);
|
|
18031
17911
|
|
|
@@ -18039,19 +17919,12 @@ async function NEYNAR() {
|
|
|
18039
17919
|
|
|
18040
17920
|
const url = `https://api.neynar.com/v2/farcaster/followers?fid=${fid}`;
|
|
18041
17921
|
|
|
18042
|
-
const
|
|
18043
|
-
|
|
18044
|
-
|
|
18045
|
-
|
|
18046
|
-
'x-neynar-experimental': 'false'
|
|
18047
|
-
}
|
|
17922
|
+
const response = await fetch(url, {
|
|
17923
|
+
headers: {
|
|
17924
|
+
'x-api-key': apiKey,
|
|
17925
|
+
'x-neynar-experimental': 'false',
|
|
18048
17926
|
}
|
|
18049
17927
|
});
|
|
18050
|
-
|
|
18051
|
-
const response = await fetch(finalUrl, {
|
|
18052
|
-
method: 'GET',
|
|
18053
|
-
headers: HEADERS,
|
|
18054
|
-
});
|
|
18055
17928
|
if (!response.ok) {
|
|
18056
17929
|
throw new NetworkError(SERVICES_API_KEY.Neynar, response.status)
|
|
18057
17930
|
}
|
|
@@ -18185,20 +18058,20 @@ async function COINGECKO() {
|
|
|
18185
18058
|
break
|
|
18186
18059
|
}
|
|
18187
18060
|
case 'market': {
|
|
18188
|
-
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' };
|
|
18189
18062
|
const _category = map[param1] || '';
|
|
18190
18063
|
const trend = param2 ? `&price_change_percentage=${param2}` : '';
|
|
18191
|
-
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}`;
|
|
18192
18065
|
break
|
|
18193
18066
|
}
|
|
18194
18067
|
case 'stablecoins': {
|
|
18195
|
-
const _category = param1
|
|
18068
|
+
const _category = param1==='all'? 'stablecoins' : param1;
|
|
18196
18069
|
const trend = param2 ? `&price_change_percentage=${param2}` : '';
|
|
18197
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}`;
|
|
18198
18071
|
break
|
|
18199
18072
|
}
|
|
18200
18073
|
case 'derivatives': {
|
|
18201
|
-
url = (!param1 || param1
|
|
18074
|
+
url = (!param1 || param1==='all')
|
|
18202
18075
|
? 'https://api.coingecko.com/api/v3/derivatives'
|
|
18203
18076
|
: `https://api.coingecko.com/api/v3/derivatives/exchanges/${param1}?include_tickers=all`;
|
|
18204
18077
|
break
|
|
@@ -18213,17 +18086,17 @@ async function COINGECKO() {
|
|
|
18213
18086
|
throw new NetworkError(SERVICES_API_KEY.Coingecko, res.status)
|
|
18214
18087
|
}
|
|
18215
18088
|
|
|
18216
|
-
if (category
|
|
18089
|
+
if (category==='price') {
|
|
18217
18090
|
const out = {};
|
|
18218
18091
|
for (const [token, prices] of Object.entries(json))
|
|
18219
|
-
for (const [cur,
|
|
18220
|
-
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;
|
|
18221
18094
|
return [out]
|
|
18222
18095
|
}
|
|
18223
18096
|
|
|
18224
18097
|
const data = Array.isArray(json) ? json : [json];
|
|
18225
|
-
return data.map(item
|
|
18226
|
-
const flat
|
|
18098
|
+
return data.map(item=>{
|
|
18099
|
+
const flat={};
|
|
18227
18100
|
for (const [key, value] of Object.entries(item)) {
|
|
18228
18101
|
if (typeof value !== 'object' || value === null) {
|
|
18229
18102
|
flat[key] = value;
|
|
@@ -18231,24 +18104,22 @@ async function COINGECKO() {
|
|
|
18231
18104
|
}
|
|
18232
18105
|
return flat
|
|
18233
18106
|
})
|
|
18234
|
-
} catch
|
|
18235
|
-
return errorMessageHandler(err,
|
|
18107
|
+
} catch(err) {
|
|
18108
|
+
return errorMessageHandler(err,'COINGECKO')
|
|
18236
18109
|
}
|
|
18237
18110
|
}
|
|
18238
18111
|
|
|
18239
18112
|
async function EOA() {
|
|
18240
|
-
console.log('EOA');
|
|
18241
18113
|
try {
|
|
18242
18114
|
const [addresses, category, chains, startTime, endTime, page = 1, offset = 10] =
|
|
18243
18115
|
argsToArray(arguments);
|
|
18244
18116
|
validateParams(eoaParamsSchema, { addresses, category, chains, startTime, endTime, page, offset });
|
|
18245
18117
|
|
|
18246
18118
|
const apiKey = window.localStorage.getItem(SERVICES_API_KEY.Etherscan);
|
|
18247
|
-
console.log('apiKey', apiKey);
|
|
18248
18119
|
if (!apiKey) throw new MissingApiKeyError(SERVICES_API_KEY.Etherscan)
|
|
18249
18120
|
|
|
18250
|
-
const INPUTS = addresses.split(',').map(s
|
|
18251
|
-
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);
|
|
18252
18123
|
|
|
18253
18124
|
const ADDRESS_MAP = {};
|
|
18254
18125
|
for (const inp of INPUTS) {
|
|
@@ -18262,16 +18133,10 @@ async function EOA() {
|
|
|
18262
18133
|
}
|
|
18263
18134
|
}
|
|
18264
18135
|
const ADDRS = Object.keys(ADDRESS_MAP);
|
|
18265
|
-
console.log('ADDRS', ADDRS);
|
|
18266
18136
|
const out = [];
|
|
18267
18137
|
|
|
18268
18138
|
async function fetchJSON(url) {
|
|
18269
|
-
const
|
|
18270
|
-
console.log('finalUrl', finalUrl, HEADERS);
|
|
18271
|
-
const res = await fetch(finalUrl, {
|
|
18272
|
-
method: 'GET',
|
|
18273
|
-
headers: HEADERS,
|
|
18274
|
-
});
|
|
18139
|
+
const res = await fetch(url);
|
|
18275
18140
|
if (!res.ok) throw new NetworkError(SERVICES_API_KEY.Etherscan, res.status)
|
|
18276
18141
|
const json = await res.json();
|
|
18277
18142
|
|
|
@@ -18284,38 +18149,32 @@ async function EOA() {
|
|
|
18284
18149
|
|
|
18285
18150
|
|
|
18286
18151
|
for (const chain of CHAINS) {
|
|
18287
|
-
console.log('chain', chain);
|
|
18288
18152
|
const chainId = CHAIN_ID_MAP[chain];
|
|
18289
18153
|
if (!chainId) throw new ValidationError(`Invalid chain: ${chain}`)
|
|
18290
|
-
console.log('chain', chain);
|
|
18291
|
-
|
|
18292
18154
|
|
|
18293
18155
|
if (category === 'balance') {
|
|
18294
|
-
console.log('balance');
|
|
18295
18156
|
// chunk 20
|
|
18296
|
-
for (let i
|
|
18297
|
-
const slice = ADDRS.slice(i,
|
|
18157
|
+
for (let i=0; i<ADDRS.length; i+=20) {
|
|
18158
|
+
const slice = ADDRS.slice(i,i+20).join(',');
|
|
18298
18159
|
const url =
|
|
18299
|
-
`https://api.etherscan.io/v2/api?chainid=${chainId}
|
|
18300
|
-
`&module=account&action=addresstokenbalance&address=${slice}
|
|
18160
|
+
`https://api.etherscan.io/v2/api?chainid=${chainId}`+
|
|
18161
|
+
`&module=account&action=addresstokenbalance&address=${slice}`+
|
|
18301
18162
|
`&page=${page}&offset=${offset}&apikey=${apiKey}`;
|
|
18302
18163
|
const data = await fetchJSON(url);
|
|
18303
18164
|
if (!Array.isArray(data)) return data
|
|
18304
|
-
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 }));
|
|
18305
18166
|
}
|
|
18306
18167
|
} else {
|
|
18307
18168
|
// txns
|
|
18308
|
-
console.log('startTime', startTime, 'endTime', endTime, chain, apiKey);
|
|
18309
18169
|
const sb = await fromTimestampToBlock.fromTimeStampToBlock(toTimestamp(startTime), chain, apiKey);
|
|
18310
18170
|
const eb = await fromTimestampToBlock.fromTimeStampToBlock(toTimestamp(endTime), chain, apiKey);
|
|
18311
|
-
console.log('sb', sb, 'eb', eb);
|
|
18312
18171
|
if (!sb) throw new ValidationError(`Invalid startTime: ${startTime}`)
|
|
18313
18172
|
if (!eb) throw new ValidationError(`Invalid endTime: ${endTime}`)
|
|
18314
18173
|
for (const addr of ADDRS) {
|
|
18315
18174
|
const url =
|
|
18316
|
-
`https://api.etherscan.io/v2/api?chainid=${chainId}
|
|
18317
|
-
`&module=account&action=tokentx&address=${addr}
|
|
18318
|
-
`&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}`+
|
|
18319
18178
|
`&page=${page}&offset=${offset}&sort=asc&apikey=${apiKey}`;
|
|
18320
18179
|
const data = await fetchJSON(url);
|
|
18321
18180
|
if (!Array.isArray(data)) return data
|
|
@@ -18390,20 +18249,20 @@ async function DEFILLAMA() {
|
|
|
18390
18249
|
|
|
18391
18250
|
switch (category) {
|
|
18392
18251
|
case 'protocols':
|
|
18393
|
-
json = Array.isArray(json) ? json.slice(0,
|
|
18252
|
+
json = Array.isArray(json) ? json.slice(0,500) : [];
|
|
18394
18253
|
break
|
|
18395
18254
|
case 'yields':
|
|
18396
|
-
json = Array.isArray(json.data) ? json.data.slice(0,
|
|
18255
|
+
json = Array.isArray(json.data) ? json.data.slice(0,500) : [];
|
|
18397
18256
|
break
|
|
18398
18257
|
case 'dex':
|
|
18399
18258
|
case 'fees':
|
|
18400
|
-
json = Array.isArray(json.protocols) ? json.protocols.slice(0,
|
|
18259
|
+
json = Array.isArray(json.protocols) ? json.protocols.slice(0,500) : [];
|
|
18401
18260
|
break
|
|
18402
18261
|
}
|
|
18403
18262
|
|
|
18404
18263
|
return (Array.isArray(json) ? json : [json]).map(item => {
|
|
18405
18264
|
const out = {};
|
|
18406
|
-
for (const [k,
|
|
18265
|
+
for (const [k,v] of Object.entries(item)) {
|
|
18407
18266
|
if (v === null || typeof v !== 'object') out[k] = v;
|
|
18408
18267
|
}
|
|
18409
18268
|
return out
|
|
@@ -18439,7 +18298,7 @@ async function UNISWAP() {
|
|
|
18439
18298
|
// flatten nested
|
|
18440
18299
|
return json.map(item => {
|
|
18441
18300
|
const flat = {};
|
|
18442
|
-
Object.entries(item).forEach(([k,
|
|
18301
|
+
Object.entries(item).forEach(([k,v]) => {
|
|
18443
18302
|
if (v === null || typeof v !== 'object') flat[k] = v;
|
|
18444
18303
|
});
|
|
18445
18304
|
return flat
|