@fundtracer/mcp 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fundtracer-mcp.js +8 -386
- package/package.json +1 -1
package/fundtracer-mcp.js
CHANGED
|
@@ -1,12 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
var __defProp = Object.defineProperty;
|
|
3
3
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
-
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
5
|
-
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
6
|
-
}) : x)(function(x) {
|
|
7
|
-
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
8
|
-
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
9
|
-
});
|
|
10
4
|
var __esm = (fn, res) => function __init() {
|
|
11
5
|
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
12
6
|
};
|
|
@@ -15,133 +9,6 @@ var __export = (target, all) => {
|
|
|
15
9
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
16
10
|
};
|
|
17
11
|
|
|
18
|
-
// src/firebase.ts
|
|
19
|
-
var firebase_exports = {};
|
|
20
|
-
__export(firebase_exports, {
|
|
21
|
-
admin: () => admin,
|
|
22
|
-
getAuth: () => getAuth,
|
|
23
|
-
getFirestore: () => getFirestore,
|
|
24
|
-
getUserByAddress: () => getUserByAddress,
|
|
25
|
-
initializeFirebase: () => initializeFirebase,
|
|
26
|
-
updateUserTier: () => updateUserTier
|
|
27
|
-
});
|
|
28
|
-
import admin from "firebase-admin";
|
|
29
|
-
import fs from "fs";
|
|
30
|
-
function initializeFirebase() {
|
|
31
|
-
if (firebaseInitialized) {
|
|
32
|
-
console.log("[Firebase] Already initialized (skipping)");
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
35
|
-
try {
|
|
36
|
-
if (admin.apps.length > 0) {
|
|
37
|
-
console.log("[Firebase] Already initialized by Firebase auto-discovery");
|
|
38
|
-
firebaseInitialized = true;
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
} catch (e) {
|
|
42
|
-
}
|
|
43
|
-
console.log("[Firebase] Starting initialization...");
|
|
44
|
-
const base64ServiceAccount = process.env.FIREBASE_SERVICE_ACCOUNT_BASE64;
|
|
45
|
-
if (base64ServiceAccount) {
|
|
46
|
-
try {
|
|
47
|
-
console.log("[Firebase] Found base64 service account, decoding...");
|
|
48
|
-
const decoded = Buffer.from(base64ServiceAccount, "base64").toString("utf-8");
|
|
49
|
-
const serviceAccount = JSON.parse(decoded);
|
|
50
|
-
admin.initializeApp({
|
|
51
|
-
credential: admin.credential.cert(serviceAccount)
|
|
52
|
-
});
|
|
53
|
-
firebaseInitialized = true;
|
|
54
|
-
console.log("[Firebase] \u2705 Initialized from base64 service account");
|
|
55
|
-
return;
|
|
56
|
-
} catch (error) {
|
|
57
|
-
console.error("[Firebase] Failed to decode base64 service account:", error);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
const credentialsPath = process.env.GOOGLE_APPLICATION_CREDENTIALS;
|
|
61
|
-
console.log("[Firebase] Checking credentials file path:", credentialsPath || "(not set)");
|
|
62
|
-
if (credentialsPath && fs.existsSync(credentialsPath)) {
|
|
63
|
-
try {
|
|
64
|
-
const serviceAccount = JSON.parse(fs.readFileSync(credentialsPath, "utf8"));
|
|
65
|
-
admin.initializeApp({
|
|
66
|
-
credential: admin.credential.cert(serviceAccount)
|
|
67
|
-
});
|
|
68
|
-
firebaseInitialized = true;
|
|
69
|
-
console.log("[Firebase] \u2705 Initialized from credentials file");
|
|
70
|
-
return;
|
|
71
|
-
} catch (error) {
|
|
72
|
-
console.error("[Firebase] Failed to load credentials file:", error);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
const projectId = process.env.FIREBASE_PROJECT_ID;
|
|
76
|
-
const clientEmail = process.env.FIREBASE_CLIENT_EMAIL;
|
|
77
|
-
let privateKey = process.env.FIREBASE_PRIVATE_KEY;
|
|
78
|
-
console.log("[Firebase] Checking env vars...");
|
|
79
|
-
console.log("[Firebase] Project ID:", projectId ? "\u2713 set" : "\u2717 missing");
|
|
80
|
-
console.log("[Firebase] Client Email:", clientEmail ? "\u2713 set" : "\u2717 missing");
|
|
81
|
-
console.log("[Firebase] Private Key:", privateKey ? `\u2713 set (${privateKey.length} chars)` : "\u2717 missing");
|
|
82
|
-
if (privateKey && !privateKey.includes("-----BEGIN")) {
|
|
83
|
-
try {
|
|
84
|
-
console.log("[Firebase] Decoding base64 private key...");
|
|
85
|
-
privateKey = Buffer.from(privateKey, "base64").toString("utf-8");
|
|
86
|
-
} catch (e) {
|
|
87
|
-
console.warn("[Firebase] Failed to decode base64 private key, using as-is");
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
privateKey = privateKey?.replace(/\\n/g, "\n");
|
|
91
|
-
console.log("[Firebase] Private key starts with BEGIN:", privateKey?.includes("-----BEGIN PRIVATE KEY-----"));
|
|
92
|
-
if (!projectId || !clientEmail || !privateKey) {
|
|
93
|
-
const errorMsg = "[Firebase] FATAL: Credentials not configured! Set FIREBASE_SERVICE_ACCOUNT_BASE64 (preferred) or FIREBASE_PROJECT_ID/CLIENT_EMAIL/PRIVATE_KEY.";
|
|
94
|
-
console.error(errorMsg);
|
|
95
|
-
throw new Error(errorMsg);
|
|
96
|
-
}
|
|
97
|
-
try {
|
|
98
|
-
admin.initializeApp({
|
|
99
|
-
credential: admin.credential.cert({
|
|
100
|
-
projectId,
|
|
101
|
-
clientEmail,
|
|
102
|
-
privateKey
|
|
103
|
-
})
|
|
104
|
-
});
|
|
105
|
-
firebaseInitialized = true;
|
|
106
|
-
console.log("Firebase Admin SDK initialized");
|
|
107
|
-
} catch (error) {
|
|
108
|
-
console.error("Failed to initialize Firebase:", error);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
function getAuth() {
|
|
112
|
-
return admin.auth();
|
|
113
|
-
}
|
|
114
|
-
function getFirestore() {
|
|
115
|
-
return admin.firestore();
|
|
116
|
-
}
|
|
117
|
-
async function getUserByAddress(address) {
|
|
118
|
-
const db = getFirestore();
|
|
119
|
-
const userDoc = await db.collection("users").doc(address.toLowerCase()).get();
|
|
120
|
-
if (!userDoc.exists) {
|
|
121
|
-
return null;
|
|
122
|
-
}
|
|
123
|
-
return {
|
|
124
|
-
address: userDoc.id,
|
|
125
|
-
...userDoc.data()
|
|
126
|
-
};
|
|
127
|
-
}
|
|
128
|
-
async function updateUserTier(address, tier, expiresAt) {
|
|
129
|
-
const db = getFirestore();
|
|
130
|
-
const userRef = db.collection("users").doc(address.toLowerCase());
|
|
131
|
-
await userRef.set({
|
|
132
|
-
tier,
|
|
133
|
-
tierExpiresAt: admin.firestore.Timestamp.fromDate(expiresAt),
|
|
134
|
-
updatedAt: admin.firestore.FieldValue.serverTimestamp()
|
|
135
|
-
}, { merge: true });
|
|
136
|
-
console.log(`[Payment] Updated user ${address} to ${tier} tier, expires ${expiresAt.toISOString()}`);
|
|
137
|
-
}
|
|
138
|
-
var firebaseInitialized;
|
|
139
|
-
var init_firebase = __esm({
|
|
140
|
-
"src/firebase.ts"() {
|
|
141
|
-
firebaseInitialized = false;
|
|
142
|
-
}
|
|
143
|
-
});
|
|
144
|
-
|
|
145
12
|
// src/mcp/tools.ts
|
|
146
13
|
var tools_exports = {};
|
|
147
14
|
__export(tools_exports, {
|
|
@@ -3395,251 +3262,6 @@ var init_handlers = __esm({
|
|
|
3395
3262
|
}
|
|
3396
3263
|
});
|
|
3397
3264
|
|
|
3398
|
-
// src/models/apiKey.ts
|
|
3399
|
-
var apiKey_exports = {};
|
|
3400
|
-
__export(apiKey_exports, {
|
|
3401
|
-
API_SCOPES: () => API_SCOPES,
|
|
3402
|
-
TIER_DEFAULT_SCOPES: () => TIER_DEFAULT_SCOPES,
|
|
3403
|
-
TIER_LIMITS: () => TIER_LIMITS,
|
|
3404
|
-
checkRateLimit: () => checkRateLimit,
|
|
3405
|
-
createAPIKey: () => createAPIKey,
|
|
3406
|
-
deactivateAPIKey: () => deactivateAPIKey,
|
|
3407
|
-
generateAPIKey: () => generateAPIKey,
|
|
3408
|
-
generateMcpKey: () => generateMcpKey,
|
|
3409
|
-
getAPIKeyById: () => getAPIKeyById,
|
|
3410
|
-
getUserAPIKeys: () => getUserAPIKeys,
|
|
3411
|
-
hasScope: () => hasScope,
|
|
3412
|
-
hashAPIKey: () => hashAPIKey,
|
|
3413
|
-
incrementAPIKeyUsage: () => incrementAPIKeyUsage,
|
|
3414
|
-
resetDailyUsageIfNeeded: () => resetDailyUsageIfNeeded,
|
|
3415
|
-
updateAPIKeyTier: () => updateAPIKeyTier,
|
|
3416
|
-
validateAPIKey: () => validateAPIKey
|
|
3417
|
-
});
|
|
3418
|
-
import { FieldValue } from "firebase-admin/firestore";
|
|
3419
|
-
function generateAPIKey(type = "live") {
|
|
3420
|
-
const prefix = type === "live" ? "ft_live_" : type === "mcp" ? "ft_mcp_" : "ft_test_";
|
|
3421
|
-
const randomPart = generateSecureRandom(32);
|
|
3422
|
-
return `${prefix}${randomPart}`;
|
|
3423
|
-
}
|
|
3424
|
-
function generateMcpKey() {
|
|
3425
|
-
return generateAPIKey("mcp");
|
|
3426
|
-
}
|
|
3427
|
-
function generateSecureRandom(length) {
|
|
3428
|
-
const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
3429
|
-
const array = new Uint8Array(length);
|
|
3430
|
-
__require("crypto").randomFillSync(array);
|
|
3431
|
-
return Array.from(array, (byte) => chars[byte % chars.length]).join("");
|
|
3432
|
-
}
|
|
3433
|
-
function hashAPIKey(key) {
|
|
3434
|
-
return __require("crypto").createHash("sha256").update(key).digest("hex");
|
|
3435
|
-
}
|
|
3436
|
-
async function createAPIKey(userId, options) {
|
|
3437
|
-
const db = getFirestore();
|
|
3438
|
-
const keyCollection = db.collection("apiKeys");
|
|
3439
|
-
const tier = options.tier || "free";
|
|
3440
|
-
const limits = TIER_LIMITS[tier];
|
|
3441
|
-
const existingKeys = await keyCollection.where("userId", "==", userId).where("isActive", "==", true).get();
|
|
3442
|
-
const currentKeyCount = existingKeys.size;
|
|
3443
|
-
if (limits.maxKeys !== Infinity && currentKeyCount >= limits.maxKeys) {
|
|
3444
|
-
throw new Error(`Maximum API keys (${limits.maxKeys}) reached for ${tier} tier. Upgrade to create more keys.`);
|
|
3445
|
-
}
|
|
3446
|
-
const keyType = options.keyType || "live";
|
|
3447
|
-
const rawKey = generateAPIKey(keyType);
|
|
3448
|
-
const keyHash = hashAPIKey(rawKey);
|
|
3449
|
-
const keyPrefix = rawKey.split("_").slice(0, 2).join("_");
|
|
3450
|
-
const scopes = options.scopes || TIER_DEFAULT_SCOPES[tier];
|
|
3451
|
-
const now = Date.now();
|
|
3452
|
-
const dailyReset = getDailyResetTimestamp();
|
|
3453
|
-
const apiKey = {
|
|
3454
|
-
id: keyCollection.doc().id,
|
|
3455
|
-
userId,
|
|
3456
|
-
keyHash,
|
|
3457
|
-
keyPrefix,
|
|
3458
|
-
keyType,
|
|
3459
|
-
name: options.name,
|
|
3460
|
-
scopes,
|
|
3461
|
-
tier,
|
|
3462
|
-
dailyUsage: 0,
|
|
3463
|
-
dailyUsageReset: dailyReset,
|
|
3464
|
-
lastUsed: now,
|
|
3465
|
-
createdAt: now,
|
|
3466
|
-
isActive: true,
|
|
3467
|
-
expiresAt: options.expiresAt,
|
|
3468
|
-
testnetOnly: options.testnetOnly || false
|
|
3469
|
-
};
|
|
3470
|
-
await keyCollection.doc(apiKey.id).set(apiKey);
|
|
3471
|
-
return { key: apiKey, rawKey };
|
|
3472
|
-
}
|
|
3473
|
-
async function validateAPIKey(rawKey) {
|
|
3474
|
-
const db = getFirestore();
|
|
3475
|
-
const keyCollection = db.collection("apiKeys");
|
|
3476
|
-
const snapshot = await keyCollection.where("isActive", "==", true).get();
|
|
3477
|
-
const keyHash = hashAPIKey(rawKey);
|
|
3478
|
-
for (const doc of snapshot.docs) {
|
|
3479
|
-
const keyData = doc.data();
|
|
3480
|
-
if (keyData.keyHash === keyHash) {
|
|
3481
|
-
if (keyData.expiresAt && keyData.expiresAt < Date.now()) {
|
|
3482
|
-
return null;
|
|
3483
|
-
}
|
|
3484
|
-
return keyData;
|
|
3485
|
-
}
|
|
3486
|
-
}
|
|
3487
|
-
return null;
|
|
3488
|
-
}
|
|
3489
|
-
async function getAPIKeyById(keyId) {
|
|
3490
|
-
const db = getFirestore();
|
|
3491
|
-
const doc = await db.collection("apiKeys").doc(keyId).get();
|
|
3492
|
-
return doc.exists ? doc.data() : null;
|
|
3493
|
-
}
|
|
3494
|
-
async function getUserAPIKeys(userId) {
|
|
3495
|
-
const db = getFirestore();
|
|
3496
|
-
const snapshot = await db.collection("apiKeys").where("userId", "==", userId).orderBy("createdAt", "desc").get();
|
|
3497
|
-
return snapshot.docs.map((doc) => doc.data());
|
|
3498
|
-
}
|
|
3499
|
-
async function incrementAPIKeyUsage(userId, rawKey) {
|
|
3500
|
-
console.log(`[INCREMENT] Starting - userId: ${userId}, rawKey: ${rawKey.substring(0, 15)}...`);
|
|
3501
|
-
const db = getFirestore();
|
|
3502
|
-
const now = Date.now();
|
|
3503
|
-
try {
|
|
3504
|
-
const topLevelRef = db.collection("apiKeys").doc(rawKey);
|
|
3505
|
-
await topLevelRef.update({
|
|
3506
|
-
lastUsed: now,
|
|
3507
|
-
requests: FieldValue.increment(1)
|
|
3508
|
-
});
|
|
3509
|
-
console.log(`[INCREMENT] Updated top-level apiKeys/${rawKey.substring(0, 15)}...`);
|
|
3510
|
-
} catch (err2) {
|
|
3511
|
-
console.error(`[INCREMENT] Failed to update top-level apiKeys doc:`, err2);
|
|
3512
|
-
}
|
|
3513
|
-
try {
|
|
3514
|
-
const subSnapshot = await db.collection("users").doc(userId).collection("apiKeys").where("key", "==", rawKey).limit(1).get();
|
|
3515
|
-
if (!subSnapshot.empty) {
|
|
3516
|
-
const subDoc = subSnapshot.docs[0];
|
|
3517
|
-
await subDoc.ref.update({
|
|
3518
|
-
lastUsed: now,
|
|
3519
|
-
requests: FieldValue.increment(1)
|
|
3520
|
-
});
|
|
3521
|
-
console.log(`[INCREMENT] Updated subcollection doc ${subDoc.id} for key`);
|
|
3522
|
-
} else {
|
|
3523
|
-
console.warn(`[INCREMENT] No subcollection doc found for key ${rawKey.substring(0, 15)}...`);
|
|
3524
|
-
}
|
|
3525
|
-
} catch (err2) {
|
|
3526
|
-
console.error(`[INCREMENT] Failed to update subcollection doc:`, err2);
|
|
3527
|
-
}
|
|
3528
|
-
try {
|
|
3529
|
-
const topLevelDoc = await db.collection("apiKeys").doc(rawKey).get();
|
|
3530
|
-
if (topLevelDoc.exists) {
|
|
3531
|
-
const dailyReset = getDailyResetTimestamp();
|
|
3532
|
-
await topLevelDoc.ref.update({
|
|
3533
|
-
dailyUsage: FieldValue.increment(1),
|
|
3534
|
-
dailyUsageReset: dailyReset
|
|
3535
|
-
});
|
|
3536
|
-
}
|
|
3537
|
-
} catch (err2) {
|
|
3538
|
-
console.error(`[INCREMENT] Failed to update daily usage:`, err2);
|
|
3539
|
-
}
|
|
3540
|
-
console.log(`[INCREMENT] Usage tracking complete for key: ${rawKey.substring(0, 15)}...`);
|
|
3541
|
-
}
|
|
3542
|
-
async function resetDailyUsageIfNeeded(key) {
|
|
3543
|
-
if (key.dailyUsageReset < Date.now()) {
|
|
3544
|
-
const db = getFirestore();
|
|
3545
|
-
await db.collection("apiKeys").doc(key.id).update({
|
|
3546
|
-
dailyUsage: 0,
|
|
3547
|
-
dailyUsageReset: getDailyResetTimestamp()
|
|
3548
|
-
});
|
|
3549
|
-
}
|
|
3550
|
-
}
|
|
3551
|
-
async function checkRateLimit(key) {
|
|
3552
|
-
const limits = TIER_LIMITS[key.tier];
|
|
3553
|
-
const now = Date.now();
|
|
3554
|
-
await resetDailyUsageIfNeeded(key);
|
|
3555
|
-
return {
|
|
3556
|
-
limit: limits.daily,
|
|
3557
|
-
remaining: Math.max(0, limits.daily - key.dailyUsage),
|
|
3558
|
-
reset: key.dailyUsageReset,
|
|
3559
|
-
tier: key.tier
|
|
3560
|
-
};
|
|
3561
|
-
}
|
|
3562
|
-
async function deactivateAPIKey(keyId, userId) {
|
|
3563
|
-
const db = getFirestore();
|
|
3564
|
-
const keyRef = db.collection("apiKeys").doc(keyId);
|
|
3565
|
-
const doc = await keyRef.get();
|
|
3566
|
-
if (!doc.exists || doc.data()?.userId !== userId) {
|
|
3567
|
-
return false;
|
|
3568
|
-
}
|
|
3569
|
-
await keyRef.update({ isActive: false });
|
|
3570
|
-
return true;
|
|
3571
|
-
}
|
|
3572
|
-
function hasScope(key, requiredScope) {
|
|
3573
|
-
if (key.scopes.includes(API_SCOPES.ADMIN)) {
|
|
3574
|
-
return true;
|
|
3575
|
-
}
|
|
3576
|
-
return key.scopes.includes(requiredScope);
|
|
3577
|
-
}
|
|
3578
|
-
function getDailyResetTimestamp() {
|
|
3579
|
-
const now = /* @__PURE__ */ new Date();
|
|
3580
|
-
const tomorrow = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate() + 1));
|
|
3581
|
-
return tomorrow.getTime();
|
|
3582
|
-
}
|
|
3583
|
-
async function updateAPIKeyTier(keyId, updates) {
|
|
3584
|
-
const db = getFirestore();
|
|
3585
|
-
await db.collection("apiKeys").doc(keyId).update({
|
|
3586
|
-
...updates.tier && { tier: updates.tier },
|
|
3587
|
-
...updates.scopes && { scopes: updates.scopes },
|
|
3588
|
-
...updates.expiresAt !== void 0 && { expiresAt: updates.expiresAt }
|
|
3589
|
-
});
|
|
3590
|
-
}
|
|
3591
|
-
var API_SCOPES, TIER_LIMITS, TIER_DEFAULT_SCOPES;
|
|
3592
|
-
var init_apiKey = __esm({
|
|
3593
|
-
"src/models/apiKey.ts"() {
|
|
3594
|
-
init_firebase();
|
|
3595
|
-
API_SCOPES = {
|
|
3596
|
-
READ_ADDRESS: "read:address",
|
|
3597
|
-
READ_TRANSACTIONS: "read:transactions",
|
|
3598
|
-
READ_GRAPH: "read:graph",
|
|
3599
|
-
WRITE_ALERTS: "write:alerts",
|
|
3600
|
-
WRITE_WEBHOOKS: "write:webhooks",
|
|
3601
|
-
ADMIN: "admin",
|
|
3602
|
-
MCP: "mcp"
|
|
3603
|
-
};
|
|
3604
|
-
TIER_LIMITS = {
|
|
3605
|
-
free: {
|
|
3606
|
-
daily: 1e3,
|
|
3607
|
-
perMinute: 100,
|
|
3608
|
-
burst: 200,
|
|
3609
|
-
maxKeys: 2,
|
|
3610
|
-
endpoints: ["address", "transactions", "tokens", "risk"],
|
|
3611
|
-
features: ["basic_address_info", "transaction_history"]
|
|
3612
|
-
},
|
|
3613
|
-
pro: {
|
|
3614
|
-
daily: 1e4,
|
|
3615
|
-
perMinute: 200,
|
|
3616
|
-
burst: 400,
|
|
3617
|
-
maxKeys: 10,
|
|
3618
|
-
endpoints: ["address", "transactions", "tokens", "risk", "graph", "sources", "destinations", "analyze", "entities"],
|
|
3619
|
-
features: ["full_graph_analysis", "async_analysis", "entity_detection"]
|
|
3620
|
-
},
|
|
3621
|
-
enterprise: {
|
|
3622
|
-
daily: 1e5,
|
|
3623
|
-
perMinute: 300,
|
|
3624
|
-
burst: 1e3,
|
|
3625
|
-
maxKeys: Infinity,
|
|
3626
|
-
endpoints: ["*"],
|
|
3627
|
-
features: ["*", "webhooks", "alerts", "websocket", "priority_support"]
|
|
3628
|
-
}
|
|
3629
|
-
};
|
|
3630
|
-
TIER_DEFAULT_SCOPES = {
|
|
3631
|
-
free: [API_SCOPES.READ_ADDRESS, API_SCOPES.READ_TRANSACTIONS],
|
|
3632
|
-
pro: [
|
|
3633
|
-
API_SCOPES.READ_ADDRESS,
|
|
3634
|
-
API_SCOPES.READ_TRANSACTIONS,
|
|
3635
|
-
API_SCOPES.READ_GRAPH,
|
|
3636
|
-
API_SCOPES.WRITE_ALERTS
|
|
3637
|
-
],
|
|
3638
|
-
enterprise: [API_SCOPES.ADMIN]
|
|
3639
|
-
};
|
|
3640
|
-
}
|
|
3641
|
-
});
|
|
3642
|
-
|
|
3643
3265
|
// src/mcp/mcpAuth.ts
|
|
3644
3266
|
var mcpAuth_exports = {};
|
|
3645
3267
|
__export(mcpAuth_exports, {
|
|
@@ -3657,8 +3279,8 @@ async function validateMcpApiKey(rawKey) {
|
|
|
3657
3279
|
return validateViaHttp(rawKey);
|
|
3658
3280
|
}
|
|
3659
3281
|
async function validateWithFirestore(rawKey) {
|
|
3660
|
-
const { getFirestore
|
|
3661
|
-
const db =
|
|
3282
|
+
const { getFirestore } = await import("../firebase.js");
|
|
3283
|
+
const db = getFirestore();
|
|
3662
3284
|
if (!db) return null;
|
|
3663
3285
|
const keyDoc = await db.collection("apiKeys").doc(rawKey).get();
|
|
3664
3286
|
if (keyDoc.exists) {
|
|
@@ -3677,8 +3299,8 @@ async function validateWithFirestore(rawKey) {
|
|
|
3677
3299
|
apiKeyPrefix: rawKey.substring(0, 15)
|
|
3678
3300
|
};
|
|
3679
3301
|
}
|
|
3680
|
-
const { hashAPIKey
|
|
3681
|
-
const keyHash =
|
|
3302
|
+
const { hashAPIKey } = await import("../models/apiKey.js");
|
|
3303
|
+
const keyHash = hashAPIKey(rawKey);
|
|
3682
3304
|
const snapshot = await db.collection("apiKeys").where("isActive", "==", true).get();
|
|
3683
3305
|
for (const doc of snapshot.docs) {
|
|
3684
3306
|
const data = doc.data();
|
|
@@ -3723,8 +3345,8 @@ async function validateViaHttp(rawKey) {
|
|
|
3723
3345
|
}
|
|
3724
3346
|
async function trackUsage(userId, rawKey) {
|
|
3725
3347
|
try {
|
|
3726
|
-
const { incrementAPIKeyUsage
|
|
3727
|
-
await
|
|
3348
|
+
const { incrementAPIKeyUsage } = await import("../models/apiKey.js");
|
|
3349
|
+
await incrementAPIKeyUsage(userId, rawKey);
|
|
3728
3350
|
} catch {
|
|
3729
3351
|
}
|
|
3730
3352
|
}
|
|
@@ -3757,8 +3379,8 @@ dotenv.config();
|
|
|
3757
3379
|
async function main() {
|
|
3758
3380
|
let firebaseAvailable = false;
|
|
3759
3381
|
try {
|
|
3760
|
-
const { initializeFirebase
|
|
3761
|
-
|
|
3382
|
+
const { initializeFirebase } = await import("../firebase.js");
|
|
3383
|
+
initializeFirebase();
|
|
3762
3384
|
firebaseAvailable = true;
|
|
3763
3385
|
console.error("[MCP] Firebase initialized");
|
|
3764
3386
|
} catch (err2) {
|
package/package.json
CHANGED